forked from KolibriOS/kolibrios
sdk: libsupc++ && gcc_eh
git-svn-id: svn://kolibrios.org@4383 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
caec3d3e42
commit
77990d14e3
55
contrib/sdk/sources/gcc_eh/Makefile
Normal file
55
contrib/sdk/sources/gcc_eh/Makefile
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
|
||||||
|
LIBRARY= gcc_eh
|
||||||
|
|
||||||
|
CC=gcc
|
||||||
|
CPP=g++
|
||||||
|
CFLAGS = -U_Win32 -U_WIN32 -U__MINGW32__ -c -O2 -fomit-frame-pointer
|
||||||
|
|
||||||
|
LD = ld
|
||||||
|
|
||||||
|
AR= ar
|
||||||
|
|
||||||
|
STRIP = $(PREFIX)strip
|
||||||
|
|
||||||
|
INCLUDES= -I. -I../newlib/include
|
||||||
|
|
||||||
|
|
||||||
|
LIBS:= -ldll -lc.dll
|
||||||
|
|
||||||
|
|
||||||
|
DEFINES= -DIN_GCC -DUSE_EMUTLS=1
|
||||||
|
|
||||||
|
|
||||||
|
SOURCES = unwind-c.c \
|
||||||
|
unwind-dw2.c \
|
||||||
|
unwind-dw2-fde.c
|
||||||
|
|
||||||
|
|
||||||
|
OBJECTS = $(patsubst %.cc, %.o, $(patsubst %.c, %.o, $(SOURCES)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# targets
|
||||||
|
|
||||||
|
|
||||||
|
all:$(LIBRARY).a
|
||||||
|
|
||||||
|
|
||||||
|
$(LIBRARY).a: $(OBJECTS) Makefile
|
||||||
|
ar cvrs $(LIBRARY).a $(OBJECTS)
|
||||||
|
mv -f $(LIBRARY).a ../../lib
|
||||||
|
|
||||||
|
|
||||||
|
%.o : %.c Makefile
|
||||||
|
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
|
||||||
|
|
||||||
|
%.o : %.cc Makefile
|
||||||
|
$(CPP) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-rm -f *.o
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
423
contrib/sdk/sources/gcc_eh/ansidecl.h
Normal file
423
contrib/sdk/sources/gcc_eh/ansidecl.h
Normal file
@ -0,0 +1,423 @@
|
|||||||
|
/* ANSI and traditional C compatability macros
|
||||||
|
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||||
|
2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
/* ANSI and traditional C compatibility macros
|
||||||
|
|
||||||
|
ANSI C is assumed if __STDC__ is #defined.
|
||||||
|
|
||||||
|
Macro ANSI C definition Traditional C definition
|
||||||
|
----- ---- - ---------- ----------- - ----------
|
||||||
|
ANSI_PROTOTYPES 1 not defined
|
||||||
|
PTR `void *' `char *'
|
||||||
|
PTRCONST `void *const' `char *'
|
||||||
|
LONG_DOUBLE `long double' `double'
|
||||||
|
const not defined `'
|
||||||
|
volatile not defined `'
|
||||||
|
signed not defined `'
|
||||||
|
VA_START(ap, var) va_start(ap, var) va_start(ap)
|
||||||
|
|
||||||
|
Note that it is safe to write "void foo();" indicating a function
|
||||||
|
with no return value, in all K+R compilers we have been able to test.
|
||||||
|
|
||||||
|
For declaring functions with prototypes, we also provide these:
|
||||||
|
|
||||||
|
PARAMS ((prototype))
|
||||||
|
-- for functions which take a fixed number of arguments. Use this
|
||||||
|
when declaring the function. When defining the function, write a
|
||||||
|
K+R style argument list. For example:
|
||||||
|
|
||||||
|
char *strcpy PARAMS ((char *dest, char *source));
|
||||||
|
...
|
||||||
|
char *
|
||||||
|
strcpy (dest, source)
|
||||||
|
char *dest;
|
||||||
|
char *source;
|
||||||
|
{ ... }
|
||||||
|
|
||||||
|
|
||||||
|
VPARAMS ((prototype, ...))
|
||||||
|
-- for functions which take a variable number of arguments. Use
|
||||||
|
PARAMS to declare the function, VPARAMS to define it. For example:
|
||||||
|
|
||||||
|
int printf PARAMS ((const char *format, ...));
|
||||||
|
...
|
||||||
|
int
|
||||||
|
printf VPARAMS ((const char *format, ...))
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
For writing functions which take variable numbers of arguments, we
|
||||||
|
also provide the VA_OPEN, VA_CLOSE, and VA_FIXEDARG macros. These
|
||||||
|
hide the differences between K+R <varargs.h> and C89 <stdarg.h> more
|
||||||
|
thoroughly than the simple VA_START() macro mentioned above.
|
||||||
|
|
||||||
|
VA_OPEN and VA_CLOSE are used *instead of* va_start and va_end.
|
||||||
|
Immediately after VA_OPEN, put a sequence of VA_FIXEDARG calls
|
||||||
|
corresponding to the list of fixed arguments. Then use va_arg
|
||||||
|
normally to get the variable arguments, or pass your va_list object
|
||||||
|
around. You do not declare the va_list yourself; VA_OPEN does it
|
||||||
|
for you.
|
||||||
|
|
||||||
|
Here is a complete example:
|
||||||
|
|
||||||
|
int
|
||||||
|
printf VPARAMS ((const char *format, ...))
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
VA_OPEN (ap, format);
|
||||||
|
VA_FIXEDARG (ap, const char *, format);
|
||||||
|
|
||||||
|
result = vfprintf (stdout, format, ap);
|
||||||
|
VA_CLOSE (ap);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
You can declare variables either before or after the VA_OPEN,
|
||||||
|
VA_FIXEDARG sequence. Also, VA_OPEN and VA_CLOSE are the beginning
|
||||||
|
and end of a block. They must appear at the same nesting level,
|
||||||
|
and any variables declared after VA_OPEN go out of scope at
|
||||||
|
VA_CLOSE. Unfortunately, with a K+R compiler, that includes the
|
||||||
|
argument list. You can have multiple instances of VA_OPEN/VA_CLOSE
|
||||||
|
pairs in a single function in case you need to traverse the
|
||||||
|
argument list more than once.
|
||||||
|
|
||||||
|
For ease of writing code which uses GCC extensions but needs to be
|
||||||
|
portable to other compilers, we provide the GCC_VERSION macro that
|
||||||
|
simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various
|
||||||
|
wrappers around __attribute__. Also, __extension__ will be #defined
|
||||||
|
to nothing if it doesn't work. See below.
|
||||||
|
|
||||||
|
This header also defines a lot of obsolete macros:
|
||||||
|
CONST, VOLATILE, SIGNED, PROTO, EXFUN, DEFUN, DEFUN_VOID,
|
||||||
|
AND, DOTS, NOARGS. Don't use them. */
|
||||||
|
|
||||||
|
#ifndef _ANSIDECL_H
|
||||||
|
#define _ANSIDECL_H 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Every source file includes this file,
|
||||||
|
so they will all get the switch for lint. */
|
||||||
|
/* LINTLIBRARY */
|
||||||
|
|
||||||
|
/* Using MACRO(x,y) in cpp #if conditionals does not work with some
|
||||||
|
older preprocessors. Thus we can't define something like this:
|
||||||
|
|
||||||
|
#define HAVE_GCC_VERSION(MAJOR, MINOR) \
|
||||||
|
(__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR)))
|
||||||
|
|
||||||
|
and then test "#if HAVE_GCC_VERSION(2,7)".
|
||||||
|
|
||||||
|
So instead we use the macro below and test it against specific values. */
|
||||||
|
|
||||||
|
/* This macro simplifies testing whether we are using gcc, and if it
|
||||||
|
is of a particular minimum version. (Both major & minor numbers are
|
||||||
|
significant.) This macro will evaluate to 0 if we are not using
|
||||||
|
gcc at all. */
|
||||||
|
#ifndef GCC_VERSION
|
||||||
|
#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
|
||||||
|
#endif /* GCC_VERSION */
|
||||||
|
|
||||||
|
#if defined (__STDC__) || defined(__cplusplus) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32)
|
||||||
|
/* All known AIX compilers implement these things (but don't always
|
||||||
|
define __STDC__). The RISC/OS MIPS compiler defines these things
|
||||||
|
in SVR4 mode, but does not define __STDC__. */
|
||||||
|
/* eraxxon@alumni.rice.edu: The Compaq C++ compiler, unlike many other
|
||||||
|
C++ compilers, does not define __STDC__, though it acts as if this
|
||||||
|
was so. (Verified versions: 5.7, 6.2, 6.3, 6.5) */
|
||||||
|
|
||||||
|
#define ANSI_PROTOTYPES 1
|
||||||
|
#define PTR void *
|
||||||
|
#define PTRCONST void *const
|
||||||
|
#define LONG_DOUBLE long double
|
||||||
|
|
||||||
|
/* PARAMS is often defined elsewhere (e.g. by libintl.h), so wrap it in
|
||||||
|
a #ifndef. */
|
||||||
|
#ifndef PARAMS
|
||||||
|
#define PARAMS(ARGS) ARGS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define VPARAMS(ARGS) ARGS
|
||||||
|
#define VA_START(VA_LIST, VAR) va_start(VA_LIST, VAR)
|
||||||
|
|
||||||
|
/* variadic function helper macros */
|
||||||
|
/* "struct Qdmy" swallows the semicolon after VA_OPEN/VA_FIXEDARG's
|
||||||
|
use without inhibiting further decls and without declaring an
|
||||||
|
actual variable. */
|
||||||
|
#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP, VAR); { struct Qdmy
|
||||||
|
#define VA_CLOSE(AP) } va_end(AP); }
|
||||||
|
#define VA_FIXEDARG(AP, T, N) struct Qdmy
|
||||||
|
|
||||||
|
#undef const
|
||||||
|
#undef volatile
|
||||||
|
#undef signed
|
||||||
|
|
||||||
|
/* inline requires special treatment; it's in C99, and GCC >=2.7 supports
|
||||||
|
it too, but it's not in C89. */
|
||||||
|
#undef inline
|
||||||
|
#if __STDC_VERSION__ >= 199901L || defined(__cplusplus) || (defined(__SUNPRO_C) && defined(__C99FEATURES__))
|
||||||
|
/* it's a keyword */
|
||||||
|
#else
|
||||||
|
# if GCC_VERSION >= 2007
|
||||||
|
# define inline __inline__ /* __inline__ prevents -pedantic warnings */
|
||||||
|
# else
|
||||||
|
# define inline /* nothing */
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* These are obsolete. Do not use. */
|
||||||
|
#ifndef IN_GCC
|
||||||
|
#define CONST const
|
||||||
|
#define VOLATILE volatile
|
||||||
|
#define SIGNED signed
|
||||||
|
|
||||||
|
#define PROTO(type, name, arglist) type name arglist
|
||||||
|
#define EXFUN(name, proto) name proto
|
||||||
|
#define DEFUN(name, arglist, args) name(args)
|
||||||
|
#define DEFUN_VOID(name) name(void)
|
||||||
|
#define AND ,
|
||||||
|
#define DOTS , ...
|
||||||
|
#define NOARGS void
|
||||||
|
#endif /* ! IN_GCC */
|
||||||
|
|
||||||
|
#else /* Not ANSI C. */
|
||||||
|
|
||||||
|
#undef ANSI_PROTOTYPES
|
||||||
|
#define PTR char *
|
||||||
|
#define PTRCONST PTR
|
||||||
|
#define LONG_DOUBLE double
|
||||||
|
|
||||||
|
#define PARAMS(args) ()
|
||||||
|
#define VPARAMS(args) (va_alist) va_dcl
|
||||||
|
#define VA_START(va_list, var) va_start(va_list)
|
||||||
|
|
||||||
|
#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP); { struct Qdmy
|
||||||
|
#define VA_CLOSE(AP) } va_end(AP); }
|
||||||
|
#define VA_FIXEDARG(AP, TYPE, NAME) TYPE NAME = va_arg(AP, TYPE)
|
||||||
|
|
||||||
|
/* some systems define these in header files for non-ansi mode */
|
||||||
|
#undef const
|
||||||
|
#undef volatile
|
||||||
|
#undef signed
|
||||||
|
#undef inline
|
||||||
|
#define const
|
||||||
|
#define volatile
|
||||||
|
#define signed
|
||||||
|
#define inline
|
||||||
|
|
||||||
|
#ifndef IN_GCC
|
||||||
|
#define CONST
|
||||||
|
#define VOLATILE
|
||||||
|
#define SIGNED
|
||||||
|
|
||||||
|
#define PROTO(type, name, arglist) type name ()
|
||||||
|
#define EXFUN(name, proto) name()
|
||||||
|
#define DEFUN(name, arglist, args) name arglist args;
|
||||||
|
#define DEFUN_VOID(name) name()
|
||||||
|
#define AND ;
|
||||||
|
#define DOTS
|
||||||
|
#define NOARGS
|
||||||
|
#endif /* ! IN_GCC */
|
||||||
|
|
||||||
|
#endif /* ANSI C. */
|
||||||
|
|
||||||
|
/* Define macros for some gcc attributes. This permits us to use the
|
||||||
|
macros freely, and know that they will come into play for the
|
||||||
|
version of gcc in which they are supported. */
|
||||||
|
|
||||||
|
#if (GCC_VERSION < 2007)
|
||||||
|
# define __attribute__(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Attribute __malloc__ on functions was valid as of gcc 2.96. */
|
||||||
|
#ifndef ATTRIBUTE_MALLOC
|
||||||
|
# if (GCC_VERSION >= 2096)
|
||||||
|
# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_MALLOC
|
||||||
|
# endif /* GNUC >= 2.96 */
|
||||||
|
#endif /* ATTRIBUTE_MALLOC */
|
||||||
|
|
||||||
|
/* Attributes on labels were valid as of gcc 2.93 and g++ 4.5. For
|
||||||
|
g++ an attribute on a label must be followed by a semicolon. */
|
||||||
|
#ifndef ATTRIBUTE_UNUSED_LABEL
|
||||||
|
# ifndef __cplusplus
|
||||||
|
# if GCC_VERSION >= 2093
|
||||||
|
# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_UNUSED_LABEL
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# if GCC_VERSION >= 4005
|
||||||
|
# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED ;
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_UNUSED_LABEL
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ATTRIBUTE_UNUSED
|
||||||
|
#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
|
||||||
|
#endif /* ATTRIBUTE_UNUSED */
|
||||||
|
|
||||||
|
/* Before GCC 3.4, the C++ frontend couldn't parse attributes placed after the
|
||||||
|
identifier name. */
|
||||||
|
#if ! defined(__cplusplus) || (GCC_VERSION >= 3004)
|
||||||
|
# define ARG_UNUSED(NAME) NAME ATTRIBUTE_UNUSED
|
||||||
|
#else /* !__cplusplus || GNUC >= 3.4 */
|
||||||
|
# define ARG_UNUSED(NAME) NAME
|
||||||
|
#endif /* !__cplusplus || GNUC >= 3.4 */
|
||||||
|
|
||||||
|
#ifndef ATTRIBUTE_NORETURN
|
||||||
|
#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
|
||||||
|
#endif /* ATTRIBUTE_NORETURN */
|
||||||
|
|
||||||
|
/* Attribute `nonnull' was valid as of gcc 3.3. */
|
||||||
|
#ifndef ATTRIBUTE_NONNULL
|
||||||
|
# if (GCC_VERSION >= 3003)
|
||||||
|
# define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m)))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_NONNULL(m)
|
||||||
|
# endif /* GNUC >= 3.3 */
|
||||||
|
#endif /* ATTRIBUTE_NONNULL */
|
||||||
|
|
||||||
|
/* Attribute `pure' was valid as of gcc 3.0. */
|
||||||
|
#ifndef ATTRIBUTE_PURE
|
||||||
|
# if (GCC_VERSION >= 3000)
|
||||||
|
# define ATTRIBUTE_PURE __attribute__ ((__pure__))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_PURE
|
||||||
|
# endif /* GNUC >= 3.0 */
|
||||||
|
#endif /* ATTRIBUTE_PURE */
|
||||||
|
|
||||||
|
/* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL.
|
||||||
|
This was the case for the `printf' format attribute by itself
|
||||||
|
before GCC 3.3, but as of 3.3 we need to add the `nonnull'
|
||||||
|
attribute to retain this behavior. */
|
||||||
|
#ifndef ATTRIBUTE_PRINTF
|
||||||
|
#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m)
|
||||||
|
#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2)
|
||||||
|
#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3)
|
||||||
|
#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4)
|
||||||
|
#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5)
|
||||||
|
#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6)
|
||||||
|
#endif /* ATTRIBUTE_PRINTF */
|
||||||
|
|
||||||
|
/* Use ATTRIBUTE_FPTR_PRINTF when the format attribute is to be set on
|
||||||
|
a function pointer. Format attributes were allowed on function
|
||||||
|
pointers as of gcc 3.1. */
|
||||||
|
#ifndef ATTRIBUTE_FPTR_PRINTF
|
||||||
|
# if (GCC_VERSION >= 3001)
|
||||||
|
# define ATTRIBUTE_FPTR_PRINTF(m, n) ATTRIBUTE_PRINTF(m, n)
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_FPTR_PRINTF(m, n)
|
||||||
|
# endif /* GNUC >= 3.1 */
|
||||||
|
# define ATTRIBUTE_FPTR_PRINTF_1 ATTRIBUTE_FPTR_PRINTF(1, 2)
|
||||||
|
# define ATTRIBUTE_FPTR_PRINTF_2 ATTRIBUTE_FPTR_PRINTF(2, 3)
|
||||||
|
# define ATTRIBUTE_FPTR_PRINTF_3 ATTRIBUTE_FPTR_PRINTF(3, 4)
|
||||||
|
# define ATTRIBUTE_FPTR_PRINTF_4 ATTRIBUTE_FPTR_PRINTF(4, 5)
|
||||||
|
# define ATTRIBUTE_FPTR_PRINTF_5 ATTRIBUTE_FPTR_PRINTF(5, 6)
|
||||||
|
#endif /* ATTRIBUTE_FPTR_PRINTF */
|
||||||
|
|
||||||
|
/* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL. A
|
||||||
|
NULL format specifier was allowed as of gcc 3.3. */
|
||||||
|
#ifndef ATTRIBUTE_NULL_PRINTF
|
||||||
|
# if (GCC_VERSION >= 3003)
|
||||||
|
# define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_NULL_PRINTF(m, n)
|
||||||
|
# endif /* GNUC >= 3.3 */
|
||||||
|
# define ATTRIBUTE_NULL_PRINTF_1 ATTRIBUTE_NULL_PRINTF(1, 2)
|
||||||
|
# define ATTRIBUTE_NULL_PRINTF_2 ATTRIBUTE_NULL_PRINTF(2, 3)
|
||||||
|
# define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4)
|
||||||
|
# define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5)
|
||||||
|
# define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6)
|
||||||
|
#endif /* ATTRIBUTE_NULL_PRINTF */
|
||||||
|
|
||||||
|
/* Attribute `sentinel' was valid as of gcc 3.5. */
|
||||||
|
#ifndef ATTRIBUTE_SENTINEL
|
||||||
|
# if (GCC_VERSION >= 3005)
|
||||||
|
# define ATTRIBUTE_SENTINEL __attribute__ ((__sentinel__))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_SENTINEL
|
||||||
|
# endif /* GNUC >= 3.5 */
|
||||||
|
#endif /* ATTRIBUTE_SENTINEL */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ATTRIBUTE_ALIGNED_ALIGNOF
|
||||||
|
# if (GCC_VERSION >= 3000)
|
||||||
|
# define ATTRIBUTE_ALIGNED_ALIGNOF(m) __attribute__ ((__aligned__ (__alignof__ (m))))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_ALIGNED_ALIGNOF(m)
|
||||||
|
# endif /* GNUC >= 3.0 */
|
||||||
|
#endif /* ATTRIBUTE_ALIGNED_ALIGNOF */
|
||||||
|
|
||||||
|
/* Useful for structures whose layout must much some binary specification
|
||||||
|
regardless of the alignment and padding qualities of the compiler. */
|
||||||
|
#ifndef ATTRIBUTE_PACKED
|
||||||
|
# define ATTRIBUTE_PACKED __attribute__ ((packed))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Attribute `hot' and `cold' was valid as of gcc 4.3. */
|
||||||
|
#ifndef ATTRIBUTE_COLD
|
||||||
|
# if (GCC_VERSION >= 4003)
|
||||||
|
# define ATTRIBUTE_COLD __attribute__ ((__cold__))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_COLD
|
||||||
|
# endif /* GNUC >= 4.3 */
|
||||||
|
#endif /* ATTRIBUTE_COLD */
|
||||||
|
#ifndef ATTRIBUTE_HOT
|
||||||
|
# if (GCC_VERSION >= 4003)
|
||||||
|
# define ATTRIBUTE_HOT __attribute__ ((__hot__))
|
||||||
|
# else
|
||||||
|
# define ATTRIBUTE_HOT
|
||||||
|
# endif /* GNUC >= 4.3 */
|
||||||
|
#endif /* ATTRIBUTE_HOT */
|
||||||
|
|
||||||
|
/* We use __extension__ in some places to suppress -pedantic warnings
|
||||||
|
about GCC extensions. This feature didn't work properly before
|
||||||
|
gcc 2.8. */
|
||||||
|
#if GCC_VERSION < 2008
|
||||||
|
#define __extension__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This is used to declare a const variable which should be visible
|
||||||
|
outside of the current compilation unit. Use it as
|
||||||
|
EXPORTED_CONST int i = 1;
|
||||||
|
This is because the semantics of const are different in C and C++.
|
||||||
|
"extern const" is permitted in C but it looks strange, and gcc
|
||||||
|
warns about it when -Wc++-compat is not used. */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define EXPORTED_CONST extern const
|
||||||
|
#else
|
||||||
|
#define EXPORTED_CONST const
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ansidecl.h */
|
1911
contrib/sdk/sources/gcc_eh/auto-host.h
Normal file
1911
contrib/sdk/sources/gcc_eh/auto-host.h
Normal file
File diff suppressed because it is too large
Load Diff
62
contrib/sdk/sources/gcc_eh/config/dbxcoff.h
Normal file
62
contrib/sdk/sources/gcc_eh/config/dbxcoff.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/* Definitions needed when using stabs embedded in COFF sections.
|
||||||
|
Copyright (C) 1996, 2004, 2007 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* This file may be included by any COFF target which wishes to
|
||||||
|
support -gstabs generating stabs in sections, as produced by gas
|
||||||
|
and understood by gdb. */
|
||||||
|
|
||||||
|
/* Output DBX (stabs) debugging information if doing -gstabs. */
|
||||||
|
|
||||||
|
#define DBX_DEBUGGING_INFO 1
|
||||||
|
|
||||||
|
/* Generate SDB debugging information by default. */
|
||||||
|
|
||||||
|
#ifndef PREFERRED_DEBUGGING_TYPE
|
||||||
|
#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Be function-relative for block and source line stab directives. */
|
||||||
|
|
||||||
|
#define DBX_BLOCKS_FUNCTION_RELATIVE 1
|
||||||
|
|
||||||
|
/* but, to make this work, functions must appear prior to line info. */
|
||||||
|
|
||||||
|
#define DBX_FUNCTION_FIRST
|
||||||
|
|
||||||
|
/* Generate a blank trailing N_SO to mark the end of the .o file, since
|
||||||
|
we can't depend upon the linker to mark .o file boundaries with
|
||||||
|
embedded stabs. */
|
||||||
|
|
||||||
|
#define DBX_OUTPUT_NULL_N_SO_AT_MAIN_SOURCE_FILE_END
|
||||||
|
|
||||||
|
/* Like block addresses, stabs line numbers are relative to the
|
||||||
|
current function. */
|
||||||
|
|
||||||
|
#define DBX_LINES_FUNCTION_RELATIVE 1
|
||||||
|
|
||||||
|
/* When generating stabs debugging, use N_BINCL entries. */
|
||||||
|
|
||||||
|
#undef DBX_USE_BINCL
|
||||||
|
#define DBX_USE_BINCL
|
||||||
|
|
||||||
|
/* There is no limit to the length of stabs strings. */
|
||||||
|
|
||||||
|
#ifndef DBX_CONTIN_LENGTH
|
||||||
|
#define DBX_CONTIN_LENGTH 0
|
||||||
|
#endif
|
100
contrib/sdk/sources/gcc_eh/config/i386/bsd.h
Normal file
100
contrib/sdk/sources/gcc_eh/config/i386/bsd.h
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/* Definitions for BSD assembler syntax for Intel 386
|
||||||
|
(actually AT&T syntax for insns and operands,
|
||||||
|
adapted to BSD conventions for symbol names and debugging.)
|
||||||
|
Copyright (C) 1988, 1996, 2000, 2002, 2007, 2008
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* Use the Sequent Symmetry assembler syntax. */
|
||||||
|
|
||||||
|
/* Define the syntax of pseudo-ops, labels and comments. */
|
||||||
|
|
||||||
|
/* Prefix for internally generated assembler labels. If we aren't using
|
||||||
|
underscores, we are using prefix `.'s to identify labels that should
|
||||||
|
be ignored, as in `i386/gas.h' --karl@cs.umb.edu */
|
||||||
|
|
||||||
|
#define LPREFIX "L"
|
||||||
|
|
||||||
|
/* Assembler pseudos to introduce constants of various size. */
|
||||||
|
|
||||||
|
#define ASM_BYTE "\t.byte\t"
|
||||||
|
#define ASM_SHORT "\t.word\t"
|
||||||
|
#define ASM_LONG "\t.long\t"
|
||||||
|
#define ASM_QUAD "\t.quad\t" /* Should not be used for 32bit compilation. */
|
||||||
|
|
||||||
|
/* This was suggested, but it shouldn't be right for DBX output. -- RMS
|
||||||
|
#define ASM_OUTPUT_SOURCE_FILENAME(FILE, NAME) */
|
||||||
|
|
||||||
|
|
||||||
|
/* Define the syntax of labels and symbol definitions/declarations. */
|
||||||
|
|
||||||
|
/* This is how to output an assembler line
|
||||||
|
that says to advance the location counter by SIZE bytes. */
|
||||||
|
|
||||||
|
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
|
||||||
|
fprintf (FILE, "\t.space "HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE))
|
||||||
|
|
||||||
|
/* Define the syntax of labels and symbol definitions/declarations. */
|
||||||
|
|
||||||
|
/* This says how to output an assembler line
|
||||||
|
to define a global common symbol. */
|
||||||
|
|
||||||
|
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
|
||||||
|
( fputs (".comm ", (FILE)), \
|
||||||
|
assemble_name ((FILE), (NAME)), \
|
||||||
|
fprintf ((FILE), ",%u\n", (int)(ROUNDED)))
|
||||||
|
|
||||||
|
/* This says how to output an assembler line
|
||||||
|
to define a local common symbol. */
|
||||||
|
|
||||||
|
#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
|
||||||
|
( fputs (".lcomm ", (FILE)), \
|
||||||
|
assemble_name ((FILE), (NAME)), \
|
||||||
|
fprintf ((FILE), ",%u\n", (int)(ROUNDED)))
|
||||||
|
|
||||||
|
#ifdef HAVE_GAS_LCOMM_WITH_ALIGNMENT
|
||||||
|
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGNMENT) \
|
||||||
|
( fputs (".lcomm ", (FILE)), \
|
||||||
|
assemble_name ((FILE), (NAME)), \
|
||||||
|
fprintf ((FILE), ",%u,%u\n", (int)(SIZE), (int)(ALIGNMENT) / BITS_PER_UNIT))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This is how to output an assembler line
|
||||||
|
that says to advance the location counter
|
||||||
|
to a multiple of 2**LOG bytes. */
|
||||||
|
|
||||||
|
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
|
||||||
|
if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", (LOG))
|
||||||
|
|
||||||
|
/* This is how to store into the string BUF
|
||||||
|
the symbol_ref name of an internal numbered label where
|
||||||
|
PREFIX is the class of label and NUM is the number within the class.
|
||||||
|
This is suitable for output with `assemble_name'. */
|
||||||
|
|
||||||
|
#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \
|
||||||
|
sprintf ((BUF), "*%s%ld", (PREFIX), (long)(NUMBER))
|
||||||
|
|
||||||
|
/* The prefix to add to user-visible assembler symbols. */
|
||||||
|
|
||||||
|
#define USER_LABEL_PREFIX "_"
|
||||||
|
|
||||||
|
/* Sequent has some changes in the format of DBX symbols. */
|
||||||
|
#define DBX_NO_XREFS 1
|
||||||
|
|
||||||
|
/* Don't split DBX symbols into continuations. */
|
||||||
|
#define DBX_CONTIN_LENGTH 0
|
448
contrib/sdk/sources/gcc_eh/config/i386/cygming.h
Normal file
448
contrib/sdk/sources/gcc_eh/config/i386/cygming.h
Normal file
@ -0,0 +1,448 @@
|
|||||||
|
/* Operating system specific defines to be used when targeting GCC for
|
||||||
|
hosting on Windows32, using a Unix style C library and tools.
|
||||||
|
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
|
||||||
|
2004, 2005, 2007, 2008, 2009, 2010
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#define DBX_DEBUGGING_INFO 1
|
||||||
|
#define SDB_DEBUGGING_INFO 1
|
||||||
|
#if TARGET_64BIT_DEFAULT || defined (HAVE_GAS_PE_SECREL32_RELOC)
|
||||||
|
#define DWARF2_DEBUGGING_INFO 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef PREFERRED_DEBUGGING_TYPE
|
||||||
|
#if (DWARF2_DEBUGGING_INFO)
|
||||||
|
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
|
||||||
|
#else
|
||||||
|
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef TARGET_64BIT_MS_ABI
|
||||||
|
#define TARGET_64BIT_MS_ABI (!cfun ? ix86_abi == MS_ABI : TARGET_64BIT && cfun->machine->call_abi == MS_ABI)
|
||||||
|
|
||||||
|
#undef DEFAULT_ABI
|
||||||
|
#define DEFAULT_ABI (TARGET_64BIT ? MS_ABI : SYSV_ABI)
|
||||||
|
|
||||||
|
#if ! defined (USE_MINGW64_LEADING_UNDERSCORES)
|
||||||
|
#undef USER_LABEL_PREFIX
|
||||||
|
#define USER_LABEL_PREFIX (TARGET_64BIT ? "" : "_")
|
||||||
|
|
||||||
|
#undef LOCAL_LABEL_PREFIX
|
||||||
|
#define LOCAL_LABEL_PREFIX (TARGET_64BIT ? "." : "")
|
||||||
|
|
||||||
|
#undef ASM_GENERATE_INTERNAL_LABEL
|
||||||
|
#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \
|
||||||
|
sprintf ((BUF), "*%s%s%ld", LOCAL_LABEL_PREFIX, \
|
||||||
|
(PREFIX), (long)(NUMBER))
|
||||||
|
|
||||||
|
#undef LPREFIX
|
||||||
|
#define LPREFIX (TARGET_64BIT ? ".L" : "L")
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef DBX_REGISTER_NUMBER
|
||||||
|
#define DBX_REGISTER_NUMBER(n) \
|
||||||
|
(TARGET_64BIT ? dbx64_register_map[n] \
|
||||||
|
: (write_symbols == DWARF2_DEBUG \
|
||||||
|
? svr4_dbx_register_map[n] : dbx_register_map[n]))
|
||||||
|
|
||||||
|
/* Map gcc register number to DWARF 2 CFA column number. For 32 bit
|
||||||
|
target, always use the svr4_dbx_register_map for DWARF .eh_frame
|
||||||
|
even if we don't use DWARF .debug_frame. */
|
||||||
|
#undef DWARF_FRAME_REGNUM
|
||||||
|
#define DWARF_FRAME_REGNUM(n) \
|
||||||
|
(TARGET_64BIT ? dbx64_register_map[(n)] \
|
||||||
|
: svr4_dbx_register_map[(n)])
|
||||||
|
|
||||||
|
#ifdef HAVE_GAS_PE_SECREL32_RELOC
|
||||||
|
/* Use section relative relocations for debugging offsets. Unlike
|
||||||
|
other targets that fake this by putting the section VMA at 0, PE
|
||||||
|
won't allow it. */
|
||||||
|
#define ASM_OUTPUT_DWARF_OFFSET(FILE, SIZE, LABEL, SECTION) \
|
||||||
|
do { \
|
||||||
|
switch (SIZE) \
|
||||||
|
{ \
|
||||||
|
case 4: \
|
||||||
|
fputs ("\t.secrel32\t", FILE); \
|
||||||
|
assemble_name (FILE, LABEL); \
|
||||||
|
break; \
|
||||||
|
case 8: \
|
||||||
|
/* This is a hack. There is no 64-bit section relative \
|
||||||
|
relocation. However, the COFF format also does not \
|
||||||
|
support 64-bit file offsets; 64-bit applications are \
|
||||||
|
limited to 32-bits of code+data in any one module. \
|
||||||
|
Fake the 64-bit offset by zero-extending it. */ \
|
||||||
|
fputs ("\t.secrel32\t", FILE); \
|
||||||
|
assemble_name (FILE, LABEL); \
|
||||||
|
fputs ("\n\t.long\t0", FILE); \
|
||||||
|
break; \
|
||||||
|
default: \
|
||||||
|
gcc_unreachable (); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TARGET_EXECUTABLE_SUFFIX ".exe"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define TARGET_OS_CPP_BUILTINS() \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (!TARGET_64BIT) \
|
||||||
|
builtin_define ("_X86_=1"); \
|
||||||
|
builtin_assert ("system=winnt"); \
|
||||||
|
builtin_define ("__stdcall=__attribute__((__stdcall__))"); \
|
||||||
|
builtin_define ("__fastcall=__attribute__((__fastcall__))"); \
|
||||||
|
builtin_define ("__cdecl=__attribute__((__cdecl__))"); \
|
||||||
|
if (!flag_iso) \
|
||||||
|
{ \
|
||||||
|
builtin_define ("_stdcall=__attribute__((__stdcall__))"); \
|
||||||
|
builtin_define ("_fastcall=__attribute__((__fastcall__))"); \
|
||||||
|
builtin_define ("_cdecl=__attribute__((__cdecl__))"); \
|
||||||
|
} \
|
||||||
|
/* Even though linkonce works with static libs, this is needed \
|
||||||
|
to compare typeinfo symbols across dll boundaries. */ \
|
||||||
|
builtin_define ("__GXX_MERGED_TYPEINFO_NAMES=0"); \
|
||||||
|
builtin_define ("__GXX_TYPEINFO_EQUALITY_INLINE=0"); \
|
||||||
|
EXTRA_OS_CPP_BUILTINS (); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
/* Get tree.c to declare a target-specific specialization of
|
||||||
|
merge_decl_attributes. */
|
||||||
|
#define TARGET_DLLIMPORT_DECL_ATTRIBUTES 1
|
||||||
|
|
||||||
|
/* This macro defines names of additional specifications to put in the specs
|
||||||
|
that can be used in various specifications like CC1_SPEC. Its definition
|
||||||
|
is an initializer with a subgrouping for each command option.
|
||||||
|
|
||||||
|
Each subgrouping contains a string constant, that defines the
|
||||||
|
specification name, and a string constant that used by the GCC driver
|
||||||
|
program.
|
||||||
|
|
||||||
|
Do not define this macro if it does not need to do anything. */
|
||||||
|
|
||||||
|
#undef SUBTARGET_EXTRA_SPECS
|
||||||
|
#define SUBTARGET_EXTRA_SPECS \
|
||||||
|
{ "mingw_include_path", DEFAULT_TARGET_MACHINE }
|
||||||
|
|
||||||
|
#undef MATH_LIBRARY
|
||||||
|
#define MATH_LIBRARY ""
|
||||||
|
|
||||||
|
#define SIZE_TYPE (TARGET_64BIT ? "long long unsigned int" : "unsigned int")
|
||||||
|
#define PTRDIFF_TYPE (TARGET_64BIT ? "long long int" : "int")
|
||||||
|
|
||||||
|
#define WCHAR_TYPE_SIZE 16
|
||||||
|
#define WCHAR_TYPE "short unsigned int"
|
||||||
|
|
||||||
|
/* Windows64 continues to use a 32-bit long type. */
|
||||||
|
#undef LONG_TYPE_SIZE
|
||||||
|
#define LONG_TYPE_SIZE 32
|
||||||
|
|
||||||
|
/* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop). */
|
||||||
|
#define HANDLE_PRAGMA_PACK_PUSH_POP 1
|
||||||
|
|
||||||
|
union tree_node;
|
||||||
|
#define TREE union tree_node *
|
||||||
|
|
||||||
|
#define drectve_section() \
|
||||||
|
(fprintf (asm_out_file, "\t.section .drectve\n"), \
|
||||||
|
in_section = NULL)
|
||||||
|
|
||||||
|
/* Older versions of gas don't handle 'r' as data.
|
||||||
|
Explicitly set data flag with 'd'. */
|
||||||
|
#define READONLY_DATA_SECTION_ASM_OP "\t.section .rdata,\"dr\""
|
||||||
|
|
||||||
|
/* Don't allow flag_pic to propagate since gas may produce invalid code
|
||||||
|
otherwise. */
|
||||||
|
|
||||||
|
#undef SUBTARGET_OVERRIDE_OPTIONS
|
||||||
|
#define SUBTARGET_OVERRIDE_OPTIONS \
|
||||||
|
do { \
|
||||||
|
if (TARGET_64BIT && flag_pic != 1) \
|
||||||
|
{ \
|
||||||
|
if (flag_pic > 1) \
|
||||||
|
warning (0, \
|
||||||
|
"-fPIC ignored for target (all code is position independent)"\
|
||||||
|
); \
|
||||||
|
flag_pic = 1; \
|
||||||
|
} \
|
||||||
|
else if (!TARGET_64BIT && flag_pic) \
|
||||||
|
{ \
|
||||||
|
warning (0, "-f%s ignored for target (all code is position independent)",\
|
||||||
|
(flag_pic > 1) ? "PIC" : "pic"); \
|
||||||
|
flag_pic = 0; \
|
||||||
|
} \
|
||||||
|
} while (0) \
|
||||||
|
|
||||||
|
/* Define this macro if references to a symbol must be treated
|
||||||
|
differently depending on something about the variable or
|
||||||
|
function named by the symbol (such as what section it is in).
|
||||||
|
|
||||||
|
On i386 running Windows NT, modify the assembler name with a suffix
|
||||||
|
consisting of an atsign (@) followed by string of digits that represents
|
||||||
|
the number of bytes of arguments passed to the function, if it has the
|
||||||
|
attribute STDCALL.
|
||||||
|
|
||||||
|
In addition, we must mark dll symbols specially. Definitions of
|
||||||
|
dllexport'd objects install some info in the .drectve section.
|
||||||
|
References to dllimport'd objects are fetched indirectly via
|
||||||
|
_imp__. If both are declared, dllexport overrides. This is also
|
||||||
|
needed to implement one-only vtables: they go into their own
|
||||||
|
section and we need to set DECL_SECTION_NAME so we do that here.
|
||||||
|
Note that we can be called twice on the same decl. */
|
||||||
|
|
||||||
|
#define SUBTARGET_ENCODE_SECTION_INFO i386_pe_encode_section_info
|
||||||
|
|
||||||
|
/* Output a common block. */
|
||||||
|
#undef ASM_OUTPUT_ALIGNED_DECL_COMMON
|
||||||
|
#define ASM_OUTPUT_ALIGNED_DECL_COMMON \
|
||||||
|
i386_pe_asm_output_aligned_decl_common
|
||||||
|
|
||||||
|
/* Output the label for an initialized variable. */
|
||||||
|
#undef ASM_DECLARE_OBJECT_NAME
|
||||||
|
#define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \
|
||||||
|
do { \
|
||||||
|
i386_pe_maybe_record_exported_symbol (DECL, NAME, 1); \
|
||||||
|
ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Output a reference to a label. Fastcall function symbols
|
||||||
|
keep their '@' prefix, while other symbols are prefixed
|
||||||
|
with user_label_prefix. */
|
||||||
|
#undef ASM_OUTPUT_LABELREF
|
||||||
|
#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
|
||||||
|
do { \
|
||||||
|
if ((NAME)[0] != FASTCALL_PREFIX) \
|
||||||
|
fputs (user_label_prefix, (STREAM)); \
|
||||||
|
fputs ((NAME), (STREAM)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
/* Emit code to check the stack when allocating more than 4000
|
||||||
|
bytes in one go. */
|
||||||
|
#define CHECK_STACK_LIMIT 4000
|
||||||
|
|
||||||
|
#undef STACK_BOUNDARY
|
||||||
|
#define STACK_BOUNDARY (ix86_abi == MS_ABI ? 128 : BITS_PER_WORD)
|
||||||
|
|
||||||
|
/* By default, target has a 80387, uses IEEE compatible arithmetic,
|
||||||
|
returns float values in the 387 and needs stack probes.
|
||||||
|
We also align doubles to 64-bits for MSVC default compatibility. */
|
||||||
|
|
||||||
|
#undef TARGET_SUBTARGET_DEFAULT
|
||||||
|
#define TARGET_SUBTARGET_DEFAULT \
|
||||||
|
(MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS \
|
||||||
|
| MASK_STACK_PROBE | MASK_ALIGN_DOUBLE)
|
||||||
|
|
||||||
|
#undef TARGET_SUBTARGET64_DEFAULT
|
||||||
|
#define TARGET_SUBTARGET64_DEFAULT \
|
||||||
|
MASK_128BIT_LONG_DOUBLE
|
||||||
|
|
||||||
|
/* This is how to output an assembler line
|
||||||
|
that says to advance the location counter
|
||||||
|
to a multiple of 2**LOG bytes. */
|
||||||
|
|
||||||
|
#undef ASM_OUTPUT_ALIGN
|
||||||
|
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
|
||||||
|
if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG))
|
||||||
|
|
||||||
|
/* Windows uses explicit import from shared libraries. */
|
||||||
|
#define MULTIPLE_SYMBOL_SPACES 1
|
||||||
|
|
||||||
|
#define TARGET_ASM_UNIQUE_SECTION i386_pe_unique_section
|
||||||
|
#define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
|
||||||
|
|
||||||
|
#define SUPPORTS_ONE_ONLY 1
|
||||||
|
|
||||||
|
/* Switch into a generic section. */
|
||||||
|
#define TARGET_ASM_NAMED_SECTION i386_pe_asm_named_section
|
||||||
|
|
||||||
|
/* Select attributes for named sections. */
|
||||||
|
#define TARGET_SECTION_TYPE_FLAGS i386_pe_section_type_flags
|
||||||
|
|
||||||
|
/* Write the extra assembler code needed to declare a function
|
||||||
|
properly. If we are generating SDB debugging information, this
|
||||||
|
will happen automatically, so we only need to handle other cases. */
|
||||||
|
#undef ASM_DECLARE_FUNCTION_NAME
|
||||||
|
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
i386_pe_maybe_record_exported_symbol (DECL, NAME, 0); \
|
||||||
|
if (write_symbols != SDB_DEBUG) \
|
||||||
|
i386_pe_declare_function_type (FILE, NAME, TREE_PUBLIC (DECL)); \
|
||||||
|
ASM_OUTPUT_LABEL (FILE, NAME); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
/* Add an external function to the list of functions to be declared at
|
||||||
|
the end of the file. */
|
||||||
|
#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (TREE_CODE (DECL) == FUNCTION_DECL) \
|
||||||
|
i386_pe_record_external_function ((DECL), (NAME)); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
/* Declare the type properly for any external libcall. */
|
||||||
|
#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
|
||||||
|
i386_pe_declare_function_type (FILE, XSTR (FUN, 0), 1)
|
||||||
|
|
||||||
|
/* This says out to put a global symbol in the BSS section. */
|
||||||
|
#undef ASM_OUTPUT_ALIGNED_BSS
|
||||||
|
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
|
||||||
|
asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
|
||||||
|
|
||||||
|
/* Output function declarations at the end of the file. */
|
||||||
|
#undef TARGET_ASM_FILE_END
|
||||||
|
#define TARGET_ASM_FILE_END i386_pe_file_end
|
||||||
|
|
||||||
|
#undef ASM_COMMENT_START
|
||||||
|
#define ASM_COMMENT_START " #"
|
||||||
|
|
||||||
|
#ifndef DWARF2_UNWIND_INFO
|
||||||
|
/* If configured with --disable-sjlj-exceptions, use DWARF2, else
|
||||||
|
default to SJLJ. */
|
||||||
|
#if (defined (CONFIG_SJLJ_EXCEPTIONS) && !CONFIG_SJLJ_EXCEPTIONS)
|
||||||
|
/* The logic of this #if must be kept synchronised with the logic
|
||||||
|
for selecting the tmake_eh_file fragment in config.gcc. */
|
||||||
|
#define DWARF2_UNWIND_INFO 1
|
||||||
|
/* If multilib is selected break build as sjlj is required. */
|
||||||
|
#if defined (TARGET_BI_ARCH)
|
||||||
|
#error For 64-bit windows and 32-bit based multilib version of gcc just SJLJ exceptions are supported.
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define DWARF2_UNWIND_INFO 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Don't assume anything about the header files. */
|
||||||
|
#define NO_IMPLICIT_EXTERN_C
|
||||||
|
|
||||||
|
#undef PROFILE_HOOK
|
||||||
|
#define PROFILE_HOOK(LABEL) \
|
||||||
|
if (MAIN_NAME_P (DECL_NAME (current_function_decl))) \
|
||||||
|
{ \
|
||||||
|
emit_call_insn (gen_rtx_CALL (VOIDmode, \
|
||||||
|
gen_rtx_MEM (FUNCTION_MODE, \
|
||||||
|
gen_rtx_SYMBOL_REF (Pmode, "_monstartup")), \
|
||||||
|
const0_rtx)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Java Native Interface (JNI) methods on Win32 are invoked using the
|
||||||
|
stdcall calling convention. */
|
||||||
|
#undef MODIFY_JNI_METHOD_CALL
|
||||||
|
#define MODIFY_JNI_METHOD_CALL(MDECL) \
|
||||||
|
build_type_attribute_variant ((MDECL), \
|
||||||
|
build_tree_list (get_identifier ("stdcall"), \
|
||||||
|
NULL))
|
||||||
|
|
||||||
|
/* For Win32 ABI compatibility */
|
||||||
|
#undef DEFAULT_PCC_STRUCT_RETURN
|
||||||
|
#define DEFAULT_PCC_STRUCT_RETURN 0
|
||||||
|
|
||||||
|
/* MSVC returns aggregate types of up to 8 bytes via registers.
|
||||||
|
See i386.c:ix86_return_in_memory. */
|
||||||
|
#undef MS_AGGREGATE_RETURN
|
||||||
|
#define MS_AGGREGATE_RETURN 1
|
||||||
|
|
||||||
|
/* Biggest alignment supported by the object file format of this
|
||||||
|
machine. Use this macro to limit the alignment which can be
|
||||||
|
specified using the `__attribute__ ((aligned (N)))' construct. If
|
||||||
|
not defined, the default value is `BIGGEST_ALIGNMENT'. */
|
||||||
|
/* IMAGE_SCN_ALIGN_8192BYTES is the largest section alignment flag
|
||||||
|
specified in the PECOFF60 spec. Native MS compiler also limits
|
||||||
|
user-specified alignment to 8192 bytes. */
|
||||||
|
#undef MAX_OFILE_ALIGNMENT
|
||||||
|
#define MAX_OFILE_ALIGNMENT (8192 * 8)
|
||||||
|
|
||||||
|
/* BIGGEST_FIELD_ALIGNMENT macro is used directly by libobjc, There, we
|
||||||
|
align internal doubles in structures on dword boundaries. Otherwise,
|
||||||
|
support vector modes using ADJUST_FIELD_ALIGN, defined in i386.h. */
|
||||||
|
#ifdef IN_TARGET_LIBS
|
||||||
|
#undef BIGGEST_FIELD_ALIGNMENT
|
||||||
|
#define BIGGEST_FIELD_ALIGNMENT 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* A bit-field declared as `int' forces `int' alignment for the struct. */
|
||||||
|
#undef PCC_BITFIELD_TYPE_MATTERS
|
||||||
|
#define PCC_BITFIELD_TYPE_MATTERS 1
|
||||||
|
#define GROUP_BITFIELDS_BY_ALIGN TYPE_NATIVE(rec)
|
||||||
|
|
||||||
|
/* Enable alias attribute support. */
|
||||||
|
#ifndef SET_ASM_OP
|
||||||
|
#define SET_ASM_OP "\t.set\t"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This implements the `alias' attribute, keeping any stdcall or
|
||||||
|
fastcall decoration. */
|
||||||
|
#undef ASM_OUTPUT_DEF_FROM_DECLS
|
||||||
|
#define ASM_OUTPUT_DEF_FROM_DECLS(STREAM, DECL, TARGET) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
const char *alias \
|
||||||
|
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \
|
||||||
|
i386_pe_maybe_record_exported_symbol (DECL, alias, 0); \
|
||||||
|
if (TREE_CODE (DECL) == FUNCTION_DECL) \
|
||||||
|
i386_pe_declare_function_type (STREAM, alias, \
|
||||||
|
TREE_PUBLIC (DECL)); \
|
||||||
|
ASM_OUTPUT_DEF (STREAM, alias, IDENTIFIER_POINTER (TARGET)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* GNU as supports weak symbols on PECOFF. */
|
||||||
|
#ifdef HAVE_GAS_WEAK
|
||||||
|
#define ASM_WEAKEN_LABEL(FILE, NAME) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
fputs ("\t.weak\t", (FILE)); \
|
||||||
|
assemble_name ((FILE), (NAME)); \
|
||||||
|
fputc ('\n', (FILE)); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
#endif /* HAVE_GAS_WEAK */
|
||||||
|
|
||||||
|
/* FIXME: SUPPORTS_WEAK && TARGET_HAVE_NAMED_SECTIONS is true,
|
||||||
|
but for .jcr section to work we also need crtbegin and crtend
|
||||||
|
objects. */
|
||||||
|
#define TARGET_USE_JCR_SECTION 1
|
||||||
|
|
||||||
|
/* Decide whether it is safe to use a local alias for a virtual function
|
||||||
|
when constructing thunks. */
|
||||||
|
#undef TARGET_USE_LOCAL_THUNK_ALIAS_P
|
||||||
|
#define TARGET_USE_LOCAL_THUNK_ALIAS_P(DECL) (!DECL_ONE_ONLY (DECL))
|
||||||
|
|
||||||
|
#define SUBTARGET_ATTRIBUTE_TABLE \
|
||||||
|
{ "selectany", 0, 0, true, false, false, ix86_handle_selectany_attribute }
|
||||||
|
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
|
||||||
|
|
||||||
|
/* mcount() does not need a counter variable. */
|
||||||
|
#undef NO_PROFILE_COUNTERS
|
||||||
|
#define NO_PROFILE_COUNTERS 1
|
||||||
|
|
||||||
|
#define TARGET_VALID_DLLIMPORT_ATTRIBUTE_P i386_pe_valid_dllimport_attribute_p
|
||||||
|
#define TARGET_CXX_ADJUST_CLASS_AT_DEFINITION i386_pe_adjust_class_at_definition
|
||||||
|
#define TARGET_MANGLE_DECL_ASSEMBLER_NAME i386_pe_mangle_decl_assembler_name
|
||||||
|
|
||||||
|
#undef TREE
|
||||||
|
|
||||||
|
#ifndef BUFSIZ
|
||||||
|
# undef FILE
|
||||||
|
#endif
|
124
contrib/sdk/sources/gcc_eh/config/i386/gas.h
Normal file
124
contrib/sdk/sources/gcc_eh/config/i386/gas.h
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
/* Definitions for Intel 386 using GAS.
|
||||||
|
Copyright (C) 1988, 1993, 1994, 1996, 2002, 2004, 2007, 2008
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* Note that i386/seq-gas.h is a GAS configuration that does not use this
|
||||||
|
file. */
|
||||||
|
|
||||||
|
/* Use the bsd assembler syntax. */
|
||||||
|
/* we need to do this because gas is really a bsd style assembler,
|
||||||
|
* and so doesn't work well this these att-isms:
|
||||||
|
*
|
||||||
|
* ASM_OUTPUT_SKIP is .set .,.+N, which isn't implemented in gas
|
||||||
|
* ASM_OUTPUT_LOCAL is done with .set .,.+N, but that can't be
|
||||||
|
* used to define bss static space
|
||||||
|
*
|
||||||
|
* Next is the question of whether to uses underscores. RMS didn't
|
||||||
|
* like this idea at first, but since it is now obvious that we
|
||||||
|
* need this separate tm file for use with gas, at least to get
|
||||||
|
* dbx debugging info, I think we should also switch to underscores.
|
||||||
|
* We can keep i386v for real att style output, and the few
|
||||||
|
* people who want both form will have to compile twice.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* these come from i386/bsd.h, but are specific to sequent */
|
||||||
|
#undef DBX_NO_XREFS
|
||||||
|
#undef DBX_CONTIN_LENGTH
|
||||||
|
|
||||||
|
/* Ask for COFF symbols. */
|
||||||
|
|
||||||
|
#define SDB_DEBUGGING_INFO 1
|
||||||
|
|
||||||
|
/* Output #ident as a .ident. */
|
||||||
|
|
||||||
|
#define ASM_OUTPUT_IDENT(FILE, NAME) fprintf (FILE, "\t.ident \"%s\"\n", NAME);
|
||||||
|
|
||||||
|
/* In the past there was confusion as to what the argument to .align was
|
||||||
|
in GAS. For the last several years the rule has been this: for a.out
|
||||||
|
file formats that argument is LOG, and for all other file formats the
|
||||||
|
argument is 1<<LOG.
|
||||||
|
|
||||||
|
However, GAS now has .p2align and .balign pseudo-ops so to remove any
|
||||||
|
doubt or guess work, and since this file is used for both a.out and other
|
||||||
|
file formats, we use one of them. */
|
||||||
|
|
||||||
|
#ifdef HAVE_GAS_BALIGN_AND_P2ALIGN
|
||||||
|
#undef ASM_OUTPUT_ALIGN
|
||||||
|
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
|
||||||
|
if ((LOG)!=0) fprintf ((FILE), "\t.balign %d\n", 1<<(LOG))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* A C statement to output to the stdio stream FILE an assembler
|
||||||
|
command to advance the location counter to a multiple of 1<<LOG
|
||||||
|
bytes if it is within MAX_SKIP bytes.
|
||||||
|
|
||||||
|
This is used to align code labels according to Intel recommendations. */
|
||||||
|
|
||||||
|
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
|
||||||
|
# define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
|
||||||
|
if ((LOG) != 0) {\
|
||||||
|
if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
|
||||||
|
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* A C statement or statements which output an assembler instruction
|
||||||
|
opcode to the stdio stream STREAM. The macro-operand PTR is a
|
||||||
|
variable of type `char *' which points to the opcode name in its
|
||||||
|
"internal" form--the form that is written in the machine description.
|
||||||
|
|
||||||
|
GAS version 1.38.1 doesn't understand the `repz' opcode mnemonic.
|
||||||
|
So use `repe' instead. */
|
||||||
|
|
||||||
|
#undef ASM_OUTPUT_OPCODE
|
||||||
|
#define ASM_OUTPUT_OPCODE(STREAM, PTR) \
|
||||||
|
{ \
|
||||||
|
if ((PTR)[0] == 'r' \
|
||||||
|
&& (PTR)[1] == 'e' \
|
||||||
|
&& (PTR)[2] == 'p') \
|
||||||
|
{ \
|
||||||
|
if ((PTR)[3] == 'z') \
|
||||||
|
{ \
|
||||||
|
fputs ("repe", (STREAM)); \
|
||||||
|
(PTR) += 4; \
|
||||||
|
} \
|
||||||
|
else if ((PTR)[3] == 'n' && (PTR)[4] == 'z') \
|
||||||
|
{ \
|
||||||
|
fputs ("repne", (STREAM)); \
|
||||||
|
(PTR) += 5; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
ASM_OUTPUT_AVX_PREFIX ((STREAM), (PTR)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Define macro used to output shift-double opcodes when the shift
|
||||||
|
count is in %cl. Some assemblers require %cl as an argument;
|
||||||
|
some don't.
|
||||||
|
|
||||||
|
GAS requires the %cl argument, so override i386/unix.h. */
|
||||||
|
|
||||||
|
#undef SHIFT_DOUBLE_OMITS_COUNT
|
||||||
|
#define SHIFT_DOUBLE_OMITS_COUNT 0
|
||||||
|
|
||||||
|
/* The comment-starter string as GAS expects it. */
|
||||||
|
#undef ASM_COMMENT_START
|
||||||
|
#define ASM_COMMENT_START "#"
|
||||||
|
|
||||||
|
#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
|
2499
contrib/sdk/sources/gcc_eh/config/i386/i386.h
Normal file
2499
contrib/sdk/sources/gcc_eh/config/i386/i386.h
Normal file
File diff suppressed because it is too large
Load Diff
50
contrib/sdk/sources/gcc_eh/config/i386/mingw-stdint.h
Normal file
50
contrib/sdk/sources/gcc_eh/config/i386/mingw-stdint.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/* Definitions for <stdint.h> types on systems using mingw.
|
||||||
|
Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#define SIG_ATOMIC_TYPE "int"
|
||||||
|
|
||||||
|
#define INT8_TYPE "signed char"
|
||||||
|
#define INT16_TYPE "short int"
|
||||||
|
#define INT32_TYPE "int"
|
||||||
|
#define INT64_TYPE "long long int"
|
||||||
|
#define UINT8_TYPE "unsigned char"
|
||||||
|
#define UINT16_TYPE "short unsigned int"
|
||||||
|
#define UINT32_TYPE "unsigned int"
|
||||||
|
#define UINT64_TYPE "long long unsigned int"
|
||||||
|
|
||||||
|
#define INT_LEAST8_TYPE "signed char"
|
||||||
|
#define INT_LEAST16_TYPE "short int"
|
||||||
|
#define INT_LEAST32_TYPE "int"
|
||||||
|
#define INT_LEAST64_TYPE "long long int"
|
||||||
|
#define UINT_LEAST8_TYPE "unsigned char"
|
||||||
|
#define UINT_LEAST16_TYPE "short unsigned int"
|
||||||
|
#define UINT_LEAST32_TYPE "unsigned int"
|
||||||
|
#define UINT_LEAST64_TYPE "long long unsigned int"
|
||||||
|
|
||||||
|
#define INT_FAST8_TYPE "signed char"
|
||||||
|
#define INT_FAST16_TYPE "short int"
|
||||||
|
#define INT_FAST32_TYPE "int"
|
||||||
|
#define INT_FAST64_TYPE "long long int"
|
||||||
|
#define UINT_FAST8_TYPE "unsigned char"
|
||||||
|
#define UINT_FAST16_TYPE "short unsigned int"
|
||||||
|
#define UINT_FAST32_TYPE "unsigned int"
|
||||||
|
#define UINT_FAST64_TYPE "long long unsigned int"
|
||||||
|
|
||||||
|
#define INTPTR_TYPE (TARGET_64BIT ? "long long int" : "int")
|
||||||
|
#define UINTPTR_TYPE (TARGET_64BIT ? "long long unsigned int" : "unsigned int")
|
249
contrib/sdk/sources/gcc_eh/config/i386/mingw32.h
Normal file
249
contrib/sdk/sources/gcc_eh/config/i386/mingw32.h
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
/* Operating system specific defines to be used when targeting GCC for
|
||||||
|
hosting on Windows32, using GNU tools and the Windows32 API Library.
|
||||||
|
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008,
|
||||||
|
2009, 2010 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#undef TARGET_VERSION
|
||||||
|
#if TARGET_64BIT_DEFAULT
|
||||||
|
#define TARGET_VERSION fprintf (stderr,"(x86_64 MinGW");
|
||||||
|
#else
|
||||||
|
#define TARGET_VERSION fprintf (stderr," (x86 MinGW)");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* See i386/crtdll.h for an alternative definition. _INTEGRAL_MAX_BITS
|
||||||
|
is for compatibility with native compiler. */
|
||||||
|
#define EXTRA_OS_CPP_BUILTINS() \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
builtin_define ("__MSVCRT__"); \
|
||||||
|
builtin_define ("__MINGW32__"); \
|
||||||
|
builtin_define ("_WIN32"); \
|
||||||
|
builtin_define_std ("WIN32"); \
|
||||||
|
builtin_define_std ("WINNT"); \
|
||||||
|
builtin_define_with_int_value ("_INTEGRAL_MAX_BITS", \
|
||||||
|
TYPE_PRECISION (intmax_type_node));\
|
||||||
|
if (TARGET_64BIT && ix86_abi == MS_ABI) \
|
||||||
|
{ \
|
||||||
|
builtin_define ("__MINGW64__"); \
|
||||||
|
builtin_define_std ("WIN64"); \
|
||||||
|
builtin_define_std ("_WIN64"); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
#undef SUB_LINK_ENTRY32
|
||||||
|
#undef SUB_LINK_ENTRY64
|
||||||
|
#define SUB_LINK_ENTRY32 "-e _DllMainCRTStartup@12"
|
||||||
|
#if defined(USE_MINGW64_LEADING_UNDERSCORES)
|
||||||
|
#define SUB_LINK_ENTRY64 "-e _DllMainCRTStartup"
|
||||||
|
#else
|
||||||
|
#define SUB_LINK_ENTRY64 "-e DllMainCRTStartup"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef SUB_LINK_ENTRY
|
||||||
|
#if TARGET_64BIT_DEFAULT
|
||||||
|
#define SUB_LINK_ENTRY SUB_LINK_ENTRY64
|
||||||
|
#else
|
||||||
|
#define SUB_LINK_ENTRY SUB_LINK_ENTRY32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Override the standard choice of /usr/include as the default prefix
|
||||||
|
to try when searching for header files. */
|
||||||
|
#undef STANDARD_INCLUDE_DIR
|
||||||
|
#define STANDARD_INCLUDE_DIR "/mingw/include"
|
||||||
|
#undef STANDARD_INCLUDE_COMPONENT
|
||||||
|
#define STANDARD_INCLUDE_COMPONENT "MINGW"
|
||||||
|
|
||||||
|
#undef CPP_SPEC
|
||||||
|
#define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT}"
|
||||||
|
|
||||||
|
/* For Windows applications, include more libraries, but always include
|
||||||
|
kernel32. */
|
||||||
|
#undef LIB_SPEC
|
||||||
|
#define LIB_SPEC "%{pg:-lgmon} %{mwindows:-lgdi32 -lcomdlg32} \
|
||||||
|
-luser32 -lkernel32 -ladvapi32 -lshell32"
|
||||||
|
|
||||||
|
/* Weak symbols do not get resolved if using a Windows dll import lib.
|
||||||
|
Make the unwind registration references strong undefs. */
|
||||||
|
#if DWARF2_UNWIND_INFO
|
||||||
|
/* DW2-unwind is just available for 32-bit mode. */
|
||||||
|
#if TARGET_64BIT_DEFAULT
|
||||||
|
#error DW2 unwind is not available for 64-bit.
|
||||||
|
#endif
|
||||||
|
#define SHARED_LIBGCC_UNDEFS_SPEC \
|
||||||
|
"%{shared-libgcc: -u ___register_frame_info -u ___deregister_frame_info}"
|
||||||
|
#else
|
||||||
|
#define SHARED_LIBGCC_UNDEFS_SPEC ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef SUBTARGET_EXTRA_SPECS
|
||||||
|
#define SUBTARGET_EXTRA_SPECS \
|
||||||
|
{ "shared_libgcc_undefs", SHARED_LIBGCC_UNDEFS_SPEC }
|
||||||
|
|
||||||
|
#define LINK_SPEC "%{mwindows:--subsystem windows} \
|
||||||
|
%{mconsole:--subsystem console} \
|
||||||
|
%{shared: %{mdll: %eshared and mdll are not compatible}} \
|
||||||
|
%{shared: --shared} %{mdll:--dll} \
|
||||||
|
%{static:-Bstatic} %{!static:-Bdynamic} \
|
||||||
|
%{shared|mdll: " SUB_LINK_ENTRY " --enable-auto-image-base} \
|
||||||
|
%(shared_libgcc_undefs)"
|
||||||
|
|
||||||
|
/* Include in the mingw32 libraries with libgcc */
|
||||||
|
#ifdef ENABLE_SHARED_LIBGCC
|
||||||
|
#define SHARED_LIBGCC_SPEC "%{shared-libgcc:-lgcc_s} %{!shared-libgcc:-lgcc_eh}"
|
||||||
|
#else
|
||||||
|
#define SHARED_LIBGCC_SPEC /*empty*/
|
||||||
|
#endif
|
||||||
|
#undef REAL_LIBGCC_SPEC
|
||||||
|
#define REAL_LIBGCC_SPEC \
|
||||||
|
"%{mthreads:-lmingwthrd} -lmingw32 \
|
||||||
|
"SHARED_LIBGCC_SPEC" \
|
||||||
|
-lgcc \
|
||||||
|
-lmoldname -lmingwex -lmsvcrt"
|
||||||
|
|
||||||
|
#undef STARTFILE_SPEC
|
||||||
|
#define STARTFILE_SPEC "%{shared|mdll:dllcrt2%O%s} \
|
||||||
|
%{!shared:%{!mdll:crt2%O%s}} %{pg:gcrt2%O%s} \
|
||||||
|
crtbegin.o%s"
|
||||||
|
|
||||||
|
#undef ENDFILE_SPEC
|
||||||
|
#define ENDFILE_SPEC \
|
||||||
|
"%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
|
||||||
|
crtend.o%s"
|
||||||
|
|
||||||
|
/* Override startfile prefix defaults. */
|
||||||
|
#ifndef STANDARD_STARTFILE_PREFIX_1
|
||||||
|
#define STANDARD_STARTFILE_PREFIX_1 "/mingw/lib/"
|
||||||
|
#endif
|
||||||
|
#ifndef STANDARD_STARTFILE_PREFIX_2
|
||||||
|
#define STANDARD_STARTFILE_PREFIX_2 ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Put all *tf routines in libgcc. */
|
||||||
|
#undef LIBGCC2_HAS_TF_MODE
|
||||||
|
#define LIBGCC2_HAS_TF_MODE 1
|
||||||
|
#undef LIBGCC2_TF_CEXT
|
||||||
|
#define LIBGCC2_TF_CEXT q
|
||||||
|
#undef TF_SIZE
|
||||||
|
#define TF_SIZE 113
|
||||||
|
|
||||||
|
/* Output STRING, a string representing a filename, to FILE.
|
||||||
|
We canonicalize it to be in Unix format (backslashes are replaced
|
||||||
|
forward slashes. */
|
||||||
|
#undef OUTPUT_QUOTED_STRING
|
||||||
|
#define OUTPUT_QUOTED_STRING(FILE, STRING) \
|
||||||
|
do { \
|
||||||
|
char c; \
|
||||||
|
\
|
||||||
|
putc ('\"', asm_file); \
|
||||||
|
\
|
||||||
|
while ((c = *string++) != 0) \
|
||||||
|
{ \
|
||||||
|
if (c == '\\') \
|
||||||
|
c = '/'; \
|
||||||
|
\
|
||||||
|
if (ISPRINT (c)) \
|
||||||
|
{ \
|
||||||
|
if (c == '\"') \
|
||||||
|
putc ('\\', asm_file); \
|
||||||
|
putc (c, asm_file); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
fprintf (asm_file, "\\%03o", (unsigned char) c); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
putc ('\"', asm_file); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* Define as short unsigned for compatibility with MS runtime. */
|
||||||
|
#undef WINT_TYPE
|
||||||
|
#define WINT_TYPE "short unsigned int"
|
||||||
|
|
||||||
|
/* mingw32 uses the -mthreads option to enable thread support. */
|
||||||
|
#undef GOMP_SELF_SPECS
|
||||||
|
#define GOMP_SELF_SPECS "%{fopenmp: -mthreads}"
|
||||||
|
|
||||||
|
/* mingw32 atexit function is safe to use in shared libraries. Use it
|
||||||
|
to register C++ static destructors. */
|
||||||
|
#define TARGET_CXX_USE_ATEXIT_FOR_CXA_ATEXIT hook_bool_void_true
|
||||||
|
|
||||||
|
/* Contains a pointer to type target_ovr_attr defining the target specific
|
||||||
|
overrides of format attributes. See c-format.h for structure
|
||||||
|
definition. */
|
||||||
|
#undef TARGET_OVERRIDES_FORMAT_ATTRIBUTES
|
||||||
|
#define TARGET_OVERRIDES_FORMAT_ATTRIBUTES mingw_format_attribute_overrides
|
||||||
|
|
||||||
|
/* Specify the count of elements in TARGET_OVERRIDES_ATTRIBUTE. */
|
||||||
|
#undef TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT
|
||||||
|
#define TARGET_OVERRIDES_FORMAT_ATTRIBUTES_COUNT 3
|
||||||
|
|
||||||
|
/* Custom initialization for warning -Wpedantic-ms-format for c-format. */
|
||||||
|
#undef TARGET_OVERRIDES_FORMAT_INIT
|
||||||
|
#define TARGET_OVERRIDES_FORMAT_INIT msformat_init
|
||||||
|
|
||||||
|
/* MS specific format attributes for ms_printf, ms_scanf, ms_strftime. */
|
||||||
|
#undef TARGET_FORMAT_TYPES
|
||||||
|
#define TARGET_FORMAT_TYPES mingw_format_attributes
|
||||||
|
|
||||||
|
#undef TARGET_N_FORMAT_TYPES
|
||||||
|
#define TARGET_N_FORMAT_TYPES 3
|
||||||
|
|
||||||
|
/* Let defaults.h definition of TARGET_USE_JCR_SECTION apply. */
|
||||||
|
#undef TARGET_USE_JCR_SECTION
|
||||||
|
|
||||||
|
#undef MINGW_ENABLE_EXECUTE_STACK
|
||||||
|
#define MINGW_ENABLE_EXECUTE_STACK \
|
||||||
|
extern void __enable_execute_stack (void *); \
|
||||||
|
void \
|
||||||
|
__enable_execute_stack (void *addr) \
|
||||||
|
{ \
|
||||||
|
MEMORY_BASIC_INFORMATION b; \
|
||||||
|
if (!VirtualQuery (addr, &b, sizeof(b))) \
|
||||||
|
abort (); \
|
||||||
|
VirtualProtect (b.BaseAddress, b.RegionSize, PAGE_EXECUTE_READWRITE, \
|
||||||
|
&b.Protect); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef ENABLE_EXECUTE_STACK
|
||||||
|
#define ENABLE_EXECUTE_STACK MINGW_ENABLE_EXECUTE_STACK
|
||||||
|
#undef CHECK_EXECUTE_STACK_ENABLED
|
||||||
|
#define CHECK_EXECUTE_STACK_ENABLED flag_setstackexecutable
|
||||||
|
|
||||||
|
#ifdef IN_LIBGCC2
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* For 64-bit Windows we can't use DW2 unwind info. Also for multilib
|
||||||
|
builds we can't use it, too. */
|
||||||
|
#if !TARGET_64BIT_DEFAULT && !defined (TARGET_BI_ARCH)
|
||||||
|
#define MD_UNWIND_SUPPORT "config/i386/w32-unwind.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This matches SHLIB_SONAME and SHLIB_SOVERSION in t-cygming. */
|
||||||
|
/* This matches SHLIB_SONAME and SHLIB_SOVERSION in t-cygwin. */
|
||||||
|
#if DWARF2_UNWIND_INFO
|
||||||
|
#define LIBGCC_EH_EXTN "_dw2"
|
||||||
|
#else
|
||||||
|
#define LIBGCC_EH_EXTN "_sjlj"
|
||||||
|
#endif
|
||||||
|
#define LIBGCC_SONAME "libgcc_s" LIBGCC_EH_EXTN "-1.dll"
|
||||||
|
|
||||||
|
/* We should find a way to not have to update this manually. */
|
||||||
|
#define LIBGCJ_SONAME "libgcj" /*LIBGCC_EH_EXTN*/ "-11.dll"
|
||||||
|
|
81
contrib/sdk/sources/gcc_eh/config/i386/unix.h
Normal file
81
contrib/sdk/sources/gcc_eh/config/i386/unix.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/* Definitions for Unix assembler syntax for the Intel 80386.
|
||||||
|
Copyright (C) 1988, 1994, 1999, 2000, 2001, 2002, 2007, 2009
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* This file defines the aspects of assembler syntax
|
||||||
|
that are the same for all the i386 Unix systems
|
||||||
|
(though they may differ in non-Unix systems). */
|
||||||
|
|
||||||
|
/* Define macro used to output shift-double opcodes when the shift
|
||||||
|
count is in %cl. Some assemblers require %cl as an argument;
|
||||||
|
some don't. This macro controls what to do: by default, don't
|
||||||
|
print %cl. */
|
||||||
|
#define SHIFT_DOUBLE_OMITS_COUNT 1
|
||||||
|
|
||||||
|
/* Define the syntax of pseudo-ops, labels and comments. */
|
||||||
|
|
||||||
|
/* String containing the assembler's comment-starter.
|
||||||
|
Note the trailing space is necessary in case the character
|
||||||
|
that immediately follows the comment is '*'. If this happens
|
||||||
|
and the space is not there the assembler will interpret this
|
||||||
|
as the start of a C-like slash-star comment and complain when
|
||||||
|
there is no terminator. */
|
||||||
|
|
||||||
|
#define ASM_COMMENT_START "/ "
|
||||||
|
|
||||||
|
/* Output to assembler file text saying following lines
|
||||||
|
may contain character constants, extra white space, comments, etc. */
|
||||||
|
|
||||||
|
#define ASM_APP_ON "/APP\n"
|
||||||
|
|
||||||
|
/* Output to assembler file text saying following lines
|
||||||
|
no longer contain unusual constructs. */
|
||||||
|
|
||||||
|
#define ASM_APP_OFF "/NO_APP\n"
|
||||||
|
|
||||||
|
/* Output before read-only data. */
|
||||||
|
|
||||||
|
#define TEXT_SECTION_ASM_OP "\t.text"
|
||||||
|
|
||||||
|
/* Output before writable (initialized) data. */
|
||||||
|
|
||||||
|
#define DATA_SECTION_ASM_OP "\t.data"
|
||||||
|
|
||||||
|
/* Output before writable (uninitialized) data. */
|
||||||
|
|
||||||
|
#define BSS_SECTION_ASM_OP "\t.bss"
|
||||||
|
|
||||||
|
/* Globalizing directive for a label. */
|
||||||
|
#define GLOBAL_ASM_OP ".globl "
|
||||||
|
|
||||||
|
/* By default, target has a 80387, uses IEEE compatible arithmetic,
|
||||||
|
and returns float values in the 387. */
|
||||||
|
#undef TARGET_SUBTARGET_DEFAULT
|
||||||
|
#define TARGET_SUBTARGET_DEFAULT \
|
||||||
|
(MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS)
|
||||||
|
|
||||||
|
/* By default, 64-bit mode uses 128-bit long double. */
|
||||||
|
#undef TARGET_SUBTARGET64_DEFAULT
|
||||||
|
#define TARGET_SUBTARGET64_DEFAULT \
|
||||||
|
MASK_128BIT_LONG_DOUBLE
|
212
contrib/sdk/sources/gcc_eh/config/i386/w32-unwind.h
Normal file
212
contrib/sdk/sources/gcc_eh/config/i386/w32-unwind.h
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
/* Definitions for Dwarf2 EH unwind support for Windows32 targets
|
||||||
|
Copyright (C) 2007, 2009
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
Contributed by Pascal Obry <obry@adacore.com>
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
|
||||||
|
/* This file implements the md_fallback_frame_state_for routine for
|
||||||
|
Windows, triggered when the GCC table based unwinding process hits a
|
||||||
|
frame for which no unwind info has been registered. This typically
|
||||||
|
occurs when raising an exception from a signal handler, because the
|
||||||
|
handler is actually called from the OS kernel.
|
||||||
|
|
||||||
|
The basic idea is to detect that we are indeed trying to unwind past a
|
||||||
|
signal handler and to fill out the GCC internal unwinding structures for
|
||||||
|
the OS kernel frame as if it had been directly called from the
|
||||||
|
interrupted context.
|
||||||
|
|
||||||
|
This is all assuming that the code to set the handler asked the kernel
|
||||||
|
to pass a pointer to such context information.
|
||||||
|
|
||||||
|
There is three main parts.
|
||||||
|
|
||||||
|
1) The first thing to do is to check if we are in a signal context. If
|
||||||
|
not we can just return as there is nothing to do. We are probably on
|
||||||
|
some foreign code for which no unwind frame can be found. If this is
|
||||||
|
a call from the Windows signal handler, then:
|
||||||
|
|
||||||
|
2) We must get the signal context information.
|
||||||
|
|
||||||
|
* With the standard exception filter:
|
||||||
|
|
||||||
|
This is on Windows pointed to by an EXCEPTION_POINTERS. We know that
|
||||||
|
the signal handle will call an UnhandledExceptionFilter with this
|
||||||
|
parameter. The spec for this routine is:
|
||||||
|
|
||||||
|
LONG WINAPI UnhandledExceptionFilter(struct _EXCEPTION_POINTERS*);
|
||||||
|
|
||||||
|
So the pointer to struct _EXCEPTION_POINTERS must be somewhere on the
|
||||||
|
stack.
|
||||||
|
|
||||||
|
This was found experimentally to always be at offset 0 of the context
|
||||||
|
frame in all cases handled by this implementation.
|
||||||
|
|
||||||
|
* With the SEH exception handler:
|
||||||
|
|
||||||
|
In this case the signal context is directly on the stack as the SEH
|
||||||
|
exception handler has the following prototype:
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
SEH_error_handler (PEXCEPTION_RECORD ExceptionRecord,
|
||||||
|
PVOID EstablisherFrame,
|
||||||
|
PCONTEXT ContextRecord,
|
||||||
|
PVOID DispatcherContext)
|
||||||
|
|
||||||
|
This was found experimentally to always be at offset 56 of the
|
||||||
|
context frame in all cases handled by this implementation.
|
||||||
|
|
||||||
|
3) When we have the signal context we just have to save some registers
|
||||||
|
and set the return address based on the program counter (Eip).
|
||||||
|
|
||||||
|
Note that this implementation follows closely the same principles as the
|
||||||
|
GNU/Linux and OSF ones. */
|
||||||
|
|
||||||
|
#define WIN32_MEAN_AND_LEAN
|
||||||
|
#include <windows.h>
|
||||||
|
/* Patterns found experimentally to be on a Windows signal handler */
|
||||||
|
|
||||||
|
/* In a standard exception filter */
|
||||||
|
|
||||||
|
#define SIG_PAT1 \
|
||||||
|
(pc_[-2] == 0xff && pc_[-1] == 0xd0 /* call %eax */ \
|
||||||
|
&& pc_[0] == 0x83 && pc_[1] == 0xf8) /* cmp 0xdepl,%eax */
|
||||||
|
|
||||||
|
#define SIG_PAT2 \
|
||||||
|
(pc_[-5] == 0xe8 && pc_[-4] == 0x68 /* call (depl16) */ \
|
||||||
|
&& pc_[0] == 0xc3) /* ret */
|
||||||
|
|
||||||
|
/* In a Win32 SEH handler */
|
||||||
|
|
||||||
|
#define SIG_SEH1 \
|
||||||
|
(pc_[-5] == 0xe8 /* call addr */ \
|
||||||
|
&& pc_[0] == 0x83 && pc_[1] == 0xc4 /* add 0xval,%esp */ \
|
||||||
|
&& pc_[3] == 0xb8) /* mov 0xval,%eax */
|
||||||
|
|
||||||
|
#define SIG_SEH2 \
|
||||||
|
(pc_[-5] == 0x8b && pc_[-4] == 0x4d /* mov depl(%ebp),%ecx */ \
|
||||||
|
&& pc_[0] == 0x64 && pc_[1] == 0x8b) /* mov %fs:(0),<reg> */ \
|
||||||
|
|
||||||
|
/* In the GCC alloca (stack probing) */
|
||||||
|
|
||||||
|
#define SIG_ALLOCA \
|
||||||
|
(pc_[-1] == 0x83 /* orl $0x0,(%ecx) */ \
|
||||||
|
&& pc_[0] == 0x9 && pc_[1] == 0 \
|
||||||
|
&& pc_[2] == 0x2d && pc_[3] == 0 /* subl $0x1000,%eax */ \
|
||||||
|
&& pc_[4] == 0x10 && pc_[5] == 0)
|
||||||
|
|
||||||
|
|
||||||
|
#define MD_FALLBACK_FRAME_STATE_FOR i386_w32_fallback_frame_state
|
||||||
|
|
||||||
|
static _Unwind_Reason_Code
|
||||||
|
i386_w32_fallback_frame_state (struct _Unwind_Context *context,
|
||||||
|
_Unwind_FrameState *fs)
|
||||||
|
|
||||||
|
{
|
||||||
|
void * ctx_ra_ = (void *)(context->ra); /* return address */
|
||||||
|
void * ctx_cfa_ = (void *)(context->cfa); /* context frame address */
|
||||||
|
unsigned char * pc_ = (unsigned char *) ctx_ra_;
|
||||||
|
|
||||||
|
/* In the test below we look for two specific patterns found
|
||||||
|
experimentally to be in the Windows signal handler. */
|
||||||
|
|
||||||
|
if (SIG_PAT1 || SIG_PAT2 || SIG_SEH1 || SIG_SEH2)
|
||||||
|
{
|
||||||
|
PEXCEPTION_POINTERS weinfo_;
|
||||||
|
PCONTEXT proc_ctx_;
|
||||||
|
long new_cfa_;
|
||||||
|
|
||||||
|
if (SIG_SEH1)
|
||||||
|
proc_ctx_ = (PCONTEXT) (*(int*)(ctx_cfa_ + 56));
|
||||||
|
else if (SIG_SEH2)
|
||||||
|
proc_ctx_ = (PCONTEXT) (*(int*)(ctx_cfa_ + 8));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
weinfo_ = (PEXCEPTION_POINTERS) (*(int*)ctx_cfa_);
|
||||||
|
proc_ctx_ = weinfo_->ContextRecord;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The new context frame address is the stack pointer. */
|
||||||
|
|
||||||
|
new_cfa_ = proc_ctx_->Esp;
|
||||||
|
fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||||
|
fs->regs.cfa_reg = __builtin_dwarf_sp_column();
|
||||||
|
fs->regs.cfa_offset = new_cfa_ - (long) ctx_cfa_;
|
||||||
|
|
||||||
|
/* Save some registers. */
|
||||||
|
|
||||||
|
fs->regs.reg[0].how = REG_SAVED_OFFSET;
|
||||||
|
fs->regs.reg[0].loc.offset = (long)&proc_ctx_->Eax - new_cfa_;
|
||||||
|
fs->regs.reg[3].how = REG_SAVED_OFFSET;
|
||||||
|
fs->regs.reg[3].loc.offset = (long)&proc_ctx_->Ebx - new_cfa_;
|
||||||
|
fs->regs.reg[1].how = REG_SAVED_OFFSET;
|
||||||
|
fs->regs.reg[1].loc.offset = (long)&proc_ctx_->Ecx - new_cfa_;
|
||||||
|
fs->regs.reg[2].how = REG_SAVED_OFFSET;
|
||||||
|
fs->regs.reg[2].loc.offset = (long)&proc_ctx_->Edx - new_cfa_;
|
||||||
|
fs->regs.reg[6].how = REG_SAVED_OFFSET;
|
||||||
|
fs->regs.reg[6].loc.offset = (long)&proc_ctx_->Esi - new_cfa_;
|
||||||
|
fs->regs.reg[7].how = REG_SAVED_OFFSET;
|
||||||
|
fs->regs.reg[7].loc.offset = (long)&proc_ctx_->Edi - new_cfa_;
|
||||||
|
fs->regs.reg[9].how = REG_SAVED_OFFSET;
|
||||||
|
fs->regs.reg[9].loc.offset = (long)&proc_ctx_->Eip - new_cfa_;
|
||||||
|
fs->regs.reg[4].how = REG_SAVED_OFFSET;
|
||||||
|
fs->regs.reg[4].loc.offset = (long)&proc_ctx_->Ebp - new_cfa_;
|
||||||
|
|
||||||
|
/* Set the return address to Eip + 1. As we can be called multiple
|
||||||
|
times we use another register for this. */
|
||||||
|
|
||||||
|
proc_ctx_->Dr0 = proc_ctx_->Eip + 1;
|
||||||
|
fs->regs.reg[8].how = REG_SAVED_OFFSET;
|
||||||
|
fs->regs.reg[8].loc.offset = (long)&proc_ctx_->Dr0 - new_cfa_;
|
||||||
|
fs->retaddr_column = 8;
|
||||||
|
return _URC_NO_REASON;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unwinding through _alloca, propagating from a trap triggered by
|
||||||
|
one of it's probes prior to the real SP adjustment. The only
|
||||||
|
operations of interest performed is "pushl %ecx", followed by
|
||||||
|
ecx clobbering. */
|
||||||
|
|
||||||
|
else if (SIG_ALLOCA)
|
||||||
|
{
|
||||||
|
/* Only one push between entry in _alloca and the probe trap. */
|
||||||
|
long new_cfa_ = (long) ctx_cfa_ + 4;
|
||||||
|
|
||||||
|
fs->regs.cfa_how = CFA_REG_OFFSET;
|
||||||
|
fs->regs.cfa_reg = __builtin_dwarf_sp_column();
|
||||||
|
fs->regs.cfa_offset = new_cfa_ - (long) ctx_cfa_;
|
||||||
|
|
||||||
|
/* The saved value of %ecx is at CFA - 4 */
|
||||||
|
fs->regs.reg[1].how = REG_SAVED_OFFSET;
|
||||||
|
fs->regs.reg[1].loc.offset = -4;
|
||||||
|
|
||||||
|
/* and what is stored at the CFA is the return address. */
|
||||||
|
fs->retaddr_column = 8;
|
||||||
|
fs->regs.reg[8].how = REG_SAVED_OFFSET;
|
||||||
|
fs->regs.reg[8].loc.offset = 0;
|
||||||
|
|
||||||
|
return _URC_NO_REASON;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return _URC_END_OF_STACK;
|
||||||
|
}
|
4
contrib/sdk/sources/gcc_eh/config/tm-dwarf2.h
Normal file
4
contrib/sdk/sources/gcc_eh/config/tm-dwarf2.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
/* Enable Dwarf2 debugging and make it the default */
|
||||||
|
#define DWARF2_DEBUGGING_INFO 1
|
||||||
|
#undef PREFERRED_DEBUGGING_TYPE
|
||||||
|
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
|
40
contrib/sdk/sources/gcc_eh/config/vxworks-dummy.h
Normal file
40
contrib/sdk/sources/gcc_eh/config/vxworks-dummy.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* Dummy definitions of VxWorks-related macros
|
||||||
|
Copyright (C) 2007, 2009 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* True if we're targetting VxWorks. */
|
||||||
|
#ifndef TARGET_VXWORKS
|
||||||
|
#define TARGET_VXWORKS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* True if generating code for a VxWorks RTP. */
|
||||||
|
#ifndef TARGET_VXWORKS_RTP
|
||||||
|
#define TARGET_VXWORKS_RTP false
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The symbol that points to an RTP's table of GOTs. */
|
||||||
|
#define VXWORKS_GOTT_BASE (gcc_unreachable (), "")
|
||||||
|
|
||||||
|
/* The symbol that holds the index of the current module's GOT in
|
||||||
|
VXWORKS_GOTT_BASE. */
|
||||||
|
#define VXWORKS_GOTT_INDEX (gcc_unreachable (), "")
|
128
contrib/sdk/sources/gcc_eh/coretypes.h
Normal file
128
contrib/sdk/sources/gcc_eh/coretypes.h
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
/* GCC core type declarations.
|
||||||
|
Copyright (C) 2002, 2004, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* Provide forward declarations of core types which are referred to by
|
||||||
|
most of the compiler. This allows header files to use these types
|
||||||
|
(e.g. in function prototypes) without concern for whether the full
|
||||||
|
definitions are visible. Some other declarations that need to be
|
||||||
|
universally visible are here, too.
|
||||||
|
|
||||||
|
In the context of tconfig.h, most of these have special definitions
|
||||||
|
which prevent them from being used except in further type
|
||||||
|
declarations. This is a kludge; the right thing is to avoid
|
||||||
|
including the "tm.h" header set in the context of tconfig.h, but
|
||||||
|
we're not there yet. */
|
||||||
|
|
||||||
|
#ifndef GCC_CORETYPES_H
|
||||||
|
#define GCC_CORETYPES_H
|
||||||
|
|
||||||
|
#ifndef GTY
|
||||||
|
#define GTY(x) /* nothing - marker for gengtype */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef USED_FOR_TARGET
|
||||||
|
|
||||||
|
struct bitmap_head_def;
|
||||||
|
typedef struct bitmap_head_def *bitmap;
|
||||||
|
typedef const struct bitmap_head_def *const_bitmap;
|
||||||
|
struct rtx_def;
|
||||||
|
typedef struct rtx_def *rtx;
|
||||||
|
typedef const struct rtx_def *const_rtx;
|
||||||
|
struct rtvec_def;
|
||||||
|
typedef struct rtvec_def *rtvec;
|
||||||
|
typedef const struct rtvec_def *const_rtvec;
|
||||||
|
union tree_node;
|
||||||
|
typedef union tree_node *tree;
|
||||||
|
union gimple_statement_d;
|
||||||
|
typedef union gimple_statement_d *gimple;
|
||||||
|
typedef const union tree_node *const_tree;
|
||||||
|
typedef const union gimple_statement_d *const_gimple;
|
||||||
|
union section;
|
||||||
|
typedef union section section;
|
||||||
|
struct cl_target_option;
|
||||||
|
struct cl_optimization;
|
||||||
|
struct gimple_seq_d;
|
||||||
|
typedef struct gimple_seq_d *gimple_seq;
|
||||||
|
typedef const struct gimple_seq_d *const_gimple_seq;
|
||||||
|
struct gimple_seq_node_d;
|
||||||
|
typedef struct gimple_seq_node_d *gimple_seq_node;
|
||||||
|
typedef const struct gimple_seq_node_d *const_gimple_seq_node;
|
||||||
|
|
||||||
|
/* Address space number for named address space support. */
|
||||||
|
typedef unsigned char addr_space_t;
|
||||||
|
|
||||||
|
/* The value of addr_space_t that represents the generic address space. */
|
||||||
|
#define ADDR_SPACE_GENERIC 0
|
||||||
|
#define ADDR_SPACE_GENERIC_P(AS) ((AS) == ADDR_SPACE_GENERIC)
|
||||||
|
|
||||||
|
/* The major intermediate representations of GCC. */
|
||||||
|
enum ir_type {
|
||||||
|
IR_GIMPLE,
|
||||||
|
IR_RTL_CFGRTL,
|
||||||
|
IR_RTL_CFGLAYOUT
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Provide forward struct declaration so that we don't have to include
|
||||||
|
all of cpplib.h whenever a random prototype includes a pointer.
|
||||||
|
Note that the cpp_reader and cpp_token typedefs remain part of
|
||||||
|
cpplib.h. */
|
||||||
|
|
||||||
|
struct cpp_reader;
|
||||||
|
struct cpp_token;
|
||||||
|
|
||||||
|
/* The thread-local storage model associated with a given VAR_DECL
|
||||||
|
or SYMBOL_REF. This isn't used much, but both trees and RTL refer
|
||||||
|
to it, so it's here. */
|
||||||
|
enum tls_model {
|
||||||
|
TLS_MODEL_NONE,
|
||||||
|
TLS_MODEL_EMULATED,
|
||||||
|
TLS_MODEL_REAL,
|
||||||
|
TLS_MODEL_GLOBAL_DYNAMIC = TLS_MODEL_REAL,
|
||||||
|
TLS_MODEL_LOCAL_DYNAMIC,
|
||||||
|
TLS_MODEL_INITIAL_EXEC,
|
||||||
|
TLS_MODEL_LOCAL_EXEC
|
||||||
|
};
|
||||||
|
|
||||||
|
struct edge_def;
|
||||||
|
typedef struct edge_def *edge;
|
||||||
|
typedef const struct edge_def *const_edge;
|
||||||
|
struct basic_block_def;
|
||||||
|
typedef struct basic_block_def *basic_block;
|
||||||
|
typedef const struct basic_block_def *const_basic_block;
|
||||||
|
#else
|
||||||
|
|
||||||
|
struct _dont_use_rtx_here_;
|
||||||
|
struct _dont_use_rtvec_here_;
|
||||||
|
union _dont_use_tree_here_;
|
||||||
|
#define rtx struct _dont_use_rtx_here_ *
|
||||||
|
#define const_rtx struct _dont_use_rtx_here_ *
|
||||||
|
#define rtvec struct _dont_use_rtvec_here *
|
||||||
|
#define const_rtvec struct _dont_use_rtvec_here *
|
||||||
|
#define tree union _dont_use_tree_here_ *
|
||||||
|
#define const_tree union _dont_use_tree_here_ *
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* coretypes.h */
|
||||||
|
|
1168
contrib/sdk/sources/gcc_eh/defaults.h
Normal file
1168
contrib/sdk/sources/gcc_eh/defaults.h
Normal file
File diff suppressed because it is too large
Load Diff
914
contrib/sdk/sources/gcc_eh/dwarf2.h
Normal file
914
contrib/sdk/sources/gcc_eh/dwarf2.h
Normal file
@ -0,0 +1,914 @@
|
|||||||
|
/* Declarations and definitions of codes relating to the DWARF2 and
|
||||||
|
DWARF3 symbolic debugging information formats.
|
||||||
|
Copyright (C) 1992, 1993, 1995, 1996, 1997, 1999, 2000, 2001, 2002,
|
||||||
|
2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
Written by Gary Funck (gary@intrepid.com) The Ada Joint Program
|
||||||
|
Office (AJPO), Florida State University and Silicon Graphics Inc.
|
||||||
|
provided support for this effort -- June 21, 1995.
|
||||||
|
|
||||||
|
Derived from the DWARF 1 implementation written by Ron Guilmette
|
||||||
|
(rfg@netcom.com), November 1990.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* This file is derived from the DWARF specification (a public document)
|
||||||
|
Revision 2.0.0 (July 27, 1993) developed by the UNIX International
|
||||||
|
Programming Languages Special Interest Group (UI/PLSIG) and distributed
|
||||||
|
by UNIX International. Copies of this specification are available from
|
||||||
|
UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054.
|
||||||
|
|
||||||
|
This file also now contains definitions from the DWARF 3 specification
|
||||||
|
published Dec 20, 2005, available from: http://dwarf.freestandards.org. */
|
||||||
|
|
||||||
|
/* This file is shared between GCC and GDB, and should not contain
|
||||||
|
prototypes. */
|
||||||
|
|
||||||
|
#ifndef _ELF_DWARF2_H
|
||||||
|
#define _ELF_DWARF2_H
|
||||||
|
|
||||||
|
/* Structure found in the .debug_line section. */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned char li_length [4];
|
||||||
|
unsigned char li_version [2];
|
||||||
|
unsigned char li_prologue_length [4];
|
||||||
|
unsigned char li_min_insn_length [1];
|
||||||
|
unsigned char li_default_is_stmt [1];
|
||||||
|
unsigned char li_line_base [1];
|
||||||
|
unsigned char li_line_range [1];
|
||||||
|
unsigned char li_opcode_base [1];
|
||||||
|
}
|
||||||
|
DWARF2_External_LineInfo;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned long li_length;
|
||||||
|
unsigned short li_version;
|
||||||
|
unsigned int li_prologue_length;
|
||||||
|
unsigned char li_min_insn_length;
|
||||||
|
unsigned char li_max_ops_per_insn;
|
||||||
|
unsigned char li_default_is_stmt;
|
||||||
|
int li_line_base;
|
||||||
|
unsigned char li_line_range;
|
||||||
|
unsigned char li_opcode_base;
|
||||||
|
}
|
||||||
|
DWARF2_Internal_LineInfo;
|
||||||
|
|
||||||
|
/* Structure found in .debug_pubnames section. */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned char pn_length [4];
|
||||||
|
unsigned char pn_version [2];
|
||||||
|
unsigned char pn_offset [4];
|
||||||
|
unsigned char pn_size [4];
|
||||||
|
}
|
||||||
|
DWARF2_External_PubNames;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned long pn_length;
|
||||||
|
unsigned short pn_version;
|
||||||
|
unsigned long pn_offset;
|
||||||
|
unsigned long pn_size;
|
||||||
|
}
|
||||||
|
DWARF2_Internal_PubNames;
|
||||||
|
|
||||||
|
/* Structure found in .debug_info section. */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned char cu_length [4];
|
||||||
|
unsigned char cu_version [2];
|
||||||
|
unsigned char cu_abbrev_offset [4];
|
||||||
|
unsigned char cu_pointer_size [1];
|
||||||
|
}
|
||||||
|
DWARF2_External_CompUnit;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned long cu_length;
|
||||||
|
unsigned short cu_version;
|
||||||
|
unsigned long cu_abbrev_offset;
|
||||||
|
unsigned char cu_pointer_size;
|
||||||
|
}
|
||||||
|
DWARF2_Internal_CompUnit;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned char ar_length [4];
|
||||||
|
unsigned char ar_version [2];
|
||||||
|
unsigned char ar_info_offset [4];
|
||||||
|
unsigned char ar_pointer_size [1];
|
||||||
|
unsigned char ar_segment_size [1];
|
||||||
|
}
|
||||||
|
DWARF2_External_ARange;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned long ar_length;
|
||||||
|
unsigned short ar_version;
|
||||||
|
unsigned long ar_info_offset;
|
||||||
|
unsigned char ar_pointer_size;
|
||||||
|
unsigned char ar_segment_size;
|
||||||
|
}
|
||||||
|
DWARF2_Internal_ARange;
|
||||||
|
|
||||||
|
|
||||||
|
/* Tag names and codes. */
|
||||||
|
enum dwarf_tag
|
||||||
|
{
|
||||||
|
DW_TAG_padding = 0x00,
|
||||||
|
DW_TAG_array_type = 0x01,
|
||||||
|
DW_TAG_class_type = 0x02,
|
||||||
|
DW_TAG_entry_point = 0x03,
|
||||||
|
DW_TAG_enumeration_type = 0x04,
|
||||||
|
DW_TAG_formal_parameter = 0x05,
|
||||||
|
DW_TAG_imported_declaration = 0x08,
|
||||||
|
DW_TAG_label = 0x0a,
|
||||||
|
DW_TAG_lexical_block = 0x0b,
|
||||||
|
DW_TAG_member = 0x0d,
|
||||||
|
DW_TAG_pointer_type = 0x0f,
|
||||||
|
DW_TAG_reference_type = 0x10,
|
||||||
|
DW_TAG_compile_unit = 0x11,
|
||||||
|
DW_TAG_string_type = 0x12,
|
||||||
|
DW_TAG_structure_type = 0x13,
|
||||||
|
DW_TAG_subroutine_type = 0x15,
|
||||||
|
DW_TAG_typedef = 0x16,
|
||||||
|
DW_TAG_union_type = 0x17,
|
||||||
|
DW_TAG_unspecified_parameters = 0x18,
|
||||||
|
DW_TAG_variant = 0x19,
|
||||||
|
DW_TAG_common_block = 0x1a,
|
||||||
|
DW_TAG_common_inclusion = 0x1b,
|
||||||
|
DW_TAG_inheritance = 0x1c,
|
||||||
|
DW_TAG_inlined_subroutine = 0x1d,
|
||||||
|
DW_TAG_module = 0x1e,
|
||||||
|
DW_TAG_ptr_to_member_type = 0x1f,
|
||||||
|
DW_TAG_set_type = 0x20,
|
||||||
|
DW_TAG_subrange_type = 0x21,
|
||||||
|
DW_TAG_with_stmt = 0x22,
|
||||||
|
DW_TAG_access_declaration = 0x23,
|
||||||
|
DW_TAG_base_type = 0x24,
|
||||||
|
DW_TAG_catch_block = 0x25,
|
||||||
|
DW_TAG_const_type = 0x26,
|
||||||
|
DW_TAG_constant = 0x27,
|
||||||
|
DW_TAG_enumerator = 0x28,
|
||||||
|
DW_TAG_file_type = 0x29,
|
||||||
|
DW_TAG_friend = 0x2a,
|
||||||
|
DW_TAG_namelist = 0x2b,
|
||||||
|
DW_TAG_namelist_item = 0x2c,
|
||||||
|
DW_TAG_packed_type = 0x2d,
|
||||||
|
DW_TAG_subprogram = 0x2e,
|
||||||
|
DW_TAG_template_type_param = 0x2f,
|
||||||
|
DW_TAG_template_value_param = 0x30,
|
||||||
|
DW_TAG_thrown_type = 0x31,
|
||||||
|
DW_TAG_try_block = 0x32,
|
||||||
|
DW_TAG_variant_part = 0x33,
|
||||||
|
DW_TAG_variable = 0x34,
|
||||||
|
DW_TAG_volatile_type = 0x35,
|
||||||
|
/* DWARF 3. */
|
||||||
|
DW_TAG_dwarf_procedure = 0x36,
|
||||||
|
DW_TAG_restrict_type = 0x37,
|
||||||
|
DW_TAG_interface_type = 0x38,
|
||||||
|
DW_TAG_namespace = 0x39,
|
||||||
|
DW_TAG_imported_module = 0x3a,
|
||||||
|
DW_TAG_unspecified_type = 0x3b,
|
||||||
|
DW_TAG_partial_unit = 0x3c,
|
||||||
|
DW_TAG_imported_unit = 0x3d,
|
||||||
|
DW_TAG_condition = 0x3f,
|
||||||
|
DW_TAG_shared_type = 0x40,
|
||||||
|
/* DWARF 4. */
|
||||||
|
DW_TAG_type_unit = 0x41,
|
||||||
|
DW_TAG_rvalue_reference_type = 0x42,
|
||||||
|
DW_TAG_template_alias = 0x43,
|
||||||
|
|
||||||
|
DW_TAG_lo_user = 0x4080,
|
||||||
|
DW_TAG_hi_user = 0xffff,
|
||||||
|
|
||||||
|
/* SGI/MIPS Extensions. */
|
||||||
|
DW_TAG_MIPS_loop = 0x4081,
|
||||||
|
/* HP extensions. See: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz . */
|
||||||
|
DW_TAG_HP_array_descriptor = 0x4090,
|
||||||
|
/* GNU extensions. */
|
||||||
|
DW_TAG_format_label = 0x4101, /* For FORTRAN 77 and Fortran 90. */
|
||||||
|
DW_TAG_function_template = 0x4102, /* For C++. */
|
||||||
|
DW_TAG_class_template = 0x4103, /* For C++. */
|
||||||
|
DW_TAG_GNU_BINCL = 0x4104,
|
||||||
|
DW_TAG_GNU_EINCL = 0x4105,
|
||||||
|
/* Template template parameter.
|
||||||
|
See http://gcc.gnu.org/wiki/TemplateParmsDwarf . */
|
||||||
|
DW_TAG_GNU_template_template_param = 0x4106,
|
||||||
|
|
||||||
|
/* Template parameter pack extension, specified at
|
||||||
|
http://wiki.dwarfstd.org/index.php?title=C%2B%2B0x:_Variadic_templates
|
||||||
|
The values of these two TAGS are in the DW_TAG_GNU_* space until the tags
|
||||||
|
are properly part of DWARF 5. */
|
||||||
|
DW_TAG_GNU_template_parameter_pack = 0x4107,
|
||||||
|
DW_TAG_GNU_formal_parameter_pack = 0x4108,
|
||||||
|
/* Extensions for UPC. See: http://upc.gwu.edu/~upc. */
|
||||||
|
DW_TAG_upc_shared_type = 0x8765,
|
||||||
|
DW_TAG_upc_strict_type = 0x8766,
|
||||||
|
DW_TAG_upc_relaxed_type = 0x8767,
|
||||||
|
/* PGI (STMicroelectronics) extensions. No documentation available. */
|
||||||
|
DW_TAG_PGI_kanji_type = 0xA000,
|
||||||
|
DW_TAG_PGI_interface_block = 0xA020
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Flag that tells whether entry has a child or not. */
|
||||||
|
#define DW_children_no 0
|
||||||
|
#define DW_children_yes 1
|
||||||
|
|
||||||
|
/* Form names and codes. */
|
||||||
|
enum dwarf_form
|
||||||
|
{
|
||||||
|
DW_FORM_addr = 0x01,
|
||||||
|
DW_FORM_block2 = 0x03,
|
||||||
|
DW_FORM_block4 = 0x04,
|
||||||
|
DW_FORM_data2 = 0x05,
|
||||||
|
DW_FORM_data4 = 0x06,
|
||||||
|
DW_FORM_data8 = 0x07,
|
||||||
|
DW_FORM_string = 0x08,
|
||||||
|
DW_FORM_block = 0x09,
|
||||||
|
DW_FORM_block1 = 0x0a,
|
||||||
|
DW_FORM_data1 = 0x0b,
|
||||||
|
DW_FORM_flag = 0x0c,
|
||||||
|
DW_FORM_sdata = 0x0d,
|
||||||
|
DW_FORM_strp = 0x0e,
|
||||||
|
DW_FORM_udata = 0x0f,
|
||||||
|
DW_FORM_ref_addr = 0x10,
|
||||||
|
DW_FORM_ref1 = 0x11,
|
||||||
|
DW_FORM_ref2 = 0x12,
|
||||||
|
DW_FORM_ref4 = 0x13,
|
||||||
|
DW_FORM_ref8 = 0x14,
|
||||||
|
DW_FORM_ref_udata = 0x15,
|
||||||
|
DW_FORM_indirect = 0x16,
|
||||||
|
/* DWARF 4. */
|
||||||
|
DW_FORM_sec_offset = 0x17,
|
||||||
|
DW_FORM_exprloc = 0x18,
|
||||||
|
DW_FORM_flag_present = 0x19,
|
||||||
|
DW_FORM_ref_sig8 = 0x20
|
||||||
|
#define DW_FORM_sig8 DW_FORM_ref_sig8 /* Note: The use of DW_FORM_sig8 is deprecated. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Attribute names and codes. */
|
||||||
|
enum dwarf_attribute
|
||||||
|
{
|
||||||
|
DW_AT_sibling = 0x01,
|
||||||
|
DW_AT_location = 0x02,
|
||||||
|
DW_AT_name = 0x03,
|
||||||
|
DW_AT_ordering = 0x09,
|
||||||
|
DW_AT_subscr_data = 0x0a,
|
||||||
|
DW_AT_byte_size = 0x0b,
|
||||||
|
DW_AT_bit_offset = 0x0c,
|
||||||
|
DW_AT_bit_size = 0x0d,
|
||||||
|
DW_AT_element_list = 0x0f,
|
||||||
|
DW_AT_stmt_list = 0x10,
|
||||||
|
DW_AT_low_pc = 0x11,
|
||||||
|
DW_AT_high_pc = 0x12,
|
||||||
|
DW_AT_language = 0x13,
|
||||||
|
DW_AT_member = 0x14,
|
||||||
|
DW_AT_discr = 0x15,
|
||||||
|
DW_AT_discr_value = 0x16,
|
||||||
|
DW_AT_visibility = 0x17,
|
||||||
|
DW_AT_import = 0x18,
|
||||||
|
DW_AT_string_length = 0x19,
|
||||||
|
DW_AT_common_reference = 0x1a,
|
||||||
|
DW_AT_comp_dir = 0x1b,
|
||||||
|
DW_AT_const_value = 0x1c,
|
||||||
|
DW_AT_containing_type = 0x1d,
|
||||||
|
DW_AT_default_value = 0x1e,
|
||||||
|
DW_AT_inline = 0x20,
|
||||||
|
DW_AT_is_optional = 0x21,
|
||||||
|
DW_AT_lower_bound = 0x22,
|
||||||
|
DW_AT_producer = 0x25,
|
||||||
|
DW_AT_prototyped = 0x27,
|
||||||
|
DW_AT_return_addr = 0x2a,
|
||||||
|
DW_AT_start_scope = 0x2c,
|
||||||
|
DW_AT_bit_stride = 0x2e,
|
||||||
|
#define DW_AT_stride_size DW_AT_bit_stride /* Note: The use of DW_AT_stride_size is deprecated. */
|
||||||
|
DW_AT_upper_bound = 0x2f,
|
||||||
|
DW_AT_abstract_origin = 0x31,
|
||||||
|
DW_AT_accessibility = 0x32,
|
||||||
|
DW_AT_address_class = 0x33,
|
||||||
|
DW_AT_artificial = 0x34,
|
||||||
|
DW_AT_base_types = 0x35,
|
||||||
|
DW_AT_calling_convention = 0x36,
|
||||||
|
DW_AT_count = 0x37,
|
||||||
|
DW_AT_data_member_location = 0x38,
|
||||||
|
DW_AT_decl_column = 0x39,
|
||||||
|
DW_AT_decl_file = 0x3a,
|
||||||
|
DW_AT_decl_line = 0x3b,
|
||||||
|
DW_AT_declaration = 0x3c,
|
||||||
|
DW_AT_discr_list = 0x3d,
|
||||||
|
DW_AT_encoding = 0x3e,
|
||||||
|
DW_AT_external = 0x3f,
|
||||||
|
DW_AT_frame_base = 0x40,
|
||||||
|
DW_AT_friend = 0x41,
|
||||||
|
DW_AT_identifier_case = 0x42,
|
||||||
|
DW_AT_macro_info = 0x43,
|
||||||
|
DW_AT_namelist_items = 0x44,
|
||||||
|
DW_AT_priority = 0x45,
|
||||||
|
DW_AT_segment = 0x46,
|
||||||
|
DW_AT_specification = 0x47,
|
||||||
|
DW_AT_static_link = 0x48,
|
||||||
|
DW_AT_type = 0x49,
|
||||||
|
DW_AT_use_location = 0x4a,
|
||||||
|
DW_AT_variable_parameter = 0x4b,
|
||||||
|
DW_AT_virtuality = 0x4c,
|
||||||
|
DW_AT_vtable_elem_location = 0x4d,
|
||||||
|
/* DWARF 3 values. */
|
||||||
|
DW_AT_allocated = 0x4e,
|
||||||
|
DW_AT_associated = 0x4f,
|
||||||
|
DW_AT_data_location = 0x50,
|
||||||
|
DW_AT_byte_stride = 0x51,
|
||||||
|
#define DW_AT_stride DW_AT_byte_stride /* Note: The use of DW_AT_stride is deprecated. */
|
||||||
|
DW_AT_entry_pc = 0x52,
|
||||||
|
DW_AT_use_UTF8 = 0x53,
|
||||||
|
DW_AT_extension = 0x54,
|
||||||
|
DW_AT_ranges = 0x55,
|
||||||
|
DW_AT_trampoline = 0x56,
|
||||||
|
DW_AT_call_column = 0x57,
|
||||||
|
DW_AT_call_file = 0x58,
|
||||||
|
DW_AT_call_line = 0x59,
|
||||||
|
DW_AT_description = 0x5a,
|
||||||
|
DW_AT_binary_scale = 0x5b,
|
||||||
|
DW_AT_decimal_scale = 0x5c,
|
||||||
|
DW_AT_small = 0x5d,
|
||||||
|
DW_AT_decimal_sign = 0x5e,
|
||||||
|
DW_AT_digit_count = 0x5f,
|
||||||
|
DW_AT_picture_string = 0x60,
|
||||||
|
DW_AT_mutable = 0x61,
|
||||||
|
DW_AT_threads_scaled = 0x62,
|
||||||
|
DW_AT_explicit = 0x63,
|
||||||
|
DW_AT_object_pointer = 0x64,
|
||||||
|
DW_AT_endianity = 0x65,
|
||||||
|
DW_AT_elemental = 0x66,
|
||||||
|
DW_AT_pure = 0x67,
|
||||||
|
DW_AT_recursive = 0x68,
|
||||||
|
/* DWARF 4. */
|
||||||
|
DW_AT_signature = 0x69,
|
||||||
|
DW_AT_main_subprogram = 0x6a,
|
||||||
|
DW_AT_data_bit_offset = 0x6b,
|
||||||
|
DW_AT_const_expr = 0x6c,
|
||||||
|
DW_AT_enum_class = 0x6d,
|
||||||
|
DW_AT_linkage_name = 0x6e,
|
||||||
|
|
||||||
|
DW_AT_lo_user = 0x2000, /* Implementation-defined range start. */
|
||||||
|
DW_AT_hi_user = 0x3ff0, /* Implementation-defined range end. */
|
||||||
|
|
||||||
|
/* SGI/MIPS extensions. */
|
||||||
|
DW_AT_MIPS_fde = 0x2001,
|
||||||
|
DW_AT_MIPS_loop_begin = 0x2002,
|
||||||
|
DW_AT_MIPS_tail_loop_begin = 0x2003,
|
||||||
|
DW_AT_MIPS_epilog_begin = 0x2004,
|
||||||
|
DW_AT_MIPS_loop_unroll_factor = 0x2005,
|
||||||
|
DW_AT_MIPS_software_pipeline_depth = 0x2006,
|
||||||
|
DW_AT_MIPS_linkage_name = 0x2007,
|
||||||
|
DW_AT_MIPS_stride = 0x2008,
|
||||||
|
DW_AT_MIPS_abstract_name = 0x2009,
|
||||||
|
DW_AT_MIPS_clone_origin = 0x200a,
|
||||||
|
DW_AT_MIPS_has_inlines = 0x200b,
|
||||||
|
/* HP extensions. */
|
||||||
|
DW_AT_HP_block_index = 0x2000,
|
||||||
|
DW_AT_HP_unmodifiable = 0x2001, /* Same as DW_AT_MIPS_fde. */
|
||||||
|
DW_AT_HP_actuals_stmt_list = 0x2010,
|
||||||
|
DW_AT_HP_proc_per_section = 0x2011,
|
||||||
|
DW_AT_HP_raw_data_ptr = 0x2012,
|
||||||
|
DW_AT_HP_pass_by_reference = 0x2013,
|
||||||
|
DW_AT_HP_opt_level = 0x2014,
|
||||||
|
DW_AT_HP_prof_version_id = 0x2015,
|
||||||
|
DW_AT_HP_opt_flags = 0x2016,
|
||||||
|
DW_AT_HP_cold_region_low_pc = 0x2017,
|
||||||
|
DW_AT_HP_cold_region_high_pc = 0x2018,
|
||||||
|
DW_AT_HP_all_variables_modifiable = 0x2019,
|
||||||
|
DW_AT_HP_linkage_name = 0x201a,
|
||||||
|
DW_AT_HP_prof_flags = 0x201b, /* In comp unit of procs_info for -g. */
|
||||||
|
/* GNU extensions. */
|
||||||
|
DW_AT_sf_names = 0x2101,
|
||||||
|
DW_AT_src_info = 0x2102,
|
||||||
|
DW_AT_mac_info = 0x2103,
|
||||||
|
DW_AT_src_coords = 0x2104,
|
||||||
|
DW_AT_body_begin = 0x2105,
|
||||||
|
DW_AT_body_end = 0x2106,
|
||||||
|
DW_AT_GNU_vector = 0x2107,
|
||||||
|
/* Thread-safety annotations.
|
||||||
|
See http://gcc.gnu.org/wiki/ThreadSafetyAnnotation . */
|
||||||
|
DW_AT_GNU_guarded_by = 0x2108,
|
||||||
|
DW_AT_GNU_pt_guarded_by = 0x2109,
|
||||||
|
DW_AT_GNU_guarded = 0x210a,
|
||||||
|
DW_AT_GNU_pt_guarded = 0x210b,
|
||||||
|
DW_AT_GNU_locks_excluded = 0x210c,
|
||||||
|
DW_AT_GNU_exclusive_locks_required = 0x210d,
|
||||||
|
DW_AT_GNU_shared_locks_required = 0x210e,
|
||||||
|
/* One-definition rule violation detection.
|
||||||
|
See http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo . */
|
||||||
|
DW_AT_GNU_odr_signature = 0x210f,
|
||||||
|
/* Template template argument name.
|
||||||
|
See http://gcc.gnu.org/wiki/TemplateParmsDwarf . */
|
||||||
|
DW_AT_GNU_template_name = 0x2110,
|
||||||
|
/* VMS extensions. */
|
||||||
|
DW_AT_VMS_rtnbeg_pd_address = 0x2201,
|
||||||
|
/* GNAT extensions. */
|
||||||
|
/* GNAT descriptive type.
|
||||||
|
See http://gcc.gnu.org/wiki/DW_AT_GNAT_descriptive_type . */
|
||||||
|
DW_AT_use_GNAT_descriptive_type = 0x2301,
|
||||||
|
DW_AT_GNAT_descriptive_type = 0x2302,
|
||||||
|
/* UPC extension. */
|
||||||
|
DW_AT_upc_threads_scaled = 0x3210,
|
||||||
|
/* PGI (STMicroelectronics) extensions. */
|
||||||
|
DW_AT_PGI_lbase = 0x3a00,
|
||||||
|
DW_AT_PGI_soffset = 0x3a01,
|
||||||
|
DW_AT_PGI_lstride = 0x3a02
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Location atom names and codes. */
|
||||||
|
enum dwarf_location_atom
|
||||||
|
{
|
||||||
|
DW_OP_addr = 0x03,
|
||||||
|
DW_OP_deref = 0x06,
|
||||||
|
DW_OP_const1u = 0x08,
|
||||||
|
DW_OP_const1s = 0x09,
|
||||||
|
DW_OP_const2u = 0x0a,
|
||||||
|
DW_OP_const2s = 0x0b,
|
||||||
|
DW_OP_const4u = 0x0c,
|
||||||
|
DW_OP_const4s = 0x0d,
|
||||||
|
DW_OP_const8u = 0x0e,
|
||||||
|
DW_OP_const8s = 0x0f,
|
||||||
|
DW_OP_constu = 0x10,
|
||||||
|
DW_OP_consts = 0x11,
|
||||||
|
DW_OP_dup = 0x12,
|
||||||
|
DW_OP_drop = 0x13,
|
||||||
|
DW_OP_over = 0x14,
|
||||||
|
DW_OP_pick = 0x15,
|
||||||
|
DW_OP_swap = 0x16,
|
||||||
|
DW_OP_rot = 0x17,
|
||||||
|
DW_OP_xderef = 0x18,
|
||||||
|
DW_OP_abs = 0x19,
|
||||||
|
DW_OP_and = 0x1a,
|
||||||
|
DW_OP_div = 0x1b,
|
||||||
|
DW_OP_minus = 0x1c,
|
||||||
|
DW_OP_mod = 0x1d,
|
||||||
|
DW_OP_mul = 0x1e,
|
||||||
|
DW_OP_neg = 0x1f,
|
||||||
|
DW_OP_not = 0x20,
|
||||||
|
DW_OP_or = 0x21,
|
||||||
|
DW_OP_plus = 0x22,
|
||||||
|
DW_OP_plus_uconst = 0x23,
|
||||||
|
DW_OP_shl = 0x24,
|
||||||
|
DW_OP_shr = 0x25,
|
||||||
|
DW_OP_shra = 0x26,
|
||||||
|
DW_OP_xor = 0x27,
|
||||||
|
DW_OP_bra = 0x28,
|
||||||
|
DW_OP_eq = 0x29,
|
||||||
|
DW_OP_ge = 0x2a,
|
||||||
|
DW_OP_gt = 0x2b,
|
||||||
|
DW_OP_le = 0x2c,
|
||||||
|
DW_OP_lt = 0x2d,
|
||||||
|
DW_OP_ne = 0x2e,
|
||||||
|
DW_OP_skip = 0x2f,
|
||||||
|
DW_OP_lit0 = 0x30,
|
||||||
|
DW_OP_lit1 = 0x31,
|
||||||
|
DW_OP_lit2 = 0x32,
|
||||||
|
DW_OP_lit3 = 0x33,
|
||||||
|
DW_OP_lit4 = 0x34,
|
||||||
|
DW_OP_lit5 = 0x35,
|
||||||
|
DW_OP_lit6 = 0x36,
|
||||||
|
DW_OP_lit7 = 0x37,
|
||||||
|
DW_OP_lit8 = 0x38,
|
||||||
|
DW_OP_lit9 = 0x39,
|
||||||
|
DW_OP_lit10 = 0x3a,
|
||||||
|
DW_OP_lit11 = 0x3b,
|
||||||
|
DW_OP_lit12 = 0x3c,
|
||||||
|
DW_OP_lit13 = 0x3d,
|
||||||
|
DW_OP_lit14 = 0x3e,
|
||||||
|
DW_OP_lit15 = 0x3f,
|
||||||
|
DW_OP_lit16 = 0x40,
|
||||||
|
DW_OP_lit17 = 0x41,
|
||||||
|
DW_OP_lit18 = 0x42,
|
||||||
|
DW_OP_lit19 = 0x43,
|
||||||
|
DW_OP_lit20 = 0x44,
|
||||||
|
DW_OP_lit21 = 0x45,
|
||||||
|
DW_OP_lit22 = 0x46,
|
||||||
|
DW_OP_lit23 = 0x47,
|
||||||
|
DW_OP_lit24 = 0x48,
|
||||||
|
DW_OP_lit25 = 0x49,
|
||||||
|
DW_OP_lit26 = 0x4a,
|
||||||
|
DW_OP_lit27 = 0x4b,
|
||||||
|
DW_OP_lit28 = 0x4c,
|
||||||
|
DW_OP_lit29 = 0x4d,
|
||||||
|
DW_OP_lit30 = 0x4e,
|
||||||
|
DW_OP_lit31 = 0x4f,
|
||||||
|
DW_OP_reg0 = 0x50,
|
||||||
|
DW_OP_reg1 = 0x51,
|
||||||
|
DW_OP_reg2 = 0x52,
|
||||||
|
DW_OP_reg3 = 0x53,
|
||||||
|
DW_OP_reg4 = 0x54,
|
||||||
|
DW_OP_reg5 = 0x55,
|
||||||
|
DW_OP_reg6 = 0x56,
|
||||||
|
DW_OP_reg7 = 0x57,
|
||||||
|
DW_OP_reg8 = 0x58,
|
||||||
|
DW_OP_reg9 = 0x59,
|
||||||
|
DW_OP_reg10 = 0x5a,
|
||||||
|
DW_OP_reg11 = 0x5b,
|
||||||
|
DW_OP_reg12 = 0x5c,
|
||||||
|
DW_OP_reg13 = 0x5d,
|
||||||
|
DW_OP_reg14 = 0x5e,
|
||||||
|
DW_OP_reg15 = 0x5f,
|
||||||
|
DW_OP_reg16 = 0x60,
|
||||||
|
DW_OP_reg17 = 0x61,
|
||||||
|
DW_OP_reg18 = 0x62,
|
||||||
|
DW_OP_reg19 = 0x63,
|
||||||
|
DW_OP_reg20 = 0x64,
|
||||||
|
DW_OP_reg21 = 0x65,
|
||||||
|
DW_OP_reg22 = 0x66,
|
||||||
|
DW_OP_reg23 = 0x67,
|
||||||
|
DW_OP_reg24 = 0x68,
|
||||||
|
DW_OP_reg25 = 0x69,
|
||||||
|
DW_OP_reg26 = 0x6a,
|
||||||
|
DW_OP_reg27 = 0x6b,
|
||||||
|
DW_OP_reg28 = 0x6c,
|
||||||
|
DW_OP_reg29 = 0x6d,
|
||||||
|
DW_OP_reg30 = 0x6e,
|
||||||
|
DW_OP_reg31 = 0x6f,
|
||||||
|
DW_OP_breg0 = 0x70,
|
||||||
|
DW_OP_breg1 = 0x71,
|
||||||
|
DW_OP_breg2 = 0x72,
|
||||||
|
DW_OP_breg3 = 0x73,
|
||||||
|
DW_OP_breg4 = 0x74,
|
||||||
|
DW_OP_breg5 = 0x75,
|
||||||
|
DW_OP_breg6 = 0x76,
|
||||||
|
DW_OP_breg7 = 0x77,
|
||||||
|
DW_OP_breg8 = 0x78,
|
||||||
|
DW_OP_breg9 = 0x79,
|
||||||
|
DW_OP_breg10 = 0x7a,
|
||||||
|
DW_OP_breg11 = 0x7b,
|
||||||
|
DW_OP_breg12 = 0x7c,
|
||||||
|
DW_OP_breg13 = 0x7d,
|
||||||
|
DW_OP_breg14 = 0x7e,
|
||||||
|
DW_OP_breg15 = 0x7f,
|
||||||
|
DW_OP_breg16 = 0x80,
|
||||||
|
DW_OP_breg17 = 0x81,
|
||||||
|
DW_OP_breg18 = 0x82,
|
||||||
|
DW_OP_breg19 = 0x83,
|
||||||
|
DW_OP_breg20 = 0x84,
|
||||||
|
DW_OP_breg21 = 0x85,
|
||||||
|
DW_OP_breg22 = 0x86,
|
||||||
|
DW_OP_breg23 = 0x87,
|
||||||
|
DW_OP_breg24 = 0x88,
|
||||||
|
DW_OP_breg25 = 0x89,
|
||||||
|
DW_OP_breg26 = 0x8a,
|
||||||
|
DW_OP_breg27 = 0x8b,
|
||||||
|
DW_OP_breg28 = 0x8c,
|
||||||
|
DW_OP_breg29 = 0x8d,
|
||||||
|
DW_OP_breg30 = 0x8e,
|
||||||
|
DW_OP_breg31 = 0x8f,
|
||||||
|
DW_OP_regx = 0x90,
|
||||||
|
DW_OP_fbreg = 0x91,
|
||||||
|
DW_OP_bregx = 0x92,
|
||||||
|
DW_OP_piece = 0x93,
|
||||||
|
DW_OP_deref_size = 0x94,
|
||||||
|
DW_OP_xderef_size = 0x95,
|
||||||
|
DW_OP_nop = 0x96,
|
||||||
|
/* DWARF 3 extensions. */
|
||||||
|
DW_OP_push_object_address = 0x97,
|
||||||
|
DW_OP_call2 = 0x98,
|
||||||
|
DW_OP_call4 = 0x99,
|
||||||
|
DW_OP_call_ref = 0x9a,
|
||||||
|
DW_OP_form_tls_address = 0x9b,
|
||||||
|
DW_OP_call_frame_cfa = 0x9c,
|
||||||
|
DW_OP_bit_piece = 0x9d,
|
||||||
|
|
||||||
|
/* DWARF 4 extensions. */
|
||||||
|
DW_OP_implicit_value = 0x9e,
|
||||||
|
DW_OP_stack_value = 0x9f,
|
||||||
|
|
||||||
|
DW_OP_lo_user = 0xe0, /* Implementation-defined range start. */
|
||||||
|
DW_OP_hi_user = 0xff, /* Implementation-defined range end. */
|
||||||
|
|
||||||
|
/* GNU extensions. */
|
||||||
|
DW_OP_GNU_push_tls_address = 0xe0,
|
||||||
|
/* The following is for marking variables that are uninitialized. */
|
||||||
|
DW_OP_GNU_uninit = 0xf0,
|
||||||
|
DW_OP_GNU_encoded_addr = 0xf1,
|
||||||
|
/* HP extensions. */
|
||||||
|
DW_OP_HP_unknown = 0xe0, /* Ouch, the same as GNU_push_tls_address. */
|
||||||
|
DW_OP_HP_is_value = 0xe1,
|
||||||
|
DW_OP_HP_fltconst4 = 0xe2,
|
||||||
|
DW_OP_HP_fltconst8 = 0xe3,
|
||||||
|
DW_OP_HP_mod_range = 0xe4,
|
||||||
|
DW_OP_HP_unmod_range = 0xe5,
|
||||||
|
DW_OP_HP_tls = 0xe6,
|
||||||
|
/* PGI (STMicroelectronics) extensions. */
|
||||||
|
DW_OP_PGI_omp_thread_num = 0xf8
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Type encodings. */
|
||||||
|
enum dwarf_type
|
||||||
|
{
|
||||||
|
DW_ATE_void = 0x0,
|
||||||
|
DW_ATE_address = 0x1,
|
||||||
|
DW_ATE_boolean = 0x2,
|
||||||
|
DW_ATE_complex_float = 0x3,
|
||||||
|
DW_ATE_float = 0x4,
|
||||||
|
DW_ATE_signed = 0x5,
|
||||||
|
DW_ATE_signed_char = 0x6,
|
||||||
|
DW_ATE_unsigned = 0x7,
|
||||||
|
DW_ATE_unsigned_char = 0x8,
|
||||||
|
/* DWARF 3. */
|
||||||
|
DW_ATE_imaginary_float = 0x9,
|
||||||
|
DW_ATE_packed_decimal = 0xa,
|
||||||
|
DW_ATE_numeric_string = 0xb,
|
||||||
|
DW_ATE_edited = 0xc,
|
||||||
|
DW_ATE_signed_fixed = 0xd,
|
||||||
|
DW_ATE_unsigned_fixed = 0xe,
|
||||||
|
DW_ATE_decimal_float = 0xf,
|
||||||
|
|
||||||
|
DW_ATE_lo_user = 0x80,
|
||||||
|
DW_ATE_hi_user = 0xff,
|
||||||
|
|
||||||
|
/* HP extensions. */
|
||||||
|
DW_ATE_HP_float80 = 0x80, /* Floating-point (80 bit). */
|
||||||
|
DW_ATE_HP_complex_float80 = 0x81, /* Complex floating-point (80 bit). */
|
||||||
|
DW_ATE_HP_float128 = 0x82, /* Floating-point (128 bit). */
|
||||||
|
DW_ATE_HP_complex_float128 = 0x83, /* Complex floating-point (128 bit). */
|
||||||
|
DW_ATE_HP_floathpintel = 0x84, /* Floating-point (82 bit IA64). */
|
||||||
|
DW_ATE_HP_imaginary_float80 = 0x85,
|
||||||
|
DW_ATE_HP_imaginary_float128 = 0x86
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Decimal sign encodings. */
|
||||||
|
enum dwarf_decimal_sign_encoding
|
||||||
|
{
|
||||||
|
/* DWARF 3. */
|
||||||
|
DW_DS_unsigned = 0x01,
|
||||||
|
DW_DS_leading_overpunch = 0x02,
|
||||||
|
DW_DS_trailing_overpunch = 0x03,
|
||||||
|
DW_DS_leading_separate = 0x04,
|
||||||
|
DW_DS_trailing_separate = 0x05
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Endianity encodings. */
|
||||||
|
enum dwarf_endianity_encoding
|
||||||
|
{
|
||||||
|
/* DWARF 3. */
|
||||||
|
DW_END_default = 0x00,
|
||||||
|
DW_END_big = 0x01,
|
||||||
|
DW_END_little = 0x02,
|
||||||
|
|
||||||
|
DW_END_lo_user = 0x40,
|
||||||
|
DW_END_hi_user = 0xff
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Array ordering names and codes. */
|
||||||
|
enum dwarf_array_dim_ordering
|
||||||
|
{
|
||||||
|
DW_ORD_row_major = 0,
|
||||||
|
DW_ORD_col_major = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Access attribute. */
|
||||||
|
enum dwarf_access_attribute
|
||||||
|
{
|
||||||
|
DW_ACCESS_public = 1,
|
||||||
|
DW_ACCESS_protected = 2,
|
||||||
|
DW_ACCESS_private = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Visibility. */
|
||||||
|
enum dwarf_visibility_attribute
|
||||||
|
{
|
||||||
|
DW_VIS_local = 1,
|
||||||
|
DW_VIS_exported = 2,
|
||||||
|
DW_VIS_qualified = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Virtuality. */
|
||||||
|
enum dwarf_virtuality_attribute
|
||||||
|
{
|
||||||
|
DW_VIRTUALITY_none = 0,
|
||||||
|
DW_VIRTUALITY_virtual = 1,
|
||||||
|
DW_VIRTUALITY_pure_virtual = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Case sensitivity. */
|
||||||
|
enum dwarf_id_case
|
||||||
|
{
|
||||||
|
DW_ID_case_sensitive = 0,
|
||||||
|
DW_ID_up_case = 1,
|
||||||
|
DW_ID_down_case = 2,
|
||||||
|
DW_ID_case_insensitive = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Calling convention. */
|
||||||
|
enum dwarf_calling_convention
|
||||||
|
{
|
||||||
|
DW_CC_normal = 0x1,
|
||||||
|
DW_CC_program = 0x2,
|
||||||
|
DW_CC_nocall = 0x3,
|
||||||
|
|
||||||
|
DW_CC_lo_user = 0x40,
|
||||||
|
DW_CC_hi_user = 0xff,
|
||||||
|
|
||||||
|
DW_CC_GNU_renesas_sh = 0x40,
|
||||||
|
DW_CC_GNU_borland_fastcall_i386 = 0x41
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Inline attribute. */
|
||||||
|
enum dwarf_inline_attribute
|
||||||
|
{
|
||||||
|
DW_INL_not_inlined = 0,
|
||||||
|
DW_INL_inlined = 1,
|
||||||
|
DW_INL_declared_not_inlined = 2,
|
||||||
|
DW_INL_declared_inlined = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Discriminant lists. */
|
||||||
|
enum dwarf_discrim_list
|
||||||
|
{
|
||||||
|
DW_DSC_label = 0,
|
||||||
|
DW_DSC_range = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Line number opcodes. */
|
||||||
|
enum dwarf_line_number_ops
|
||||||
|
{
|
||||||
|
DW_LNS_extended_op = 0,
|
||||||
|
DW_LNS_copy = 1,
|
||||||
|
DW_LNS_advance_pc = 2,
|
||||||
|
DW_LNS_advance_line = 3,
|
||||||
|
DW_LNS_set_file = 4,
|
||||||
|
DW_LNS_set_column = 5,
|
||||||
|
DW_LNS_negate_stmt = 6,
|
||||||
|
DW_LNS_set_basic_block = 7,
|
||||||
|
DW_LNS_const_add_pc = 8,
|
||||||
|
DW_LNS_fixed_advance_pc = 9,
|
||||||
|
/* DWARF 3. */
|
||||||
|
DW_LNS_set_prologue_end = 10,
|
||||||
|
DW_LNS_set_epilogue_begin = 11,
|
||||||
|
DW_LNS_set_isa = 12
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Line number extended opcodes. */
|
||||||
|
enum dwarf_line_number_x_ops
|
||||||
|
{
|
||||||
|
DW_LNE_end_sequence = 1,
|
||||||
|
DW_LNE_set_address = 2,
|
||||||
|
DW_LNE_define_file = 3,
|
||||||
|
DW_LNE_set_discriminator = 4,
|
||||||
|
/* HP extensions. */
|
||||||
|
DW_LNE_HP_negate_is_UV_update = 0x11,
|
||||||
|
DW_LNE_HP_push_context = 0x12,
|
||||||
|
DW_LNE_HP_pop_context = 0x13,
|
||||||
|
DW_LNE_HP_set_file_line_column = 0x14,
|
||||||
|
DW_LNE_HP_set_routine_name = 0x15,
|
||||||
|
DW_LNE_HP_set_sequence = 0x16,
|
||||||
|
DW_LNE_HP_negate_post_semantics = 0x17,
|
||||||
|
DW_LNE_HP_negate_function_exit = 0x18,
|
||||||
|
DW_LNE_HP_negate_front_end_logical = 0x19,
|
||||||
|
DW_LNE_HP_define_proc = 0x20,
|
||||||
|
|
||||||
|
DW_LNE_lo_user = 0x80,
|
||||||
|
DW_LNE_hi_user = 0xff
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Call frame information. */
|
||||||
|
enum dwarf_call_frame_info
|
||||||
|
{
|
||||||
|
DW_CFA_advance_loc = 0x40,
|
||||||
|
DW_CFA_offset = 0x80,
|
||||||
|
DW_CFA_restore = 0xc0,
|
||||||
|
DW_CFA_nop = 0x00,
|
||||||
|
DW_CFA_set_loc = 0x01,
|
||||||
|
DW_CFA_advance_loc1 = 0x02,
|
||||||
|
DW_CFA_advance_loc2 = 0x03,
|
||||||
|
DW_CFA_advance_loc4 = 0x04,
|
||||||
|
DW_CFA_offset_extended = 0x05,
|
||||||
|
DW_CFA_restore_extended = 0x06,
|
||||||
|
DW_CFA_undefined = 0x07,
|
||||||
|
DW_CFA_same_value = 0x08,
|
||||||
|
DW_CFA_register = 0x09,
|
||||||
|
DW_CFA_remember_state = 0x0a,
|
||||||
|
DW_CFA_restore_state = 0x0b,
|
||||||
|
DW_CFA_def_cfa = 0x0c,
|
||||||
|
DW_CFA_def_cfa_register = 0x0d,
|
||||||
|
DW_CFA_def_cfa_offset = 0x0e,
|
||||||
|
/* DWARF 3. */
|
||||||
|
DW_CFA_def_cfa_expression = 0x0f,
|
||||||
|
DW_CFA_expression = 0x10,
|
||||||
|
DW_CFA_offset_extended_sf = 0x11,
|
||||||
|
DW_CFA_def_cfa_sf = 0x12,
|
||||||
|
DW_CFA_def_cfa_offset_sf = 0x13,
|
||||||
|
DW_CFA_val_offset = 0x14,
|
||||||
|
DW_CFA_val_offset_sf = 0x15,
|
||||||
|
DW_CFA_val_expression = 0x16,
|
||||||
|
|
||||||
|
DW_CFA_lo_user = 0x1c,
|
||||||
|
DW_CFA_hi_user = 0x3f,
|
||||||
|
|
||||||
|
/* SGI/MIPS specific. */
|
||||||
|
DW_CFA_MIPS_advance_loc8 = 0x1d,
|
||||||
|
/* GNU extensions. */
|
||||||
|
DW_CFA_GNU_window_save = 0x2d,
|
||||||
|
DW_CFA_GNU_args_size = 0x2e,
|
||||||
|
DW_CFA_GNU_negative_offset_extended = 0x2f
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DW_CIE_ID 0xffffffff
|
||||||
|
#define DW64_CIE_ID 0xffffffffffffffffULL
|
||||||
|
#define DW_CIE_VERSION 1
|
||||||
|
|
||||||
|
#define DW_CFA_extended 0
|
||||||
|
|
||||||
|
#define DW_CHILDREN_no 0x00
|
||||||
|
#define DW_CHILDREN_yes 0x01
|
||||||
|
|
||||||
|
#define DW_ADDR_none 0
|
||||||
|
|
||||||
|
/* Source language names and codes. */
|
||||||
|
enum dwarf_source_language
|
||||||
|
{
|
||||||
|
DW_LANG_C89 = 0x0001,
|
||||||
|
DW_LANG_C = 0x0002,
|
||||||
|
DW_LANG_Ada83 = 0x0003,
|
||||||
|
DW_LANG_C_plus_plus = 0x0004,
|
||||||
|
DW_LANG_Cobol74 = 0x0005,
|
||||||
|
DW_LANG_Cobol85 = 0x0006,
|
||||||
|
DW_LANG_Fortran77 = 0x0007,
|
||||||
|
DW_LANG_Fortran90 = 0x0008,
|
||||||
|
DW_LANG_Pascal83 = 0x0009,
|
||||||
|
DW_LANG_Modula2 = 0x000a,
|
||||||
|
/* DWARF 3. */
|
||||||
|
DW_LANG_Java = 0x000b,
|
||||||
|
DW_LANG_C99 = 0x000c,
|
||||||
|
DW_LANG_Ada95 = 0x000d,
|
||||||
|
DW_LANG_Fortran95 = 0x000e,
|
||||||
|
DW_LANG_PLI = 0x000f,
|
||||||
|
DW_LANG_ObjC = 0x0010,
|
||||||
|
DW_LANG_ObjC_plus_plus = 0x0011,
|
||||||
|
DW_LANG_UPC = 0x0012,
|
||||||
|
DW_LANG_D = 0x0013,
|
||||||
|
/* DWARF 4. */
|
||||||
|
DW_LANG_Python = 0x0014,
|
||||||
|
|
||||||
|
DW_LANG_lo_user = 0x8000, /* Implementation-defined range start. */
|
||||||
|
DW_LANG_hi_user = 0xffff, /* Implementation-defined range start. */
|
||||||
|
|
||||||
|
/* MIPS. */
|
||||||
|
DW_LANG_Mips_Assembler = 0x8001,
|
||||||
|
/* UPC. */
|
||||||
|
DW_LANG_Upc = 0x8765
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Names and codes for macro information. */
|
||||||
|
enum dwarf_macinfo_record_type
|
||||||
|
{
|
||||||
|
DW_MACINFO_define = 1,
|
||||||
|
DW_MACINFO_undef = 2,
|
||||||
|
DW_MACINFO_start_file = 3,
|
||||||
|
DW_MACINFO_end_file = 4,
|
||||||
|
DW_MACINFO_vendor_ext = 255
|
||||||
|
};
|
||||||
|
|
||||||
|
/* @@@ For use with GNU frame unwind information. */
|
||||||
|
|
||||||
|
#define DW_EH_PE_absptr 0x00
|
||||||
|
#define DW_EH_PE_omit 0xff
|
||||||
|
|
||||||
|
#define DW_EH_PE_uleb128 0x01
|
||||||
|
#define DW_EH_PE_udata2 0x02
|
||||||
|
#define DW_EH_PE_udata4 0x03
|
||||||
|
#define DW_EH_PE_udata8 0x04
|
||||||
|
#define DW_EH_PE_sleb128 0x09
|
||||||
|
#define DW_EH_PE_sdata2 0x0A
|
||||||
|
#define DW_EH_PE_sdata4 0x0B
|
||||||
|
#define DW_EH_PE_sdata8 0x0C
|
||||||
|
#define DW_EH_PE_signed 0x08
|
||||||
|
|
||||||
|
#define DW_EH_PE_pcrel 0x10
|
||||||
|
#define DW_EH_PE_textrel 0x20
|
||||||
|
#define DW_EH_PE_datarel 0x30
|
||||||
|
#define DW_EH_PE_funcrel 0x40
|
||||||
|
#define DW_EH_PE_aligned 0x50
|
||||||
|
|
||||||
|
#define DW_EH_PE_indirect 0x80
|
||||||
|
|
||||||
|
#endif /* _ELF_DWARF2_H */
|
60
contrib/sdk/sources/gcc_eh/filenames.h
Normal file
60
contrib/sdk/sources/gcc_eh/filenames.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/* Macros for taking apart, interpreting and processing file names.
|
||||||
|
|
||||||
|
These are here because some non-Posix (a.k.a. DOSish) systems have
|
||||||
|
drive letter brain-damage at the beginning of an absolute file name,
|
||||||
|
use forward- and back-slash in path names interchangeably, and
|
||||||
|
some of them have case-insensitive file names.
|
||||||
|
|
||||||
|
Copyright 2000, 2001, 2007 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of BFD, the Binary File Descriptor library.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||||
|
|
||||||
|
#ifndef FILENAMES_H
|
||||||
|
#define FILENAMES_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__) || defined (__CYGWIN__)
|
||||||
|
|
||||||
|
#ifndef HAVE_DOS_BASED_FILE_SYSTEM
|
||||||
|
#define HAVE_DOS_BASED_FILE_SYSTEM 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IS_DIR_SEPARATOR(c) ((c) == '/' || (c) == '\\')
|
||||||
|
/* Note that IS_ABSOLUTE_PATH accepts d:foo as well, although it is
|
||||||
|
only semi-absolute. This is because the users of IS_ABSOLUTE_PATH
|
||||||
|
want to know whether to prepend the current working directory to
|
||||||
|
a file name, which should not be done with a name like d:foo. */
|
||||||
|
#define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0]) || (((f)[0]) && ((f)[1] == ':')))
|
||||||
|
|
||||||
|
#else /* not DOSish */
|
||||||
|
|
||||||
|
#define IS_DIR_SEPARATOR(c) ((c) == '/')
|
||||||
|
#define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0]))
|
||||||
|
|
||||||
|
#endif /* not DOSish */
|
||||||
|
|
||||||
|
extern int filename_cmp (const char *s1, const char *s2);
|
||||||
|
#define FILENAME_CMP(s1, s2) filename_cmp(s1, s2)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* FILENAMES_H */
|
292
contrib/sdk/sources/gcc_eh/gthr-single.h
Normal file
292
contrib/sdk/sources/gcc_eh/gthr-single.h
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
/* Threads compatibility routines for libgcc2 and libobjc. */
|
||||||
|
/* Compile this one with gcc. */
|
||||||
|
/* Copyright (C) 1997, 1999, 2000, 2004, 2008, 2009
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_GTHR_SINGLE_H
|
||||||
|
#define GCC_GTHR_SINGLE_H
|
||||||
|
|
||||||
|
/* Just provide compatibility for mutex handling. */
|
||||||
|
|
||||||
|
typedef int __gthread_key_t;
|
||||||
|
typedef int __gthread_once_t;
|
||||||
|
typedef int __gthread_mutex_t;
|
||||||
|
typedef int __gthread_recursive_mutex_t;
|
||||||
|
|
||||||
|
#define __GTHREAD_ONCE_INIT 0
|
||||||
|
#define __GTHREAD_MUTEX_INIT 0
|
||||||
|
#define __GTHREAD_RECURSIVE_MUTEX_INIT 0
|
||||||
|
|
||||||
|
#define UNUSED __attribute__((unused))
|
||||||
|
|
||||||
|
#ifdef _LIBOBJC
|
||||||
|
|
||||||
|
/* Thread local storage for a single thread */
|
||||||
|
static void *thread_local_storage = NULL;
|
||||||
|
|
||||||
|
/* Backend initialization functions */
|
||||||
|
|
||||||
|
/* Initialize the threads subsystem. */
|
||||||
|
static inline int
|
||||||
|
__gthread_objc_init_thread_system (void)
|
||||||
|
{
|
||||||
|
/* No thread support available */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the threads subsystem. */
|
||||||
|
static inline int
|
||||||
|
__gthread_objc_close_thread_system (void)
|
||||||
|
{
|
||||||
|
/* No thread support available */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Backend thread functions */
|
||||||
|
|
||||||
|
/* Create a new thread of execution. */
|
||||||
|
static inline objc_thread_t
|
||||||
|
__gthread_objc_thread_detach (void (* func)(void *), void * arg UNUSED)
|
||||||
|
{
|
||||||
|
/* No thread support available */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the current thread's priority. */
|
||||||
|
static inline int
|
||||||
|
__gthread_objc_thread_set_priority (int priority UNUSED)
|
||||||
|
{
|
||||||
|
/* No thread support available */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the current thread's priority. */
|
||||||
|
static inline int
|
||||||
|
__gthread_objc_thread_get_priority (void)
|
||||||
|
{
|
||||||
|
return OBJC_THREAD_INTERACTIVE_PRIORITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Yield our process time to another thread. */
|
||||||
|
static inline void
|
||||||
|
__gthread_objc_thread_yield (void)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Terminate the current thread. */
|
||||||
|
static inline int
|
||||||
|
__gthread_objc_thread_exit (void)
|
||||||
|
{
|
||||||
|
/* No thread support available */
|
||||||
|
/* Should we really exit the program */
|
||||||
|
/* exit (&__objc_thread_exit_status); */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns an integer value which uniquely describes a thread. */
|
||||||
|
static inline objc_thread_t
|
||||||
|
__gthread_objc_thread_id (void)
|
||||||
|
{
|
||||||
|
/* No thread support, use 1. */
|
||||||
|
return (objc_thread_t) 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sets the thread's local storage pointer. */
|
||||||
|
static inline int
|
||||||
|
__gthread_objc_thread_set_data (void *value)
|
||||||
|
{
|
||||||
|
thread_local_storage = value;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the thread's local storage pointer. */
|
||||||
|
static inline void *
|
||||||
|
__gthread_objc_thread_get_data (void)
|
||||||
|
{
|
||||||
|
return thread_local_storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Backend mutex functions */
|
||||||
|
|
||||||
|
/* Allocate a mutex. */
|
||||||
|
static inline int
|
||||||
|
__gthread_objc_mutex_allocate (objc_mutex_t mutex UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Deallocate a mutex. */
|
||||||
|
static inline int
|
||||||
|
__gthread_objc_mutex_deallocate (objc_mutex_t mutex UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grab a lock on a mutex. */
|
||||||
|
static inline int
|
||||||
|
__gthread_objc_mutex_lock (objc_mutex_t mutex UNUSED)
|
||||||
|
{
|
||||||
|
/* There can only be one thread, so we always get the lock */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to grab a lock on a mutex. */
|
||||||
|
static inline int
|
||||||
|
__gthread_objc_mutex_trylock (objc_mutex_t mutex UNUSED)
|
||||||
|
{
|
||||||
|
/* There can only be one thread, so we always get the lock */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlock the mutex */
|
||||||
|
static inline int
|
||||||
|
__gthread_objc_mutex_unlock (objc_mutex_t mutex UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Backend condition mutex functions */
|
||||||
|
|
||||||
|
/* Allocate a condition. */
|
||||||
|
static inline int
|
||||||
|
__gthread_objc_condition_allocate (objc_condition_t condition UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Deallocate a condition. */
|
||||||
|
static inline int
|
||||||
|
__gthread_objc_condition_deallocate (objc_condition_t condition UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait on the condition */
|
||||||
|
static inline int
|
||||||
|
__gthread_objc_condition_wait (objc_condition_t condition UNUSED,
|
||||||
|
objc_mutex_t mutex UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wake up all threads waiting on this condition. */
|
||||||
|
static inline int
|
||||||
|
__gthread_objc_condition_broadcast (objc_condition_t condition UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wake up one thread waiting on this condition. */
|
||||||
|
static inline int
|
||||||
|
__gthread_objc_condition_signal (objc_condition_t condition UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* _LIBOBJC */
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_active_p (void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_once (__gthread_once_t *__once UNUSED, void (*__func) (void) UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int UNUSED
|
||||||
|
__gthread_key_create (__gthread_key_t *__key UNUSED, void (*__func) (void *) UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int UNUSED
|
||||||
|
__gthread_key_delete (__gthread_key_t __key UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
__gthread_getspecific (__gthread_key_t __key UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_setspecific (__gthread_key_t __key UNUSED, const void *__v UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_mutex_destroy (__gthread_mutex_t *__mutex UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_mutex_lock (__gthread_mutex_t *__mutex UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_mutex_trylock (__gthread_mutex_t *__mutex UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_mutex_unlock (__gthread_mutex_t *__mutex UNUSED)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
return __gthread_mutex_lock (__mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
return __gthread_mutex_trylock (__mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
return __gthread_mutex_unlock (__mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _LIBOBJC */
|
||||||
|
|
||||||
|
#undef UNUSED
|
||||||
|
|
||||||
|
#endif /* ! GCC_GTHR_SINGLE_H */
|
173
contrib/sdk/sources/gcc_eh/gthr.h
Normal file
173
contrib/sdk/sources/gcc_eh/gthr.h
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
/* Threads compatibility routines for libgcc2. */
|
||||||
|
/* Compile this one with gcc. */
|
||||||
|
/* Copyright (C) 1997, 1998, 2004, 2008, 2009 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_GTHR_H
|
||||||
|
#define GCC_GTHR_H
|
||||||
|
|
||||||
|
#ifndef HIDE_EXPORTS
|
||||||
|
#pragma GCC visibility push(default)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If this file is compiled with threads support, it must
|
||||||
|
#define __GTHREADS 1
|
||||||
|
to indicate that threads support is present. Also it has define
|
||||||
|
function
|
||||||
|
int __gthread_active_p ()
|
||||||
|
that returns 1 if thread system is active, 0 if not.
|
||||||
|
|
||||||
|
The threads interface must define the following types:
|
||||||
|
__gthread_key_t
|
||||||
|
__gthread_once_t
|
||||||
|
__gthread_mutex_t
|
||||||
|
__gthread_recursive_mutex_t
|
||||||
|
|
||||||
|
The threads interface must define the following macros:
|
||||||
|
|
||||||
|
__GTHREAD_ONCE_INIT
|
||||||
|
to initialize __gthread_once_t
|
||||||
|
__GTHREAD_MUTEX_INIT
|
||||||
|
to initialize __gthread_mutex_t to get a fast
|
||||||
|
non-recursive mutex.
|
||||||
|
__GTHREAD_MUTEX_INIT_FUNCTION
|
||||||
|
some systems can't initialize a mutex without a
|
||||||
|
function call. On such systems, define this to a
|
||||||
|
function which looks like this:
|
||||||
|
void __GTHREAD_MUTEX_INIT_FUNCTION (__gthread_mutex_t *)
|
||||||
|
Don't define __GTHREAD_MUTEX_INIT in this case
|
||||||
|
__GTHREAD_RECURSIVE_MUTEX_INIT
|
||||||
|
__GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION
|
||||||
|
as above, but for a recursive mutex.
|
||||||
|
|
||||||
|
The threads interface must define the following static functions:
|
||||||
|
|
||||||
|
int __gthread_once (__gthread_once_t *once, void (*func) ())
|
||||||
|
|
||||||
|
int __gthread_key_create (__gthread_key_t *keyp, void (*dtor) (void *))
|
||||||
|
int __gthread_key_delete (__gthread_key_t key)
|
||||||
|
|
||||||
|
void *__gthread_getspecific (__gthread_key_t key)
|
||||||
|
int __gthread_setspecific (__gthread_key_t key, const void *ptr)
|
||||||
|
|
||||||
|
int __gthread_mutex_destroy (__gthread_mutex_t *mutex);
|
||||||
|
|
||||||
|
int __gthread_mutex_lock (__gthread_mutex_t *mutex);
|
||||||
|
int __gthread_mutex_trylock (__gthread_mutex_t *mutex);
|
||||||
|
int __gthread_mutex_unlock (__gthread_mutex_t *mutex);
|
||||||
|
|
||||||
|
int __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex);
|
||||||
|
int __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex);
|
||||||
|
int __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex);
|
||||||
|
|
||||||
|
The following are supported in POSIX threads only. They are required to
|
||||||
|
fix a deadlock in static initialization inside libsupc++. The header file
|
||||||
|
gthr-posix.h defines a symbol __GTHREAD_HAS_COND to signify that these extra
|
||||||
|
features are supported.
|
||||||
|
|
||||||
|
Types:
|
||||||
|
__gthread_cond_t
|
||||||
|
|
||||||
|
Macros:
|
||||||
|
__GTHREAD_COND_INIT
|
||||||
|
__GTHREAD_COND_INIT_FUNCTION
|
||||||
|
|
||||||
|
Interface:
|
||||||
|
int __gthread_cond_broadcast (__gthread_cond_t *cond);
|
||||||
|
int __gthread_cond_wait (__gthread_cond_t *cond, __gthread_mutex_t *mutex);
|
||||||
|
int __gthread_cond_wait_recursive (__gthread_cond_t *cond,
|
||||||
|
__gthread_recursive_mutex_t *mutex);
|
||||||
|
|
||||||
|
All functions returning int should return zero on success or the error
|
||||||
|
number. If the operation is not supported, -1 is returned.
|
||||||
|
|
||||||
|
If the following are also defined, you should
|
||||||
|
#define __GTHREADS_CXX0X 1
|
||||||
|
to enable the c++0x thread library.
|
||||||
|
|
||||||
|
Types:
|
||||||
|
__gthread_t
|
||||||
|
__gthread_time_t
|
||||||
|
|
||||||
|
Interface:
|
||||||
|
int __gthread_create (__gthread_t *thread, void *(*func) (void*),
|
||||||
|
void *args);
|
||||||
|
int __gthread_join (__gthread_t thread, void **value_ptr);
|
||||||
|
int __gthread_detach (__gthread_t thread);
|
||||||
|
int __gthread_equal (__gthread_t t1, __gthread_t t2);
|
||||||
|
__gthread_t __gthread_self (void);
|
||||||
|
int __gthread_yield (void);
|
||||||
|
|
||||||
|
int __gthread_mutex_timedlock (__gthread_mutex_t *m,
|
||||||
|
const __gthread_time_t *abs_timeout);
|
||||||
|
int __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *m,
|
||||||
|
const __gthread_time_t *abs_time);
|
||||||
|
|
||||||
|
int __gthread_cond_signal (__gthread_cond_t *cond);
|
||||||
|
int __gthread_cond_timedwait (__gthread_cond_t *cond,
|
||||||
|
__gthread_mutex_t *mutex,
|
||||||
|
const __gthread_time_t *abs_timeout);
|
||||||
|
int __gthread_cond_timedwait_recursive (__gthread_cond_t *cond,
|
||||||
|
__gthread_recursive_mutex_t *mutex,
|
||||||
|
const __gthread_time_t *abs_time)
|
||||||
|
|
||||||
|
Currently supported threads packages are
|
||||||
|
TPF threads with -D__tpf__
|
||||||
|
POSIX/Unix98 threads with -D_PTHREADS
|
||||||
|
POSIX/Unix95 threads with -D_PTHREADS95
|
||||||
|
DCE threads with -D_DCE_THREADS
|
||||||
|
Solaris/UI threads with -D_SOLARIS_THREADS
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Check first for thread specific defines. */
|
||||||
|
#if defined (__tpf__)
|
||||||
|
#include "gthr-tpf.h"
|
||||||
|
#elif _PTHREADS
|
||||||
|
#include "gthr-posix.h"
|
||||||
|
#elif _PTHREADS95
|
||||||
|
#include "gthr-posix95.h"
|
||||||
|
#elif _DCE_THREADS
|
||||||
|
#include "gthr-dce.h"
|
||||||
|
#elif _SOLARIS_THREADS
|
||||||
|
#include "gthr-solaris.h"
|
||||||
|
|
||||||
|
/* Include GTHREAD_FILE if one is defined. */
|
||||||
|
#elif defined(HAVE_GTHR_DEFAULT)
|
||||||
|
#if SUPPORTS_WEAK
|
||||||
|
#ifndef GTHREAD_USE_WEAK
|
||||||
|
#define GTHREAD_USE_WEAK 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#include "gthr-default.h"
|
||||||
|
|
||||||
|
/* Fallback to single thread definitions. */
|
||||||
|
#else
|
||||||
|
#include "gthr-single.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HIDE_EXPORTS
|
||||||
|
#pragma GCC visibility pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ! GCC_GTHR_H */
|
1608
contrib/sdk/sources/gcc_eh/options.h
Normal file
1608
contrib/sdk/sources/gcc_eh/options.h
Normal file
File diff suppressed because it is too large
Load Diff
11
contrib/sdk/sources/gcc_eh/tconfig.h
Normal file
11
contrib/sdk/sources/gcc_eh/tconfig.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef GCC_TCONFIG_H
|
||||||
|
#define GCC_TCONFIG_H
|
||||||
|
#ifndef USED_FOR_TARGET
|
||||||
|
# define USED_FOR_TARGET
|
||||||
|
#endif
|
||||||
|
#include "auto-host.h"
|
||||||
|
#ifdef IN_GCC
|
||||||
|
# include "ansidecl.h"
|
||||||
|
# include "xm-mingw32.h"
|
||||||
|
#endif
|
||||||
|
#endif /* GCC_TCONFIG_H */
|
21
contrib/sdk/sources/gcc_eh/tm.h
Normal file
21
contrib/sdk/sources/gcc_eh/tm.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef GCC_TM_H
|
||||||
|
#define GCC_TM_H
|
||||||
|
#ifdef IN_GCC
|
||||||
|
# include "options.h"
|
||||||
|
# include "config/vxworks-dummy.h"
|
||||||
|
# include "config/i386/i386.h"
|
||||||
|
# include "config/i386/unix.h"
|
||||||
|
# include "config/i386/bsd.h"
|
||||||
|
# include "config/i386/gas.h"
|
||||||
|
# include "config/dbxcoff.h"
|
||||||
|
# include "config/i386/cygming.h"
|
||||||
|
# include "config/i386/mingw32.h"
|
||||||
|
# include "config/i386/mingw-stdint.h"
|
||||||
|
# include "config/tm-dwarf2.h"
|
||||||
|
# include "defaults.h"
|
||||||
|
#endif
|
||||||
|
#if defined IN_GCC && !defined GENERATOR_FILE && !defined USED_FOR_TARGET
|
||||||
|
# include "insn-constants.h"
|
||||||
|
# include "insn-flags.h"
|
||||||
|
#endif
|
||||||
|
#endif /* GCC_TM_H */
|
134
contrib/sdk/sources/gcc_eh/tsystem.h
Normal file
134
contrib/sdk/sources/gcc_eh/tsystem.h
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/* Get common system includes and various definitions and declarations
|
||||||
|
based on target macros.
|
||||||
|
Copyright (C) 2000, 2001, 2004, 2005, 2009 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_TSYSTEM_H
|
||||||
|
#define GCC_TSYSTEM_H
|
||||||
|
|
||||||
|
/* System headers (e.g. stdio.h, stdlib.h, unistd.h) sometimes
|
||||||
|
indirectly include getopt.h. Our -I flags will cause gcc's gnu
|
||||||
|
getopt.h to be included, not the platform's copy. In the default
|
||||||
|
case, gnu getopt.h will provide us with a no-argument prototype
|
||||||
|
which will generate -Wstrict-prototypes warnings. None of the
|
||||||
|
target files actually use getopt, so it is safe to tell gnu
|
||||||
|
getopt.h we never need this prototype. */
|
||||||
|
#ifndef HAVE_DECL_GETOPT
|
||||||
|
#define HAVE_DECL_GETOPT 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* We want everything from the glibc headers. */
|
||||||
|
#define _GNU_SOURCE 1
|
||||||
|
|
||||||
|
/* GCC supplies these headers. */
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
|
#ifdef inhibit_libc
|
||||||
|
|
||||||
|
#ifndef malloc
|
||||||
|
extern void *malloc (size_t);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef free
|
||||||
|
extern void free (void *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef atexit
|
||||||
|
extern int atexit (void (*)(void));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef abort
|
||||||
|
extern void abort (void) __attribute__ ((__noreturn__));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef strlen
|
||||||
|
extern size_t strlen (const char *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef memcpy
|
||||||
|
extern void *memcpy (void *, const void *, size_t);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef memset
|
||||||
|
extern void *memset (void *, int, size_t);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else /* ! inhibit_libc */
|
||||||
|
/* We disable this when inhibit_libc, so that gcc can still be built without
|
||||||
|
needing header files first. */
|
||||||
|
/* ??? This is not a good solution, since prototypes may be required in
|
||||||
|
some cases for correct code. */
|
||||||
|
|
||||||
|
/* GCC supplies this header. */
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
/* All systems have this header. */
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* All systems have this header. */
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
/* All systems have this header. */
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#ifndef errno
|
||||||
|
extern int errno;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If these system headers do not exist, fixincludes must create them. */
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/* GCC supplies this header. */
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
/* If these system headers do not exist, fixincludes must create them. */
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#endif /* inhibit_libc */
|
||||||
|
|
||||||
|
/* Define a generic NULL if one hasn't already been defined. */
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* GCC always provides __builtin_alloca(x). */
|
||||||
|
#undef alloca
|
||||||
|
#define alloca(x) __builtin_alloca(x)
|
||||||
|
|
||||||
|
#ifdef ENABLE_RUNTIME_CHECKING
|
||||||
|
#define gcc_assert(EXPR) ((void)(!(EXPR) ? abort (), 0 : 0))
|
||||||
|
#else
|
||||||
|
/* Include EXPR, so that unused variable warnings do not occur. */
|
||||||
|
#define gcc_assert(EXPR) ((void)(0 && (EXPR)))
|
||||||
|
#endif
|
||||||
|
/* Use gcc_unreachable() to mark unreachable locations (like an
|
||||||
|
unreachable default case of a switch. Do not use gcc_assert(0). */
|
||||||
|
#define gcc_unreachable() (abort ())
|
||||||
|
|
||||||
|
/* Filename handling macros. */
|
||||||
|
#include "filenames.h"
|
||||||
|
|
||||||
|
#endif /* ! GCC_TSYSTEM_H */
|
229
contrib/sdk/sources/gcc_eh/unwind-c.c
Normal file
229
contrib/sdk/sources/gcc_eh/unwind-c.c
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
/* Supporting functions for C exception handling.
|
||||||
|
Copyright (C) 2002, 2003, 2009 Free Software Foundation, Inc.
|
||||||
|
Contributed by Aldy Hernandez <aldy@quesejoda.com>.
|
||||||
|
Shamelessly stolen from the Java front end.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include "tconfig.h"
|
||||||
|
#include "tsystem.h"
|
||||||
|
#include "unwind.h"
|
||||||
|
#define NO_SIZE_OF_ENCODED_VALUE
|
||||||
|
#include "unwind-pe.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
_Unwind_Ptr Start;
|
||||||
|
_Unwind_Ptr LPStart;
|
||||||
|
_Unwind_Ptr ttype_base;
|
||||||
|
const unsigned char *TType;
|
||||||
|
const unsigned char *action_table;
|
||||||
|
unsigned char ttype_encoding;
|
||||||
|
unsigned char call_site_encoding;
|
||||||
|
} lsda_header_info;
|
||||||
|
|
||||||
|
static const unsigned char *
|
||||||
|
parse_lsda_header (struct _Unwind_Context *context, const unsigned char *p,
|
||||||
|
lsda_header_info *info)
|
||||||
|
{
|
||||||
|
_uleb128_t tmp;
|
||||||
|
unsigned char lpstart_encoding;
|
||||||
|
|
||||||
|
info->Start = (context ? _Unwind_GetRegionStart (context) : 0);
|
||||||
|
|
||||||
|
/* Find @LPStart, the base to which landing pad offsets are relative. */
|
||||||
|
lpstart_encoding = *p++;
|
||||||
|
if (lpstart_encoding != DW_EH_PE_omit)
|
||||||
|
p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart);
|
||||||
|
else
|
||||||
|
info->LPStart = info->Start;
|
||||||
|
|
||||||
|
/* Find @TType, the base of the handler and exception spec type data. */
|
||||||
|
info->ttype_encoding = *p++;
|
||||||
|
if (info->ttype_encoding != DW_EH_PE_omit)
|
||||||
|
{
|
||||||
|
p = read_uleb128 (p, &tmp);
|
||||||
|
info->TType = p + tmp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
info->TType = 0;
|
||||||
|
|
||||||
|
/* The encoding and length of the call-site table; the action table
|
||||||
|
immediately follows. */
|
||||||
|
info->call_site_encoding = *p++;
|
||||||
|
p = read_uleb128 (p, &tmp);
|
||||||
|
info->action_table = p + tmp;
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __ARM_EABI_UNWINDER__
|
||||||
|
/* ARM EABI personality routines must also unwind the stack. */
|
||||||
|
#define CONTINUE_UNWINDING \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (__gnu_unwind_frame (ue_header, context) != _URC_OK) \
|
||||||
|
return _URC_FAILURE; \
|
||||||
|
return _URC_CONTINUE_UNWIND; \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
#else
|
||||||
|
#define CONTINUE_UNWINDING return _URC_CONTINUE_UNWIND
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __USING_SJLJ_EXCEPTIONS__
|
||||||
|
#define PERSONALITY_FUNCTION __gcc_personality_sj0
|
||||||
|
#define __builtin_eh_return_data_regno(x) x
|
||||||
|
#else
|
||||||
|
#define PERSONALITY_FUNCTION __gcc_personality_v0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __ARM_EABI_UNWINDER__
|
||||||
|
_Unwind_Reason_Code
|
||||||
|
PERSONALITY_FUNCTION (_Unwind_State, struct _Unwind_Exception *,
|
||||||
|
struct _Unwind_Context *);
|
||||||
|
|
||||||
|
_Unwind_Reason_Code
|
||||||
|
PERSONALITY_FUNCTION (_Unwind_State state,
|
||||||
|
struct _Unwind_Exception * ue_header,
|
||||||
|
struct _Unwind_Context * context)
|
||||||
|
#else
|
||||||
|
_Unwind_Reason_Code
|
||||||
|
PERSONALITY_FUNCTION (int, _Unwind_Action, _Unwind_Exception_Class,
|
||||||
|
struct _Unwind_Exception *, struct _Unwind_Context *);
|
||||||
|
|
||||||
|
_Unwind_Reason_Code
|
||||||
|
PERSONALITY_FUNCTION (int version,
|
||||||
|
_Unwind_Action actions,
|
||||||
|
_Unwind_Exception_Class exception_class ATTRIBUTE_UNUSED,
|
||||||
|
struct _Unwind_Exception *ue_header,
|
||||||
|
struct _Unwind_Context *context)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
lsda_header_info info;
|
||||||
|
const unsigned char *language_specific_data, *p;
|
||||||
|
_Unwind_Ptr landing_pad, ip;
|
||||||
|
int ip_before_insn = 0;
|
||||||
|
|
||||||
|
#ifdef __ARM_EABI_UNWINDER__
|
||||||
|
if ((state & _US_ACTION_MASK) != _US_UNWIND_FRAME_STARTING)
|
||||||
|
CONTINUE_UNWINDING;
|
||||||
|
|
||||||
|
/* The dwarf unwinder assumes the context structure holds things like the
|
||||||
|
function and LSDA pointers. The ARM implementation caches these in
|
||||||
|
the exception header (UCB). To avoid rewriting everything we make the
|
||||||
|
virtual IP register point at the UCB. */
|
||||||
|
ip = (_Unwind_Ptr) ue_header;
|
||||||
|
_Unwind_SetGR (context, 12, ip);
|
||||||
|
#else
|
||||||
|
if (version != 1)
|
||||||
|
return _URC_FATAL_PHASE1_ERROR;
|
||||||
|
|
||||||
|
/* Currently we only support cleanups for C. */
|
||||||
|
if ((actions & _UA_CLEANUP_PHASE) == 0)
|
||||||
|
CONTINUE_UNWINDING;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
language_specific_data = (const unsigned char *)
|
||||||
|
_Unwind_GetLanguageSpecificData (context);
|
||||||
|
|
||||||
|
/* If no LSDA, then there are no handlers or cleanups. */
|
||||||
|
if (! language_specific_data)
|
||||||
|
CONTINUE_UNWINDING;
|
||||||
|
|
||||||
|
/* Parse the LSDA header. */
|
||||||
|
p = parse_lsda_header (context, language_specific_data, &info);
|
||||||
|
#ifdef HAVE_GETIPINFO
|
||||||
|
ip = _Unwind_GetIPInfo (context, &ip_before_insn);
|
||||||
|
#else
|
||||||
|
ip = _Unwind_GetIP (context);
|
||||||
|
#endif
|
||||||
|
if (! ip_before_insn)
|
||||||
|
--ip;
|
||||||
|
landing_pad = 0;
|
||||||
|
|
||||||
|
#ifdef __USING_SJLJ_EXCEPTIONS__
|
||||||
|
/* The given "IP" is an index into the call-site table, with two
|
||||||
|
exceptions -- -1 means no-action, and 0 means terminate. But
|
||||||
|
since we're using uleb128 values, we've not got random access
|
||||||
|
to the array. */
|
||||||
|
if ((int) ip <= 0)
|
||||||
|
return _URC_CONTINUE_UNWIND;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_uleb128_t cs_lp, cs_action;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
p = read_uleb128 (p, &cs_lp);
|
||||||
|
p = read_uleb128 (p, &cs_action);
|
||||||
|
}
|
||||||
|
while (--ip);
|
||||||
|
|
||||||
|
/* Can never have null landing pad for sjlj -- that would have
|
||||||
|
been indicated by a -1 call site index. */
|
||||||
|
landing_pad = (_Unwind_Ptr)cs_lp + 1;
|
||||||
|
goto found_something;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* Search the call-site table for the action associated with this IP. */
|
||||||
|
while (p < info.action_table)
|
||||||
|
{
|
||||||
|
_Unwind_Ptr cs_start, cs_len, cs_lp;
|
||||||
|
_uleb128_t cs_action;
|
||||||
|
|
||||||
|
/* Note that all call-site encodings are "absolute" displacements. */
|
||||||
|
p = read_encoded_value (0, info.call_site_encoding, p, &cs_start);
|
||||||
|
p = read_encoded_value (0, info.call_site_encoding, p, &cs_len);
|
||||||
|
p = read_encoded_value (0, info.call_site_encoding, p, &cs_lp);
|
||||||
|
p = read_uleb128 (p, &cs_action);
|
||||||
|
|
||||||
|
/* The table is sorted, so if we've passed the ip, stop. */
|
||||||
|
if (ip < info.Start + cs_start)
|
||||||
|
p = info.action_table;
|
||||||
|
else if (ip < info.Start + cs_start + cs_len)
|
||||||
|
{
|
||||||
|
if (cs_lp)
|
||||||
|
landing_pad = info.LPStart + cs_lp;
|
||||||
|
goto found_something;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* IP is not in table. No associated cleanups. */
|
||||||
|
/* ??? This is where C++ calls std::terminate to catch throw
|
||||||
|
from a destructor. */
|
||||||
|
CONTINUE_UNWINDING;
|
||||||
|
|
||||||
|
found_something:
|
||||||
|
if (landing_pad == 0)
|
||||||
|
{
|
||||||
|
/* IP is present, but has a null landing pad.
|
||||||
|
No handler to be run. */
|
||||||
|
CONTINUE_UNWINDING;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Unwind_SetGR (context, __builtin_eh_return_data_regno (0),
|
||||||
|
(_Unwind_Ptr) ue_header);
|
||||||
|
_Unwind_SetGR (context, __builtin_eh_return_data_regno (1), 0);
|
||||||
|
_Unwind_SetIP (context, landing_pad);
|
||||||
|
return _URC_INSTALL_CONTEXT;
|
||||||
|
}
|
1028
contrib/sdk/sources/gcc_eh/unwind-dw2-fde.c
Normal file
1028
contrib/sdk/sources/gcc_eh/unwind-dw2-fde.c
Normal file
File diff suppressed because it is too large
Load Diff
183
contrib/sdk/sources/gcc_eh/unwind-dw2-fde.h
Normal file
183
contrib/sdk/sources/gcc_eh/unwind-dw2-fde.h
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
/* Subroutines needed for unwinding stack frames for exception handling. */
|
||||||
|
/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2009
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
Contributed by Jason Merrill <jason@cygnus.com>.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_UNWIND_DW2_FDE_H
|
||||||
|
#define GCC_UNWIND_DW2_FDE_H
|
||||||
|
|
||||||
|
#ifndef HIDE_EXPORTS
|
||||||
|
#pragma GCC visibility push(default)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct fde_vector
|
||||||
|
{
|
||||||
|
const void *orig_data;
|
||||||
|
size_t count;
|
||||||
|
const struct dwarf_fde *array[];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct object
|
||||||
|
{
|
||||||
|
void *pc_begin;
|
||||||
|
void *tbase;
|
||||||
|
void *dbase;
|
||||||
|
union {
|
||||||
|
const struct dwarf_fde *single;
|
||||||
|
struct dwarf_fde **array;
|
||||||
|
struct fde_vector *sort;
|
||||||
|
} u;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
unsigned long sorted : 1;
|
||||||
|
unsigned long from_array : 1;
|
||||||
|
unsigned long mixed_encoding : 1;
|
||||||
|
unsigned long encoding : 8;
|
||||||
|
/* ??? Wish there was an easy way to detect a 64-bit host here;
|
||||||
|
we've got 32 bits left to play with... */
|
||||||
|
unsigned long count : 21;
|
||||||
|
} b;
|
||||||
|
size_t i;
|
||||||
|
} s;
|
||||||
|
|
||||||
|
#ifdef DWARF2_OBJECT_END_PTR_EXTENSION
|
||||||
|
char *fde_end;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct object *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This is the original definition of struct object. While the struct
|
||||||
|
itself was opaque to users, they did know how large it was, and
|
||||||
|
allocate one statically in crtbegin for each DSO. Keep this around
|
||||||
|
so that we're aware of the static size limitations for the new struct. */
|
||||||
|
struct old_object
|
||||||
|
{
|
||||||
|
void *pc_begin;
|
||||||
|
void *pc_end;
|
||||||
|
struct dwarf_fde *fde_begin;
|
||||||
|
struct dwarf_fde **fde_array;
|
||||||
|
size_t count;
|
||||||
|
struct old_object *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dwarf_eh_bases
|
||||||
|
{
|
||||||
|
void *tbase;
|
||||||
|
void *dbase;
|
||||||
|
void *func;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern void __register_frame_info_bases (const void *, struct object *,
|
||||||
|
void *, void *);
|
||||||
|
extern void __register_frame_info (const void *, struct object *);
|
||||||
|
extern void __register_frame (void *);
|
||||||
|
extern void __register_frame_info_table_bases (void *, struct object *,
|
||||||
|
void *, void *);
|
||||||
|
extern void __register_frame_info_table (void *, struct object *);
|
||||||
|
extern void __register_frame_table (void *);
|
||||||
|
extern void *__deregister_frame_info (const void *);
|
||||||
|
extern void *__deregister_frame_info_bases (const void *);
|
||||||
|
extern void __deregister_frame (void *);
|
||||||
|
|
||||||
|
|
||||||
|
typedef int sword __attribute__ ((mode (SI)));
|
||||||
|
typedef unsigned int uword __attribute__ ((mode (SI)));
|
||||||
|
typedef unsigned int uaddr __attribute__ ((mode (pointer)));
|
||||||
|
typedef int saddr __attribute__ ((mode (pointer)));
|
||||||
|
typedef unsigned char ubyte;
|
||||||
|
|
||||||
|
/* Terminology:
|
||||||
|
CIE - Common Information Element
|
||||||
|
FDE - Frame Descriptor Element
|
||||||
|
|
||||||
|
There is one per function, and it describes where the function code
|
||||||
|
is located, and what the register lifetimes and stack layout are
|
||||||
|
within the function.
|
||||||
|
|
||||||
|
The data structures are defined in the DWARF specification, although
|
||||||
|
not in a very readable way (see LITERATURE).
|
||||||
|
|
||||||
|
Every time an exception is thrown, the code needs to locate the FDE
|
||||||
|
for the current function, and starts to look for exception regions
|
||||||
|
from that FDE. This works in a two-level search:
|
||||||
|
a) in a linear search, find the shared image (i.e. DLL) containing
|
||||||
|
the PC
|
||||||
|
b) using the FDE table for that shared object, locate the FDE using
|
||||||
|
binary search (which requires the sorting). */
|
||||||
|
|
||||||
|
/* The first few fields of a CIE. The CIE_id field is 0 for a CIE,
|
||||||
|
to distinguish it from a valid FDE. FDEs are aligned to an addressing
|
||||||
|
unit boundary, but the fields within are unaligned. */
|
||||||
|
struct dwarf_cie
|
||||||
|
{
|
||||||
|
uword length;
|
||||||
|
sword CIE_id;
|
||||||
|
ubyte version;
|
||||||
|
unsigned char augmentation[];
|
||||||
|
} __attribute__ ((packed, aligned (__alignof__ (void *))));
|
||||||
|
|
||||||
|
/* The first few fields of an FDE. */
|
||||||
|
struct dwarf_fde
|
||||||
|
{
|
||||||
|
uword length;
|
||||||
|
sword CIE_delta;
|
||||||
|
unsigned char pc_begin[];
|
||||||
|
} __attribute__ ((packed, aligned (__alignof__ (void *))));
|
||||||
|
|
||||||
|
typedef struct dwarf_fde fde;
|
||||||
|
|
||||||
|
/* Locate the CIE for a given FDE. */
|
||||||
|
|
||||||
|
static inline const struct dwarf_cie *
|
||||||
|
get_cie (const struct dwarf_fde *f)
|
||||||
|
{
|
||||||
|
return (const void *)&f->CIE_delta - f->CIE_delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const fde *
|
||||||
|
next_fde (const fde *f)
|
||||||
|
{
|
||||||
|
return (const fde *) ((const char *) f + f->length + sizeof (f->length));
|
||||||
|
}
|
||||||
|
|
||||||
|
extern const fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *);
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
last_fde (struct object *obj __attribute__ ((__unused__)), const fde *f)
|
||||||
|
{
|
||||||
|
#ifdef DWARF2_OBJECT_END_PTR_EXTENSION
|
||||||
|
return (char *)f == obj->fde_end || f->length == 0;
|
||||||
|
#else
|
||||||
|
return f->length == 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef HIDE_EXPORTS
|
||||||
|
#pragma GCC visibility pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* unwind-dw2-fde.h */
|
1594
contrib/sdk/sources/gcc_eh/unwind-dw2.c
Normal file
1594
contrib/sdk/sources/gcc_eh/unwind-dw2.c
Normal file
File diff suppressed because it is too large
Load Diff
87
contrib/sdk/sources/gcc_eh/unwind-dw2.h
Normal file
87
contrib/sdk/sources/gcc_eh/unwind-dw2.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/* DWARF2 frame unwind data structure.
|
||||||
|
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2009
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* A target can override (perhaps for backward compatibility) how
|
||||||
|
many dwarf2 columns are unwound. */
|
||||||
|
#ifndef DWARF_FRAME_REGISTERS
|
||||||
|
#define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The result of interpreting the frame unwind info for a frame.
|
||||||
|
This is all symbolic at this point, as none of the values can
|
||||||
|
be resolved until the target pc is located. */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* Each register save state can be described in terms of a CFA slot,
|
||||||
|
another register, or a location expression. */
|
||||||
|
struct frame_state_reg_info
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
union {
|
||||||
|
_Unwind_Word reg;
|
||||||
|
_Unwind_Sword offset;
|
||||||
|
const unsigned char *exp;
|
||||||
|
} loc;
|
||||||
|
enum {
|
||||||
|
REG_UNSAVED,
|
||||||
|
REG_SAVED_OFFSET,
|
||||||
|
REG_SAVED_REG,
|
||||||
|
REG_SAVED_EXP,
|
||||||
|
REG_SAVED_VAL_OFFSET,
|
||||||
|
REG_SAVED_VAL_EXP,
|
||||||
|
REG_UNDEFINED
|
||||||
|
} how;
|
||||||
|
} reg[DWARF_FRAME_REGISTERS+1];
|
||||||
|
|
||||||
|
/* Used to implement DW_CFA_remember_state. */
|
||||||
|
struct frame_state_reg_info *prev;
|
||||||
|
|
||||||
|
/* The CFA can be described in terms of a reg+offset or a
|
||||||
|
location expression. */
|
||||||
|
_Unwind_Sword cfa_offset;
|
||||||
|
_Unwind_Word cfa_reg;
|
||||||
|
const unsigned char *cfa_exp;
|
||||||
|
enum {
|
||||||
|
CFA_UNSET,
|
||||||
|
CFA_REG_OFFSET,
|
||||||
|
CFA_EXP
|
||||||
|
} cfa_how;
|
||||||
|
} regs;
|
||||||
|
|
||||||
|
/* The PC described by the current frame state. */
|
||||||
|
void *pc;
|
||||||
|
|
||||||
|
/* The information we care about from the CIE/FDE. */
|
||||||
|
_Unwind_Personality_Fn personality;
|
||||||
|
_Unwind_Sword data_align;
|
||||||
|
_Unwind_Word code_align;
|
||||||
|
_Unwind_Word retaddr_column;
|
||||||
|
unsigned char fde_encoding;
|
||||||
|
unsigned char lsda_encoding;
|
||||||
|
unsigned char saw_z;
|
||||||
|
unsigned char signal_frame;
|
||||||
|
void *eh_ptr;
|
||||||
|
} _Unwind_FrameState;
|
||||||
|
|
289
contrib/sdk/sources/gcc_eh/unwind-pe.h
Normal file
289
contrib/sdk/sources/gcc_eh/unwind-pe.h
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
/* Exception handling and frame unwind runtime interface routines.
|
||||||
|
Copyright (C) 2001, 2002, 2003, 2004, 2008, 2009 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* @@@ Really this should be out of line, but this also causes link
|
||||||
|
compatibility problems with the base ABI. This is slightly better
|
||||||
|
than duplicating code, however. */
|
||||||
|
|
||||||
|
#ifndef GCC_UNWIND_PE_H
|
||||||
|
#define GCC_UNWIND_PE_H
|
||||||
|
|
||||||
|
/* If using C++, references to abort have to be qualified with std::. */
|
||||||
|
#if __cplusplus
|
||||||
|
#define __gxx_abort std::abort
|
||||||
|
#else
|
||||||
|
#define __gxx_abort abort
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Pointer encodings, from dwarf2.h. */
|
||||||
|
#define DW_EH_PE_absptr 0x00
|
||||||
|
#define DW_EH_PE_omit 0xff
|
||||||
|
|
||||||
|
#define DW_EH_PE_uleb128 0x01
|
||||||
|
#define DW_EH_PE_udata2 0x02
|
||||||
|
#define DW_EH_PE_udata4 0x03
|
||||||
|
#define DW_EH_PE_udata8 0x04
|
||||||
|
#define DW_EH_PE_sleb128 0x09
|
||||||
|
#define DW_EH_PE_sdata2 0x0A
|
||||||
|
#define DW_EH_PE_sdata4 0x0B
|
||||||
|
#define DW_EH_PE_sdata8 0x0C
|
||||||
|
#define DW_EH_PE_signed 0x08
|
||||||
|
|
||||||
|
#define DW_EH_PE_pcrel 0x10
|
||||||
|
#define DW_EH_PE_textrel 0x20
|
||||||
|
#define DW_EH_PE_datarel 0x30
|
||||||
|
#define DW_EH_PE_funcrel 0x40
|
||||||
|
#define DW_EH_PE_aligned 0x50
|
||||||
|
|
||||||
|
#define DW_EH_PE_indirect 0x80
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NO_SIZE_OF_ENCODED_VALUE
|
||||||
|
|
||||||
|
/* Given an encoding, return the number of bytes the format occupies.
|
||||||
|
This is only defined for fixed-size encodings, and so does not
|
||||||
|
include leb128. */
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
size_of_encoded_value (unsigned char encoding) __attribute__ ((unused));
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
size_of_encoded_value (unsigned char encoding)
|
||||||
|
{
|
||||||
|
if (encoding == DW_EH_PE_omit)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (encoding & 0x07)
|
||||||
|
{
|
||||||
|
case DW_EH_PE_absptr:
|
||||||
|
return sizeof (void *);
|
||||||
|
case DW_EH_PE_udata2:
|
||||||
|
return 2;
|
||||||
|
case DW_EH_PE_udata4:
|
||||||
|
return 4;
|
||||||
|
case DW_EH_PE_udata8:
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
__gxx_abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NO_BASE_OF_ENCODED_VALUE
|
||||||
|
|
||||||
|
/* Given an encoding and an _Unwind_Context, return the base to which
|
||||||
|
the encoding is relative. This base may then be passed to
|
||||||
|
read_encoded_value_with_base for use when the _Unwind_Context is
|
||||||
|
not available. */
|
||||||
|
|
||||||
|
static _Unwind_Ptr
|
||||||
|
base_of_encoded_value (unsigned char encoding, struct _Unwind_Context *context)
|
||||||
|
{
|
||||||
|
if (encoding == DW_EH_PE_omit)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (encoding & 0x70)
|
||||||
|
{
|
||||||
|
case DW_EH_PE_absptr:
|
||||||
|
case DW_EH_PE_pcrel:
|
||||||
|
case DW_EH_PE_aligned:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case DW_EH_PE_textrel:
|
||||||
|
return _Unwind_GetTextRelBase (context);
|
||||||
|
case DW_EH_PE_datarel:
|
||||||
|
return _Unwind_GetDataRelBase (context);
|
||||||
|
case DW_EH_PE_funcrel:
|
||||||
|
return _Unwind_GetRegionStart (context);
|
||||||
|
}
|
||||||
|
__gxx_abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Read an unsigned leb128 value from P, store the value in VAL, return
|
||||||
|
P incremented past the value. We assume that a word is large enough to
|
||||||
|
hold any value so encoded; if it is smaller than a pointer on some target,
|
||||||
|
pointers should not be leb128 encoded on that target. */
|
||||||
|
|
||||||
|
static const unsigned char *
|
||||||
|
read_uleb128 (const unsigned char *p, _uleb128_t *val)
|
||||||
|
{
|
||||||
|
unsigned int shift = 0;
|
||||||
|
unsigned char byte;
|
||||||
|
_uleb128_t result;
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
byte = *p++;
|
||||||
|
result |= ((_uleb128_t)byte & 0x7f) << shift;
|
||||||
|
shift += 7;
|
||||||
|
}
|
||||||
|
while (byte & 0x80);
|
||||||
|
|
||||||
|
*val = result;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Similar, but read a signed leb128 value. */
|
||||||
|
|
||||||
|
static const unsigned char *
|
||||||
|
read_sleb128 (const unsigned char *p, _sleb128_t *val)
|
||||||
|
{
|
||||||
|
unsigned int shift = 0;
|
||||||
|
unsigned char byte;
|
||||||
|
_uleb128_t result;
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
byte = *p++;
|
||||||
|
result |= ((_uleb128_t)byte & 0x7f) << shift;
|
||||||
|
shift += 7;
|
||||||
|
}
|
||||||
|
while (byte & 0x80);
|
||||||
|
|
||||||
|
/* Sign-extend a negative value. */
|
||||||
|
if (shift < 8 * sizeof(result) && (byte & 0x40) != 0)
|
||||||
|
result |= -(((_uleb128_t)1L) << shift);
|
||||||
|
|
||||||
|
*val = (_sleb128_t) result;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load an encoded value from memory at P. The value is returned in VAL;
|
||||||
|
The function returns P incremented past the value. BASE is as given
|
||||||
|
by base_of_encoded_value for this encoding in the appropriate context. */
|
||||||
|
|
||||||
|
static const unsigned char *
|
||||||
|
read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
|
||||||
|
const unsigned char *p, _Unwind_Ptr *val)
|
||||||
|
{
|
||||||
|
union unaligned
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
unsigned u2 __attribute__ ((mode (HI)));
|
||||||
|
unsigned u4 __attribute__ ((mode (SI)));
|
||||||
|
unsigned u8 __attribute__ ((mode (DI)));
|
||||||
|
signed s2 __attribute__ ((mode (HI)));
|
||||||
|
signed s4 __attribute__ ((mode (SI)));
|
||||||
|
signed s8 __attribute__ ((mode (DI)));
|
||||||
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
|
const union unaligned *u = (const union unaligned *) p;
|
||||||
|
_Unwind_Internal_Ptr result;
|
||||||
|
|
||||||
|
if (encoding == DW_EH_PE_aligned)
|
||||||
|
{
|
||||||
|
_Unwind_Internal_Ptr a = (_Unwind_Internal_Ptr) p;
|
||||||
|
a = (a + sizeof (void *) - 1) & - sizeof(void *);
|
||||||
|
result = *(_Unwind_Internal_Ptr *) a;
|
||||||
|
p = (const unsigned char *) (_Unwind_Internal_Ptr) (a + sizeof (void *));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (encoding & 0x0f)
|
||||||
|
{
|
||||||
|
case DW_EH_PE_absptr:
|
||||||
|
result = (_Unwind_Internal_Ptr) u->ptr;
|
||||||
|
p += sizeof (void *);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DW_EH_PE_uleb128:
|
||||||
|
{
|
||||||
|
_uleb128_t tmp;
|
||||||
|
p = read_uleb128 (p, &tmp);
|
||||||
|
result = (_Unwind_Internal_Ptr) tmp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DW_EH_PE_sleb128:
|
||||||
|
{
|
||||||
|
_sleb128_t tmp;
|
||||||
|
p = read_sleb128 (p, &tmp);
|
||||||
|
result = (_Unwind_Internal_Ptr) tmp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DW_EH_PE_udata2:
|
||||||
|
result = u->u2;
|
||||||
|
p += 2;
|
||||||
|
break;
|
||||||
|
case DW_EH_PE_udata4:
|
||||||
|
result = u->u4;
|
||||||
|
p += 4;
|
||||||
|
break;
|
||||||
|
case DW_EH_PE_udata8:
|
||||||
|
result = u->u8;
|
||||||
|
p += 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DW_EH_PE_sdata2:
|
||||||
|
result = u->s2;
|
||||||
|
p += 2;
|
||||||
|
break;
|
||||||
|
case DW_EH_PE_sdata4:
|
||||||
|
result = u->s4;
|
||||||
|
p += 4;
|
||||||
|
break;
|
||||||
|
case DW_EH_PE_sdata8:
|
||||||
|
result = u->s8;
|
||||||
|
p += 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
__gxx_abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != 0)
|
||||||
|
{
|
||||||
|
result += ((encoding & 0x70) == DW_EH_PE_pcrel
|
||||||
|
? (_Unwind_Internal_Ptr) u : base);
|
||||||
|
if (encoding & DW_EH_PE_indirect)
|
||||||
|
result = *(_Unwind_Internal_Ptr *) result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*val = result;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NO_BASE_OF_ENCODED_VALUE
|
||||||
|
|
||||||
|
/* Like read_encoded_value_with_base, but get the base from the context
|
||||||
|
rather than providing it directly. */
|
||||||
|
|
||||||
|
static inline const unsigned char *
|
||||||
|
read_encoded_value (struct _Unwind_Context *context, unsigned char encoding,
|
||||||
|
const unsigned char *p, _Unwind_Ptr *val)
|
||||||
|
{
|
||||||
|
return read_encoded_value_with_base (encoding,
|
||||||
|
base_of_encoded_value (encoding, context),
|
||||||
|
p, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* unwind-pe.h */
|
307
contrib/sdk/sources/gcc_eh/unwind.inc
Normal file
307
contrib/sdk/sources/gcc_eh/unwind.inc
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
/* Exception handling and frame unwind runtime interface routines. -*- C -*-
|
||||||
|
Copyright (C) 2001, 2003, 2008, 2009 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* This is derived from the C++ ABI for IA-64. Where we diverge
|
||||||
|
for cross-architecture compatibility are noted with "@@@".
|
||||||
|
This file is included from unwind-dw2.c, unwind-sjlj.c or
|
||||||
|
unwind-ia64.c. */
|
||||||
|
|
||||||
|
/* Subroutine of _Unwind_RaiseException also invoked from _Unwind_Resume.
|
||||||
|
|
||||||
|
Unwind the stack calling the personality routine to find both the
|
||||||
|
exception handler and intermediary cleanup code. We'll only locate
|
||||||
|
the first such frame here. Cleanup code will call back into
|
||||||
|
_Unwind_Resume and we'll continue Phase 2 there. */
|
||||||
|
|
||||||
|
static _Unwind_Reason_Code
|
||||||
|
_Unwind_RaiseException_Phase2(struct _Unwind_Exception *exc,
|
||||||
|
struct _Unwind_Context *context)
|
||||||
|
{
|
||||||
|
_Unwind_Reason_Code code;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
_Unwind_FrameState fs;
|
||||||
|
int match_handler;
|
||||||
|
|
||||||
|
code = uw_frame_state_for (context, &fs);
|
||||||
|
|
||||||
|
/* Identify when we've reached the designated handler context. */
|
||||||
|
match_handler = (uw_identify_context (context) == exc->private_2
|
||||||
|
? _UA_HANDLER_FRAME : 0);
|
||||||
|
|
||||||
|
if (code != _URC_NO_REASON)
|
||||||
|
/* Some error encountered. Usually the unwinder doesn't
|
||||||
|
diagnose these and merely crashes. */
|
||||||
|
return _URC_FATAL_PHASE2_ERROR;
|
||||||
|
|
||||||
|
/* Unwind successful. Run the personality routine, if any. */
|
||||||
|
if (fs.personality)
|
||||||
|
{
|
||||||
|
code = (*fs.personality) (1, _UA_CLEANUP_PHASE | match_handler,
|
||||||
|
exc->exception_class, exc, context);
|
||||||
|
if (code == _URC_INSTALL_CONTEXT)
|
||||||
|
break;
|
||||||
|
if (code != _URC_CONTINUE_UNWIND)
|
||||||
|
return _URC_FATAL_PHASE2_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't let us unwind past the handler context. */
|
||||||
|
gcc_assert (!match_handler);
|
||||||
|
|
||||||
|
uw_update_context (context, &fs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Raise an exception, passing along the given exception object. */
|
||||||
|
|
||||||
|
_Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
|
||||||
|
_Unwind_RaiseException(struct _Unwind_Exception *exc)
|
||||||
|
{
|
||||||
|
struct _Unwind_Context this_context, cur_context;
|
||||||
|
_Unwind_Reason_Code code;
|
||||||
|
|
||||||
|
/* Set up this_context to describe the current stack frame. */
|
||||||
|
uw_init_context (&this_context);
|
||||||
|
cur_context = this_context;
|
||||||
|
|
||||||
|
/* Phase 1: Search. Unwind the stack, calling the personality routine
|
||||||
|
with the _UA_SEARCH_PHASE flag set. Do not modify the stack yet. */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
_Unwind_FrameState fs;
|
||||||
|
|
||||||
|
/* Set up fs to describe the FDE for the caller of cur_context. The
|
||||||
|
first time through the loop, that means __cxa_throw. */
|
||||||
|
code = uw_frame_state_for (&cur_context, &fs);
|
||||||
|
|
||||||
|
if (code == _URC_END_OF_STACK)
|
||||||
|
/* Hit end of stack with no handler found. */
|
||||||
|
return _URC_END_OF_STACK;
|
||||||
|
|
||||||
|
if (code != _URC_NO_REASON)
|
||||||
|
/* Some error encountered. Usually the unwinder doesn't
|
||||||
|
diagnose these and merely crashes. */
|
||||||
|
return _URC_FATAL_PHASE1_ERROR;
|
||||||
|
|
||||||
|
/* Unwind successful. Run the personality routine, if any. */
|
||||||
|
if (fs.personality)
|
||||||
|
{
|
||||||
|
code = (*fs.personality) (1, _UA_SEARCH_PHASE, exc->exception_class,
|
||||||
|
exc, &cur_context);
|
||||||
|
if (code == _URC_HANDLER_FOUND)
|
||||||
|
break;
|
||||||
|
else if (code != _URC_CONTINUE_UNWIND)
|
||||||
|
return _URC_FATAL_PHASE1_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update cur_context to describe the same frame as fs. */
|
||||||
|
uw_update_context (&cur_context, &fs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Indicate to _Unwind_Resume and associated subroutines that this
|
||||||
|
is not a forced unwind. Further, note where we found a handler. */
|
||||||
|
exc->private_1 = 0;
|
||||||
|
exc->private_2 = uw_identify_context (&cur_context);
|
||||||
|
|
||||||
|
cur_context = this_context;
|
||||||
|
code = _Unwind_RaiseException_Phase2 (exc, &cur_context);
|
||||||
|
if (code != _URC_INSTALL_CONTEXT)
|
||||||
|
return code;
|
||||||
|
|
||||||
|
uw_install_context (&this_context, &cur_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Subroutine of _Unwind_ForcedUnwind also invoked from _Unwind_Resume. */
|
||||||
|
|
||||||
|
static _Unwind_Reason_Code
|
||||||
|
_Unwind_ForcedUnwind_Phase2 (struct _Unwind_Exception *exc,
|
||||||
|
struct _Unwind_Context *context)
|
||||||
|
{
|
||||||
|
_Unwind_Stop_Fn stop = (_Unwind_Stop_Fn) (_Unwind_Ptr) exc->private_1;
|
||||||
|
void *stop_argument = (void *) (_Unwind_Ptr) exc->private_2;
|
||||||
|
_Unwind_Reason_Code code, stop_code;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
_Unwind_FrameState fs;
|
||||||
|
int action;
|
||||||
|
|
||||||
|
/* Set up fs to describe the FDE for the caller of cur_context. */
|
||||||
|
code = uw_frame_state_for (context, &fs);
|
||||||
|
if (code != _URC_NO_REASON && code != _URC_END_OF_STACK)
|
||||||
|
return _URC_FATAL_PHASE2_ERROR;
|
||||||
|
|
||||||
|
/* Unwind successful. */
|
||||||
|
action = _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE;
|
||||||
|
if (code == _URC_END_OF_STACK)
|
||||||
|
action |= _UA_END_OF_STACK;
|
||||||
|
stop_code = (*stop) (1, action, exc->exception_class, exc,
|
||||||
|
context, stop_argument);
|
||||||
|
if (stop_code != _URC_NO_REASON)
|
||||||
|
return _URC_FATAL_PHASE2_ERROR;
|
||||||
|
|
||||||
|
/* Stop didn't want to do anything. Invoke the personality
|
||||||
|
handler, if applicable, to run cleanups. */
|
||||||
|
if (code == _URC_END_OF_STACK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (fs.personality)
|
||||||
|
{
|
||||||
|
code = (*fs.personality) (1, _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE,
|
||||||
|
exc->exception_class, exc, context);
|
||||||
|
if (code == _URC_INSTALL_CONTEXT)
|
||||||
|
break;
|
||||||
|
if (code != _URC_CONTINUE_UNWIND)
|
||||||
|
return _URC_FATAL_PHASE2_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update cur_context to describe the same frame as fs, and discard
|
||||||
|
the previous context if necessary. */
|
||||||
|
uw_advance_context (context, &fs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Raise an exception for forced unwinding. */
|
||||||
|
|
||||||
|
_Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
|
||||||
|
_Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
|
||||||
|
_Unwind_Stop_Fn stop, void * stop_argument)
|
||||||
|
{
|
||||||
|
struct _Unwind_Context this_context, cur_context;
|
||||||
|
_Unwind_Reason_Code code;
|
||||||
|
|
||||||
|
uw_init_context (&this_context);
|
||||||
|
cur_context = this_context;
|
||||||
|
|
||||||
|
exc->private_1 = (_Unwind_Ptr) stop;
|
||||||
|
exc->private_2 = (_Unwind_Ptr) stop_argument;
|
||||||
|
|
||||||
|
code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
|
||||||
|
if (code != _URC_INSTALL_CONTEXT)
|
||||||
|
return code;
|
||||||
|
|
||||||
|
uw_install_context (&this_context, &cur_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Resume propagation of an existing exception. This is used after
|
||||||
|
e.g. executing cleanup code, and not to implement rethrowing. */
|
||||||
|
|
||||||
|
void LIBGCC2_UNWIND_ATTRIBUTE
|
||||||
|
_Unwind_Resume (struct _Unwind_Exception *exc)
|
||||||
|
{
|
||||||
|
struct _Unwind_Context this_context, cur_context;
|
||||||
|
_Unwind_Reason_Code code;
|
||||||
|
|
||||||
|
uw_init_context (&this_context);
|
||||||
|
cur_context = this_context;
|
||||||
|
|
||||||
|
/* Choose between continuing to process _Unwind_RaiseException
|
||||||
|
or _Unwind_ForcedUnwind. */
|
||||||
|
if (exc->private_1 == 0)
|
||||||
|
code = _Unwind_RaiseException_Phase2 (exc, &cur_context);
|
||||||
|
else
|
||||||
|
code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
|
||||||
|
|
||||||
|
gcc_assert (code == _URC_INSTALL_CONTEXT);
|
||||||
|
|
||||||
|
uw_install_context (&this_context, &cur_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Resume propagation of an FORCE_UNWIND exception, or to rethrow
|
||||||
|
a normal exception that was handled. */
|
||||||
|
|
||||||
|
_Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
|
||||||
|
_Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
|
||||||
|
{
|
||||||
|
struct _Unwind_Context this_context, cur_context;
|
||||||
|
_Unwind_Reason_Code code;
|
||||||
|
|
||||||
|
/* Choose between continuing to process _Unwind_RaiseException
|
||||||
|
or _Unwind_ForcedUnwind. */
|
||||||
|
if (exc->private_1 == 0)
|
||||||
|
return _Unwind_RaiseException (exc);
|
||||||
|
|
||||||
|
uw_init_context (&this_context);
|
||||||
|
cur_context = this_context;
|
||||||
|
|
||||||
|
code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
|
||||||
|
|
||||||
|
gcc_assert (code == _URC_INSTALL_CONTEXT);
|
||||||
|
|
||||||
|
uw_install_context (&this_context, &cur_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* A convenience function that calls the exception_cleanup field. */
|
||||||
|
|
||||||
|
void
|
||||||
|
_Unwind_DeleteException (struct _Unwind_Exception *exc)
|
||||||
|
{
|
||||||
|
if (exc->exception_cleanup)
|
||||||
|
(*exc->exception_cleanup) (_URC_FOREIGN_EXCEPTION_CAUGHT, exc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Perform stack backtrace through unwind data. */
|
||||||
|
|
||||||
|
_Unwind_Reason_Code LIBGCC2_UNWIND_ATTRIBUTE
|
||||||
|
_Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument)
|
||||||
|
{
|
||||||
|
struct _Unwind_Context context;
|
||||||
|
_Unwind_Reason_Code code;
|
||||||
|
|
||||||
|
uw_init_context (&context);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
_Unwind_FrameState fs;
|
||||||
|
|
||||||
|
/* Set up fs to describe the FDE for the caller of context. */
|
||||||
|
code = uw_frame_state_for (&context, &fs);
|
||||||
|
if (code != _URC_NO_REASON && code != _URC_END_OF_STACK)
|
||||||
|
return _URC_FATAL_PHASE1_ERROR;
|
||||||
|
|
||||||
|
/* Call trace function. */
|
||||||
|
if ((*trace) (&context, trace_argument) != _URC_NO_REASON)
|
||||||
|
return _URC_FATAL_PHASE1_ERROR;
|
||||||
|
|
||||||
|
/* We're done at end of stack. */
|
||||||
|
if (code == _URC_END_OF_STACK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Update context to describe the same frame as fs. */
|
||||||
|
uw_update_context (&context, &fs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
35
contrib/sdk/sources/gcc_eh/xm-mingw32.h
Normal file
35
contrib/sdk/sources/gcc_eh/xm-mingw32.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* Configuration for GCC for hosting on Windows32.
|
||||||
|
using GNU tools and the Windows32 API Library.
|
||||||
|
Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2007
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GCC; see the file COPYING3. If not see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#define HOST_EXECUTABLE_SUFFIX ".exe"
|
||||||
|
|
||||||
|
#undef PATH_SEPARATOR
|
||||||
|
#define PATH_SEPARATOR ';'
|
||||||
|
|
||||||
|
/* This is the name of the null device on windows. */
|
||||||
|
#define HOST_BIT_BUCKET "nul"
|
||||||
|
|
||||||
|
/* The st_ino field of struct stat is always 0. */
|
||||||
|
#define HOST_LACKS_INODE_NUMBERS
|
||||||
|
|
||||||
|
/* MSVCRT does not support the "ll" format specifier for printing
|
||||||
|
"long long" values. Instead, we use "I64". */
|
||||||
|
#define HOST_LONG_LONG_FORMAT "I64"
|
81
contrib/sdk/sources/libsupc++/Makefile
Normal file
81
contrib/sdk/sources/libsupc++/Makefile
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
|
||||||
|
LIBRARY= libsup++
|
||||||
|
|
||||||
|
CC=gcc
|
||||||
|
CPP=g++
|
||||||
|
CFLAGS = -U_Win32 -U_WIN32 -U__MINGW32__ -c -O2 -fomit-frame-pointer
|
||||||
|
|
||||||
|
LD = ld
|
||||||
|
|
||||||
|
AR= ar
|
||||||
|
|
||||||
|
STRIP = $(PREFIX)strip
|
||||||
|
|
||||||
|
INCLUDES= -I. -I../newlib/include
|
||||||
|
|
||||||
|
|
||||||
|
LIBS:= -ldll -lc.dll
|
||||||
|
|
||||||
|
|
||||||
|
DEFINES= -DIN_GCC -DUSE_EMUTLS=1
|
||||||
|
|
||||||
|
|
||||||
|
SOURCES = gthr_mutex.c \
|
||||||
|
bad_alloc.cc \
|
||||||
|
class_type_info.cc \
|
||||||
|
del_op.cc \
|
||||||
|
del_opv.cc \
|
||||||
|
eh_alloc.cc \
|
||||||
|
eh_aux_runtime.cc \
|
||||||
|
eh_call.cc \
|
||||||
|
eh_catch.cc \
|
||||||
|
eh_exception.cc \
|
||||||
|
eh_globals.cc \
|
||||||
|
eh_personality.cc \
|
||||||
|
eh_term_handler.cc \
|
||||||
|
eh_terminate.cc \
|
||||||
|
eh_throw.cc \
|
||||||
|
eh_type.c \
|
||||||
|
eh_unex_handler.cc \
|
||||||
|
guard.cc \
|
||||||
|
guard_error.cc \
|
||||||
|
new_handler.cc \
|
||||||
|
new_op.cc \
|
||||||
|
new_opnt.cc \
|
||||||
|
new_opv.cc \
|
||||||
|
pbase_type_info.cc \
|
||||||
|
pure.cc \
|
||||||
|
si_class_type_info.cc \
|
||||||
|
tinfo.cc \
|
||||||
|
vmi_class_type_info.cc \
|
||||||
|
vterminate.cc
|
||||||
|
|
||||||
|
|
||||||
|
OBJECTS = $(patsubst %.cc, %.o, $(patsubst %.c, %.o, $(SOURCES)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# targets
|
||||||
|
|
||||||
|
|
||||||
|
all:$(LIBRARY).a
|
||||||
|
|
||||||
|
|
||||||
|
$(LIBRARY).a: $(OBJECTS) Makefile
|
||||||
|
ar cvrs $(LIBRARY).a $(OBJECTS)
|
||||||
|
mv -f $(LIBRARY).a ../../lib
|
||||||
|
|
||||||
|
|
||||||
|
%.o : %.c Makefile
|
||||||
|
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
|
||||||
|
|
||||||
|
%.o : %.cc Makefile
|
||||||
|
$(CPP) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-rm -f *.o
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
34
contrib/sdk/sources/libsupc++/bad_alloc.cc
Normal file
34
contrib/sdk/sources/libsupc++/bad_alloc.cc
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Implementation file for the -*- C++ -*- dynamic memory management header.
|
||||||
|
|
||||||
|
// Copyright (C) 2010, 2011 Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "new"
|
||||||
|
|
||||||
|
std::bad_alloc::~bad_alloc() _GLIBCXX_USE_NOEXCEPT { }
|
||||||
|
|
||||||
|
const char*
|
||||||
|
std::bad_alloc::what() const _GLIBCXX_USE_NOEXCEPT
|
||||||
|
{
|
||||||
|
return "std::bad_alloc";
|
||||||
|
}
|
111
contrib/sdk/sources/libsupc++/class_type_info.cc
Normal file
111
contrib/sdk/sources/libsupc++/class_type_info.cc
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007,
|
||||||
|
// 2009 Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "tinfo.h"
|
||||||
|
|
||||||
|
namespace __cxxabiv1 {
|
||||||
|
|
||||||
|
__class_type_info::
|
||||||
|
~__class_type_info ()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool __class_type_info::
|
||||||
|
__do_catch (const type_info *thr_type,
|
||||||
|
void **thr_obj,
|
||||||
|
unsigned outer) const
|
||||||
|
{
|
||||||
|
if (*this == *thr_type)
|
||||||
|
return true;
|
||||||
|
if (outer >= 4)
|
||||||
|
// Neither `A' nor `A *'.
|
||||||
|
return false;
|
||||||
|
return thr_type->__do_upcast (this, thr_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool __class_type_info::
|
||||||
|
__do_upcast (const __class_type_info *dst_type,
|
||||||
|
void **obj_ptr) const
|
||||||
|
{
|
||||||
|
__upcast_result result (__vmi_class_type_info::__flags_unknown_mask);
|
||||||
|
|
||||||
|
__do_upcast (dst_type, *obj_ptr, result);
|
||||||
|
if (!contained_public_p (result.part2dst))
|
||||||
|
return false;
|
||||||
|
*obj_ptr = const_cast <void *> (result.dst_ptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
__class_type_info::__sub_kind __class_type_info::
|
||||||
|
__do_find_public_src (ptrdiff_t,
|
||||||
|
const void *obj_ptr,
|
||||||
|
const __class_type_info *,
|
||||||
|
const void *src_ptr) const
|
||||||
|
{
|
||||||
|
if (src_ptr == obj_ptr)
|
||||||
|
// Must be our type, as the pointers match.
|
||||||
|
return __contained_public;
|
||||||
|
return __not_contained;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool __class_type_info::
|
||||||
|
__do_dyncast (ptrdiff_t,
|
||||||
|
__sub_kind access_path,
|
||||||
|
const __class_type_info *dst_type,
|
||||||
|
const void *obj_ptr,
|
||||||
|
const __class_type_info *src_type,
|
||||||
|
const void *src_ptr,
|
||||||
|
__dyncast_result &__restrict result) const
|
||||||
|
{
|
||||||
|
if (obj_ptr == src_ptr && *this == *src_type)
|
||||||
|
{
|
||||||
|
// The src object we started from. Indicate how we are accessible from
|
||||||
|
// the most derived object.
|
||||||
|
result.whole2src = access_path;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (*this == *dst_type)
|
||||||
|
{
|
||||||
|
result.dst_ptr = obj_ptr;
|
||||||
|
result.whole2dst = access_path;
|
||||||
|
result.dst2src = __not_contained;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool __class_type_info::
|
||||||
|
__do_upcast (const __class_type_info *dst, const void *obj,
|
||||||
|
__upcast_result &__restrict result) const
|
||||||
|
{
|
||||||
|
if (*this == *dst)
|
||||||
|
{
|
||||||
|
result.dst_ptr = obj;
|
||||||
|
result.base_type = nonvirtual_base_type;
|
||||||
|
result.part2dst = __contained_public;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
49
contrib/sdk/sources/libsupc++/del_op.cc
Normal file
49
contrib/sdk/sources/libsupc++/del_op.cc
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
|
||||||
|
|
||||||
|
// Copyright (C) 1997, 1998, 1999, 2000, 2004, 2007, 2009, 2010, 2011
|
||||||
|
// Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <bits/c++config.h>
|
||||||
|
|
||||||
|
#if !_GLIBCXX_HOSTED
|
||||||
|
// A freestanding C runtime may not provide "free" -- but there is no
|
||||||
|
// other reasonable way to implement "operator delete".
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
extern "C" void free(void*);
|
||||||
|
_GLIBCXX_END_NAMESPACE_VERSION
|
||||||
|
} // namespace
|
||||||
|
#else
|
||||||
|
# include <cstdlib>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "new"
|
||||||
|
|
||||||
|
_GLIBCXX_WEAK_DEFINITION void
|
||||||
|
operator delete(void* ptr) _GLIBCXX_USE_NOEXCEPT
|
||||||
|
{
|
||||||
|
if (ptr)
|
||||||
|
std::free(ptr);
|
||||||
|
}
|
34
contrib/sdk/sources/libsupc++/del_opv.cc
Normal file
34
contrib/sdk/sources/libsupc++/del_opv.cc
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
|
||||||
|
|
||||||
|
// Copyright (C) 1997, 1998, 1999, 2000, 2004, 2009, 2010, 2011
|
||||||
|
// Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <bits/c++config.h>
|
||||||
|
#include "new"
|
||||||
|
|
||||||
|
_GLIBCXX_WEAK_DEFINITION void
|
||||||
|
operator delete[] (void *ptr) _GLIBCXX_USE_NOEXCEPT
|
||||||
|
{
|
||||||
|
::operator delete (ptr);
|
||||||
|
}
|
220
contrib/sdk/sources/libsupc++/eh_alloc.cc
Normal file
220
contrib/sdk/sources/libsupc++/eh_alloc.cc
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
// -*- C++ -*- Allocate exception objects.
|
||||||
|
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2011
|
||||||
|
// Free Software Foundation, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// This is derived from the C++ ABI for IA-64. Where we diverge
|
||||||
|
// for cross-architecture compatibility are noted with "@@@".
|
||||||
|
|
||||||
|
#include <bits/c++config.h>
|
||||||
|
#include <cstdlib>
|
||||||
|
#if _GLIBCXX_HOSTED
|
||||||
|
#include <cstring>
|
||||||
|
#endif
|
||||||
|
#include <climits>
|
||||||
|
#include <exception>
|
||||||
|
#include "unwind-cxx.h"
|
||||||
|
#include <ext/concurrence.h>
|
||||||
|
|
||||||
|
#if _GLIBCXX_HOSTED
|
||||||
|
using std::free;
|
||||||
|
using std::malloc;
|
||||||
|
using std::memset;
|
||||||
|
#else
|
||||||
|
// In a freestanding environment, these functions may not be available
|
||||||
|
// -- but for now, we assume that they are.
|
||||||
|
extern "C" void *malloc (std::size_t);
|
||||||
|
extern "C" void free(void *);
|
||||||
|
extern "C" void *memset (void *, int, std::size_t);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using namespace __cxxabiv1;
|
||||||
|
|
||||||
|
// ??? How to control these parameters.
|
||||||
|
|
||||||
|
// Guess from the size of basic types how large a buffer is reasonable.
|
||||||
|
// Note that the basic c++ exception header has 13 pointers and 2 ints,
|
||||||
|
// so on a system with PSImode pointers we're talking about 56 bytes
|
||||||
|
// just for overhead.
|
||||||
|
|
||||||
|
#if INT_MAX == 32767
|
||||||
|
# define EMERGENCY_OBJ_SIZE 128
|
||||||
|
# define EMERGENCY_OBJ_COUNT 16
|
||||||
|
#elif LONG_MAX == 2147483647
|
||||||
|
# define EMERGENCY_OBJ_SIZE 512
|
||||||
|
# define EMERGENCY_OBJ_COUNT 32
|
||||||
|
#else
|
||||||
|
# define EMERGENCY_OBJ_SIZE 1024
|
||||||
|
# define EMERGENCY_OBJ_COUNT 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __GTHREADS
|
||||||
|
# undef EMERGENCY_OBJ_COUNT
|
||||||
|
# define EMERGENCY_OBJ_COUNT 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if INT_MAX == 32767 || EMERGENCY_OBJ_COUNT <= 32
|
||||||
|
typedef unsigned int bitmask_type;
|
||||||
|
#else
|
||||||
|
typedef unsigned long bitmask_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef char one_buffer[EMERGENCY_OBJ_SIZE] __attribute__((aligned));
|
||||||
|
static one_buffer emergency_buffer[EMERGENCY_OBJ_COUNT];
|
||||||
|
static bitmask_type emergency_used;
|
||||||
|
|
||||||
|
static __cxa_dependent_exception dependents_buffer[EMERGENCY_OBJ_COUNT];
|
||||||
|
static bitmask_type dependents_used;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// A single mutex controlling emergency allocations.
|
||||||
|
__gnu_cxx::__mutex emergency_mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void *
|
||||||
|
__cxxabiv1::__cxa_allocate_exception(std::size_t thrown_size) _GLIBCXX_NOTHROW
|
||||||
|
{
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
thrown_size += sizeof (__cxa_refcounted_exception);
|
||||||
|
ret = malloc (thrown_size);
|
||||||
|
|
||||||
|
if (! ret)
|
||||||
|
{
|
||||||
|
__gnu_cxx::__scoped_lock sentry(emergency_mutex);
|
||||||
|
|
||||||
|
bitmask_type used = emergency_used;
|
||||||
|
unsigned int which = 0;
|
||||||
|
|
||||||
|
if (thrown_size > EMERGENCY_OBJ_SIZE)
|
||||||
|
goto failed;
|
||||||
|
while (used & 1)
|
||||||
|
{
|
||||||
|
used >>= 1;
|
||||||
|
if (++which >= EMERGENCY_OBJ_COUNT)
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
emergency_used |= (bitmask_type)1 << which;
|
||||||
|
ret = &emergency_buffer[which][0];
|
||||||
|
|
||||||
|
failed:;
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
std::terminate ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have an uncaught exception as soon as we allocate memory. This
|
||||||
|
// yields uncaught_exception() true during the copy-constructor that
|
||||||
|
// initializes the exception object. See Issue 475.
|
||||||
|
__cxa_eh_globals *globals = __cxa_get_globals ();
|
||||||
|
globals->uncaughtExceptions += 1;
|
||||||
|
|
||||||
|
memset (ret, 0, sizeof (__cxa_refcounted_exception));
|
||||||
|
|
||||||
|
return (void *)((char *)ret + sizeof (__cxa_refcounted_exception));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__cxxabiv1::__cxa_free_exception(void *vptr) _GLIBCXX_NOTHROW
|
||||||
|
{
|
||||||
|
char *base = (char *) emergency_buffer;
|
||||||
|
char *ptr = (char *) vptr;
|
||||||
|
if (ptr >= base
|
||||||
|
&& ptr < base + sizeof (emergency_buffer))
|
||||||
|
{
|
||||||
|
const unsigned int which
|
||||||
|
= (unsigned) (ptr - base) / EMERGENCY_OBJ_SIZE;
|
||||||
|
|
||||||
|
__gnu_cxx::__scoped_lock sentry(emergency_mutex);
|
||||||
|
emergency_used &= ~((bitmask_type)1 << which);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
free (ptr - sizeof (__cxa_refcounted_exception));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" __cxa_dependent_exception*
|
||||||
|
__cxxabiv1::__cxa_allocate_dependent_exception() _GLIBCXX_NOTHROW
|
||||||
|
{
|
||||||
|
__cxa_dependent_exception *ret;
|
||||||
|
|
||||||
|
ret = static_cast<__cxa_dependent_exception*>
|
||||||
|
(malloc (sizeof (__cxa_dependent_exception)));
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
__gnu_cxx::__scoped_lock sentry(emergency_mutex);
|
||||||
|
|
||||||
|
bitmask_type used = dependents_used;
|
||||||
|
unsigned int which = 0;
|
||||||
|
|
||||||
|
while (used & 1)
|
||||||
|
{
|
||||||
|
used >>= 1;
|
||||||
|
if (++which >= EMERGENCY_OBJ_COUNT)
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
dependents_used |= (bitmask_type)1 << which;
|
||||||
|
ret = &dependents_buffer[which];
|
||||||
|
|
||||||
|
failed:;
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
std::terminate ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have an uncaught exception as soon as we allocate memory. This
|
||||||
|
// yields uncaught_exception() true during the copy-constructor that
|
||||||
|
// initializes the exception object. See Issue 475.
|
||||||
|
__cxa_eh_globals *globals = __cxa_get_globals ();
|
||||||
|
globals->uncaughtExceptions += 1;
|
||||||
|
|
||||||
|
memset (ret, 0, sizeof (__cxa_dependent_exception));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__cxxabiv1::__cxa_free_dependent_exception
|
||||||
|
(__cxa_dependent_exception *vptr) _GLIBCXX_NOTHROW
|
||||||
|
{
|
||||||
|
char *base = (char *) dependents_buffer;
|
||||||
|
char *ptr = (char *) vptr;
|
||||||
|
if (ptr >= base
|
||||||
|
&& ptr < base + sizeof (dependents_buffer))
|
||||||
|
{
|
||||||
|
const unsigned int which
|
||||||
|
= (unsigned) (ptr - base) / sizeof (__cxa_dependent_exception);
|
||||||
|
|
||||||
|
__gnu_cxx::__scoped_lock sentry(emergency_mutex);
|
||||||
|
dependents_used &= ~((bitmask_type)1 << which);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
free (vptr);
|
||||||
|
}
|
51
contrib/sdk/sources/libsupc++/eh_aux_runtime.cc
Normal file
51
contrib/sdk/sources/libsupc++/eh_aux_runtime.cc
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// -*- C++ -*- Common throw conditions.
|
||||||
|
// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2009, 2011
|
||||||
|
// Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "typeinfo"
|
||||||
|
#include "exception"
|
||||||
|
#include <cstdlib>
|
||||||
|
#include "unwind-cxx.h"
|
||||||
|
#include <bits/exception_defines.h>
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__cxxabiv1::__cxa_bad_cast ()
|
||||||
|
{
|
||||||
|
#ifdef __EXCEPTIONS
|
||||||
|
throw std::bad_cast();
|
||||||
|
#else
|
||||||
|
std::abort();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__cxxabiv1::__cxa_bad_typeid ()
|
||||||
|
{
|
||||||
|
#ifdef __EXCEPTIONS
|
||||||
|
throw std::bad_typeid();
|
||||||
|
#else
|
||||||
|
std::abort();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
159
contrib/sdk/sources/libsupc++/eh_call.cc
Normal file
159
contrib/sdk/sources/libsupc++/eh_call.cc
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
// -*- C++ -*- Helpers for calling unextected and terminate
|
||||||
|
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||||
|
// 2011
|
||||||
|
// Free Software Foundation, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <bits/c++config.h>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <bits/exception_defines.h>
|
||||||
|
#include "unwind-cxx.h"
|
||||||
|
|
||||||
|
using namespace __cxxabiv1;
|
||||||
|
|
||||||
|
#include "unwind-pe.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Helper routine for when the exception handling code needs to call
|
||||||
|
// terminate.
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__cxa_call_terminate(_Unwind_Exception* ue_header) throw ()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (ue_header)
|
||||||
|
{
|
||||||
|
// terminate is classed as a catch handler.
|
||||||
|
__cxa_begin_catch(ue_header);
|
||||||
|
|
||||||
|
// Call the terminate handler that was in effect when we threw this
|
||||||
|
// exception. */
|
||||||
|
if (__is_gxx_exception_class(ue_header->exception_class))
|
||||||
|
{
|
||||||
|
__cxa_exception* xh;
|
||||||
|
|
||||||
|
xh = __get_exception_header_from_ue(ue_header);
|
||||||
|
__terminate(xh->terminateHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Call the global routine if we don't have anything better. */
|
||||||
|
std::terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __ARM_EABI_UNWINDER__
|
||||||
|
// The ARM EABI __cxa_call_unexpected has the same semantics as the generic
|
||||||
|
// routine, but the exception specification has a different format.
|
||||||
|
extern "C" void
|
||||||
|
__cxa_call_unexpected(void* exc_obj_in)
|
||||||
|
{
|
||||||
|
_Unwind_Exception* exc_obj
|
||||||
|
= reinterpret_cast<_Unwind_Exception*>(exc_obj_in);
|
||||||
|
|
||||||
|
int rtti_count = 0;
|
||||||
|
_Unwind_Word rtti_stride = 0;
|
||||||
|
_Unwind_Word* rtti_list = NULL;
|
||||||
|
_Unwind_Ptr rtti_base = 0;
|
||||||
|
bool foreign_exception;
|
||||||
|
std::unexpected_handler unexpectedHandler = NULL;
|
||||||
|
std::terminate_handler terminateHandler = NULL;
|
||||||
|
__cxa_exception* xh;
|
||||||
|
if (__is_gxx_exception_class(exc_obj->exception_class))
|
||||||
|
{
|
||||||
|
// Save data from the EO, which may be clobbered by _cxa_begin_catch.
|
||||||
|
xh = __get_exception_header_from_ue(exc_obj);
|
||||||
|
unexpectedHandler = xh->unexpectedHandler;
|
||||||
|
terminateHandler = xh->terminateHandler;
|
||||||
|
rtti_count = exc_obj->barrier_cache.bitpattern[1];
|
||||||
|
rtti_base = (_Unwind_Ptr) exc_obj->barrier_cache.bitpattern[2];
|
||||||
|
rtti_stride = exc_obj->barrier_cache.bitpattern[3];
|
||||||
|
rtti_list = (_Unwind_Word*) exc_obj->barrier_cache.bitpattern[4];
|
||||||
|
foreign_exception = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
foreign_exception = true;
|
||||||
|
|
||||||
|
/* This must be called after extracting data from the EO, but before
|
||||||
|
calling unexpected(). */
|
||||||
|
__cxa_begin_catch(exc_obj);
|
||||||
|
|
||||||
|
// This function is a handler for our exception argument. If we exit
|
||||||
|
// by throwing a different exception, we'll need the original cleaned up.
|
||||||
|
struct end_catch_protect
|
||||||
|
{
|
||||||
|
end_catch_protect() { }
|
||||||
|
~end_catch_protect() { __cxa_end_catch(); }
|
||||||
|
} end_catch_protect_obj;
|
||||||
|
|
||||||
|
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
if (foreign_exception)
|
||||||
|
std::unexpected();
|
||||||
|
else
|
||||||
|
__unexpected(unexpectedHandler);
|
||||||
|
}
|
||||||
|
__catch(...)
|
||||||
|
{
|
||||||
|
/* See if the new exception matches the rtti list. */
|
||||||
|
if (foreign_exception)
|
||||||
|
std::terminate();
|
||||||
|
|
||||||
|
// Get the exception thrown from unexpected.
|
||||||
|
|
||||||
|
__cxa_eh_globals* globals = __cxa_get_globals_fast();
|
||||||
|
__cxa_exception* new_xh = globals->caughtExceptions;
|
||||||
|
void* new_ptr = __get_object_from_ambiguous_exception (new_xh);
|
||||||
|
const std::type_info* catch_type;
|
||||||
|
int n;
|
||||||
|
bool bad_exception_allowed = false;
|
||||||
|
const std::type_info& bad_exc = typeid(std::bad_exception);
|
||||||
|
|
||||||
|
// Check the new exception against the rtti list
|
||||||
|
for (n = 0; n < rtti_count; n++)
|
||||||
|
{
|
||||||
|
_Unwind_Word offset;
|
||||||
|
|
||||||
|
offset = (_Unwind_Word) &rtti_list[n * (rtti_stride >> 2)];
|
||||||
|
offset = _Unwind_decode_typeinfo_ptr(rtti_base, offset);
|
||||||
|
catch_type = (const std::type_info*) (offset);
|
||||||
|
|
||||||
|
if (__cxa_type_match(&new_xh->unwindHeader, catch_type, false,
|
||||||
|
&new_ptr) != ctm_failed)
|
||||||
|
__throw_exception_again;
|
||||||
|
|
||||||
|
if (catch_type->__do_catch(&bad_exc, 0, 1))
|
||||||
|
bad_exception_allowed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the exception spec allows std::bad_exception, throw that.
|
||||||
|
#ifdef __EXCEPTIONS
|
||||||
|
if (bad_exception_allowed)
|
||||||
|
throw std::bad_exception();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Otherwise, die.
|
||||||
|
__terminate(terminateHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // __ARM_EABI_UNWINDER__
|
138
contrib/sdk/sources/libsupc++/eh_catch.cc
Normal file
138
contrib/sdk/sources/libsupc++/eh_catch.cc
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
// -*- C++ -*- Exception handling routines for catching.
|
||||||
|
// Copyright (C) 2001, 2003, 2004, 2009, 2011 Free Software Foundation, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include "unwind-cxx.h"
|
||||||
|
|
||||||
|
using namespace __cxxabiv1;
|
||||||
|
|
||||||
|
extern "C" void *
|
||||||
|
__cxxabiv1::__cxa_get_exception_ptr(void *exc_obj_in) _GLIBCXX_NOTHROW
|
||||||
|
{
|
||||||
|
_Unwind_Exception *exceptionObject
|
||||||
|
= reinterpret_cast <_Unwind_Exception *>(exc_obj_in);
|
||||||
|
|
||||||
|
return __gxx_caught_object(exceptionObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void *
|
||||||
|
__cxxabiv1::__cxa_begin_catch (void *exc_obj_in) _GLIBCXX_NOTHROW
|
||||||
|
{
|
||||||
|
_Unwind_Exception *exceptionObject
|
||||||
|
= reinterpret_cast <_Unwind_Exception *>(exc_obj_in);
|
||||||
|
__cxa_eh_globals *globals = __cxa_get_globals ();
|
||||||
|
__cxa_exception *prev = globals->caughtExceptions;
|
||||||
|
__cxa_exception *header = __get_exception_header_from_ue (exceptionObject);
|
||||||
|
void* objectp;
|
||||||
|
|
||||||
|
// Foreign exceptions can't be stacked here. If the exception stack is
|
||||||
|
// empty, then fine. Otherwise we really have no choice but to terminate.
|
||||||
|
// Note that this use of "header" is a lie. It's fine so long as we only
|
||||||
|
// examine header->unwindHeader though.
|
||||||
|
if (!__is_gxx_exception_class(header->unwindHeader.exception_class))
|
||||||
|
{
|
||||||
|
if (prev != 0)
|
||||||
|
std::terminate ();
|
||||||
|
|
||||||
|
// Remember for end_catch and rethrow.
|
||||||
|
globals->caughtExceptions = header;
|
||||||
|
|
||||||
|
// ??? No sensible value to return; we don't know what the
|
||||||
|
// object is, much less where it is in relation to the header.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = header->handlerCount;
|
||||||
|
// Count is less than zero if this exception was rethrown from an
|
||||||
|
// immediately enclosing region.
|
||||||
|
if (count < 0)
|
||||||
|
count = -count + 1;
|
||||||
|
else
|
||||||
|
count += 1;
|
||||||
|
header->handlerCount = count;
|
||||||
|
globals->uncaughtExceptions -= 1;
|
||||||
|
|
||||||
|
if (header != prev)
|
||||||
|
{
|
||||||
|
header->nextException = prev;
|
||||||
|
globals->caughtExceptions = header;
|
||||||
|
}
|
||||||
|
|
||||||
|
objectp = __gxx_caught_object(exceptionObject);
|
||||||
|
#ifdef __ARM_EABI_UNWINDER__
|
||||||
|
_Unwind_Complete(exceptionObject);
|
||||||
|
#endif
|
||||||
|
return objectp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__cxxabiv1::__cxa_end_catch ()
|
||||||
|
{
|
||||||
|
__cxa_eh_globals *globals = __cxa_get_globals_fast ();
|
||||||
|
__cxa_exception *header = globals->caughtExceptions;
|
||||||
|
|
||||||
|
// A rethrow of a foreign exception will be removed from the
|
||||||
|
// the exception stack immediately by __cxa_rethrow.
|
||||||
|
if (!header)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// A foreign exception couldn't have been stacked (see above),
|
||||||
|
// so by definition processing must be complete.
|
||||||
|
if (!__is_gxx_exception_class(header->unwindHeader.exception_class))
|
||||||
|
{
|
||||||
|
globals->caughtExceptions = 0;
|
||||||
|
_Unwind_DeleteException (&header->unwindHeader);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = header->handlerCount;
|
||||||
|
if (count < 0)
|
||||||
|
{
|
||||||
|
// This exception was rethrown. Decrement the (inverted) catch
|
||||||
|
// count and remove it from the chain when it reaches zero.
|
||||||
|
if (++count == 0)
|
||||||
|
globals->caughtExceptions = header->nextException;
|
||||||
|
}
|
||||||
|
else if (--count == 0)
|
||||||
|
{
|
||||||
|
// Handling for this exception is complete. Destroy the object.
|
||||||
|
globals->caughtExceptions = header->nextException;
|
||||||
|
_Unwind_DeleteException (&header->unwindHeader);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (count < 0)
|
||||||
|
// A bug in the exception handling library or compiler.
|
||||||
|
std::terminate ();
|
||||||
|
|
||||||
|
header->handlerCount = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
std::uncaught_exception() throw()
|
||||||
|
{
|
||||||
|
__cxa_eh_globals *globals = __cxa_get_globals ();
|
||||||
|
return globals->uncaughtExceptions != 0;
|
||||||
|
}
|
52
contrib/sdk/sources/libsupc++/eh_exception.cc
Normal file
52
contrib/sdk/sources/libsupc++/eh_exception.cc
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// -*- C++ -*- std::exception implementation.
|
||||||
|
// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||||
|
// 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011
|
||||||
|
// Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "typeinfo"
|
||||||
|
#include "exception"
|
||||||
|
#include <cxxabi.h>
|
||||||
|
|
||||||
|
std::exception::~exception() _GLIBCXX_USE_NOEXCEPT { }
|
||||||
|
|
||||||
|
std::bad_exception::~bad_exception() _GLIBCXX_USE_NOEXCEPT { }
|
||||||
|
|
||||||
|
abi::__forced_unwind::~__forced_unwind() throw() { }
|
||||||
|
|
||||||
|
abi::__foreign_exception::~__foreign_exception() throw() { }
|
||||||
|
|
||||||
|
const char*
|
||||||
|
std::exception::what() const _GLIBCXX_USE_NOEXCEPT
|
||||||
|
{
|
||||||
|
// NB: Another elegant option would be returning typeid(*this).name()
|
||||||
|
// and not overriding what() in bad_exception, bad_alloc, etc. In
|
||||||
|
// that case, however, mangled names would be returned, PR 14493.
|
||||||
|
return "std::exception";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char*
|
||||||
|
std::bad_exception::what() const _GLIBCXX_USE_NOEXCEPT
|
||||||
|
{
|
||||||
|
return "std::bad_exception";
|
||||||
|
}
|
160
contrib/sdk/sources/libsupc++/eh_globals.cc
Normal file
160
contrib/sdk/sources/libsupc++/eh_globals.cc
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
// -*- C++ -*- Manage the thread-local exception globals.
|
||||||
|
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2011
|
||||||
|
// Free Software Foundation, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <bits/c++config.h>
|
||||||
|
#include <exception>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include "cxxabi.h"
|
||||||
|
#include "unwind-cxx.h"
|
||||||
|
#include "bits/gthr.h"
|
||||||
|
|
||||||
|
#if _GLIBCXX_HOSTED
|
||||||
|
using std::free;
|
||||||
|
using std::malloc;
|
||||||
|
#else
|
||||||
|
// In a freestanding environment, these functions may not be
|
||||||
|
// available -- but for now, we assume that they are.
|
||||||
|
extern "C" void *malloc (std::size_t);
|
||||||
|
extern "C" void free(void *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using namespace __cxxabiv1;
|
||||||
|
|
||||||
|
#if _GLIBCXX_HAVE_TLS
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
abi::__cxa_eh_globals*
|
||||||
|
get_global() _GLIBCXX_NOTHROW
|
||||||
|
{
|
||||||
|
static __thread abi::__cxa_eh_globals global;
|
||||||
|
return &global;
|
||||||
|
}
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
extern "C" __cxa_eh_globals*
|
||||||
|
__cxxabiv1::__cxa_get_globals_fast() _GLIBCXX_NOTHROW
|
||||||
|
{ return get_global(); }
|
||||||
|
|
||||||
|
extern "C" __cxa_eh_globals*
|
||||||
|
__cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW
|
||||||
|
{ return get_global(); }
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Single-threaded fallback buffer.
|
||||||
|
static __cxa_eh_globals eh_globals;
|
||||||
|
|
||||||
|
#if __GTHREADS
|
||||||
|
|
||||||
|
static void
|
||||||
|
eh_globals_dtor(void* ptr)
|
||||||
|
{
|
||||||
|
if (ptr)
|
||||||
|
{
|
||||||
|
__cxa_eh_globals* g = reinterpret_cast<__cxa_eh_globals*>(ptr);
|
||||||
|
__cxa_exception* exn = g->caughtExceptions;
|
||||||
|
__cxa_exception* next;
|
||||||
|
while (exn)
|
||||||
|
{
|
||||||
|
next = exn->nextException;
|
||||||
|
_Unwind_DeleteException(&exn->unwindHeader);
|
||||||
|
exn = next;
|
||||||
|
}
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct __eh_globals_init
|
||||||
|
{
|
||||||
|
__gthread_key_t _M_key;
|
||||||
|
bool _M_init;
|
||||||
|
|
||||||
|
__eh_globals_init() : _M_init(false)
|
||||||
|
{
|
||||||
|
if (__gthread_active_p())
|
||||||
|
_M_init = __gthread_key_create(&_M_key, eh_globals_dtor) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
~__eh_globals_init()
|
||||||
|
{
|
||||||
|
if (_M_init)
|
||||||
|
__gthread_key_delete(_M_key);
|
||||||
|
_M_init = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static __eh_globals_init init;
|
||||||
|
|
||||||
|
extern "C" __cxa_eh_globals*
|
||||||
|
__cxxabiv1::__cxa_get_globals_fast() _GLIBCXX_NOTHROW
|
||||||
|
{
|
||||||
|
__cxa_eh_globals* g;
|
||||||
|
if (init._M_init)
|
||||||
|
g = static_cast<__cxa_eh_globals*>(__gthread_getspecific(init._M_key));
|
||||||
|
else
|
||||||
|
g = &eh_globals;
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" __cxa_eh_globals*
|
||||||
|
__cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW
|
||||||
|
{
|
||||||
|
__cxa_eh_globals* g;
|
||||||
|
if (init._M_init)
|
||||||
|
{
|
||||||
|
g = static_cast<__cxa_eh_globals*>(__gthread_getspecific(init._M_key));
|
||||||
|
if (!g)
|
||||||
|
{
|
||||||
|
void* v = malloc(sizeof(__cxa_eh_globals));
|
||||||
|
if (v == 0 || __gthread_setspecific(init._M_key, v) != 0)
|
||||||
|
std::terminate();
|
||||||
|
g = static_cast<__cxa_eh_globals*>(v);
|
||||||
|
g->caughtExceptions = 0;
|
||||||
|
g->uncaughtExceptions = 0;
|
||||||
|
#ifdef __ARM_EABI_UNWINDER__
|
||||||
|
g->propagatingExceptions = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g = &eh_globals;
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
extern "C" __cxa_eh_globals*
|
||||||
|
__cxxabiv1::__cxa_get_globals_fast() _GLIBCXX_NOTHROW
|
||||||
|
{ return &eh_globals; }
|
||||||
|
|
||||||
|
extern "C" __cxa_eh_globals*
|
||||||
|
__cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW
|
||||||
|
{ return &eh_globals; }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
781
contrib/sdk/sources/libsupc++/eh_personality.cc
Normal file
781
contrib/sdk/sources/libsupc++/eh_personality.cc
Normal file
@ -0,0 +1,781 @@
|
|||||||
|
// -*- C++ -*- The GNU C++ exception personality routine.
|
||||||
|
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||||
|
// 2011
|
||||||
|
// Free Software Foundation, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <bits/c++config.h>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <bits/exception_defines.h>
|
||||||
|
#include <cxxabi.h>
|
||||||
|
#include "unwind-cxx.h"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace __cxxabiv1;
|
||||||
|
|
||||||
|
#include "unwind-pe.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct lsda_header_info
|
||||||
|
{
|
||||||
|
_Unwind_Ptr Start;
|
||||||
|
_Unwind_Ptr LPStart;
|
||||||
|
_Unwind_Ptr ttype_base;
|
||||||
|
const unsigned char *TType;
|
||||||
|
const unsigned char *action_table;
|
||||||
|
unsigned char ttype_encoding;
|
||||||
|
unsigned char call_site_encoding;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char *
|
||||||
|
parse_lsda_header (_Unwind_Context *context, const unsigned char *p,
|
||||||
|
lsda_header_info *info)
|
||||||
|
{
|
||||||
|
_uleb128_t tmp;
|
||||||
|
unsigned char lpstart_encoding;
|
||||||
|
|
||||||
|
info->Start = (context ? _Unwind_GetRegionStart (context) : 0);
|
||||||
|
|
||||||
|
// Find @LPStart, the base to which landing pad offsets are relative.
|
||||||
|
lpstart_encoding = *p++;
|
||||||
|
if (lpstart_encoding != DW_EH_PE_omit)
|
||||||
|
p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart);
|
||||||
|
else
|
||||||
|
info->LPStart = info->Start;
|
||||||
|
|
||||||
|
// Find @TType, the base of the handler and exception spec type data.
|
||||||
|
info->ttype_encoding = *p++;
|
||||||
|
if (info->ttype_encoding != DW_EH_PE_omit)
|
||||||
|
{
|
||||||
|
#if _GLIBCXX_OVERRIDE_TTYPE_ENCODING
|
||||||
|
/* Older ARM EABI toolchains set this value incorrectly, so use a
|
||||||
|
hardcoded OS-specific format. */
|
||||||
|
info->ttype_encoding = _GLIBCXX_OVERRIDE_TTYPE_ENCODING;
|
||||||
|
#endif
|
||||||
|
p = read_uleb128 (p, &tmp);
|
||||||
|
info->TType = p + tmp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
info->TType = 0;
|
||||||
|
|
||||||
|
// The encoding and length of the call-site table; the action table
|
||||||
|
// immediately follows.
|
||||||
|
info->call_site_encoding = *p++;
|
||||||
|
p = read_uleb128 (p, &tmp);
|
||||||
|
info->action_table = p + tmp;
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return an element from a type table.
|
||||||
|
|
||||||
|
static const std::type_info*
|
||||||
|
get_ttype_entry(lsda_header_info* info, _uleb128_t i)
|
||||||
|
{
|
||||||
|
_Unwind_Ptr ptr;
|
||||||
|
|
||||||
|
i *= size_of_encoded_value (info->ttype_encoding);
|
||||||
|
read_encoded_value_with_base (info->ttype_encoding, info->ttype_base,
|
||||||
|
info->TType - i, &ptr);
|
||||||
|
|
||||||
|
return reinterpret_cast<const std::type_info *>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __ARM_EABI_UNWINDER__
|
||||||
|
|
||||||
|
// The ABI provides a routine for matching exception object types.
|
||||||
|
typedef _Unwind_Control_Block _throw_typet;
|
||||||
|
#define get_adjusted_ptr(catch_type, throw_type, thrown_ptr_p) \
|
||||||
|
(__cxa_type_match (throw_type, catch_type, false, thrown_ptr_p) \
|
||||||
|
!= ctm_failed)
|
||||||
|
|
||||||
|
// Return true if THROW_TYPE matches one if the filter types.
|
||||||
|
|
||||||
|
static bool
|
||||||
|
check_exception_spec(lsda_header_info* info, _throw_typet* throw_type,
|
||||||
|
void* thrown_ptr, _sleb128_t filter_value)
|
||||||
|
{
|
||||||
|
const _uleb128_t* e = ((const _uleb128_t*) info->TType)
|
||||||
|
- filter_value - 1;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
const std::type_info* catch_type;
|
||||||
|
_uleb128_t tmp;
|
||||||
|
|
||||||
|
tmp = *e;
|
||||||
|
|
||||||
|
// Zero signals the end of the list. If we've not found
|
||||||
|
// a match by now, then we've failed the specification.
|
||||||
|
if (tmp == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tmp = _Unwind_decode_typeinfo_ptr(info->ttype_base, (_Unwind_Word) e);
|
||||||
|
|
||||||
|
// Match a ttype entry.
|
||||||
|
catch_type = reinterpret_cast<const std::type_info*>(tmp);
|
||||||
|
|
||||||
|
// ??? There is currently no way to ask the RTTI code about the
|
||||||
|
// relationship between two types without reference to a specific
|
||||||
|
// object. There should be; then we wouldn't need to mess with
|
||||||
|
// thrown_ptr here.
|
||||||
|
if (get_adjusted_ptr(catch_type, throw_type, &thrown_ptr))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Advance to the next entry.
|
||||||
|
e++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Save stage1 handler information in the exception object
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
save_caught_exception(struct _Unwind_Exception* ue_header,
|
||||||
|
struct _Unwind_Context* context,
|
||||||
|
void* thrown_ptr,
|
||||||
|
int handler_switch_value,
|
||||||
|
const unsigned char* language_specific_data,
|
||||||
|
_Unwind_Ptr landing_pad,
|
||||||
|
const unsigned char* action_record
|
||||||
|
__attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
ue_header->barrier_cache.sp = _Unwind_GetGR(context, UNWIND_STACK_REG);
|
||||||
|
ue_header->barrier_cache.bitpattern[0] = (_uw) thrown_ptr;
|
||||||
|
ue_header->barrier_cache.bitpattern[1]
|
||||||
|
= (_uw) handler_switch_value;
|
||||||
|
ue_header->barrier_cache.bitpattern[2]
|
||||||
|
= (_uw) language_specific_data;
|
||||||
|
ue_header->barrier_cache.bitpattern[3] = (_uw) landing_pad;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Restore the catch handler data saved during phase1.
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
restore_caught_exception(struct _Unwind_Exception* ue_header,
|
||||||
|
int& handler_switch_value,
|
||||||
|
const unsigned char*& language_specific_data,
|
||||||
|
_Unwind_Ptr& landing_pad)
|
||||||
|
{
|
||||||
|
handler_switch_value = (int) ue_header->barrier_cache.bitpattern[1];
|
||||||
|
language_specific_data =
|
||||||
|
(const unsigned char*) ue_header->barrier_cache.bitpattern[2];
|
||||||
|
landing_pad = (_Unwind_Ptr) ue_header->barrier_cache.bitpattern[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CONTINUE_UNWINDING \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (__gnu_unwind_frame(ue_header, context) != _URC_OK) \
|
||||||
|
return _URC_FAILURE; \
|
||||||
|
return _URC_CONTINUE_UNWIND; \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
// Return true if the filter spec is empty, ie throw().
|
||||||
|
|
||||||
|
static bool
|
||||||
|
empty_exception_spec (lsda_header_info *info, _Unwind_Sword filter_value)
|
||||||
|
{
|
||||||
|
const _Unwind_Word* e = ((const _Unwind_Word*) info->TType)
|
||||||
|
- filter_value - 1;
|
||||||
|
|
||||||
|
return *e == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
typedef const std::type_info _throw_typet;
|
||||||
|
|
||||||
|
|
||||||
|
// Given the thrown type THROW_TYPE, pointer to a variable containing a
|
||||||
|
// pointer to the exception object THROWN_PTR_P and a type CATCH_TYPE to
|
||||||
|
// compare against, return whether or not there is a match and if so,
|
||||||
|
// update *THROWN_PTR_P.
|
||||||
|
|
||||||
|
static bool
|
||||||
|
get_adjusted_ptr (const std::type_info *catch_type,
|
||||||
|
const std::type_info *throw_type,
|
||||||
|
void **thrown_ptr_p)
|
||||||
|
{
|
||||||
|
void *thrown_ptr = *thrown_ptr_p;
|
||||||
|
|
||||||
|
// Pointer types need to adjust the actual pointer, not
|
||||||
|
// the pointer to pointer that is the exception object.
|
||||||
|
// This also has the effect of passing pointer types
|
||||||
|
// "by value" through the __cxa_begin_catch return value.
|
||||||
|
if (throw_type->__is_pointer_p ())
|
||||||
|
thrown_ptr = *(void **) thrown_ptr;
|
||||||
|
|
||||||
|
if (catch_type->__do_catch (throw_type, &thrown_ptr, 1))
|
||||||
|
{
|
||||||
|
*thrown_ptr_p = thrown_ptr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return true if THROW_TYPE matches one if the filter types.
|
||||||
|
|
||||||
|
static bool
|
||||||
|
check_exception_spec(lsda_header_info* info, _throw_typet* throw_type,
|
||||||
|
void* thrown_ptr, _sleb128_t filter_value)
|
||||||
|
{
|
||||||
|
const unsigned char *e = info->TType - filter_value - 1;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
const std::type_info *catch_type;
|
||||||
|
_uleb128_t tmp;
|
||||||
|
|
||||||
|
e = read_uleb128 (e, &tmp);
|
||||||
|
|
||||||
|
// Zero signals the end of the list. If we've not found
|
||||||
|
// a match by now, then we've failed the specification.
|
||||||
|
if (tmp == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Match a ttype entry.
|
||||||
|
catch_type = get_ttype_entry (info, tmp);
|
||||||
|
|
||||||
|
// ??? There is currently no way to ask the RTTI code about the
|
||||||
|
// relationship between two types without reference to a specific
|
||||||
|
// object. There should be; then we wouldn't need to mess with
|
||||||
|
// thrown_ptr here.
|
||||||
|
if (get_adjusted_ptr (catch_type, throw_type, &thrown_ptr))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Save stage1 handler information in the exception object
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
save_caught_exception(struct _Unwind_Exception* ue_header,
|
||||||
|
struct _Unwind_Context* context
|
||||||
|
__attribute__((__unused__)),
|
||||||
|
void* thrown_ptr,
|
||||||
|
int handler_switch_value,
|
||||||
|
const unsigned char* language_specific_data,
|
||||||
|
_Unwind_Ptr landing_pad __attribute__((__unused__)),
|
||||||
|
const unsigned char* action_record)
|
||||||
|
{
|
||||||
|
__cxa_exception* xh = __get_exception_header_from_ue(ue_header);
|
||||||
|
|
||||||
|
xh->handlerSwitchValue = handler_switch_value;
|
||||||
|
xh->actionRecord = action_record;
|
||||||
|
xh->languageSpecificData = language_specific_data;
|
||||||
|
xh->adjustedPtr = thrown_ptr;
|
||||||
|
|
||||||
|
// ??? Completely unknown what this field is supposed to be for.
|
||||||
|
// ??? Need to cache TType encoding base for call_unexpected.
|
||||||
|
xh->catchTemp = landing_pad;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Restore the catch handler information saved during phase1.
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
restore_caught_exception(struct _Unwind_Exception* ue_header,
|
||||||
|
int& handler_switch_value,
|
||||||
|
const unsigned char*& language_specific_data,
|
||||||
|
_Unwind_Ptr& landing_pad)
|
||||||
|
{
|
||||||
|
__cxa_exception* xh = __get_exception_header_from_ue(ue_header);
|
||||||
|
handler_switch_value = xh->handlerSwitchValue;
|
||||||
|
language_specific_data = xh->languageSpecificData;
|
||||||
|
landing_pad = (_Unwind_Ptr) xh->catchTemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CONTINUE_UNWINDING return _URC_CONTINUE_UNWIND
|
||||||
|
|
||||||
|
// Return true if the filter spec is empty, ie throw().
|
||||||
|
|
||||||
|
static bool
|
||||||
|
empty_exception_spec (lsda_header_info *info, _Unwind_Sword filter_value)
|
||||||
|
{
|
||||||
|
const unsigned char *e = info->TType - filter_value - 1;
|
||||||
|
_uleb128_t tmp;
|
||||||
|
|
||||||
|
e = read_uleb128 (e, &tmp);
|
||||||
|
return tmp == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !__ARM_EABI_UNWINDER__
|
||||||
|
|
||||||
|
namespace __cxxabiv1
|
||||||
|
{
|
||||||
|
|
||||||
|
// Using a different personality function name causes link failures
|
||||||
|
// when trying to mix code using different exception handling models.
|
||||||
|
#ifdef _GLIBCXX_SJLJ_EXCEPTIONS
|
||||||
|
#define PERSONALITY_FUNCTION __gxx_personality_sj0
|
||||||
|
#define __builtin_eh_return_data_regno(x) x
|
||||||
|
#else
|
||||||
|
#define PERSONALITY_FUNCTION __gxx_personality_v0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern "C" _Unwind_Reason_Code
|
||||||
|
#ifdef __ARM_EABI_UNWINDER__
|
||||||
|
PERSONALITY_FUNCTION (_Unwind_State state,
|
||||||
|
struct _Unwind_Exception* ue_header,
|
||||||
|
struct _Unwind_Context* context)
|
||||||
|
#else
|
||||||
|
PERSONALITY_FUNCTION (int version,
|
||||||
|
_Unwind_Action actions,
|
||||||
|
_Unwind_Exception_Class exception_class,
|
||||||
|
struct _Unwind_Exception *ue_header,
|
||||||
|
struct _Unwind_Context *context)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
enum found_handler_type
|
||||||
|
{
|
||||||
|
found_nothing,
|
||||||
|
found_terminate,
|
||||||
|
found_cleanup,
|
||||||
|
found_handler
|
||||||
|
} found_type;
|
||||||
|
|
||||||
|
lsda_header_info info;
|
||||||
|
const unsigned char *language_specific_data;
|
||||||
|
const unsigned char *action_record;
|
||||||
|
const unsigned char *p;
|
||||||
|
_Unwind_Ptr landing_pad, ip;
|
||||||
|
int handler_switch_value;
|
||||||
|
void* thrown_ptr = 0;
|
||||||
|
bool foreign_exception;
|
||||||
|
int ip_before_insn = 0;
|
||||||
|
|
||||||
|
#ifdef __ARM_EABI_UNWINDER__
|
||||||
|
_Unwind_Action actions;
|
||||||
|
|
||||||
|
switch (state & _US_ACTION_MASK)
|
||||||
|
{
|
||||||
|
case _US_VIRTUAL_UNWIND_FRAME:
|
||||||
|
actions = _UA_SEARCH_PHASE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _US_UNWIND_FRAME_STARTING:
|
||||||
|
actions = _UA_CLEANUP_PHASE;
|
||||||
|
if (!(state & _US_FORCE_UNWIND)
|
||||||
|
&& ue_header->barrier_cache.sp == _Unwind_GetGR(context,
|
||||||
|
UNWIND_STACK_REG))
|
||||||
|
actions |= _UA_HANDLER_FRAME;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _US_UNWIND_FRAME_RESUME:
|
||||||
|
CONTINUE_UNWINDING;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
actions |= state & _US_FORCE_UNWIND;
|
||||||
|
|
||||||
|
// We don't know which runtime we're working with, so can't check this.
|
||||||
|
// However the ABI routines hide this from us, and we don't actually need
|
||||||
|
// to know.
|
||||||
|
foreign_exception = false;
|
||||||
|
|
||||||
|
// The dwarf unwinder assumes the context structure holds things like the
|
||||||
|
// function and LSDA pointers. The ARM implementation caches these in
|
||||||
|
// the exception header (UCB). To avoid rewriting everything we make a
|
||||||
|
// virtual scratch register point at the UCB.
|
||||||
|
ip = (_Unwind_Ptr) ue_header;
|
||||||
|
_Unwind_SetGR(context, UNWIND_POINTER_REG, ip);
|
||||||
|
#else
|
||||||
|
__cxa_exception* xh = __get_exception_header_from_ue(ue_header);
|
||||||
|
|
||||||
|
// Interface version check.
|
||||||
|
if (version != 1)
|
||||||
|
return _URC_FATAL_PHASE1_ERROR;
|
||||||
|
foreign_exception = !__is_gxx_exception_class(exception_class);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Shortcut for phase 2 found handler for domestic exception.
|
||||||
|
if (actions == (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME)
|
||||||
|
&& !foreign_exception)
|
||||||
|
{
|
||||||
|
restore_caught_exception(ue_header, handler_switch_value,
|
||||||
|
language_specific_data, landing_pad);
|
||||||
|
found_type = (landing_pad == 0 ? found_terminate : found_handler);
|
||||||
|
goto install_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
language_specific_data = (const unsigned char *)
|
||||||
|
_Unwind_GetLanguageSpecificData (context);
|
||||||
|
|
||||||
|
// If no LSDA, then there are no handlers or cleanups.
|
||||||
|
if (! language_specific_data)
|
||||||
|
CONTINUE_UNWINDING;
|
||||||
|
|
||||||
|
// Parse the LSDA header.
|
||||||
|
p = parse_lsda_header (context, language_specific_data, &info);
|
||||||
|
info.ttype_base = base_of_encoded_value (info.ttype_encoding, context);
|
||||||
|
#ifdef _GLIBCXX_HAVE_GETIPINFO
|
||||||
|
ip = _Unwind_GetIPInfo (context, &ip_before_insn);
|
||||||
|
#else
|
||||||
|
ip = _Unwind_GetIP (context);
|
||||||
|
#endif
|
||||||
|
if (! ip_before_insn)
|
||||||
|
--ip;
|
||||||
|
landing_pad = 0;
|
||||||
|
action_record = 0;
|
||||||
|
handler_switch_value = 0;
|
||||||
|
|
||||||
|
#ifdef _GLIBCXX_SJLJ_EXCEPTIONS
|
||||||
|
// The given "IP" is an index into the call-site table, with two
|
||||||
|
// exceptions -- -1 means no-action, and 0 means terminate. But
|
||||||
|
// since we're using uleb128 values, we've not got random access
|
||||||
|
// to the array.
|
||||||
|
if ((int) ip < 0)
|
||||||
|
return _URC_CONTINUE_UNWIND;
|
||||||
|
else if (ip == 0)
|
||||||
|
{
|
||||||
|
// Fall through to set found_terminate.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_uleb128_t cs_lp, cs_action;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
p = read_uleb128 (p, &cs_lp);
|
||||||
|
p = read_uleb128 (p, &cs_action);
|
||||||
|
}
|
||||||
|
while (--ip);
|
||||||
|
|
||||||
|
// Can never have null landing pad for sjlj -- that would have
|
||||||
|
// been indicated by a -1 call site index.
|
||||||
|
landing_pad = cs_lp + 1;
|
||||||
|
if (cs_action)
|
||||||
|
action_record = info.action_table + cs_action - 1;
|
||||||
|
goto found_something;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// Search the call-site table for the action associated with this IP.
|
||||||
|
while (p < info.action_table)
|
||||||
|
{
|
||||||
|
_Unwind_Ptr cs_start, cs_len, cs_lp;
|
||||||
|
_uleb128_t cs_action;
|
||||||
|
|
||||||
|
// Note that all call-site encodings are "absolute" displacements.
|
||||||
|
p = read_encoded_value (0, info.call_site_encoding, p, &cs_start);
|
||||||
|
p = read_encoded_value (0, info.call_site_encoding, p, &cs_len);
|
||||||
|
p = read_encoded_value (0, info.call_site_encoding, p, &cs_lp);
|
||||||
|
p = read_uleb128 (p, &cs_action);
|
||||||
|
|
||||||
|
// The table is sorted, so if we've passed the ip, stop.
|
||||||
|
if (ip < info.Start + cs_start)
|
||||||
|
p = info.action_table;
|
||||||
|
else if (ip < info.Start + cs_start + cs_len)
|
||||||
|
{
|
||||||
|
if (cs_lp)
|
||||||
|
landing_pad = info.LPStart + cs_lp;
|
||||||
|
if (cs_action)
|
||||||
|
action_record = info.action_table + cs_action - 1;
|
||||||
|
goto found_something;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // _GLIBCXX_SJLJ_EXCEPTIONS
|
||||||
|
|
||||||
|
// If ip is not present in the table, call terminate. This is for
|
||||||
|
// a destructor inside a cleanup, or a library routine the compiler
|
||||||
|
// was not expecting to throw.
|
||||||
|
found_type = found_terminate;
|
||||||
|
goto do_something;
|
||||||
|
|
||||||
|
found_something:
|
||||||
|
if (landing_pad == 0)
|
||||||
|
{
|
||||||
|
// If ip is present, and has a null landing pad, there are
|
||||||
|
// no cleanups or handlers to be run.
|
||||||
|
found_type = found_nothing;
|
||||||
|
}
|
||||||
|
else if (action_record == 0)
|
||||||
|
{
|
||||||
|
// If ip is present, has a non-null landing pad, and a null
|
||||||
|
// action table offset, then there are only cleanups present.
|
||||||
|
// Cleanups use a zero switch value, as set above.
|
||||||
|
found_type = found_cleanup;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Otherwise we have a catch handler or exception specification.
|
||||||
|
|
||||||
|
_sleb128_t ar_filter, ar_disp;
|
||||||
|
const std::type_info* catch_type;
|
||||||
|
_throw_typet* throw_type;
|
||||||
|
bool saw_cleanup = false;
|
||||||
|
bool saw_handler = false;
|
||||||
|
|
||||||
|
#ifdef __ARM_EABI_UNWINDER__
|
||||||
|
// ??? How does this work - more importantly, how does it interact with
|
||||||
|
// dependent exceptions?
|
||||||
|
throw_type = ue_header;
|
||||||
|
if (actions & _UA_FORCE_UNWIND)
|
||||||
|
{
|
||||||
|
__GXX_INIT_FORCED_UNWIND_CLASS(ue_header->exception_class);
|
||||||
|
}
|
||||||
|
else if (!foreign_exception)
|
||||||
|
thrown_ptr = __get_object_from_ue (ue_header);
|
||||||
|
#else
|
||||||
|
#ifdef __GXX_RTTI
|
||||||
|
// During forced unwinding, match a magic exception type.
|
||||||
|
if (actions & _UA_FORCE_UNWIND)
|
||||||
|
{
|
||||||
|
throw_type = &typeid(abi::__forced_unwind);
|
||||||
|
}
|
||||||
|
// With a foreign exception class, there's no exception type.
|
||||||
|
// ??? What to do about GNU Java and GNU Ada exceptions?
|
||||||
|
else if (foreign_exception)
|
||||||
|
{
|
||||||
|
throw_type = &typeid(abi::__foreign_exception);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
thrown_ptr = __get_object_from_ue (ue_header);
|
||||||
|
throw_type = __get_exception_header_from_obj
|
||||||
|
(thrown_ptr)->exceptionType;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
p = action_record;
|
||||||
|
p = read_sleb128 (p, &ar_filter);
|
||||||
|
read_sleb128 (p, &ar_disp);
|
||||||
|
|
||||||
|
if (ar_filter == 0)
|
||||||
|
{
|
||||||
|
// Zero filter values are cleanups.
|
||||||
|
saw_cleanup = true;
|
||||||
|
}
|
||||||
|
else if (ar_filter > 0)
|
||||||
|
{
|
||||||
|
// Positive filter values are handlers.
|
||||||
|
catch_type = get_ttype_entry (&info, ar_filter);
|
||||||
|
|
||||||
|
// Null catch type is a catch-all handler; we can catch foreign
|
||||||
|
// exceptions with this. Otherwise we must match types.
|
||||||
|
if (! catch_type
|
||||||
|
|| (throw_type
|
||||||
|
&& get_adjusted_ptr (catch_type, throw_type,
|
||||||
|
&thrown_ptr)))
|
||||||
|
{
|
||||||
|
saw_handler = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Negative filter values are exception specifications.
|
||||||
|
// ??? How do foreign exceptions fit in? As far as I can
|
||||||
|
// see we can't match because there's no __cxa_exception
|
||||||
|
// object to stuff bits in for __cxa_call_unexpected to use.
|
||||||
|
// Allow them iff the exception spec is non-empty. I.e.
|
||||||
|
// a throw() specification results in __unexpected.
|
||||||
|
if ((throw_type
|
||||||
|
&& !(actions & _UA_FORCE_UNWIND)
|
||||||
|
&& !foreign_exception)
|
||||||
|
? ! check_exception_spec (&info, throw_type, thrown_ptr,
|
||||||
|
ar_filter)
|
||||||
|
: empty_exception_spec (&info, ar_filter))
|
||||||
|
{
|
||||||
|
saw_handler = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ar_disp == 0)
|
||||||
|
break;
|
||||||
|
action_record = p + ar_disp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saw_handler)
|
||||||
|
{
|
||||||
|
handler_switch_value = ar_filter;
|
||||||
|
found_type = found_handler;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
found_type = (saw_cleanup ? found_cleanup : found_nothing);
|
||||||
|
}
|
||||||
|
|
||||||
|
do_something:
|
||||||
|
if (found_type == found_nothing)
|
||||||
|
CONTINUE_UNWINDING;
|
||||||
|
|
||||||
|
if (actions & _UA_SEARCH_PHASE)
|
||||||
|
{
|
||||||
|
if (found_type == found_cleanup)
|
||||||
|
CONTINUE_UNWINDING;
|
||||||
|
|
||||||
|
// For domestic exceptions, we cache data from phase 1 for phase 2.
|
||||||
|
if (!foreign_exception)
|
||||||
|
{
|
||||||
|
save_caught_exception(ue_header, context, thrown_ptr,
|
||||||
|
handler_switch_value, language_specific_data,
|
||||||
|
landing_pad, action_record);
|
||||||
|
}
|
||||||
|
return _URC_HANDLER_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
install_context:
|
||||||
|
|
||||||
|
// We can't use any of the cxa routines with foreign exceptions,
|
||||||
|
// because they all expect ue_header to be a struct __cxa_exception.
|
||||||
|
// So in that case, call terminate or unexpected directly.
|
||||||
|
if ((actions & _UA_FORCE_UNWIND)
|
||||||
|
|| foreign_exception)
|
||||||
|
{
|
||||||
|
if (found_type == found_terminate)
|
||||||
|
std::terminate ();
|
||||||
|
else if (handler_switch_value < 0)
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{ std::unexpected (); }
|
||||||
|
__catch(...)
|
||||||
|
{ std::terminate (); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (found_type == found_terminate)
|
||||||
|
__cxa_call_terminate(ue_header);
|
||||||
|
|
||||||
|
// Cache the TType base value for __cxa_call_unexpected, as we won't
|
||||||
|
// have an _Unwind_Context then.
|
||||||
|
if (handler_switch_value < 0)
|
||||||
|
{
|
||||||
|
parse_lsda_header (context, language_specific_data, &info);
|
||||||
|
info.ttype_base = base_of_encoded_value (info.ttype_encoding,
|
||||||
|
context);
|
||||||
|
|
||||||
|
#ifdef __ARM_EABI_UNWINDER__
|
||||||
|
const _Unwind_Word* e;
|
||||||
|
_Unwind_Word n;
|
||||||
|
|
||||||
|
e = ((const _Unwind_Word*) info.TType) - handler_switch_value - 1;
|
||||||
|
// Count the number of rtti objects.
|
||||||
|
n = 0;
|
||||||
|
while (e[n] != 0)
|
||||||
|
n++;
|
||||||
|
|
||||||
|
// Count.
|
||||||
|
ue_header->barrier_cache.bitpattern[1] = n;
|
||||||
|
// Base
|
||||||
|
ue_header->barrier_cache.bitpattern[2] = info.ttype_base;
|
||||||
|
// Stride.
|
||||||
|
ue_header->barrier_cache.bitpattern[3] = 4;
|
||||||
|
// List head.
|
||||||
|
ue_header->barrier_cache.bitpattern[4] = (_Unwind_Word) e;
|
||||||
|
#else
|
||||||
|
xh->catchTemp = base_of_encoded_value (info.ttype_encoding, context);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For targets with pointers smaller than the word size, we must extend the
|
||||||
|
pointer, and this extension is target dependent. */
|
||||||
|
_Unwind_SetGR (context, __builtin_eh_return_data_regno (0),
|
||||||
|
__builtin_extend_pointer (ue_header));
|
||||||
|
_Unwind_SetGR (context, __builtin_eh_return_data_regno (1),
|
||||||
|
handler_switch_value);
|
||||||
|
_Unwind_SetIP (context, landing_pad);
|
||||||
|
#ifdef __ARM_EABI_UNWINDER__
|
||||||
|
if (found_type == found_cleanup)
|
||||||
|
__cxa_begin_cleanup(ue_header);
|
||||||
|
#endif
|
||||||
|
return _URC_INSTALL_CONTEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The ARM EABI implementation of __cxa_call_unexpected is in a
|
||||||
|
different file so that the personality routine (PR) can be used
|
||||||
|
standalone. The generic routine shared datastructures with the PR
|
||||||
|
so it is most convenient to implement it here. */
|
||||||
|
#ifndef __ARM_EABI_UNWINDER__
|
||||||
|
extern "C" void
|
||||||
|
__cxa_call_unexpected (void *exc_obj_in)
|
||||||
|
{
|
||||||
|
_Unwind_Exception *exc_obj
|
||||||
|
= reinterpret_cast <_Unwind_Exception *>(exc_obj_in);
|
||||||
|
|
||||||
|
__cxa_begin_catch (exc_obj);
|
||||||
|
|
||||||
|
// This function is a handler for our exception argument. If we exit
|
||||||
|
// by throwing a different exception, we'll need the original cleaned up.
|
||||||
|
struct end_catch_protect
|
||||||
|
{
|
||||||
|
end_catch_protect() { }
|
||||||
|
~end_catch_protect() { __cxa_end_catch(); }
|
||||||
|
} end_catch_protect_obj;
|
||||||
|
|
||||||
|
lsda_header_info info;
|
||||||
|
__cxa_exception *xh = __get_exception_header_from_ue (exc_obj);
|
||||||
|
const unsigned char *xh_lsda;
|
||||||
|
_Unwind_Sword xh_switch_value;
|
||||||
|
std::terminate_handler xh_terminate_handler;
|
||||||
|
|
||||||
|
// If the unexpectedHandler rethrows the exception (e.g. to categorize it),
|
||||||
|
// it will clobber data about the current handler. So copy the data out now.
|
||||||
|
xh_lsda = xh->languageSpecificData;
|
||||||
|
xh_switch_value = xh->handlerSwitchValue;
|
||||||
|
xh_terminate_handler = xh->terminateHandler;
|
||||||
|
info.ttype_base = (_Unwind_Ptr) xh->catchTemp;
|
||||||
|
|
||||||
|
__try
|
||||||
|
{ __unexpected (xh->unexpectedHandler); }
|
||||||
|
__catch(...)
|
||||||
|
{
|
||||||
|
// Get the exception thrown from unexpected.
|
||||||
|
|
||||||
|
__cxa_eh_globals *globals = __cxa_get_globals_fast ();
|
||||||
|
__cxa_exception *new_xh = globals->caughtExceptions;
|
||||||
|
void *new_ptr = __get_object_from_ambiguous_exception (new_xh);
|
||||||
|
|
||||||
|
// We don't quite have enough stuff cached; re-parse the LSDA.
|
||||||
|
parse_lsda_header (0, xh_lsda, &info);
|
||||||
|
|
||||||
|
// If this new exception meets the exception spec, allow it.
|
||||||
|
if (check_exception_spec (&info, __get_exception_header_from_obj
|
||||||
|
(new_ptr)->exceptionType,
|
||||||
|
new_ptr, xh_switch_value))
|
||||||
|
__throw_exception_again;
|
||||||
|
|
||||||
|
// If the exception spec allows std::bad_exception, throw that.
|
||||||
|
// We don't have a thrown object to compare against, but since
|
||||||
|
// bad_exception doesn't have virtual bases, that's OK; just pass 0.
|
||||||
|
#if defined(__EXCEPTIONS) && defined(__GXX_RTTI)
|
||||||
|
const std::type_info &bad_exc = typeid (std::bad_exception);
|
||||||
|
if (check_exception_spec (&info, &bad_exc, 0, xh_switch_value))
|
||||||
|
throw std::bad_exception();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Otherwise, die.
|
||||||
|
__terminate (xh_terminate_handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace __cxxabiv1
|
46
contrib/sdk/sources/libsupc++/eh_term_handler.cc
Normal file
46
contrib/sdk/sources/libsupc++/eh_term_handler.cc
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// -*- C++ -*- std::terminate handler
|
||||||
|
// Copyright (C) 2002, 2003, 2009 Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <bits/c++config.h>
|
||||||
|
#include "unwind-cxx.h"
|
||||||
|
|
||||||
|
/* We default to the talkative, informative handler in a normal hosted
|
||||||
|
library. This pulls in the demangler, the dyn-string utilities, and
|
||||||
|
elements of the I/O library. For a low-memory environment, you can return
|
||||||
|
to the earlier "silent death" handler by including <cstdlib>, initializing
|
||||||
|
to "std::abort", and rebuilding the library. In a freestanding mode, we
|
||||||
|
default to this latter approach. */
|
||||||
|
|
||||||
|
#if ! _GLIBCXX_HOSTED
|
||||||
|
# include <cstdlib>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The current installed user handler. */
|
||||||
|
std::terminate_handler __cxxabiv1::__terminate_handler =
|
||||||
|
#if _GLIBCXX_HOSTED
|
||||||
|
__gnu_cxx::__verbose_terminate_handler;
|
||||||
|
#else
|
||||||
|
std::abort;
|
||||||
|
#endif
|
||||||
|
|
80
contrib/sdk/sources/libsupc++/eh_terminate.cc
Normal file
80
contrib/sdk/sources/libsupc++/eh_terminate.cc
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// -*- C++ -*- std::terminate, std::unexpected and friends.
|
||||||
|
// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2009,
|
||||||
|
// 2011
|
||||||
|
// Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "typeinfo"
|
||||||
|
#include "exception"
|
||||||
|
#include <cstdlib>
|
||||||
|
#include "unwind-cxx.h"
|
||||||
|
#include <bits/exception_defines.h>
|
||||||
|
|
||||||
|
using namespace __cxxabiv1;
|
||||||
|
|
||||||
|
void
|
||||||
|
__cxxabiv1::__terminate (std::terminate_handler handler) throw ()
|
||||||
|
{
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
handler ();
|
||||||
|
std::abort ();
|
||||||
|
}
|
||||||
|
__catch(...)
|
||||||
|
{ std::abort (); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
std::terminate () throw()
|
||||||
|
{
|
||||||
|
__terminate (__terminate_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
__cxxabiv1::__unexpected (std::unexpected_handler handler)
|
||||||
|
{
|
||||||
|
handler();
|
||||||
|
std::terminate ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
std::unexpected ()
|
||||||
|
{
|
||||||
|
__unexpected (__unexpected_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::terminate_handler
|
||||||
|
std::set_terminate (std::terminate_handler func) throw()
|
||||||
|
{
|
||||||
|
std::terminate_handler old = __terminate_handler;
|
||||||
|
__terminate_handler = func;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unexpected_handler
|
||||||
|
std::set_unexpected (std::unexpected_handler func) throw()
|
||||||
|
{
|
||||||
|
std::unexpected_handler old = __unexpected_handler;
|
||||||
|
__unexpected_handler = func;
|
||||||
|
return old;
|
||||||
|
}
|
117
contrib/sdk/sources/libsupc++/eh_throw.cc
Normal file
117
contrib/sdk/sources/libsupc++/eh_throw.cc
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
// -*- C++ -*- Exception handling routines for throwing.
|
||||||
|
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||||
|
// 2011, 2012 Free Software Foundation, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <bits/c++config.h>
|
||||||
|
#include "unwind-cxx.h"
|
||||||
|
|
||||||
|
using namespace __cxxabiv1;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
__gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc)
|
||||||
|
{
|
||||||
|
// This cleanup is set only for primaries.
|
||||||
|
__cxa_refcounted_exception *header
|
||||||
|
= __get_refcounted_exception_header_from_ue (exc);
|
||||||
|
|
||||||
|
// We only want to be called through _Unwind_DeleteException.
|
||||||
|
// _Unwind_DeleteException in the HP-UX IA64 libunwind library
|
||||||
|
// returns _URC_NO_REASON and not _URC_FOREIGN_EXCEPTION_CAUGHT
|
||||||
|
// like the GCC _Unwind_DeleteException function does.
|
||||||
|
if (code != _URC_FOREIGN_EXCEPTION_CAUGHT && code != _URC_NO_REASON)
|
||||||
|
__terminate (header->exc.terminateHandler);
|
||||||
|
|
||||||
|
#if ATOMIC_INT_LOCK_FREE > 1
|
||||||
|
if (__atomic_sub_fetch (&header->referenceCount, 1, __ATOMIC_ACQ_REL) == 0)
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
if (header->exc.exceptionDestructor)
|
||||||
|
header->exc.exceptionDestructor (header + 1);
|
||||||
|
|
||||||
|
__cxa_free_exception (header + 1);
|
||||||
|
#if ATOMIC_INT_LOCK_FREE > 1
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__cxxabiv1::__cxa_throw (void *obj, std::type_info *tinfo,
|
||||||
|
void (_GLIBCXX_CDTOR_CALLABI *dest) (void *))
|
||||||
|
{
|
||||||
|
// Definitely a primary.
|
||||||
|
__cxa_refcounted_exception *header
|
||||||
|
= __get_refcounted_exception_header_from_obj (obj);
|
||||||
|
header->referenceCount = 1;
|
||||||
|
header->exc.exceptionType = tinfo;
|
||||||
|
header->exc.exceptionDestructor = dest;
|
||||||
|
header->exc.unexpectedHandler = __unexpected_handler;
|
||||||
|
header->exc.terminateHandler = __terminate_handler;
|
||||||
|
__GXX_INIT_PRIMARY_EXCEPTION_CLASS(header->exc.unwindHeader.exception_class);
|
||||||
|
header->exc.unwindHeader.exception_cleanup = __gxx_exception_cleanup;
|
||||||
|
|
||||||
|
#ifdef _GLIBCXX_SJLJ_EXCEPTIONS
|
||||||
|
_Unwind_SjLj_RaiseException (&header->exc.unwindHeader);
|
||||||
|
#else
|
||||||
|
_Unwind_RaiseException (&header->exc.unwindHeader);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Some sort of unwinding error. Note that terminate is a handler.
|
||||||
|
__cxa_begin_catch (&header->exc.unwindHeader);
|
||||||
|
std::terminate ();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__cxxabiv1::__cxa_rethrow ()
|
||||||
|
{
|
||||||
|
__cxa_eh_globals *globals = __cxa_get_globals ();
|
||||||
|
__cxa_exception *header = globals->caughtExceptions;
|
||||||
|
|
||||||
|
globals->uncaughtExceptions += 1;
|
||||||
|
|
||||||
|
// Watch for luser rethrowing with no active exception.
|
||||||
|
if (header)
|
||||||
|
{
|
||||||
|
// Tell __cxa_end_catch this is a rethrow.
|
||||||
|
if (!__is_gxx_exception_class(header->unwindHeader.exception_class))
|
||||||
|
globals->caughtExceptions = 0;
|
||||||
|
else
|
||||||
|
header->handlerCount = -header->handlerCount;
|
||||||
|
|
||||||
|
#ifdef _GLIBCXX_SJLJ_EXCEPTIONS
|
||||||
|
_Unwind_SjLj_Resume_or_Rethrow (&header->unwindHeader);
|
||||||
|
#else
|
||||||
|
#if defined(_LIBUNWIND_STD_ABI)
|
||||||
|
_Unwind_RaiseException (&header->unwindHeader);
|
||||||
|
#else
|
||||||
|
_Unwind_Resume_or_Rethrow (&header->unwindHeader);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Some sort of unwinding error. Note that terminate is a handler.
|
||||||
|
__cxa_begin_catch (&header->unwindHeader);
|
||||||
|
}
|
||||||
|
std::terminate ();
|
||||||
|
}
|
54
contrib/sdk/sources/libsupc++/eh_type.cc
Normal file
54
contrib/sdk/sources/libsupc++/eh_type.cc
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// -*- C++ -*- Exception handling routines for catching.
|
||||||
|
// Copyright (C) 2001, 2008, 2009, 2011 Free Software Foundation, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <cxxabi.h>
|
||||||
|
#include "unwind-cxx.h"
|
||||||
|
|
||||||
|
namespace __cxxabiv1
|
||||||
|
{
|
||||||
|
|
||||||
|
// Returns the type_info for the currently handled exception [15.3/8], or
|
||||||
|
// null if there is none.
|
||||||
|
extern "C"
|
||||||
|
std::type_info *__cxa_current_exception_type () _GLIBCXX_NOTHROW
|
||||||
|
{
|
||||||
|
__cxa_eh_globals *globals = __cxa_get_globals ();
|
||||||
|
__cxa_exception *header = globals->caughtExceptions;
|
||||||
|
if (header)
|
||||||
|
{
|
||||||
|
if (__is_dependent_exception (header->unwindHeader.exception_class))
|
||||||
|
{
|
||||||
|
__cxa_dependent_exception *de =
|
||||||
|
__get_dependent_exception_from_ue (&header->unwindHeader);
|
||||||
|
header = __get_exception_header_from_obj (de->primaryException);
|
||||||
|
}
|
||||||
|
return header->exceptionType;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace __cxxabiv1
|
29
contrib/sdk/sources/libsupc++/eh_unex_handler.cc
Normal file
29
contrib/sdk/sources/libsupc++/eh_unex_handler.cc
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// -*- C++ -*- std::unexpected handler
|
||||||
|
// Copyright (C) 2002, 2009 Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "unwind-cxx.h"
|
||||||
|
|
||||||
|
/* The current installed user handler. */
|
||||||
|
std::unexpected_handler __cxxabiv1::__unexpected_handler = std::terminate;
|
||||||
|
|
158
contrib/sdk/sources/libsupc++/exception
Normal file
158
contrib/sdk/sources/libsupc++/exception
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
// Exception Handling support header for -*- C++ -*-
|
||||||
|
|
||||||
|
// Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
|
||||||
|
// 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
||||||
|
// Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
/** @file exception
|
||||||
|
* This is a Standard C++ Library header.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __EXCEPTION__
|
||||||
|
#define __EXCEPTION__
|
||||||
|
|
||||||
|
#pragma GCC system_header
|
||||||
|
|
||||||
|
#pragma GCC visibility push(default)
|
||||||
|
|
||||||
|
#include <bits/c++config.h>
|
||||||
|
#include <bits/atomic_lockfree_defines.h>
|
||||||
|
|
||||||
|
extern "C++" {
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @defgroup exceptions Exceptions
|
||||||
|
* @ingroup diagnostics
|
||||||
|
*
|
||||||
|
* Classes and functions for reporting errors via exception classes.
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Base class for all library exceptions.
|
||||||
|
*
|
||||||
|
* This is the base class for all exceptions thrown by the standard
|
||||||
|
* library, and by certain language expressions. You are free to derive
|
||||||
|
* your own %exception classes, or use a different hierarchy, or to
|
||||||
|
* throw non-class data (e.g., fundamental types).
|
||||||
|
*/
|
||||||
|
class exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
exception() _GLIBCXX_USE_NOEXCEPT { }
|
||||||
|
virtual ~exception() _GLIBCXX_USE_NOEXCEPT;
|
||||||
|
|
||||||
|
/** Returns a C-style character string describing the general cause
|
||||||
|
* of the current error. */
|
||||||
|
virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** If an %exception is thrown which is not listed in a function's
|
||||||
|
* %exception specification, one of these may be thrown. */
|
||||||
|
class bad_exception : public exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bad_exception() _GLIBCXX_USE_NOEXCEPT { }
|
||||||
|
|
||||||
|
// This declaration is not useless:
|
||||||
|
// http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
|
||||||
|
virtual ~bad_exception() _GLIBCXX_USE_NOEXCEPT;
|
||||||
|
|
||||||
|
// See comment in eh_exception.cc.
|
||||||
|
virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// If you write a replacement %terminate handler, it must be of this type.
|
||||||
|
typedef void (*terminate_handler) ();
|
||||||
|
|
||||||
|
/// If you write a replacement %unexpected handler, it must be of this type.
|
||||||
|
typedef void (*unexpected_handler) ();
|
||||||
|
|
||||||
|
/// Takes a new handler function as an argument, returns the old function.
|
||||||
|
terminate_handler set_terminate(terminate_handler) _GLIBCXX_USE_NOEXCEPT;
|
||||||
|
|
||||||
|
/** The runtime will call this function if %exception handling must be
|
||||||
|
* abandoned for any reason. It can also be called by the user. */
|
||||||
|
void terminate() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__noreturn__));
|
||||||
|
|
||||||
|
/// Takes a new handler function as an argument, returns the old function.
|
||||||
|
unexpected_handler set_unexpected(unexpected_handler) _GLIBCXX_USE_NOEXCEPT;
|
||||||
|
|
||||||
|
/** The runtime will call this function if an %exception is thrown which
|
||||||
|
* violates the function's %exception specification. */
|
||||||
|
void unexpected() __attribute__ ((__noreturn__));
|
||||||
|
|
||||||
|
/** [18.6.4]/1: 'Returns true after completing evaluation of a
|
||||||
|
* throw-expression until either completing initialization of the
|
||||||
|
* exception-declaration in the matching handler or entering @c unexpected()
|
||||||
|
* due to the throw; or after entering @c terminate() for any reason
|
||||||
|
* other than an explicit call to @c terminate(). [Note: This includes
|
||||||
|
* stack unwinding [15.2]. end note]'
|
||||||
|
*
|
||||||
|
* 2: 'When @c uncaught_exception() is true, throwing an
|
||||||
|
* %exception can result in a call of @c terminate()
|
||||||
|
* (15.5.1).'
|
||||||
|
*/
|
||||||
|
bool uncaught_exception() _GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__));
|
||||||
|
|
||||||
|
// @} group exceptions
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
namespace __gnu_cxx
|
||||||
|
{
|
||||||
|
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A replacement for the standard terminate_handler which
|
||||||
|
* prints more information about the terminating exception (if any)
|
||||||
|
* on stderr.
|
||||||
|
*
|
||||||
|
* @ingroup exceptions
|
||||||
|
*
|
||||||
|
* Call
|
||||||
|
* @code
|
||||||
|
* std::set_terminate(__gnu_cxx::__verbose_terminate_handler)
|
||||||
|
* @endcode
|
||||||
|
* to use. For more info, see
|
||||||
|
* http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt02ch06s02.html
|
||||||
|
*
|
||||||
|
* In 3.4 and later, this is on by default.
|
||||||
|
*/
|
||||||
|
void __verbose_terminate_handler();
|
||||||
|
|
||||||
|
_GLIBCXX_END_NAMESPACE_VERSION
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
} // extern "C++"
|
||||||
|
|
||||||
|
#pragma GCC visibility pop
|
||||||
|
|
||||||
|
#if defined(__GXX_EXPERIMENTAL_CXX0X__) && (ATOMIC_INT_LOCK_FREE > 1)
|
||||||
|
#include <bits/exception_ptr.h>
|
||||||
|
#include <bits/nested_exception.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
47
contrib/sdk/sources/libsupc++/exception_defines.h
Normal file
47
contrib/sdk/sources/libsupc++/exception_defines.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// -fno-exceptions Support -*- C++ -*-
|
||||||
|
|
||||||
|
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2006, 2007, 2008, 2009,
|
||||||
|
// 2011
|
||||||
|
// Free Software Foundation, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of the GNU ISO C++ Library. This library is free
|
||||||
|
// software; you can redistribute it and/or modify it under the
|
||||||
|
// terms of the GNU General Public License as published by the
|
||||||
|
// Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
/** @file bits/exception_defines.h
|
||||||
|
* This is an internal header file, included by other library headers.
|
||||||
|
* Do not attempt to use it directly. @headername{exception}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _EXCEPTION_DEFINES_H
|
||||||
|
#define _EXCEPTION_DEFINES_H 1
|
||||||
|
|
||||||
|
#ifndef __EXCEPTIONS
|
||||||
|
// Iff -fno-exceptions, transform error handling code to work without it.
|
||||||
|
# define __try if (true)
|
||||||
|
# define __catch(X) if (false)
|
||||||
|
# define __throw_exception_again
|
||||||
|
#else
|
||||||
|
// Else proceed normally.
|
||||||
|
# define __try try
|
||||||
|
# define __catch(X) catch(X)
|
||||||
|
# define __throw_exception_again throw
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
772
contrib/sdk/sources/libsupc++/gthr-default.h
Normal file
772
contrib/sdk/sources/libsupc++/gthr-default.h
Normal file
@ -0,0 +1,772 @@
|
|||||||
|
/* Threads compatibility routines for libgcc2 and libobjc. */
|
||||||
|
/* Compile this one with gcc. */
|
||||||
|
|
||||||
|
/* Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2008, 2009
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
Contributed by Mumit Khan <khan@xraylith.wisc.edu>.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation; either version 3, or (at your option) any later
|
||||||
|
version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#ifndef GCC_GTHR_WIN32_H
|
||||||
|
#define GCC_GTHR_WIN32_H
|
||||||
|
|
||||||
|
/* Make sure CONST_CAST2 (origin in system.h) is declared. */
|
||||||
|
#ifndef CONST_CAST2
|
||||||
|
#define CONST_CAST2(TOTYPE,FROMTYPE,X) ((__extension__(union {FROMTYPE _q; TOTYPE _nq;})(X))._nq)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Windows32 threads specific definitions. The windows32 threading model
|
||||||
|
does not map well into pthread-inspired gcc's threading model, and so
|
||||||
|
there are caveats one needs to be aware of.
|
||||||
|
|
||||||
|
1. The destructor supplied to __gthread_key_create is ignored for
|
||||||
|
generic x86-win32 ports. This will certainly cause memory leaks
|
||||||
|
due to unreclaimed eh contexts (sizeof (eh_context) is at least
|
||||||
|
24 bytes for x86 currently).
|
||||||
|
|
||||||
|
This memory leak may be significant for long-running applications
|
||||||
|
that make heavy use of C++ EH.
|
||||||
|
|
||||||
|
However, Mingw runtime (version 0.3 or newer) provides a mechanism
|
||||||
|
to emulate pthreads key dtors; the runtime provides a special DLL,
|
||||||
|
linked in if -mthreads option is specified, that runs the dtors in
|
||||||
|
the reverse order of registration when each thread exits. If
|
||||||
|
-mthreads option is not given, a stub is linked in instead of the
|
||||||
|
DLL, which results in memory leak. Other x86-win32 ports can use
|
||||||
|
the same technique of course to avoid the leak.
|
||||||
|
|
||||||
|
2. The error codes returned are non-POSIX like, and cast into ints.
|
||||||
|
This may cause incorrect error return due to truncation values on
|
||||||
|
hw where sizeof (DWORD) > sizeof (int).
|
||||||
|
|
||||||
|
3. We are currently using a special mutex instead of the Critical
|
||||||
|
Sections, since Win9x does not support TryEnterCriticalSection
|
||||||
|
(while NT does).
|
||||||
|
|
||||||
|
The basic framework should work well enough. In the long term, GCC
|
||||||
|
needs to use Structured Exception Handling on Windows32. */
|
||||||
|
|
||||||
|
#define __GTHREADS 1
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
#include <_mingw.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ___GLIBCXX_UNUSED_PARAM
|
||||||
|
#define ___GLIBCXX_UNUSED_PARAM(x) x
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _LIBOBJC
|
||||||
|
|
||||||
|
/* This is necessary to prevent windef.h (included from windows.h) from
|
||||||
|
defining its own BOOL as a typedef. */
|
||||||
|
#ifndef __OBJC__
|
||||||
|
#define __OBJC__
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
/* Now undef the windows BOOL. */
|
||||||
|
#undef BOOL
|
||||||
|
|
||||||
|
/* Key structure for maintaining thread specific storage */
|
||||||
|
static DWORD __gthread_objc_data_tls = (DWORD) -1;
|
||||||
|
|
||||||
|
/* Backend initialization functions */
|
||||||
|
|
||||||
|
/* Initialize the threads subsystem. */
|
||||||
|
int
|
||||||
|
__gthread_objc_init_thread_system (void)
|
||||||
|
{
|
||||||
|
/* Initialize the thread storage key. */
|
||||||
|
if ((__gthread_objc_data_tls = TlsAlloc ()) != (DWORD) -1)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the threads subsystem. */
|
||||||
|
int
|
||||||
|
__gthread_objc_close_thread_system (void)
|
||||||
|
{
|
||||||
|
if (__gthread_objc_data_tls != (DWORD) -1)
|
||||||
|
TlsFree (__gthread_objc_data_tls);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Backend thread functions */
|
||||||
|
|
||||||
|
/* Create a new thread of execution. */
|
||||||
|
objc_thread_t
|
||||||
|
__gthread_objc_thread_detach (void (*func)(void *arg), void *arg)
|
||||||
|
{
|
||||||
|
DWORD thread_id = 0;
|
||||||
|
HANDLE win32_handle;
|
||||||
|
|
||||||
|
if (!(win32_handle = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) func,
|
||||||
|
arg, 0, &thread_id)))
|
||||||
|
thread_id = 0;
|
||||||
|
|
||||||
|
return (objc_thread_t) (INT_PTR) thread_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the current thread's priority. */
|
||||||
|
int
|
||||||
|
__gthread_objc_thread_set_priority (int priority)
|
||||||
|
{
|
||||||
|
int sys_priority = 0;
|
||||||
|
|
||||||
|
switch (priority)
|
||||||
|
{
|
||||||
|
case OBJC_THREAD_INTERACTIVE_PRIORITY:
|
||||||
|
sys_priority = THREAD_PRIORITY_NORMAL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
case OBJC_THREAD_BACKGROUND_PRIORITY:
|
||||||
|
sys_priority = THREAD_PRIORITY_BELOW_NORMAL;
|
||||||
|
break;
|
||||||
|
case OBJC_THREAD_LOW_PRIORITY:
|
||||||
|
sys_priority = THREAD_PRIORITY_LOWEST;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Change priority */
|
||||||
|
if (SetThreadPriority (GetCurrentThread (), sys_priority))
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the current thread's priority. */
|
||||||
|
int
|
||||||
|
__gthread_objc_thread_get_priority (void)
|
||||||
|
{
|
||||||
|
int sys_priority;
|
||||||
|
|
||||||
|
sys_priority = GetThreadPriority (GetCurrentThread ());
|
||||||
|
|
||||||
|
switch (sys_priority)
|
||||||
|
{
|
||||||
|
case THREAD_PRIORITY_HIGHEST:
|
||||||
|
case THREAD_PRIORITY_TIME_CRITICAL:
|
||||||
|
case THREAD_PRIORITY_ABOVE_NORMAL:
|
||||||
|
case THREAD_PRIORITY_NORMAL:
|
||||||
|
return OBJC_THREAD_INTERACTIVE_PRIORITY;
|
||||||
|
|
||||||
|
default:
|
||||||
|
case THREAD_PRIORITY_BELOW_NORMAL:
|
||||||
|
return OBJC_THREAD_BACKGROUND_PRIORITY;
|
||||||
|
|
||||||
|
case THREAD_PRIORITY_IDLE:
|
||||||
|
case THREAD_PRIORITY_LOWEST:
|
||||||
|
return OBJC_THREAD_LOW_PRIORITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Couldn't get priority. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Yield our process time to another thread. */
|
||||||
|
void
|
||||||
|
__gthread_objc_thread_yield (void)
|
||||||
|
{
|
||||||
|
Sleep (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Terminate the current thread. */
|
||||||
|
int
|
||||||
|
__gthread_objc_thread_exit (void)
|
||||||
|
{
|
||||||
|
/* exit the thread */
|
||||||
|
ExitThread (__objc_thread_exit_status);
|
||||||
|
|
||||||
|
/* Failed if we reached here */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns an integer value which uniquely describes a thread. */
|
||||||
|
objc_thread_t
|
||||||
|
__gthread_objc_thread_id (void)
|
||||||
|
{
|
||||||
|
return (objc_thread_t) (INT_PTR) GetCurrentThreadId ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sets the thread's local storage pointer. */
|
||||||
|
int
|
||||||
|
__gthread_objc_thread_set_data (void *value)
|
||||||
|
{
|
||||||
|
if (TlsSetValue (__gthread_objc_data_tls, value))
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the thread's local storage pointer. */
|
||||||
|
void *
|
||||||
|
__gthread_objc_thread_get_data (void)
|
||||||
|
{
|
||||||
|
DWORD lasterror;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
lasterror = GetLastError ();
|
||||||
|
|
||||||
|
ptr = TlsGetValue (__gthread_objc_data_tls); /* Return thread data. */
|
||||||
|
|
||||||
|
SetLastError (lasterror);
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Backend mutex functions */
|
||||||
|
|
||||||
|
/* Allocate a mutex. */
|
||||||
|
int
|
||||||
|
__gthread_objc_mutex_allocate (objc_mutex_t mutex)
|
||||||
|
{
|
||||||
|
if ((mutex->backend = (void *) CreateMutex (NULL, 0, NULL)) == NULL)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Deallocate a mutex. */
|
||||||
|
int
|
||||||
|
__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
|
||||||
|
{
|
||||||
|
CloseHandle ((HANDLE) (mutex->backend));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grab a lock on a mutex. */
|
||||||
|
int
|
||||||
|
__gthread_objc_mutex_lock (objc_mutex_t mutex)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = WaitForSingleObject ((HANDLE) (mutex->backend), INFINITE);
|
||||||
|
if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to grab a lock on a mutex. */
|
||||||
|
int
|
||||||
|
__gthread_objc_mutex_trylock (objc_mutex_t mutex)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = WaitForSingleObject ((HANDLE) (mutex->backend), 0);
|
||||||
|
if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlock the mutex */
|
||||||
|
int
|
||||||
|
__gthread_objc_mutex_unlock (objc_mutex_t mutex)
|
||||||
|
{
|
||||||
|
if (ReleaseMutex ((HANDLE) (mutex->backend)) == 0)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Backend condition mutex functions */
|
||||||
|
|
||||||
|
/* Allocate a condition. */
|
||||||
|
int
|
||||||
|
__gthread_objc_condition_allocate (objc_condition_t ___GLIBCXX_UNUSED_PARAM(condition))
|
||||||
|
{
|
||||||
|
/* Unimplemented. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Deallocate a condition. */
|
||||||
|
int
|
||||||
|
__gthread_objc_condition_deallocate (objc_condition_t ___GLIBCXX_UNUSED_PARAM(condition))
|
||||||
|
{
|
||||||
|
/* Unimplemented. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait on the condition */
|
||||||
|
int
|
||||||
|
__gthread_objc_condition_wait (objc_condition_t ___GLIBCXX_UNUSED_PARAM(condition),
|
||||||
|
objc_mutex_t ___GLIBCXX_UNUSED_PARAM(mutex))
|
||||||
|
{
|
||||||
|
/* Unimplemented. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wake up all threads waiting on this condition. */
|
||||||
|
int
|
||||||
|
__gthread_objc_condition_broadcast (objc_condition_t ___GLIBCXX_UNUSED_PARAM(condition))
|
||||||
|
{
|
||||||
|
/* Unimplemented. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wake up one thread waiting on this condition. */
|
||||||
|
int
|
||||||
|
__gthread_objc_condition_signal (objc_condition_t ___GLIBCXX_UNUSED_PARAM(condition))
|
||||||
|
{
|
||||||
|
/* Unimplemented. */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* _LIBOBJC */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef unsigned long __gthread_key_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int done;
|
||||||
|
long started;
|
||||||
|
} __gthread_once_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
long counter;
|
||||||
|
void *sema;
|
||||||
|
} __gthread_mutex_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
long counter;
|
||||||
|
long depth;
|
||||||
|
unsigned long owner;
|
||||||
|
void *sema;
|
||||||
|
} __gthread_recursive_mutex_t;
|
||||||
|
|
||||||
|
#define __GTHREAD_ONCE_INIT {0, -1}
|
||||||
|
#define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
|
||||||
|
#define __GTHREAD_MUTEX_INIT_DEFAULT {-1, 0}
|
||||||
|
#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION \
|
||||||
|
__gthread_recursive_mutex_init_function
|
||||||
|
#define __GTHREAD_RECURSIVE_MUTEX_INIT_DEFAULT {-1, 0, 0, 0}
|
||||||
|
|
||||||
|
#if defined (_WIN32) && !defined(__CYGWIN__)
|
||||||
|
#define MINGW32_SUPPORTS_MT_EH 1
|
||||||
|
/* Mingw runtime >= v0.3 provides a magic variable that is set to nonzero
|
||||||
|
if -mthreads option was specified, or 0 otherwise. This is to get around
|
||||||
|
the lack of weak symbols in PE-COFF. */
|
||||||
|
extern int _CRT_MT;
|
||||||
|
extern int __mingwthr_key_dtor (unsigned long, void (*) (void *));
|
||||||
|
#endif /* _WIN32 && !__CYGWIN__ */
|
||||||
|
|
||||||
|
/* The Windows95 kernel does not export InterlockedCompareExchange.
|
||||||
|
This provides a substitute. When building apps that reference
|
||||||
|
gthread_mutex_try_lock, the __GTHREAD_I486_INLINE_LOCK_PRIMITIVES
|
||||||
|
macro must be defined if Windows95 is a target. Currently
|
||||||
|
gthread_mutex_try_lock is not referenced by libgcc or libstdc++. */
|
||||||
|
#ifdef __GTHREAD_I486_INLINE_LOCK_PRIMITIVES
|
||||||
|
static inline long
|
||||||
|
__gthr_i486_lock_cmp_xchg(long *__dest, long __xchg, long __comperand)
|
||||||
|
{
|
||||||
|
long result;
|
||||||
|
__asm__ __volatile__ ("\n\
|
||||||
|
lock\n\
|
||||||
|
cmpxchg{l} {%4, %1|%1, %4}\n"
|
||||||
|
: "=a" (result), "=m" (*__dest)
|
||||||
|
: "0" (__comperand), "m" (*__dest), "r" (__xchg)
|
||||||
|
: "cc");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#define __GTHR_W32_InterlockedCompareExchange __gthr_i486_lock_cmp_xchg
|
||||||
|
#else /* __GTHREAD_I486_INLINE_LOCK_PRIMITIVES */
|
||||||
|
#define __GTHR_W32_InterlockedCompareExchange InterlockedCompareExchange
|
||||||
|
#endif /* __GTHREAD_I486_INLINE_LOCK_PRIMITIVES */
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_active_p (void)
|
||||||
|
{
|
||||||
|
#ifdef MINGW32_SUPPORTS_MT_EH
|
||||||
|
return _CRT_MT;
|
||||||
|
#else
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __GTHREAD_HIDE_WIN32API
|
||||||
|
|
||||||
|
/* The implementations are in config/i386/gthr-win32.c in libgcc.a.
|
||||||
|
Only stubs are exposed to avoid polluting the C++ namespace with
|
||||||
|
windows api definitions. */
|
||||||
|
|
||||||
|
extern int __gthr_win32_once (__gthread_once_t *, void (*) (void));
|
||||||
|
extern int __gthr_win32_key_create (__gthread_key_t *, void (*) (void*));
|
||||||
|
extern int __gthr_win32_key_delete (__gthread_key_t);
|
||||||
|
extern void * __gthr_win32_getspecific (__gthread_key_t);
|
||||||
|
extern int __gthr_win32_setspecific (__gthread_key_t, const void *);
|
||||||
|
extern void __gthr_win32_mutex_init_function (__gthread_mutex_t *);
|
||||||
|
extern int __gthr_win32_mutex_lock (__gthread_mutex_t *);
|
||||||
|
extern int __gthr_win32_mutex_trylock (__gthread_mutex_t *);
|
||||||
|
extern int __gthr_win32_mutex_unlock (__gthread_mutex_t *);
|
||||||
|
extern void
|
||||||
|
__gthr_win32_recursive_mutex_init_function (__gthread_recursive_mutex_t *);
|
||||||
|
extern int __gthr_win32_recursive_mutex_lock (__gthread_recursive_mutex_t *);
|
||||||
|
extern int
|
||||||
|
__gthr_win32_recursive_mutex_trylock (__gthread_recursive_mutex_t *);
|
||||||
|
extern int __gthr_win32_recursive_mutex_unlock (__gthread_recursive_mutex_t *);
|
||||||
|
extern void __gthr_win32_mutex_destroy (__gthread_mutex_t *);
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_once (__gthread_once_t *__once, void (*__func) (void))
|
||||||
|
{
|
||||||
|
if (__gthread_active_p ())
|
||||||
|
return __gthr_win32_once (__once, __func);
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
|
||||||
|
{
|
||||||
|
return __gthr_win32_key_create (__key, __dtor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_key_delete (__gthread_key_t __key)
|
||||||
|
{
|
||||||
|
return __gthr_win32_key_delete (__key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
__gthread_getspecific (__gthread_key_t __key)
|
||||||
|
{
|
||||||
|
return __gthr_win32_getspecific (__key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_setspecific (__gthread_key_t __key, const void *__ptr)
|
||||||
|
{
|
||||||
|
return __gthr_win32_setspecific (__key, __ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
__gthread_mutex_init_function (__gthread_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
__gthr_win32_mutex_init_function (__mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
__gthread_mutex_destroy (__gthread_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
__gthr_win32_mutex_destroy (__mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_mutex_lock (__gthread_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
if (__gthread_active_p ())
|
||||||
|
return __gthr_win32_mutex_lock (__mutex);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_mutex_trylock (__gthread_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
if (__gthread_active_p ())
|
||||||
|
return __gthr_win32_mutex_trylock (__mutex);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_mutex_unlock (__gthread_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
if (__gthread_active_p ())
|
||||||
|
return __gthr_win32_mutex_unlock (__mutex);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
__gthr_win32_recursive_mutex_init_function (__mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
if (__gthread_active_p ())
|
||||||
|
return __gthr_win32_recursive_mutex_lock (__mutex);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
if (__gthread_active_p ())
|
||||||
|
return __gthr_win32_recursive_mutex_trylock (__mutex);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
if (__gthread_active_p ())
|
||||||
|
return __gthr_win32_recursive_mutex_unlock (__mutex);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* ! __GTHREAD_HIDE_WIN32API */
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_once (__gthread_once_t *__once, void (*__func) (void))
|
||||||
|
{
|
||||||
|
if (! __gthread_active_p ())
|
||||||
|
return -1;
|
||||||
|
else if (__once == NULL || __func == NULL)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
if (! __once->done)
|
||||||
|
{
|
||||||
|
if (InterlockedIncrement (&(__once->started)) == 0)
|
||||||
|
{
|
||||||
|
(*__func) ();
|
||||||
|
__once->done = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Another thread is currently executing the code, so wait for it
|
||||||
|
to finish; yield the CPU in the meantime. If performance
|
||||||
|
does become an issue, the solution is to use an Event that
|
||||||
|
we wait on here (and set above), but that implies a place to
|
||||||
|
create the event before this routine is called. */
|
||||||
|
while (! __once->done)
|
||||||
|
Sleep (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Windows32 thread local keys don't support destructors; this leads to
|
||||||
|
leaks, especially in threaded applications making extensive use of
|
||||||
|
C++ EH. Mingw uses a thread-support DLL to work-around this problem. */
|
||||||
|
static inline int
|
||||||
|
__gthread_key_create (__gthread_key_t *__key,
|
||||||
|
void (*__dtor) (void *) __attribute__((unused)))
|
||||||
|
{
|
||||||
|
int __status = 0;
|
||||||
|
DWORD __tls_index = TlsAlloc ();
|
||||||
|
if (__tls_index != 0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
*__key = __tls_index;
|
||||||
|
#ifdef MINGW32_SUPPORTS_MT_EH
|
||||||
|
/* Mingw runtime will run the dtors in reverse order for each thread
|
||||||
|
when the thread exits. */
|
||||||
|
__status = __mingwthr_key_dtor (*__key, __dtor);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
__status = (int) GetLastError ();
|
||||||
|
return __status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_key_delete (__gthread_key_t __key)
|
||||||
|
{
|
||||||
|
return (TlsFree (__key) != 0) ? 0 : (int) GetLastError ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
__gthread_getspecific (__gthread_key_t __key)
|
||||||
|
{
|
||||||
|
DWORD __lasterror;
|
||||||
|
void *__ptr;
|
||||||
|
|
||||||
|
__lasterror = GetLastError ();
|
||||||
|
|
||||||
|
__ptr = TlsGetValue (__key);
|
||||||
|
|
||||||
|
SetLastError (__lasterror);
|
||||||
|
|
||||||
|
return __ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_setspecific (__gthread_key_t __key, const void *__ptr)
|
||||||
|
{
|
||||||
|
if (TlsSetValue (__key, CONST_CAST2(void *, const void *, __ptr)) != 0)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return GetLastError ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
__gthread_mutex_init_function (__gthread_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
__mutex->counter = -1;
|
||||||
|
__mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
__gthread_mutex_destroy (__gthread_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
CloseHandle ((HANDLE) __mutex->sema);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_mutex_lock (__gthread_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
int __status = 0;
|
||||||
|
|
||||||
|
if (__gthread_active_p ())
|
||||||
|
{
|
||||||
|
if (InterlockedIncrement (&__mutex->counter) == 0 ||
|
||||||
|
WaitForSingleObject (__mutex->sema, INFINITE) == WAIT_OBJECT_0)
|
||||||
|
__status = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* WaitForSingleObject returns WAIT_FAILED, and we can only do
|
||||||
|
some best-effort cleanup here. */
|
||||||
|
InterlockedDecrement (&__mutex->counter);
|
||||||
|
__status = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return __status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_mutex_trylock (__gthread_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
int __status = 0;
|
||||||
|
|
||||||
|
if (__gthread_active_p ())
|
||||||
|
{
|
||||||
|
if (__GTHR_W32_InterlockedCompareExchange (&__mutex->counter, 0, -1) < 0)
|
||||||
|
__status = 0;
|
||||||
|
else
|
||||||
|
__status = 1;
|
||||||
|
}
|
||||||
|
return __status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_mutex_unlock (__gthread_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
if (__gthread_active_p ())
|
||||||
|
{
|
||||||
|
if (InterlockedDecrement (&__mutex->counter) >= 0)
|
||||||
|
return ReleaseSemaphore (__mutex->sema, 1, NULL) ? 0 : 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
__mutex->counter = -1;
|
||||||
|
__mutex->depth = 0;
|
||||||
|
__mutex->owner = 0;
|
||||||
|
__mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
if (__gthread_active_p ())
|
||||||
|
{
|
||||||
|
DWORD __me = GetCurrentThreadId();
|
||||||
|
if (InterlockedIncrement (&__mutex->counter) == 0)
|
||||||
|
{
|
||||||
|
__mutex->depth = 1;
|
||||||
|
__mutex->owner = __me;
|
||||||
|
}
|
||||||
|
else if (__mutex->owner == __me)
|
||||||
|
{
|
||||||
|
InterlockedDecrement (&__mutex->counter);
|
||||||
|
++(__mutex->depth);
|
||||||
|
}
|
||||||
|
else if (WaitForSingleObject (__mutex->sema, INFINITE) == WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
__mutex->depth = 1;
|
||||||
|
__mutex->owner = __me;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* WaitForSingleObject returns WAIT_FAILED, and we can only do
|
||||||
|
some best-effort cleanup here. */
|
||||||
|
InterlockedDecrement (&__mutex->counter);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
if (__gthread_active_p ())
|
||||||
|
{
|
||||||
|
DWORD __me = GetCurrentThreadId();
|
||||||
|
if (__GTHR_W32_InterlockedCompareExchange (&__mutex->counter, 0, -1) < 0)
|
||||||
|
{
|
||||||
|
__mutex->depth = 1;
|
||||||
|
__mutex->owner = __me;
|
||||||
|
}
|
||||||
|
else if (__mutex->owner == __me)
|
||||||
|
++(__mutex->depth);
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
|
||||||
|
{
|
||||||
|
if (__gthread_active_p ())
|
||||||
|
{
|
||||||
|
--(__mutex->depth);
|
||||||
|
if (__mutex->depth == 0)
|
||||||
|
{
|
||||||
|
__mutex->owner = 0;
|
||||||
|
|
||||||
|
if (InterlockedDecrement (&__mutex->counter) >= 0)
|
||||||
|
return ReleaseSemaphore (__mutex->sema, 1, NULL) ? 0 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __GTHREAD_HIDE_WIN32API */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _LIBOBJC */
|
||||||
|
|
||||||
|
#endif /* ! GCC_GTHR_WIN32_H */
|
27
contrib/sdk/sources/libsupc++/gthr_mutex.c
Normal file
27
contrib/sdk/sources/libsupc++/gthr_mutex.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
void __mutex_lock(volatile int *val);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int counter;
|
||||||
|
void *sema;
|
||||||
|
} __gthread_mutex_t;
|
||||||
|
|
||||||
|
void __gthr_win32_mutex_init_function (__gthread_mutex_t *mutex)
|
||||||
|
{
|
||||||
|
mutex->counter = 0;
|
||||||
|
mutex->sema = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __gthr_win32_mutex_lock (__gthread_mutex_t *mutex)
|
||||||
|
{
|
||||||
|
__mutex_lock(&mutex->counter);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
__gthr_win32_mutex_unlock (__gthread_mutex_t *mutex)
|
||||||
|
{
|
||||||
|
mutex->counter = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
416
contrib/sdk/sources/libsupc++/guard.cc
Normal file
416
contrib/sdk/sources/libsupc++/guard.cc
Normal file
@ -0,0 +1,416 @@
|
|||||||
|
// Copyright (C) 2002, 2004, 2006, 2008, 2009, 2010, 2011, 2012
|
||||||
|
// Free Software Foundation, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Written by Mark Mitchell, CodeSourcery LLC, <mark@codesourcery.com>
|
||||||
|
// Thread support written by Jason Merrill, Red Hat Inc. <jason@redhat.com>
|
||||||
|
|
||||||
|
#include <bits/c++config.h>
|
||||||
|
#include <cxxabi.h>
|
||||||
|
#include <exception>
|
||||||
|
#include <new>
|
||||||
|
#include <ext/atomicity.h>
|
||||||
|
#include <ext/concurrence.h>
|
||||||
|
#if defined(__GTHREADS) && defined(__GTHREAD_HAS_COND) \
|
||||||
|
&& (ATOMIC_INT_LOCK_FREE > 1) && defined(_GLIBCXX_HAVE_LINUX_FUTEX)
|
||||||
|
# include <climits>
|
||||||
|
# include <syscall.h>
|
||||||
|
# include <unistd.h>
|
||||||
|
# define _GLIBCXX_USE_FUTEX
|
||||||
|
# define _GLIBCXX_FUTEX_WAIT 0
|
||||||
|
# define _GLIBCXX_FUTEX_WAKE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The IA64/generic ABI uses the first byte of the guard variable.
|
||||||
|
// The ARM EABI uses the least significant bit.
|
||||||
|
|
||||||
|
// Thread-safe static local initialization support.
|
||||||
|
#ifdef __GTHREADS
|
||||||
|
# ifndef _GLIBCXX_USE_FUTEX
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// A single mutex controlling all static initializations.
|
||||||
|
static __gnu_cxx::__recursive_mutex* static_mutex;
|
||||||
|
|
||||||
|
typedef char fake_recursive_mutex[sizeof(__gnu_cxx::__recursive_mutex)]
|
||||||
|
__attribute__ ((aligned(__alignof__(__gnu_cxx::__recursive_mutex))));
|
||||||
|
fake_recursive_mutex fake_mutex;
|
||||||
|
|
||||||
|
static void init()
|
||||||
|
{ static_mutex = new (&fake_mutex) __gnu_cxx::__recursive_mutex(); }
|
||||||
|
|
||||||
|
__gnu_cxx::__recursive_mutex&
|
||||||
|
get_static_mutex()
|
||||||
|
{
|
||||||
|
static __gthread_once_t once = __GTHREAD_ONCE_INIT;
|
||||||
|
__gthread_once(&once, init);
|
||||||
|
return *static_mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple wrapper for exception safety.
|
||||||
|
struct mutex_wrapper
|
||||||
|
{
|
||||||
|
bool unlock;
|
||||||
|
mutex_wrapper() : unlock(true)
|
||||||
|
{ get_static_mutex().lock(); }
|
||||||
|
|
||||||
|
~mutex_wrapper()
|
||||||
|
{
|
||||||
|
if (unlock)
|
||||||
|
static_mutex->unlock();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(__GTHREAD_HAS_COND) && !defined(_GLIBCXX_USE_FUTEX)
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// A single condition variable controlling all static initializations.
|
||||||
|
static __gnu_cxx::__cond* static_cond;
|
||||||
|
|
||||||
|
// using a fake type to avoid initializing a static class.
|
||||||
|
typedef char fake_cond_t[sizeof(__gnu_cxx::__cond)]
|
||||||
|
__attribute__ ((aligned(__alignof__(__gnu_cxx::__cond))));
|
||||||
|
fake_cond_t fake_cond;
|
||||||
|
|
||||||
|
static void init_static_cond()
|
||||||
|
{ static_cond = new (&fake_cond) __gnu_cxx::__cond(); }
|
||||||
|
|
||||||
|
__gnu_cxx::__cond&
|
||||||
|
get_static_cond()
|
||||||
|
{
|
||||||
|
static __gthread_once_t once = __GTHREAD_ONCE_INIT;
|
||||||
|
__gthread_once(&once, init_static_cond);
|
||||||
|
return *static_cond;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifndef _GLIBCXX_GUARD_TEST_AND_ACQUIRE
|
||||||
|
inline bool
|
||||||
|
__test_and_acquire (__cxxabiv1::__guard *g)
|
||||||
|
{
|
||||||
|
bool b = _GLIBCXX_GUARD_TEST (g);
|
||||||
|
_GLIBCXX_READ_MEM_BARRIER;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
# define _GLIBCXX_GUARD_TEST_AND_ACQUIRE(G) __test_and_acquire (G)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifndef _GLIBCXX_GUARD_SET_AND_RELEASE
|
||||||
|
inline void
|
||||||
|
__set_and_release (__cxxabiv1::__guard *g)
|
||||||
|
{
|
||||||
|
_GLIBCXX_WRITE_MEM_BARRIER;
|
||||||
|
_GLIBCXX_GUARD_SET (g);
|
||||||
|
}
|
||||||
|
# define _GLIBCXX_GUARD_SET_AND_RELEASE(G) __set_and_release (G)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#else /* !__GTHREADS */
|
||||||
|
|
||||||
|
# undef _GLIBCXX_GUARD_TEST_AND_ACQUIRE
|
||||||
|
# undef _GLIBCXX_GUARD_SET_AND_RELEASE
|
||||||
|
# define _GLIBCXX_GUARD_SET_AND_RELEASE(G) _GLIBCXX_GUARD_SET (G)
|
||||||
|
|
||||||
|
#endif /* __GTHREADS */
|
||||||
|
|
||||||
|
//
|
||||||
|
// Here are C++ run-time routines for guarded initialization of static
|
||||||
|
// variables. There are 4 scenarios under which these routines are called:
|
||||||
|
//
|
||||||
|
// 1. Threads not supported (__GTHREADS not defined)
|
||||||
|
// 2. Threads are supported but not enabled at run-time.
|
||||||
|
// 3. Threads enabled at run-time but __gthreads_* are not fully POSIX.
|
||||||
|
// 4. Threads enabled at run-time and __gthreads_* support all POSIX threads
|
||||||
|
// primitives we need here.
|
||||||
|
//
|
||||||
|
// The old code supported scenarios 1-3 but was broken since it used a global
|
||||||
|
// mutex for all threads and had the mutex locked during the whole duration of
|
||||||
|
// initialization of a guarded static variable. The following created a
|
||||||
|
// dead-lock with the old code.
|
||||||
|
//
|
||||||
|
// Thread 1 acquires the global mutex.
|
||||||
|
// Thread 1 starts initializing static variable.
|
||||||
|
// Thread 1 creates thread 2 during initialization.
|
||||||
|
// Thread 2 attempts to acquire mutex to initialize another variable.
|
||||||
|
// Thread 2 blocks since thread 1 is locking the mutex.
|
||||||
|
// Thread 1 waits for result from thread 2 and also blocks. A deadlock.
|
||||||
|
//
|
||||||
|
// The new code here can handle this situation and thus is more robust. However,
|
||||||
|
// we need to use the POSIX thread condition variable, which is not supported
|
||||||
|
// in all platforms, notably older versions of Microsoft Windows. The gthr*.h
|
||||||
|
// headers define a symbol __GTHREAD_HAS_COND for platforms that support POSIX
|
||||||
|
// like condition variables. For platforms that do not support condition
|
||||||
|
// variables, we need to fall back to the old code.
|
||||||
|
|
||||||
|
// If _GLIBCXX_USE_FUTEX, no global mutex or condition variable is used,
|
||||||
|
// only atomic operations are used together with futex syscall.
|
||||||
|
// Valid values of the first integer in guard are:
|
||||||
|
// 0 No thread encountered the guarded init
|
||||||
|
// yet or it has been aborted.
|
||||||
|
// _GLIBCXX_GUARD_BIT The guarded static var has been successfully
|
||||||
|
// initialized.
|
||||||
|
// _GLIBCXX_GUARD_PENDING_BIT The guarded static var is being initialized
|
||||||
|
// and no other thread is waiting for its
|
||||||
|
// initialization.
|
||||||
|
// (_GLIBCXX_GUARD_PENDING_BIT The guarded static var is being initialized
|
||||||
|
// | _GLIBCXX_GUARD_WAITING_BIT) and some other threads are waiting until
|
||||||
|
// it is initialized.
|
||||||
|
|
||||||
|
namespace __cxxabiv1
|
||||||
|
{
|
||||||
|
#ifdef _GLIBCXX_USE_FUTEX
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
static inline int __guard_test_bit (const int __byte, const int __val)
|
||||||
|
{
|
||||||
|
union { int __i; char __c[sizeof (int)]; } __u = { 0 };
|
||||||
|
__u.__c[__byte] = __val;
|
||||||
|
return __u.__i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
init_in_progress_flag(__guard* g)
|
||||||
|
{ return ((char *)g)[1]; }
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
set_init_in_progress_flag(__guard* g, int v)
|
||||||
|
{ ((char *)g)[1] = v; }
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
throw_recursive_init_exception()
|
||||||
|
{
|
||||||
|
#ifdef __EXCEPTIONS
|
||||||
|
throw __gnu_cxx::recursive_init_error();
|
||||||
|
#else
|
||||||
|
// Use __builtin_trap so we don't require abort().
|
||||||
|
__builtin_trap();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// acquire() is a helper function used to acquire guard if thread support is
|
||||||
|
// not compiled in or is compiled in but not enabled at run-time.
|
||||||
|
static int
|
||||||
|
acquire(__guard *g)
|
||||||
|
{
|
||||||
|
// Quit if the object is already initialized.
|
||||||
|
if (_GLIBCXX_GUARD_TEST(g))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (init_in_progress_flag(g))
|
||||||
|
throw_recursive_init_exception();
|
||||||
|
|
||||||
|
set_init_in_progress_flag(g, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int __cxa_guard_acquire (__guard *g)
|
||||||
|
{
|
||||||
|
#ifdef __GTHREADS
|
||||||
|
// If the target can reorder loads, we need to insert a read memory
|
||||||
|
// barrier so that accesses to the guarded variable happen after the
|
||||||
|
// guard test.
|
||||||
|
if (_GLIBCXX_GUARD_TEST_AND_ACQUIRE (g))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
# ifdef _GLIBCXX_USE_FUTEX
|
||||||
|
// If __atomic_* and futex syscall are supported, don't use any global
|
||||||
|
// mutex.
|
||||||
|
if (__gthread_active_p ())
|
||||||
|
{
|
||||||
|
int *gi = (int *) (void *) g;
|
||||||
|
const int guard_bit = _GLIBCXX_GUARD_BIT;
|
||||||
|
const int pending_bit = _GLIBCXX_GUARD_PENDING_BIT;
|
||||||
|
const int waiting_bit = _GLIBCXX_GUARD_WAITING_BIT;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
int expected(0);
|
||||||
|
if (__atomic_compare_exchange_n(gi, &expected, pending_bit, false,
|
||||||
|
__ATOMIC_ACQ_REL,
|
||||||
|
__ATOMIC_ACQUIRE))
|
||||||
|
{
|
||||||
|
// This thread should do the initialization.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expected == guard_bit)
|
||||||
|
{
|
||||||
|
// Already initialized.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expected == pending_bit)
|
||||||
|
{
|
||||||
|
// Use acquire here.
|
||||||
|
int newv = expected | waiting_bit;
|
||||||
|
if (!__atomic_compare_exchange_n(gi, &expected, newv, false,
|
||||||
|
__ATOMIC_ACQ_REL,
|
||||||
|
__ATOMIC_ACQUIRE))
|
||||||
|
{
|
||||||
|
if (expected == guard_bit)
|
||||||
|
{
|
||||||
|
// Make a thread that failed to set the
|
||||||
|
// waiting bit exit the function earlier,
|
||||||
|
// if it detects that another thread has
|
||||||
|
// successfully finished initialising.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (expected == 0)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
expected = newv;
|
||||||
|
}
|
||||||
|
|
||||||
|
syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAIT, expected, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
if (__gthread_active_p ())
|
||||||
|
{
|
||||||
|
mutex_wrapper mw;
|
||||||
|
|
||||||
|
while (1) // When this loop is executing, mutex is locked.
|
||||||
|
{
|
||||||
|
# ifdef __GTHREAD_HAS_COND
|
||||||
|
// The static is already initialized.
|
||||||
|
if (_GLIBCXX_GUARD_TEST(g))
|
||||||
|
return 0; // The mutex will be unlocked via wrapper
|
||||||
|
|
||||||
|
if (init_in_progress_flag(g))
|
||||||
|
{
|
||||||
|
// The guarded static is currently being initialized by
|
||||||
|
// another thread, so we release mutex and wait for the
|
||||||
|
// condition variable. We will lock the mutex again after
|
||||||
|
// this.
|
||||||
|
get_static_cond().wait_recursive(&get_static_mutex());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_init_in_progress_flag(g, 1);
|
||||||
|
return 1; // The mutex will be unlocked via wrapper.
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
// This provides compatibility with older systems not supporting
|
||||||
|
// POSIX like condition variables.
|
||||||
|
if (acquire(g))
|
||||||
|
{
|
||||||
|
mw.unlock = false;
|
||||||
|
return 1; // The mutex still locked.
|
||||||
|
}
|
||||||
|
return 0; // The mutex will be unlocked via wrapper.
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return acquire (g);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void __cxa_guard_abort (__guard *g) throw ()
|
||||||
|
{
|
||||||
|
#ifdef _GLIBCXX_USE_FUTEX
|
||||||
|
// If __atomic_* and futex syscall are supported, don't use any global
|
||||||
|
// mutex.
|
||||||
|
if (__gthread_active_p ())
|
||||||
|
{
|
||||||
|
int *gi = (int *) (void *) g;
|
||||||
|
const int waiting_bit = _GLIBCXX_GUARD_WAITING_BIT;
|
||||||
|
int old = __atomic_exchange_n (gi, 0, __ATOMIC_ACQ_REL);
|
||||||
|
|
||||||
|
if ((old & waiting_bit) != 0)
|
||||||
|
syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAKE, INT_MAX);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#elif defined(__GTHREAD_HAS_COND)
|
||||||
|
if (__gthread_active_p())
|
||||||
|
{
|
||||||
|
mutex_wrapper mw;
|
||||||
|
|
||||||
|
set_init_in_progress_flag(g, 0);
|
||||||
|
|
||||||
|
// If we abort, we still need to wake up all other threads waiting for
|
||||||
|
// the condition variable.
|
||||||
|
get_static_cond().broadcast();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
set_init_in_progress_flag(g, 0);
|
||||||
|
#if defined(__GTHREADS) && !defined(__GTHREAD_HAS_COND)
|
||||||
|
// This provides compatibility with older systems not supporting POSIX like
|
||||||
|
// condition variables.
|
||||||
|
if (__gthread_active_p ())
|
||||||
|
static_mutex->unlock();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
void __cxa_guard_release (__guard *g) throw ()
|
||||||
|
{
|
||||||
|
#ifdef _GLIBCXX_USE_FUTEX
|
||||||
|
// If __atomic_* and futex syscall are supported, don't use any global
|
||||||
|
// mutex.
|
||||||
|
if (__gthread_active_p ())
|
||||||
|
{
|
||||||
|
int *gi = (int *) (void *) g;
|
||||||
|
const int guard_bit = _GLIBCXX_GUARD_BIT;
|
||||||
|
const int waiting_bit = _GLIBCXX_GUARD_WAITING_BIT;
|
||||||
|
int old = __atomic_exchange_n (gi, guard_bit, __ATOMIC_ACQ_REL);
|
||||||
|
|
||||||
|
if ((old & waiting_bit) != 0)
|
||||||
|
syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAKE, INT_MAX);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#elif defined(__GTHREAD_HAS_COND)
|
||||||
|
if (__gthread_active_p())
|
||||||
|
{
|
||||||
|
mutex_wrapper mw;
|
||||||
|
|
||||||
|
set_init_in_progress_flag(g, 0);
|
||||||
|
_GLIBCXX_GUARD_SET_AND_RELEASE(g);
|
||||||
|
|
||||||
|
get_static_cond().broadcast();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
set_init_in_progress_flag(g, 0);
|
||||||
|
_GLIBCXX_GUARD_SET_AND_RELEASE (g);
|
||||||
|
|
||||||
|
#if defined(__GTHREADS) && !defined(__GTHREAD_HAS_COND)
|
||||||
|
// This provides compatibility with older systems not supporting POSIX like
|
||||||
|
// condition variables.
|
||||||
|
if (__gthread_active_p())
|
||||||
|
static_mutex->unlock();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
31
contrib/sdk/sources/libsupc++/guard_error.cc
Normal file
31
contrib/sdk/sources/libsupc++/guard_error.cc
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright (C) 2011 Free Software Foundation, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <bits/c++config.h>
|
||||||
|
#include <cxxabi.h>
|
||||||
|
|
||||||
|
namespace __gnu_cxx
|
||||||
|
{
|
||||||
|
recursive_init_error::~recursive_init_error() throw() { }
|
||||||
|
}
|
||||||
|
|
107
contrib/sdk/sources/libsupc++/initializer_list
Normal file
107
contrib/sdk/sources/libsupc++/initializer_list
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
// std::initializer_list support -*- C++ -*-
|
||||||
|
|
||||||
|
// Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
/** @file initializer_list
|
||||||
|
* This is a Standard C++ Library header.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INITIALIZER_LIST
|
||||||
|
#define _INITIALIZER_LIST
|
||||||
|
|
||||||
|
#pragma GCC system_header
|
||||||
|
|
||||||
|
#ifndef __GXX_EXPERIMENTAL_CXX0X__
|
||||||
|
# include <bits/c++0x_warning.h>
|
||||||
|
#else // C++0x
|
||||||
|
|
||||||
|
#pragma GCC visibility push(default)
|
||||||
|
|
||||||
|
#include <bits/c++config.h>
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
/// initializer_list
|
||||||
|
template<class _E>
|
||||||
|
class initializer_list
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef _E value_type;
|
||||||
|
typedef const _E& reference;
|
||||||
|
typedef const _E& const_reference;
|
||||||
|
typedef size_t size_type;
|
||||||
|
typedef const _E* iterator;
|
||||||
|
typedef const _E* const_iterator;
|
||||||
|
|
||||||
|
private:
|
||||||
|
iterator _M_array;
|
||||||
|
size_type _M_len;
|
||||||
|
|
||||||
|
// The compiler can call a private constructor.
|
||||||
|
constexpr initializer_list(const_iterator __a, size_type __l)
|
||||||
|
: _M_array(__a), _M_len(__l) { }
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr initializer_list() noexcept
|
||||||
|
: _M_array(0), _M_len(0) { }
|
||||||
|
|
||||||
|
// Number of elements.
|
||||||
|
constexpr size_type
|
||||||
|
size() const noexcept { return _M_len; }
|
||||||
|
|
||||||
|
// First element.
|
||||||
|
constexpr const_iterator
|
||||||
|
begin() const noexcept { return _M_array; }
|
||||||
|
|
||||||
|
// One past the last element.
|
||||||
|
constexpr const_iterator
|
||||||
|
end() const noexcept { return begin() + size(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return an iterator pointing to the first element of
|
||||||
|
* the initilizer_list.
|
||||||
|
* @param __ils Initializer list.
|
||||||
|
*/
|
||||||
|
template<class _Tp>
|
||||||
|
constexpr const _Tp*
|
||||||
|
begin(initializer_list<_Tp> __ils) noexcept
|
||||||
|
{ return __ils.begin(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return an iterator pointing to one past the last element
|
||||||
|
* of the initilizer_list.
|
||||||
|
* @param __ils Initializer list.
|
||||||
|
*/
|
||||||
|
template<class _Tp>
|
||||||
|
constexpr const _Tp*
|
||||||
|
end(initializer_list<_Tp> __ils) noexcept
|
||||||
|
{ return __ils.end(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma GCC visibility pop
|
||||||
|
|
||||||
|
#endif // __GXX_EXPERIMENTAL_CXX0X__
|
||||||
|
|
||||||
|
#endif // _INITIALIZER_LIST
|
124
contrib/sdk/sources/libsupc++/new
Normal file
124
contrib/sdk/sources/libsupc++/new
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
// The -*- C++ -*- dynamic memory management header.
|
||||||
|
|
||||||
|
// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||||
|
// 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011
|
||||||
|
// Free Software Foundation
|
||||||
|
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
/** @file new
|
||||||
|
* This is a Standard C++ Library header.
|
||||||
|
*
|
||||||
|
* The header @c new defines several functions to manage dynamic memory and
|
||||||
|
* handling memory allocation errors; see
|
||||||
|
* http://gcc.gnu.org/onlinedocs/libstdc++/18_support/howto.html#4 for more.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _NEW
|
||||||
|
#define _NEW
|
||||||
|
|
||||||
|
#pragma GCC system_header
|
||||||
|
|
||||||
|
#include <bits/c++config.h>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
#pragma GCC visibility push(default)
|
||||||
|
|
||||||
|
extern "C++" {
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @brief Exception possibly thrown by @c new.
|
||||||
|
* @ingroup exceptions
|
||||||
|
*
|
||||||
|
* @c bad_alloc (or classes derived from it) is used to report allocation
|
||||||
|
* errors from the throwing forms of @c new. */
|
||||||
|
class bad_alloc : public exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bad_alloc() throw() { }
|
||||||
|
|
||||||
|
// This declaration is not useless:
|
||||||
|
// http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
|
||||||
|
virtual ~bad_alloc() throw();
|
||||||
|
|
||||||
|
// See comment in eh_exception.cc.
|
||||||
|
virtual const char* what() const throw();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nothrow_t { };
|
||||||
|
|
||||||
|
extern const nothrow_t nothrow;
|
||||||
|
|
||||||
|
/** If you write your own error handler to be called by @c new, it must
|
||||||
|
* be of this type. */
|
||||||
|
typedef void (*new_handler)();
|
||||||
|
|
||||||
|
/// Takes a replacement handler as the argument, returns the
|
||||||
|
/// previous handler.
|
||||||
|
new_handler set_new_handler(new_handler) throw();
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
//@{
|
||||||
|
/** These are replaceable signatures:
|
||||||
|
* - normal single new and delete (no arguments, throw @c bad_alloc on error)
|
||||||
|
* - normal array new and delete (same)
|
||||||
|
* - @c nothrow single new and delete (take a @c nothrow argument, return
|
||||||
|
* @c NULL on error)
|
||||||
|
* - @c nothrow array new and delete (same)
|
||||||
|
*
|
||||||
|
* Placement new and delete signatures (take a memory address argument,
|
||||||
|
* does nothing) may not be replaced by a user's program.
|
||||||
|
*/
|
||||||
|
void* operator new(std::size_t) _GLIBCXX_THROW (std::bad_alloc)
|
||||||
|
__attribute__((__externally_visible__));
|
||||||
|
void* operator new[](std::size_t) _GLIBCXX_THROW (std::bad_alloc)
|
||||||
|
__attribute__((__externally_visible__));
|
||||||
|
void operator delete(void*) _GLIBCXX_USE_NOEXCEPT
|
||||||
|
__attribute__((__externally_visible__));
|
||||||
|
void operator delete[](void*) _GLIBCXX_USE_NOEXCEPT
|
||||||
|
__attribute__((__externally_visible__));
|
||||||
|
void* operator new(std::size_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
|
||||||
|
__attribute__((__externally_visible__));
|
||||||
|
void* operator new[](std::size_t, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
|
||||||
|
__attribute__((__externally_visible__));
|
||||||
|
void operator delete(void*, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
|
||||||
|
__attribute__((__externally_visible__));
|
||||||
|
void operator delete[](void*, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
|
||||||
|
__attribute__((__externally_visible__));
|
||||||
|
|
||||||
|
// Default placement versions of operator new.
|
||||||
|
inline void* operator new(std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
|
||||||
|
{ return __p; }
|
||||||
|
inline void* operator new[](std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
|
||||||
|
{ return __p; }
|
||||||
|
|
||||||
|
// Default placement versions of operator delete.
|
||||||
|
inline void operator delete (void*, void*) _GLIBCXX_USE_NOEXCEPT { }
|
||||||
|
inline void operator delete[](void*, void*) _GLIBCXX_USE_NOEXCEPT { }
|
||||||
|
//@}
|
||||||
|
} // extern "C++"
|
||||||
|
|
||||||
|
#pragma GCC visibility pop
|
||||||
|
|
||||||
|
#endif
|
41
contrib/sdk/sources/libsupc++/new_handler.cc
Normal file
41
contrib/sdk/sources/libsupc++/new_handler.cc
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// Implementation file for the -*- C++ -*- dynamic memory management header.
|
||||||
|
|
||||||
|
// Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||||
|
// 2005, 2006, 2007, 2008, 2009, 2010
|
||||||
|
// Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "new"
|
||||||
|
|
||||||
|
const std::nothrow_t std::nothrow = { };
|
||||||
|
|
||||||
|
using std::new_handler;
|
||||||
|
new_handler __new_handler;
|
||||||
|
|
||||||
|
new_handler
|
||||||
|
std::set_new_handler (new_handler handler) throw()
|
||||||
|
{
|
||||||
|
new_handler prev_handler = __new_handler;
|
||||||
|
__new_handler = handler;
|
||||||
|
return prev_handler;
|
||||||
|
}
|
67
contrib/sdk/sources/libsupc++/new_op.cc
Normal file
67
contrib/sdk/sources/libsupc++/new_op.cc
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Support routines for the -*- C++ -*- dynamic memory management.
|
||||||
|
|
||||||
|
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2009, 2011
|
||||||
|
// Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <bits/c++config.h>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <bits/exception_defines.h>
|
||||||
|
#include "new"
|
||||||
|
|
||||||
|
using std::new_handler;
|
||||||
|
using std::bad_alloc;
|
||||||
|
#if _GLIBCXX_HOSTED
|
||||||
|
using std::malloc;
|
||||||
|
#else
|
||||||
|
// A freestanding C runtime may not provide "malloc" -- but there is no
|
||||||
|
// other reasonable way to implement "operator new".
|
||||||
|
extern "C" void *malloc (std::size_t);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern new_handler __new_handler;
|
||||||
|
|
||||||
|
_GLIBCXX_WEAK_DEFINITION void *
|
||||||
|
operator new (std::size_t sz) _GLIBCXX_THROW (std::bad_alloc)
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
/* malloc (0) is unpredictable; avoid it. */
|
||||||
|
if (sz == 0)
|
||||||
|
sz = 1;
|
||||||
|
p = (void *) malloc (sz);
|
||||||
|
while (p == 0)
|
||||||
|
{
|
||||||
|
new_handler handler = __new_handler;
|
||||||
|
if (! handler)
|
||||||
|
#ifdef __EXCEPTIONS
|
||||||
|
throw bad_alloc();
|
||||||
|
#else
|
||||||
|
std::abort();
|
||||||
|
#endif
|
||||||
|
handler ();
|
||||||
|
p = (void *) malloc (sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
63
contrib/sdk/sources/libsupc++/new_opnt.cc
Normal file
63
contrib/sdk/sources/libsupc++/new_opnt.cc
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// Support routines for the -*- C++ -*- dynamic memory management.
|
||||||
|
// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2004, 2009, 2011
|
||||||
|
// Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <bits/c++config.h>
|
||||||
|
#include <bits/exception_defines.h>
|
||||||
|
#include "new"
|
||||||
|
|
||||||
|
using std::new_handler;
|
||||||
|
using std::bad_alloc;
|
||||||
|
|
||||||
|
extern "C" void *malloc (std::size_t);
|
||||||
|
extern new_handler __new_handler;
|
||||||
|
|
||||||
|
_GLIBCXX_WEAK_DEFINITION void *
|
||||||
|
operator new (std::size_t sz, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
/* malloc (0) is unpredictable; avoid it. */
|
||||||
|
if (sz == 0)
|
||||||
|
sz = 1;
|
||||||
|
p = (void *) malloc (sz);
|
||||||
|
while (p == 0)
|
||||||
|
{
|
||||||
|
new_handler handler = __new_handler;
|
||||||
|
if (! handler)
|
||||||
|
return 0;
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
handler ();
|
||||||
|
}
|
||||||
|
__catch(const bad_alloc&)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = (void *) malloc (sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
34
contrib/sdk/sources/libsupc++/new_opv.cc
Normal file
34
contrib/sdk/sources/libsupc++/new_opv.cc
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
|
||||||
|
|
||||||
|
// Copyright (C) 1997, 1998, 1999, 2000, 2004, 2009, 2010, 2011
|
||||||
|
// Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <bits/c++config.h>
|
||||||
|
#include "new"
|
||||||
|
|
||||||
|
_GLIBCXX_WEAK_DEFINITION void*
|
||||||
|
operator new[] (std::size_t sz) _GLIBCXX_THROW (std::bad_alloc)
|
||||||
|
{
|
||||||
|
return ::operator new(sz);
|
||||||
|
}
|
66
contrib/sdk/sources/libsupc++/pbase_type_info.cc
Normal file
66
contrib/sdk/sources/libsupc++/pbase_type_info.cc
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007,
|
||||||
|
// 2009, 2010
|
||||||
|
// Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "tinfo.h"
|
||||||
|
|
||||||
|
namespace __cxxabiv1 {
|
||||||
|
|
||||||
|
__pbase_type_info::
|
||||||
|
~__pbase_type_info ()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool __pbase_type_info::
|
||||||
|
__do_catch (const type_info *thr_type,
|
||||||
|
void **thr_obj,
|
||||||
|
unsigned outer) const
|
||||||
|
{
|
||||||
|
if (*this == *thr_type)
|
||||||
|
return true; // same type
|
||||||
|
|
||||||
|
#ifdef __GXX_RTTI
|
||||||
|
if (typeid (*this) != typeid (*thr_type))
|
||||||
|
return false; // not both same kind of pointers
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!(outer & 1))
|
||||||
|
// We're not the same and our outer pointers are not all const qualified
|
||||||
|
// Therefore there must at least be a qualification conversion involved
|
||||||
|
// But for that to be valid, our outer pointers must be const qualified.
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const __pbase_type_info *thrown_type =
|
||||||
|
static_cast <const __pbase_type_info *> (thr_type);
|
||||||
|
|
||||||
|
if (thrown_type->__flags & ~__flags)
|
||||||
|
// We're less qualified.
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!(__flags & __const_mask))
|
||||||
|
outer &= ~1;
|
||||||
|
|
||||||
|
return __pointer_catch (thrown_type, thr_obj, outer);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
58
contrib/sdk/sources/libsupc++/pure.cc
Normal file
58
contrib/sdk/sources/libsupc++/pure.cc
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
// -*- C++ -*-
|
||||||
|
// Copyright (C) 2000, 2001, 2009, 2011 Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <bits/c++config.h>
|
||||||
|
#include <cxxabi.h>
|
||||||
|
#include "unwind-cxx.h"
|
||||||
|
|
||||||
|
#if _GLIBCXX_HOSTED
|
||||||
|
#ifdef _GLIBCXX_HAVE_UNISTD_H
|
||||||
|
# include <unistd.h>
|
||||||
|
# define writestr(str) write(2, str, sizeof(str) - 1)
|
||||||
|
# ifdef __GNU_LIBRARY__
|
||||||
|
/* Avoid forcing the library's meaning of `write' on the user program
|
||||||
|
by using the "internal" name (for use within the library). */
|
||||||
|
/*# define write(fd, buf, n) __write((fd), (buf), (n))*/
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# include <cstdio>
|
||||||
|
# define writestr(str) std::fputs(str, stderr)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
# define writestr(str) /* Empty */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__cxxabiv1::__cxa_pure_virtual (void)
|
||||||
|
{
|
||||||
|
writestr ("pure virtual method called\n");
|
||||||
|
std::terminate ();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
__cxxabiv1::__cxa_deleted_virtual (void)
|
||||||
|
{
|
||||||
|
writestr ("deleted virtual method called\n");
|
||||||
|
std::terminate ();
|
||||||
|
}
|
85
contrib/sdk/sources/libsupc++/si_class_type_info.cc
Normal file
85
contrib/sdk/sources/libsupc++/si_class_type_info.cc
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007, 2009
|
||||||
|
// Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "tinfo.h"
|
||||||
|
|
||||||
|
namespace __cxxabiv1 {
|
||||||
|
|
||||||
|
__si_class_type_info::
|
||||||
|
~__si_class_type_info ()
|
||||||
|
{}
|
||||||
|
|
||||||
|
__class_type_info::__sub_kind __si_class_type_info::
|
||||||
|
__do_find_public_src (ptrdiff_t src2dst,
|
||||||
|
const void *obj_ptr,
|
||||||
|
const __class_type_info *src_type,
|
||||||
|
const void *src_ptr) const
|
||||||
|
{
|
||||||
|
if (src_ptr == obj_ptr && *this == *src_type)
|
||||||
|
return __contained_public;
|
||||||
|
return __base_type->__do_find_public_src (src2dst, obj_ptr, src_type, src_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool __si_class_type_info::
|
||||||
|
__do_dyncast (ptrdiff_t src2dst,
|
||||||
|
__sub_kind access_path,
|
||||||
|
const __class_type_info *dst_type,
|
||||||
|
const void *obj_ptr,
|
||||||
|
const __class_type_info *src_type,
|
||||||
|
const void *src_ptr,
|
||||||
|
__dyncast_result &__restrict result) const
|
||||||
|
{
|
||||||
|
if (*this == *dst_type)
|
||||||
|
{
|
||||||
|
result.dst_ptr = obj_ptr;
|
||||||
|
result.whole2dst = access_path;
|
||||||
|
if (src2dst >= 0)
|
||||||
|
result.dst2src = adjust_pointer <void> (obj_ptr, src2dst) == src_ptr
|
||||||
|
? __contained_public : __not_contained;
|
||||||
|
else if (src2dst == -2)
|
||||||
|
result.dst2src = __not_contained;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (obj_ptr == src_ptr && *this == *src_type)
|
||||||
|
{
|
||||||
|
// The src object we started from. Indicate how we are accessible from
|
||||||
|
// the most derived object.
|
||||||
|
result.whole2src = access_path;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return __base_type->__do_dyncast (src2dst, access_path, dst_type, obj_ptr,
|
||||||
|
src_type, src_ptr, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool __si_class_type_info::
|
||||||
|
__do_upcast (const __class_type_info *dst, const void *obj_ptr,
|
||||||
|
__upcast_result &__restrict result) const
|
||||||
|
{
|
||||||
|
if (__class_type_info::__do_upcast (dst, obj_ptr, result))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return __base_type->__do_upcast (dst, obj_ptr, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
84
contrib/sdk/sources/libsupc++/tinfo.cc
Normal file
84
contrib/sdk/sources/libsupc++/tinfo.cc
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// Methods for type_info for -*- C++ -*- Run Time Type Identification.
|
||||||
|
// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||||
|
// 2003, 2004, 2005, 2006, 2007, 2009
|
||||||
|
// Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <bits/c++config.h>
|
||||||
|
#include <cstddef>
|
||||||
|
#include "tinfo.h"
|
||||||
|
|
||||||
|
std::type_info::
|
||||||
|
~type_info ()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
#if !__GXX_TYPEINFO_EQUALITY_INLINE
|
||||||
|
|
||||||
|
// We can't rely on common symbols being shared between shared objects.
|
||||||
|
bool std::type_info::
|
||||||
|
operator== (const std::type_info& arg) const
|
||||||
|
{
|
||||||
|
#if __GXX_MERGED_TYPEINFO_NAMES
|
||||||
|
return name () == arg.name ();
|
||||||
|
#else
|
||||||
|
/* The name() method will strip any leading '*' prefix. Therefore
|
||||||
|
take care to look at __name rather than name() when looking for
|
||||||
|
the "pointer" prefix. */
|
||||||
|
return (&arg == this)
|
||||||
|
|| (__name[0] != '*' && (__builtin_strcmp (name (), arg.name ()) == 0));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
// return true if this is a type_info for a pointer type
|
||||||
|
bool type_info::
|
||||||
|
__is_pointer_p () const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return true if this is a type_info for a function type
|
||||||
|
bool type_info::
|
||||||
|
__is_function_p () const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try and catch a thrown object.
|
||||||
|
bool type_info::
|
||||||
|
__do_catch (const type_info *thr_type, void **, unsigned) const
|
||||||
|
{
|
||||||
|
return *this == *thr_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
// upcast from this type to the target. __class_type_info will override
|
||||||
|
bool type_info::
|
||||||
|
__do_upcast (const abi::__class_type_info *, void **) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
183
contrib/sdk/sources/libsupc++/tinfo.h
Normal file
183
contrib/sdk/sources/libsupc++/tinfo.h
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
// RTTI support internals for -*- C++ -*-
|
||||||
|
// Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2004, 2009
|
||||||
|
// Free Software Foundation
|
||||||
|
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "typeinfo"
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
// Class declarations shared between the typeinfo implementation files.
|
||||||
|
|
||||||
|
#include <cxxabi.h>
|
||||||
|
|
||||||
|
namespace __cxxabiv1 {
|
||||||
|
|
||||||
|
inline bool __pbase_type_info::
|
||||||
|
__pointer_catch (const __pbase_type_info *thrown_type,
|
||||||
|
void **thr_obj,
|
||||||
|
unsigned outer) const
|
||||||
|
{
|
||||||
|
return __pointee->__do_catch (thrown_type->__pointee, thr_obj, outer + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace abi;
|
||||||
|
|
||||||
|
// Initial part of a vtable, this structure is used with offsetof, so we don't
|
||||||
|
// have to keep alignments consistent manually.
|
||||||
|
struct vtable_prefix
|
||||||
|
{
|
||||||
|
// Offset to most derived object.
|
||||||
|
ptrdiff_t whole_object;
|
||||||
|
|
||||||
|
// Additional padding if necessary.
|
||||||
|
#ifdef _GLIBCXX_VTABLE_PADDING
|
||||||
|
ptrdiff_t padding1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Pointer to most derived type_info.
|
||||||
|
const __class_type_info *whole_type;
|
||||||
|
|
||||||
|
// Additional padding if necessary.
|
||||||
|
#ifdef _GLIBCXX_VTABLE_PADDING
|
||||||
|
ptrdiff_t padding2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// What a class's vptr points to.
|
||||||
|
const void *origin;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline const T *
|
||||||
|
adjust_pointer (const void *base, ptrdiff_t offset)
|
||||||
|
{
|
||||||
|
return reinterpret_cast <const T *>
|
||||||
|
(reinterpret_cast <const char *> (base) + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ADDR is a pointer to an object. Convert it to a pointer to a base,
|
||||||
|
// using OFFSET. IS_VIRTUAL is true, if we are getting a virtual base.
|
||||||
|
inline void const *
|
||||||
|
convert_to_base (void const *addr, bool is_virtual, ptrdiff_t offset)
|
||||||
|
{
|
||||||
|
if (is_virtual)
|
||||||
|
{
|
||||||
|
const void *vtable = *static_cast <const void *const *> (addr);
|
||||||
|
|
||||||
|
offset = *adjust_pointer<ptrdiff_t> (vtable, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return adjust_pointer<void> (addr, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// some predicate functions for __class_type_info::__sub_kind
|
||||||
|
inline bool contained_p (__class_type_info::__sub_kind access_path)
|
||||||
|
{
|
||||||
|
return access_path >= __class_type_info::__contained_mask;
|
||||||
|
}
|
||||||
|
inline bool public_p (__class_type_info::__sub_kind access_path)
|
||||||
|
{
|
||||||
|
return access_path & __class_type_info::__contained_public_mask;
|
||||||
|
}
|
||||||
|
inline bool virtual_p (__class_type_info::__sub_kind access_path)
|
||||||
|
{
|
||||||
|
return (access_path & __class_type_info::__contained_virtual_mask);
|
||||||
|
}
|
||||||
|
inline bool contained_public_p (__class_type_info::__sub_kind access_path)
|
||||||
|
{
|
||||||
|
return ((access_path & __class_type_info::__contained_public)
|
||||||
|
== __class_type_info::__contained_public);
|
||||||
|
}
|
||||||
|
inline bool contained_nonpublic_p (__class_type_info::__sub_kind access_path)
|
||||||
|
{
|
||||||
|
return ((access_path & __class_type_info::__contained_public)
|
||||||
|
== __class_type_info::__contained_mask);
|
||||||
|
}
|
||||||
|
inline bool contained_nonvirtual_p (__class_type_info::__sub_kind access_path)
|
||||||
|
{
|
||||||
|
return ((access_path & (__class_type_info::__contained_mask
|
||||||
|
| __class_type_info::__contained_virtual_mask))
|
||||||
|
== __class_type_info::__contained_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const __class_type_info *const nonvirtual_base_type =
|
||||||
|
static_cast <const __class_type_info *> (0) + 1;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// __upcast_result is used to hold information during traversal of a class
|
||||||
|
// hierarchy when catch matching.
|
||||||
|
struct __class_type_info::__upcast_result
|
||||||
|
{
|
||||||
|
const void *dst_ptr; // pointer to caught object
|
||||||
|
__sub_kind part2dst; // path from current base to target
|
||||||
|
int src_details; // hints about the source type hierarchy
|
||||||
|
const __class_type_info *base_type; // where we found the target,
|
||||||
|
// if in vbase the __class_type_info of vbase
|
||||||
|
// if a non-virtual base then 1
|
||||||
|
// else NULL
|
||||||
|
__upcast_result (int d)
|
||||||
|
:dst_ptr (NULL), part2dst (__unknown), src_details (d), base_type (NULL)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
// __dyncast_result is used to hold information during traversal of a class
|
||||||
|
// hierarchy when dynamic casting.
|
||||||
|
struct __class_type_info::__dyncast_result
|
||||||
|
{
|
||||||
|
const void *dst_ptr; // pointer to target object or NULL
|
||||||
|
__sub_kind whole2dst; // path from most derived object to target
|
||||||
|
__sub_kind whole2src; // path from most derived object to sub object
|
||||||
|
__sub_kind dst2src; // path from target to sub object
|
||||||
|
int whole_details; // details of the whole class hierarchy
|
||||||
|
|
||||||
|
__dyncast_result (int details_ = __vmi_class_type_info::__flags_unknown_mask)
|
||||||
|
:dst_ptr (NULL), whole2dst (__unknown),
|
||||||
|
whole2src (__unknown), dst2src (__unknown),
|
||||||
|
whole_details (details_)
|
||||||
|
{}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
__dyncast_result(const __dyncast_result&);
|
||||||
|
|
||||||
|
__dyncast_result&
|
||||||
|
operator=(const __dyncast_result&);
|
||||||
|
};
|
||||||
|
|
||||||
|
inline __class_type_info::__sub_kind __class_type_info::
|
||||||
|
__find_public_src (ptrdiff_t src2dst,
|
||||||
|
const void *obj_ptr,
|
||||||
|
const __class_type_info *src_type,
|
||||||
|
const void *src_ptr) const
|
||||||
|
{
|
||||||
|
if (src2dst >= 0)
|
||||||
|
return adjust_pointer <void> (obj_ptr, src2dst) == src_ptr
|
||||||
|
? __contained_public : __not_contained;
|
||||||
|
if (src2dst == -2)
|
||||||
|
return __not_contained;
|
||||||
|
return __do_find_public_src (src2dst, obj_ptr, src_type, src_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
224
contrib/sdk/sources/libsupc++/typeinfo
Normal file
224
contrib/sdk/sources/libsupc++/typeinfo
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
// RTTI support for -*- C++ -*-
|
||||||
|
// Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||||
|
// 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011, 2012
|
||||||
|
// Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
/** @file typeinfo
|
||||||
|
* This is a Standard C++ Library header.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _TYPEINFO
|
||||||
|
#define _TYPEINFO
|
||||||
|
|
||||||
|
#pragma GCC system_header
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||||
|
#include <bits/hash_bytes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma GCC visibility push(default)
|
||||||
|
|
||||||
|
extern "C++" {
|
||||||
|
|
||||||
|
namespace __cxxabiv1
|
||||||
|
{
|
||||||
|
class __class_type_info;
|
||||||
|
} // namespace __cxxabiv1
|
||||||
|
|
||||||
|
// Determine whether typeinfo names for the same type are merged (in which
|
||||||
|
// case comparison can just compare pointers) or not (in which case strings
|
||||||
|
// must be compared), and whether comparison is to be implemented inline or
|
||||||
|
// not. We used to do inline pointer comparison by default if weak symbols
|
||||||
|
// are available, but even with weak symbols sometimes names are not merged
|
||||||
|
// when objects are loaded with RTLD_LOCAL, so now we always use strcmp by
|
||||||
|
// default. For ABI compatibility, we do the strcmp inline if weak symbols
|
||||||
|
// are available, and out-of-line if not. Out-of-line pointer comparison
|
||||||
|
// is used where the object files are to be portable to multiple systems,
|
||||||
|
// some of which may not be able to use pointer comparison, but the
|
||||||
|
// particular system for which libstdc++ is being built can use pointer
|
||||||
|
// comparison; in particular for most ARM EABI systems, where the ABI
|
||||||
|
// specifies out-of-line comparison. The compiler's target configuration
|
||||||
|
// can override the defaults by defining __GXX_TYPEINFO_EQUALITY_INLINE to
|
||||||
|
// 1 or 0 to indicate whether or not comparison is inline, and
|
||||||
|
// __GXX_MERGED_TYPEINFO_NAMES to 1 or 0 to indicate whether or not pointer
|
||||||
|
// comparison can be used.
|
||||||
|
|
||||||
|
#ifndef __GXX_MERGED_TYPEINFO_NAMES
|
||||||
|
// By default, typeinfo names are not merged.
|
||||||
|
#define __GXX_MERGED_TYPEINFO_NAMES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// By default follow the old inline rules to avoid ABI changes.
|
||||||
|
#ifndef __GXX_TYPEINFO_EQUALITY_INLINE
|
||||||
|
#if !__GXX_WEAK__
|
||||||
|
#define __GXX_TYPEINFO_EQUALITY_INLINE 0
|
||||||
|
#else
|
||||||
|
#define __GXX_TYPEINFO_EQUALITY_INLINE 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @brief Part of RTTI.
|
||||||
|
*
|
||||||
|
* The @c type_info class describes type information generated by
|
||||||
|
* an implementation.
|
||||||
|
*/
|
||||||
|
class type_info
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Destructor first. Being the first non-inline virtual function, this
|
||||||
|
* controls in which translation unit the vtable is emitted. The
|
||||||
|
* compiler makes use of that information to know where to emit
|
||||||
|
* the runtime-mandated type_info structures in the new-abi. */
|
||||||
|
virtual ~type_info();
|
||||||
|
|
||||||
|
/** Returns an @e implementation-defined byte string; this is not
|
||||||
|
* portable between compilers! */
|
||||||
|
const char* name() const
|
||||||
|
{ return __name[0] == '*' ? __name + 1 : __name; }
|
||||||
|
|
||||||
|
#if !__GXX_TYPEINFO_EQUALITY_INLINE
|
||||||
|
// In old abi, or when weak symbols are not supported, there can
|
||||||
|
// be multiple instances of a type_info object for one
|
||||||
|
// type. Uniqueness must use the _name value, not object address.
|
||||||
|
bool before(const type_info& __arg) const;
|
||||||
|
bool operator==(const type_info& __arg) const;
|
||||||
|
#else
|
||||||
|
#if !__GXX_MERGED_TYPEINFO_NAMES
|
||||||
|
/** Returns true if @c *this precedes @c __arg in the implementation's
|
||||||
|
* collation order. */
|
||||||
|
// Even with the new abi, on systems that support dlopen
|
||||||
|
// we can run into cases where type_info names aren't merged,
|
||||||
|
// so we still need to do string comparison.
|
||||||
|
bool before(const type_info& __arg) const
|
||||||
|
{ return (__name[0] == '*' && __arg.__name[0] == '*')
|
||||||
|
? __name < __arg.__name
|
||||||
|
: __builtin_strcmp (__name, __arg.__name) < 0; }
|
||||||
|
|
||||||
|
bool operator==(const type_info& __arg) const
|
||||||
|
{
|
||||||
|
return ((__name == __arg.__name)
|
||||||
|
|| (__name[0] != '*' &&
|
||||||
|
__builtin_strcmp (__name, __arg.__name) == 0));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// On some targets we can rely on type_info's NTBS being unique,
|
||||||
|
// and therefore address comparisons are sufficient.
|
||||||
|
bool before(const type_info& __arg) const
|
||||||
|
{ return __name < __arg.__name; }
|
||||||
|
|
||||||
|
bool operator==(const type_info& __arg) const
|
||||||
|
{ return __name == __arg.__name; }
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
bool operator!=(const type_info& __arg) const
|
||||||
|
{ return !operator==(__arg); }
|
||||||
|
|
||||||
|
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||||
|
size_t hash_code() const noexcept
|
||||||
|
{
|
||||||
|
# if !__GXX_MERGED_TYPEINFO_NAMES
|
||||||
|
return _Hash_bytes(name(), __builtin_strlen(name()),
|
||||||
|
static_cast<size_t>(0xc70f6907UL));
|
||||||
|
# else
|
||||||
|
return reinterpret_cast<size_t>(__name);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
#endif // __GXX_EXPERIMENTAL_CXX0X__
|
||||||
|
|
||||||
|
// Return true if this is a pointer type of some kind
|
||||||
|
virtual bool __is_pointer_p() const;
|
||||||
|
|
||||||
|
// Return true if this is a function type
|
||||||
|
virtual bool __is_function_p() const;
|
||||||
|
|
||||||
|
// Try and catch a thrown type. Store an adjusted pointer to the
|
||||||
|
// caught type in THR_OBJ. If THR_TYPE is not a pointer type, then
|
||||||
|
// THR_OBJ points to the thrown object. If THR_TYPE is a pointer
|
||||||
|
// type, then THR_OBJ is the pointer itself. OUTER indicates the
|
||||||
|
// number of outer pointers, and whether they were const
|
||||||
|
// qualified.
|
||||||
|
virtual bool __do_catch(const type_info *__thr_type, void **__thr_obj,
|
||||||
|
unsigned __outer) const;
|
||||||
|
|
||||||
|
// Internally used during catch matching
|
||||||
|
virtual bool __do_upcast(const __cxxabiv1::__class_type_info *__target,
|
||||||
|
void **__obj_ptr) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const char *__name;
|
||||||
|
|
||||||
|
explicit type_info(const char *__n): __name(__n) { }
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Assigning type_info is not supported.
|
||||||
|
type_info& operator=(const type_info&);
|
||||||
|
type_info(const type_info&);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Thrown during incorrect typecasting.
|
||||||
|
* @ingroup exceptions
|
||||||
|
*
|
||||||
|
* If you attempt an invalid @c dynamic_cast expression, an instance of
|
||||||
|
* this class (or something derived from this class) is thrown. */
|
||||||
|
class bad_cast : public exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bad_cast() _GLIBCXX_USE_NOEXCEPT { }
|
||||||
|
|
||||||
|
// This declaration is not useless:
|
||||||
|
// http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
|
||||||
|
virtual ~bad_cast() _GLIBCXX_USE_NOEXCEPT;
|
||||||
|
|
||||||
|
// See comment in eh_exception.cc.
|
||||||
|
virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Thrown when a NULL pointer in a @c typeid expression is used.
|
||||||
|
* @ingroup exceptions
|
||||||
|
*/
|
||||||
|
class bad_typeid : public exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bad_typeid () _GLIBCXX_USE_NOEXCEPT { }
|
||||||
|
|
||||||
|
// This declaration is not useless:
|
||||||
|
// http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
|
||||||
|
virtual ~bad_typeid() _GLIBCXX_USE_NOEXCEPT;
|
||||||
|
|
||||||
|
// See comment in eh_exception.cc.
|
||||||
|
virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
|
||||||
|
};
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
} // extern "C++"
|
||||||
|
|
||||||
|
#pragma GCC visibility pop
|
||||||
|
|
||||||
|
#endif
|
382
contrib/sdk/sources/libsupc++/unwind-cxx.h
Normal file
382
contrib/sdk/sources/libsupc++/unwind-cxx.h
Normal file
@ -0,0 +1,382 @@
|
|||||||
|
// -*- C++ -*- Exception handling and frame unwind runtime interface routines.
|
||||||
|
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||||
|
// 2011 Free Software Foundation, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// This is derived from the C++ ABI for IA-64. Where we diverge
|
||||||
|
// for cross-architecture compatibility are noted with "@@@".
|
||||||
|
|
||||||
|
#ifndef _UNWIND_CXX_H
|
||||||
|
#define _UNWIND_CXX_H 1
|
||||||
|
|
||||||
|
// Level 2: C++ ABI
|
||||||
|
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <exception>
|
||||||
|
#include <cstddef>
|
||||||
|
#include "unwind.h"
|
||||||
|
#include <bits/atomic_word.h>
|
||||||
|
#include <cxxabi.h>
|
||||||
|
|
||||||
|
#pragma GCC visibility push(default)
|
||||||
|
|
||||||
|
namespace __cxxabiv1
|
||||||
|
{
|
||||||
|
|
||||||
|
// A primary C++ exception object consists of a header, which is a wrapper
|
||||||
|
// around an unwind object header with additional C++ specific information,
|
||||||
|
// followed by the exception object itself.
|
||||||
|
|
||||||
|
struct __cxa_exception
|
||||||
|
{
|
||||||
|
// Manage the exception object itself.
|
||||||
|
std::type_info *exceptionType;
|
||||||
|
void (_GLIBCXX_CDTOR_CALLABI *exceptionDestructor)(void *);
|
||||||
|
|
||||||
|
// The C++ standard has entertaining rules wrt calling set_terminate
|
||||||
|
// and set_unexpected in the middle of the exception cleanup process.
|
||||||
|
std::unexpected_handler unexpectedHandler;
|
||||||
|
std::terminate_handler terminateHandler;
|
||||||
|
|
||||||
|
// The caught exception stack threads through here.
|
||||||
|
__cxa_exception *nextException;
|
||||||
|
|
||||||
|
// How many nested handlers have caught this exception. A negated
|
||||||
|
// value is a signal that this object has been rethrown.
|
||||||
|
int handlerCount;
|
||||||
|
|
||||||
|
#ifdef __ARM_EABI_UNWINDER__
|
||||||
|
// Stack of exceptions in cleanups.
|
||||||
|
__cxa_exception* nextPropagatingException;
|
||||||
|
|
||||||
|
// The nuber of active cleanup handlers for this exception.
|
||||||
|
int propagationCount;
|
||||||
|
#else
|
||||||
|
// Cache parsed handler data from the personality routine Phase 1
|
||||||
|
// for Phase 2 and __cxa_call_unexpected.
|
||||||
|
int handlerSwitchValue;
|
||||||
|
const unsigned char *actionRecord;
|
||||||
|
const unsigned char *languageSpecificData;
|
||||||
|
_Unwind_Ptr catchTemp;
|
||||||
|
void *adjustedPtr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The generic exception header. Must be last.
|
||||||
|
_Unwind_Exception unwindHeader;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct __cxa_refcounted_exception
|
||||||
|
{
|
||||||
|
// Manage this header.
|
||||||
|
_Atomic_word referenceCount;
|
||||||
|
// __cxa_exception must be last, and no padding can be after it.
|
||||||
|
__cxa_exception exc;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A dependent C++ exception object consists of a wrapper around an unwind
|
||||||
|
// object header with additional C++ specific information, containing a pointer
|
||||||
|
// to a primary exception object.
|
||||||
|
|
||||||
|
struct __cxa_dependent_exception
|
||||||
|
{
|
||||||
|
// The primary exception this thing depends on.
|
||||||
|
void *primaryException;
|
||||||
|
|
||||||
|
// The C++ standard has entertaining rules wrt calling set_terminate
|
||||||
|
// and set_unexpected in the middle of the exception cleanup process.
|
||||||
|
std::unexpected_handler unexpectedHandler;
|
||||||
|
std::terminate_handler terminateHandler;
|
||||||
|
|
||||||
|
// The caught exception stack threads through here.
|
||||||
|
__cxa_exception *nextException;
|
||||||
|
|
||||||
|
// How many nested handlers have caught this exception. A negated
|
||||||
|
// value is a signal that this object has been rethrown.
|
||||||
|
int handlerCount;
|
||||||
|
|
||||||
|
#ifdef __ARM_EABI_UNWINDER__
|
||||||
|
// Stack of exceptions in cleanups.
|
||||||
|
__cxa_exception* nextPropagatingException;
|
||||||
|
|
||||||
|
// The nuber of active cleanup handlers for this exception.
|
||||||
|
int propagationCount;
|
||||||
|
#else
|
||||||
|
// Cache parsed handler data from the personality routine Phase 1
|
||||||
|
// for Phase 2 and __cxa_call_unexpected.
|
||||||
|
int handlerSwitchValue;
|
||||||
|
const unsigned char *actionRecord;
|
||||||
|
const unsigned char *languageSpecificData;
|
||||||
|
_Unwind_Ptr catchTemp;
|
||||||
|
void *adjustedPtr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The generic exception header. Must be last.
|
||||||
|
_Unwind_Exception unwindHeader;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Each thread in a C++ program has access to a __cxa_eh_globals object.
|
||||||
|
struct __cxa_eh_globals
|
||||||
|
{
|
||||||
|
__cxa_exception *caughtExceptions;
|
||||||
|
unsigned int uncaughtExceptions;
|
||||||
|
#ifdef __ARM_EABI_UNWINDER__
|
||||||
|
__cxa_exception* propagatingExceptions;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
// @@@ These are not directly specified by the IA-64 C++ ABI.
|
||||||
|
|
||||||
|
// Handles re-checking the exception specification if unexpectedHandler
|
||||||
|
// throws, and if bad_exception needs to be thrown. Called from the
|
||||||
|
// compiler.
|
||||||
|
extern "C" void __cxa_call_unexpected (void *) __attribute__((__noreturn__));
|
||||||
|
extern "C" void __cxa_call_terminate (_Unwind_Exception*) throw ()
|
||||||
|
__attribute__((__noreturn__));
|
||||||
|
|
||||||
|
#ifdef __ARM_EABI_UNWINDER__
|
||||||
|
// Arm EABI specified routines.
|
||||||
|
typedef enum {
|
||||||
|
ctm_failed = 0,
|
||||||
|
ctm_succeeded = 1,
|
||||||
|
ctm_succeeded_with_ptr_to_base = 2
|
||||||
|
} __cxa_type_match_result;
|
||||||
|
extern "C" __cxa_type_match_result __cxa_type_match(_Unwind_Exception*,
|
||||||
|
const std::type_info*,
|
||||||
|
bool, void**);
|
||||||
|
extern "C" bool __cxa_begin_cleanup (_Unwind_Exception*);
|
||||||
|
extern "C" void __cxa_end_cleanup (void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Handles cleanup from transactional memory restart.
|
||||||
|
extern "C" void __cxa_tm_cleanup (void *, void *, unsigned int) throw();
|
||||||
|
|
||||||
|
// Invokes given handler, dying appropriately if the user handler was
|
||||||
|
// so inconsiderate as to return.
|
||||||
|
extern void __terminate(std::terminate_handler) throw ()
|
||||||
|
__attribute__((__noreturn__));
|
||||||
|
extern void __unexpected(std::unexpected_handler)
|
||||||
|
__attribute__((__noreturn__));
|
||||||
|
|
||||||
|
// The current installed user handlers.
|
||||||
|
extern std::terminate_handler __terminate_handler;
|
||||||
|
extern std::unexpected_handler __unexpected_handler;
|
||||||
|
|
||||||
|
// These are explicitly GNU C++ specific.
|
||||||
|
|
||||||
|
// Acquire the C++ exception header from the C++ object.
|
||||||
|
static inline __cxa_exception *
|
||||||
|
__get_exception_header_from_obj (void *ptr)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<__cxa_exception *>(ptr) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Acquire the C++ exception header from the generic exception header.
|
||||||
|
static inline __cxa_exception *
|
||||||
|
__get_exception_header_from_ue (_Unwind_Exception *exc)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<__cxa_exception *>(exc + 1) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Acquire the C++ refcounted exception header from the C++ object.
|
||||||
|
static inline __cxa_refcounted_exception *
|
||||||
|
__get_refcounted_exception_header_from_obj (void *ptr)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<__cxa_refcounted_exception *>(ptr) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Acquire the C++ refcounted exception header from the generic exception
|
||||||
|
// header.
|
||||||
|
static inline __cxa_refcounted_exception *
|
||||||
|
__get_refcounted_exception_header_from_ue (_Unwind_Exception *exc)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<__cxa_refcounted_exception *>(exc + 1) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline __cxa_dependent_exception *
|
||||||
|
__get_dependent_exception_from_ue (_Unwind_Exception *exc)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<__cxa_dependent_exception *>(exc + 1) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __ARM_EABI_UNWINDER__
|
||||||
|
static inline bool
|
||||||
|
__is_gxx_exception_class(_Unwind_Exception_Class c)
|
||||||
|
{
|
||||||
|
// TODO: Take advantage of the fact that c will always be word aligned.
|
||||||
|
return c[0] == 'G'
|
||||||
|
&& c[1] == 'N'
|
||||||
|
&& c[2] == 'U'
|
||||||
|
&& c[3] == 'C'
|
||||||
|
&& c[4] == 'C'
|
||||||
|
&& c[5] == '+'
|
||||||
|
&& c[6] == '+'
|
||||||
|
&& (c[7] == '\0' || c[7] == '\x01');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only checks for primary or dependent, but not that it is a C++ exception at
|
||||||
|
// all.
|
||||||
|
static inline bool
|
||||||
|
__is_dependent_exception(_Unwind_Exception_Class c)
|
||||||
|
{
|
||||||
|
return c[7] == '\x01';
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
__GXX_INIT_PRIMARY_EXCEPTION_CLASS(_Unwind_Exception_Class c)
|
||||||
|
{
|
||||||
|
c[0] = 'G';
|
||||||
|
c[1] = 'N';
|
||||||
|
c[2] = 'U';
|
||||||
|
c[3] = 'C';
|
||||||
|
c[4] = 'C';
|
||||||
|
c[5] = '+';
|
||||||
|
c[6] = '+';
|
||||||
|
c[7] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
__GXX_INIT_DEPENDENT_EXCEPTION_CLASS(_Unwind_Exception_Class c)
|
||||||
|
{
|
||||||
|
c[0] = 'G';
|
||||||
|
c[1] = 'N';
|
||||||
|
c[2] = 'U';
|
||||||
|
c[3] = 'C';
|
||||||
|
c[4] = 'C';
|
||||||
|
c[5] = '+';
|
||||||
|
c[6] = '+';
|
||||||
|
c[7] = '\x01';
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
__is_gxx_forced_unwind_class(_Unwind_Exception_Class c)
|
||||||
|
{
|
||||||
|
return c[0] == 'G'
|
||||||
|
&& c[1] == 'N'
|
||||||
|
&& c[2] == 'U'
|
||||||
|
&& c[3] == 'C'
|
||||||
|
&& c[4] == 'F'
|
||||||
|
&& c[5] == 'O'
|
||||||
|
&& c[6] == 'R'
|
||||||
|
&& c[7] == '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
__GXX_INIT_FORCED_UNWIND_CLASS(_Unwind_Exception_Class c)
|
||||||
|
{
|
||||||
|
c[0] = 'G';
|
||||||
|
c[1] = 'N';
|
||||||
|
c[2] = 'U';
|
||||||
|
c[3] = 'C';
|
||||||
|
c[4] = 'F';
|
||||||
|
c[5] = 'O';
|
||||||
|
c[6] = 'R';
|
||||||
|
c[7] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void*
|
||||||
|
__gxx_caught_object(_Unwind_Exception* eo)
|
||||||
|
{
|
||||||
|
return (void*)eo->barrier_cache.bitpattern[0];
|
||||||
|
}
|
||||||
|
#else // !__ARM_EABI_UNWINDER__
|
||||||
|
// This is the primary exception class we report -- "GNUCC++\0".
|
||||||
|
const _Unwind_Exception_Class __gxx_primary_exception_class
|
||||||
|
= ((((((((_Unwind_Exception_Class) 'G'
|
||||||
|
<< 8 | (_Unwind_Exception_Class) 'N')
|
||||||
|
<< 8 | (_Unwind_Exception_Class) 'U')
|
||||||
|
<< 8 | (_Unwind_Exception_Class) 'C')
|
||||||
|
<< 8 | (_Unwind_Exception_Class) 'C')
|
||||||
|
<< 8 | (_Unwind_Exception_Class) '+')
|
||||||
|
<< 8 | (_Unwind_Exception_Class) '+')
|
||||||
|
<< 8 | (_Unwind_Exception_Class) '\0');
|
||||||
|
|
||||||
|
// This is the dependent (from std::rethrow_exception) exception class we report
|
||||||
|
// "GNUCC++\x01"
|
||||||
|
const _Unwind_Exception_Class __gxx_dependent_exception_class
|
||||||
|
= ((((((((_Unwind_Exception_Class) 'G'
|
||||||
|
<< 8 | (_Unwind_Exception_Class) 'N')
|
||||||
|
<< 8 | (_Unwind_Exception_Class) 'U')
|
||||||
|
<< 8 | (_Unwind_Exception_Class) 'C')
|
||||||
|
<< 8 | (_Unwind_Exception_Class) 'C')
|
||||||
|
<< 8 | (_Unwind_Exception_Class) '+')
|
||||||
|
<< 8 | (_Unwind_Exception_Class) '+')
|
||||||
|
<< 8 | (_Unwind_Exception_Class) '\x01');
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
__is_gxx_exception_class(_Unwind_Exception_Class c)
|
||||||
|
{
|
||||||
|
return c == __gxx_primary_exception_class
|
||||||
|
|| c == __gxx_dependent_exception_class;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only checks for primary or dependent, but not that it is a C++ exception at
|
||||||
|
// all.
|
||||||
|
static inline bool
|
||||||
|
__is_dependent_exception(_Unwind_Exception_Class c)
|
||||||
|
{
|
||||||
|
return (c & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __GXX_INIT_PRIMARY_EXCEPTION_CLASS(c) c = __gxx_primary_exception_class
|
||||||
|
#define __GXX_INIT_DEPENDENT_EXCEPTION_CLASS(c) \
|
||||||
|
c = __gxx_dependent_exception_class
|
||||||
|
|
||||||
|
// GNU C++ personality routine, Version 0.
|
||||||
|
extern "C" _Unwind_Reason_Code __gxx_personality_v0
|
||||||
|
(int, _Unwind_Action, _Unwind_Exception_Class,
|
||||||
|
struct _Unwind_Exception *, struct _Unwind_Context *);
|
||||||
|
|
||||||
|
// GNU C++ sjlj personality routine, Version 0.
|
||||||
|
extern "C" _Unwind_Reason_Code __gxx_personality_sj0
|
||||||
|
(int, _Unwind_Action, _Unwind_Exception_Class,
|
||||||
|
struct _Unwind_Exception *, struct _Unwind_Context *);
|
||||||
|
|
||||||
|
static inline void*
|
||||||
|
__gxx_caught_object(_Unwind_Exception* eo)
|
||||||
|
{
|
||||||
|
// Bad as it looks, this actually works for dependent exceptions too.
|
||||||
|
__cxa_exception* header = __get_exception_header_from_ue (eo);
|
||||||
|
return header->adjustedPtr;
|
||||||
|
}
|
||||||
|
#endif // !__ARM_EABI_UNWINDER__
|
||||||
|
|
||||||
|
static inline void*
|
||||||
|
__get_object_from_ue(_Unwind_Exception* eo) throw()
|
||||||
|
{
|
||||||
|
return __is_dependent_exception (eo->exception_class) ?
|
||||||
|
__get_dependent_exception_from_ue (eo)->primaryException :
|
||||||
|
eo + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
__get_object_from_ambiguous_exception(__cxa_exception *p_or_d) throw()
|
||||||
|
{
|
||||||
|
return __get_object_from_ue (&p_or_d->unwindHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace __cxxabiv1 */
|
||||||
|
|
||||||
|
#pragma GCC visibility pop
|
||||||
|
|
||||||
|
#endif // _UNWIND_CXX_H
|
289
contrib/sdk/sources/libsupc++/unwind-pe.h
Normal file
289
contrib/sdk/sources/libsupc++/unwind-pe.h
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
/* Exception handling and frame unwind runtime interface routines.
|
||||||
|
Copyright (C) 2001, 2002, 2003, 2004, 2008, 2009 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of GCC.
|
||||||
|
|
||||||
|
GCC is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
permissions described in the GCC Runtime Library Exception, version
|
||||||
|
3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License and
|
||||||
|
a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* @@@ Really this should be out of line, but this also causes link
|
||||||
|
compatibility problems with the base ABI. This is slightly better
|
||||||
|
than duplicating code, however. */
|
||||||
|
|
||||||
|
#ifndef GCC_UNWIND_PE_H
|
||||||
|
#define GCC_UNWIND_PE_H
|
||||||
|
|
||||||
|
/* If using C++, references to abort have to be qualified with std::. */
|
||||||
|
#if __cplusplus
|
||||||
|
#define __gxx_abort std::abort
|
||||||
|
#else
|
||||||
|
#define __gxx_abort abort
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Pointer encodings, from dwarf2.h. */
|
||||||
|
#define DW_EH_PE_absptr 0x00
|
||||||
|
#define DW_EH_PE_omit 0xff
|
||||||
|
|
||||||
|
#define DW_EH_PE_uleb128 0x01
|
||||||
|
#define DW_EH_PE_udata2 0x02
|
||||||
|
#define DW_EH_PE_udata4 0x03
|
||||||
|
#define DW_EH_PE_udata8 0x04
|
||||||
|
#define DW_EH_PE_sleb128 0x09
|
||||||
|
#define DW_EH_PE_sdata2 0x0A
|
||||||
|
#define DW_EH_PE_sdata4 0x0B
|
||||||
|
#define DW_EH_PE_sdata8 0x0C
|
||||||
|
#define DW_EH_PE_signed 0x08
|
||||||
|
|
||||||
|
#define DW_EH_PE_pcrel 0x10
|
||||||
|
#define DW_EH_PE_textrel 0x20
|
||||||
|
#define DW_EH_PE_datarel 0x30
|
||||||
|
#define DW_EH_PE_funcrel 0x40
|
||||||
|
#define DW_EH_PE_aligned 0x50
|
||||||
|
|
||||||
|
#define DW_EH_PE_indirect 0x80
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NO_SIZE_OF_ENCODED_VALUE
|
||||||
|
|
||||||
|
/* Given an encoding, return the number of bytes the format occupies.
|
||||||
|
This is only defined for fixed-size encodings, and so does not
|
||||||
|
include leb128. */
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
size_of_encoded_value (unsigned char encoding) __attribute__ ((unused));
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
size_of_encoded_value (unsigned char encoding)
|
||||||
|
{
|
||||||
|
if (encoding == DW_EH_PE_omit)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (encoding & 0x07)
|
||||||
|
{
|
||||||
|
case DW_EH_PE_absptr:
|
||||||
|
return sizeof (void *);
|
||||||
|
case DW_EH_PE_udata2:
|
||||||
|
return 2;
|
||||||
|
case DW_EH_PE_udata4:
|
||||||
|
return 4;
|
||||||
|
case DW_EH_PE_udata8:
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
__gxx_abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NO_BASE_OF_ENCODED_VALUE
|
||||||
|
|
||||||
|
/* Given an encoding and an _Unwind_Context, return the base to which
|
||||||
|
the encoding is relative. This base may then be passed to
|
||||||
|
read_encoded_value_with_base for use when the _Unwind_Context is
|
||||||
|
not available. */
|
||||||
|
|
||||||
|
static _Unwind_Ptr
|
||||||
|
base_of_encoded_value (unsigned char encoding, struct _Unwind_Context *context)
|
||||||
|
{
|
||||||
|
if (encoding == DW_EH_PE_omit)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (encoding & 0x70)
|
||||||
|
{
|
||||||
|
case DW_EH_PE_absptr:
|
||||||
|
case DW_EH_PE_pcrel:
|
||||||
|
case DW_EH_PE_aligned:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case DW_EH_PE_textrel:
|
||||||
|
return _Unwind_GetTextRelBase (context);
|
||||||
|
case DW_EH_PE_datarel:
|
||||||
|
return _Unwind_GetDataRelBase (context);
|
||||||
|
case DW_EH_PE_funcrel:
|
||||||
|
return _Unwind_GetRegionStart (context);
|
||||||
|
}
|
||||||
|
__gxx_abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Read an unsigned leb128 value from P, store the value in VAL, return
|
||||||
|
P incremented past the value. We assume that a word is large enough to
|
||||||
|
hold any value so encoded; if it is smaller than a pointer on some target,
|
||||||
|
pointers should not be leb128 encoded on that target. */
|
||||||
|
|
||||||
|
static const unsigned char *
|
||||||
|
read_uleb128 (const unsigned char *p, _uleb128_t *val)
|
||||||
|
{
|
||||||
|
unsigned int shift = 0;
|
||||||
|
unsigned char byte;
|
||||||
|
_uleb128_t result;
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
byte = *p++;
|
||||||
|
result |= ((_uleb128_t)byte & 0x7f) << shift;
|
||||||
|
shift += 7;
|
||||||
|
}
|
||||||
|
while (byte & 0x80);
|
||||||
|
|
||||||
|
*val = result;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Similar, but read a signed leb128 value. */
|
||||||
|
|
||||||
|
static const unsigned char *
|
||||||
|
read_sleb128 (const unsigned char *p, _sleb128_t *val)
|
||||||
|
{
|
||||||
|
unsigned int shift = 0;
|
||||||
|
unsigned char byte;
|
||||||
|
_uleb128_t result;
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
byte = *p++;
|
||||||
|
result |= ((_uleb128_t)byte & 0x7f) << shift;
|
||||||
|
shift += 7;
|
||||||
|
}
|
||||||
|
while (byte & 0x80);
|
||||||
|
|
||||||
|
/* Sign-extend a negative value. */
|
||||||
|
if (shift < 8 * sizeof(result) && (byte & 0x40) != 0)
|
||||||
|
result |= -(((_uleb128_t)1L) << shift);
|
||||||
|
|
||||||
|
*val = (_sleb128_t) result;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load an encoded value from memory at P. The value is returned in VAL;
|
||||||
|
The function returns P incremented past the value. BASE is as given
|
||||||
|
by base_of_encoded_value for this encoding in the appropriate context. */
|
||||||
|
|
||||||
|
static const unsigned char *
|
||||||
|
read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
|
||||||
|
const unsigned char *p, _Unwind_Ptr *val)
|
||||||
|
{
|
||||||
|
union unaligned
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
unsigned u2 __attribute__ ((mode (HI)));
|
||||||
|
unsigned u4 __attribute__ ((mode (SI)));
|
||||||
|
unsigned u8 __attribute__ ((mode (DI)));
|
||||||
|
signed s2 __attribute__ ((mode (HI)));
|
||||||
|
signed s4 __attribute__ ((mode (SI)));
|
||||||
|
signed s8 __attribute__ ((mode (DI)));
|
||||||
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
|
const union unaligned *u = (const union unaligned *) p;
|
||||||
|
_Unwind_Internal_Ptr result;
|
||||||
|
|
||||||
|
if (encoding == DW_EH_PE_aligned)
|
||||||
|
{
|
||||||
|
_Unwind_Internal_Ptr a = (_Unwind_Internal_Ptr) p;
|
||||||
|
a = (a + sizeof (void *) - 1) & - sizeof(void *);
|
||||||
|
result = *(_Unwind_Internal_Ptr *) a;
|
||||||
|
p = (const unsigned char *) (_Unwind_Internal_Ptr) (a + sizeof (void *));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (encoding & 0x0f)
|
||||||
|
{
|
||||||
|
case DW_EH_PE_absptr:
|
||||||
|
result = (_Unwind_Internal_Ptr) u->ptr;
|
||||||
|
p += sizeof (void *);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DW_EH_PE_uleb128:
|
||||||
|
{
|
||||||
|
_uleb128_t tmp;
|
||||||
|
p = read_uleb128 (p, &tmp);
|
||||||
|
result = (_Unwind_Internal_Ptr) tmp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DW_EH_PE_sleb128:
|
||||||
|
{
|
||||||
|
_sleb128_t tmp;
|
||||||
|
p = read_sleb128 (p, &tmp);
|
||||||
|
result = (_Unwind_Internal_Ptr) tmp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DW_EH_PE_udata2:
|
||||||
|
result = u->u2;
|
||||||
|
p += 2;
|
||||||
|
break;
|
||||||
|
case DW_EH_PE_udata4:
|
||||||
|
result = u->u4;
|
||||||
|
p += 4;
|
||||||
|
break;
|
||||||
|
case DW_EH_PE_udata8:
|
||||||
|
result = u->u8;
|
||||||
|
p += 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DW_EH_PE_sdata2:
|
||||||
|
result = u->s2;
|
||||||
|
p += 2;
|
||||||
|
break;
|
||||||
|
case DW_EH_PE_sdata4:
|
||||||
|
result = u->s4;
|
||||||
|
p += 4;
|
||||||
|
break;
|
||||||
|
case DW_EH_PE_sdata8:
|
||||||
|
result = u->s8;
|
||||||
|
p += 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
__gxx_abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != 0)
|
||||||
|
{
|
||||||
|
result += ((encoding & 0x70) == DW_EH_PE_pcrel
|
||||||
|
? (_Unwind_Internal_Ptr) u : base);
|
||||||
|
if (encoding & DW_EH_PE_indirect)
|
||||||
|
result = *(_Unwind_Internal_Ptr *) result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*val = result;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NO_BASE_OF_ENCODED_VALUE
|
||||||
|
|
||||||
|
/* Like read_encoded_value_with_base, but get the base from the context
|
||||||
|
rather than providing it directly. */
|
||||||
|
|
||||||
|
static inline const unsigned char *
|
||||||
|
read_encoded_value (struct _Unwind_Context *context, unsigned char encoding,
|
||||||
|
const unsigned char *p, _Unwind_Ptr *val)
|
||||||
|
{
|
||||||
|
return read_encoded_value_with_base (encoding,
|
||||||
|
base_of_encoded_value (encoding, context),
|
||||||
|
p, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* unwind-pe.h */
|
391
contrib/sdk/sources/libsupc++/vmi_class_type_info.cc
Normal file
391
contrib/sdk/sources/libsupc++/vmi_class_type_info.cc
Normal file
@ -0,0 +1,391 @@
|
|||||||
|
// Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007, 2009
|
||||||
|
// Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of GCC.
|
||||||
|
//
|
||||||
|
// GCC is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// GCC is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "tinfo.h"
|
||||||
|
|
||||||
|
namespace __cxxabiv1 {
|
||||||
|
|
||||||
|
__vmi_class_type_info::
|
||||||
|
~__vmi_class_type_info ()
|
||||||
|
{}
|
||||||
|
|
||||||
|
__class_type_info::__sub_kind __vmi_class_type_info::
|
||||||
|
__do_find_public_src (ptrdiff_t src2dst,
|
||||||
|
const void *obj_ptr,
|
||||||
|
const __class_type_info *src_type,
|
||||||
|
const void *src_ptr) const
|
||||||
|
{
|
||||||
|
if (obj_ptr == src_ptr && *this == *src_type)
|
||||||
|
return __contained_public;
|
||||||
|
|
||||||
|
for (std::size_t i = __base_count; i--;)
|
||||||
|
{
|
||||||
|
if (!__base_info[i].__is_public_p ())
|
||||||
|
continue; // Not public, can't be here.
|
||||||
|
|
||||||
|
const void *base = obj_ptr;
|
||||||
|
ptrdiff_t offset = __base_info[i].__offset ();
|
||||||
|
bool is_virtual = __base_info[i].__is_virtual_p ();
|
||||||
|
|
||||||
|
if (is_virtual)
|
||||||
|
{
|
||||||
|
if (src2dst == -3)
|
||||||
|
continue; // Not a virtual base, so can't be here.
|
||||||
|
}
|
||||||
|
base = convert_to_base (base, is_virtual, offset);
|
||||||
|
|
||||||
|
__sub_kind base_kind = __base_info[i].__base_type->__do_find_public_src
|
||||||
|
(src2dst, base, src_type, src_ptr);
|
||||||
|
if (contained_p (base_kind))
|
||||||
|
{
|
||||||
|
if (is_virtual)
|
||||||
|
base_kind = __sub_kind (base_kind | __contained_virtual_mask);
|
||||||
|
return base_kind;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return __not_contained;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a big hairy function. Although the run-time behaviour of
|
||||||
|
// dynamic_cast is simple to describe, it gives rise to some non-obvious
|
||||||
|
// behaviour. We also desire to determine as early as possible any definite
|
||||||
|
// answer we can get. Because it is unknown what the run-time ratio of
|
||||||
|
// succeeding to failing dynamic casts is, we do not know in which direction
|
||||||
|
// to bias any optimizations. To that end we make no particular effort towards
|
||||||
|
// early fail answers or early success answers. Instead we try to minimize
|
||||||
|
// work by filling in things lazily (when we know we need the information),
|
||||||
|
// and opportunisticly take early success or failure results.
|
||||||
|
bool __vmi_class_type_info::
|
||||||
|
__do_dyncast (ptrdiff_t src2dst,
|
||||||
|
__sub_kind access_path,
|
||||||
|
const __class_type_info *dst_type,
|
||||||
|
const void *obj_ptr,
|
||||||
|
const __class_type_info *src_type,
|
||||||
|
const void *src_ptr,
|
||||||
|
__dyncast_result &__restrict result) const
|
||||||
|
{
|
||||||
|
if (result.whole_details & __flags_unknown_mask)
|
||||||
|
result.whole_details = __flags;
|
||||||
|
|
||||||
|
if (obj_ptr == src_ptr && *this == *src_type)
|
||||||
|
{
|
||||||
|
// The src object we started from. Indicate how we are accessible from
|
||||||
|
// the most derived object.
|
||||||
|
result.whole2src = access_path;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (*this == *dst_type)
|
||||||
|
{
|
||||||
|
result.dst_ptr = obj_ptr;
|
||||||
|
result.whole2dst = access_path;
|
||||||
|
if (src2dst >= 0)
|
||||||
|
result.dst2src = adjust_pointer <void> (obj_ptr, src2dst) == src_ptr
|
||||||
|
? __contained_public : __not_contained;
|
||||||
|
else if (src2dst == -2)
|
||||||
|
result.dst2src = __not_contained;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If src_type is a unique non-virtual base of dst_type, we have a good
|
||||||
|
// guess at the address we want, so in the first pass try skipping any
|
||||||
|
// bases which don't contain that address.
|
||||||
|
const void *dst_cand = NULL;
|
||||||
|
if (src2dst >= 0)
|
||||||
|
dst_cand = adjust_pointer<void>(src_ptr, -src2dst);
|
||||||
|
bool first_pass = true;
|
||||||
|
bool skipped = false;
|
||||||
|
|
||||||
|
bool result_ambig = false;
|
||||||
|
again:
|
||||||
|
for (std::size_t i = __base_count; i--;)
|
||||||
|
{
|
||||||
|
__dyncast_result result2 (result.whole_details);
|
||||||
|
void const *base = obj_ptr;
|
||||||
|
__sub_kind base_access = access_path;
|
||||||
|
ptrdiff_t offset = __base_info[i].__offset ();
|
||||||
|
bool is_virtual = __base_info[i].__is_virtual_p ();
|
||||||
|
|
||||||
|
if (is_virtual)
|
||||||
|
base_access = __sub_kind (base_access | __contained_virtual_mask);
|
||||||
|
base = convert_to_base (base, is_virtual, offset);
|
||||||
|
|
||||||
|
if (dst_cand)
|
||||||
|
{
|
||||||
|
bool skip_on_first_pass = base > dst_cand;
|
||||||
|
if (skip_on_first_pass == first_pass)
|
||||||
|
{
|
||||||
|
// We aren't interested in this base on this pass: either
|
||||||
|
// we're on the first pass and this base doesn't contain the
|
||||||
|
// likely address, or we're on the second pass and we checked
|
||||||
|
// this base on the first pass.
|
||||||
|
skipped = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!__base_info[i].__is_public_p ())
|
||||||
|
{
|
||||||
|
if (src2dst == -2 &&
|
||||||
|
!(result.whole_details
|
||||||
|
& (__non_diamond_repeat_mask | __diamond_shaped_mask)))
|
||||||
|
// The hierarchy has no duplicate bases (which might ambiguate
|
||||||
|
// things) and where we started is not a public base of what we
|
||||||
|
// want (so it cannot be a downcast). There is nothing of interest
|
||||||
|
// hiding in a non-public base.
|
||||||
|
continue;
|
||||||
|
base_access = __sub_kind (base_access & ~__contained_public_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result2_ambig
|
||||||
|
= __base_info[i].__base_type->__do_dyncast (src2dst, base_access,
|
||||||
|
dst_type, base,
|
||||||
|
src_type, src_ptr, result2);
|
||||||
|
result.whole2src = __sub_kind (result.whole2src | result2.whole2src);
|
||||||
|
if (result2.dst2src == __contained_public
|
||||||
|
|| result2.dst2src == __contained_ambig)
|
||||||
|
{
|
||||||
|
result.dst_ptr = result2.dst_ptr;
|
||||||
|
result.whole2dst = result2.whole2dst;
|
||||||
|
result.dst2src = result2.dst2src;
|
||||||
|
// Found a downcast which can't be bettered or an ambiguous downcast
|
||||||
|
// which can't be disambiguated
|
||||||
|
return result2_ambig;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result_ambig && !result.dst_ptr)
|
||||||
|
{
|
||||||
|
// Not found anything yet.
|
||||||
|
result.dst_ptr = result2.dst_ptr;
|
||||||
|
result.whole2dst = result2.whole2dst;
|
||||||
|
result_ambig = result2_ambig;
|
||||||
|
if (result.dst_ptr && result.whole2src != __unknown
|
||||||
|
&& !(__flags & __non_diamond_repeat_mask))
|
||||||
|
// Found dst and src and we don't have repeated bases.
|
||||||
|
return result_ambig;
|
||||||
|
}
|
||||||
|
else if (result.dst_ptr && result.dst_ptr == result2.dst_ptr)
|
||||||
|
{
|
||||||
|
// Found at same address, must be via virtual. Pick the most
|
||||||
|
// accessible path.
|
||||||
|
result.whole2dst =
|
||||||
|
__sub_kind (result.whole2dst | result2.whole2dst);
|
||||||
|
}
|
||||||
|
else if ((result.dst_ptr != 0 && result2.dst_ptr != 0)
|
||||||
|
|| (result.dst_ptr != 0 && result2_ambig)
|
||||||
|
|| (result2.dst_ptr != 0 && result_ambig))
|
||||||
|
{
|
||||||
|
// Found two different DST_TYPE bases, or a valid one and a set of
|
||||||
|
// ambiguous ones, must disambiguate. See whether SRC_PTR is
|
||||||
|
// contained publicly within one of the non-ambiguous choices. If it
|
||||||
|
// is in only one, then that's the choice. If it is in both, then
|
||||||
|
// we're ambiguous and fail. If it is in neither, we're ambiguous,
|
||||||
|
// but don't yet fail as we might later find a third base which does
|
||||||
|
// contain SRC_PTR.
|
||||||
|
|
||||||
|
__sub_kind new_sub_kind = result2.dst2src;
|
||||||
|
__sub_kind old_sub_kind = result.dst2src;
|
||||||
|
|
||||||
|
if (contained_p (result.whole2src)
|
||||||
|
&& (!virtual_p (result.whole2src)
|
||||||
|
|| !(result.whole_details & __diamond_shaped_mask)))
|
||||||
|
{
|
||||||
|
// We already found SRC_PTR as a base of most derived, and
|
||||||
|
// either it was non-virtual, or the whole hierarchy is
|
||||||
|
// not-diamond shaped. Therefore if it is in either choice, it
|
||||||
|
// can only be in one of them, and we will already know.
|
||||||
|
if (old_sub_kind == __unknown)
|
||||||
|
old_sub_kind = __not_contained;
|
||||||
|
if (new_sub_kind == __unknown)
|
||||||
|
new_sub_kind = __not_contained;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (old_sub_kind >= __not_contained)
|
||||||
|
;// already calculated
|
||||||
|
else if (contained_p (new_sub_kind)
|
||||||
|
&& (!virtual_p (new_sub_kind)
|
||||||
|
|| !(__flags & __diamond_shaped_mask)))
|
||||||
|
// Already found inside the other choice, and it was
|
||||||
|
// non-virtual or we are not diamond shaped.
|
||||||
|
old_sub_kind = __not_contained;
|
||||||
|
else
|
||||||
|
old_sub_kind = dst_type->__find_public_src
|
||||||
|
(src2dst, result.dst_ptr, src_type, src_ptr);
|
||||||
|
|
||||||
|
if (new_sub_kind >= __not_contained)
|
||||||
|
;// already calculated
|
||||||
|
else if (contained_p (old_sub_kind)
|
||||||
|
&& (!virtual_p (old_sub_kind)
|
||||||
|
|| !(__flags & __diamond_shaped_mask)))
|
||||||
|
// Already found inside the other choice, and it was
|
||||||
|
// non-virtual or we are not diamond shaped.
|
||||||
|
new_sub_kind = __not_contained;
|
||||||
|
else
|
||||||
|
new_sub_kind = dst_type->__find_public_src
|
||||||
|
(src2dst, result2.dst_ptr, src_type, src_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Neither sub_kind can be contained_ambig -- we bail out early
|
||||||
|
// when we find those.
|
||||||
|
if (contained_p (__sub_kind (new_sub_kind ^ old_sub_kind)))
|
||||||
|
{
|
||||||
|
// Only on one choice, not ambiguous.
|
||||||
|
if (contained_p (new_sub_kind))
|
||||||
|
{
|
||||||
|
// Only in new.
|
||||||
|
result.dst_ptr = result2.dst_ptr;
|
||||||
|
result.whole2dst = result2.whole2dst;
|
||||||
|
result_ambig = false;
|
||||||
|
old_sub_kind = new_sub_kind;
|
||||||
|
}
|
||||||
|
result.dst2src = old_sub_kind;
|
||||||
|
if (public_p (result.dst2src))
|
||||||
|
return false; // Can't be an ambiguating downcast for later discovery.
|
||||||
|
if (!virtual_p (result.dst2src))
|
||||||
|
return false; // Found non-virtually can't be bettered
|
||||||
|
}
|
||||||
|
else if (contained_p (__sub_kind (new_sub_kind & old_sub_kind)))
|
||||||
|
{
|
||||||
|
// In both.
|
||||||
|
result.dst_ptr = NULL;
|
||||||
|
result.dst2src = __contained_ambig;
|
||||||
|
return true; // Fail.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// In neither publicly, ambiguous for the moment, but keep
|
||||||
|
// looking. It is possible that it was private in one or
|
||||||
|
// both and therefore we should fail, but that's just tough.
|
||||||
|
result.dst_ptr = NULL;
|
||||||
|
result.dst2src = __not_contained;
|
||||||
|
result_ambig = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.whole2src == __contained_private)
|
||||||
|
// We found SRC_PTR as a private non-virtual base, therefore all
|
||||||
|
// cross casts will fail. We have already found a down cast, if
|
||||||
|
// there is one.
|
||||||
|
return result_ambig;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skipped && first_pass)
|
||||||
|
{
|
||||||
|
// We didn't find dst where we expected it, so let's go back and try
|
||||||
|
// the bases we skipped (if any).
|
||||||
|
first_pass = false;
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result_ambig;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool __vmi_class_type_info::
|
||||||
|
__do_upcast (const __class_type_info *dst, const void *obj_ptr,
|
||||||
|
__upcast_result &__restrict result) const
|
||||||
|
{
|
||||||
|
if (__class_type_info::__do_upcast (dst, obj_ptr, result))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
int src_details = result.src_details;
|
||||||
|
if (src_details & __flags_unknown_mask)
|
||||||
|
src_details = __flags;
|
||||||
|
|
||||||
|
for (std::size_t i = __base_count; i--;)
|
||||||
|
{
|
||||||
|
__upcast_result result2 (src_details);
|
||||||
|
const void *base = obj_ptr;
|
||||||
|
ptrdiff_t offset = __base_info[i].__offset ();
|
||||||
|
bool is_virtual = __base_info[i].__is_virtual_p ();
|
||||||
|
bool is_public = __base_info[i].__is_public_p ();
|
||||||
|
|
||||||
|
if (!is_public && !(src_details & __non_diamond_repeat_mask))
|
||||||
|
// original cannot have an ambiguous base, so skip private bases
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (base)
|
||||||
|
base = convert_to_base (base, is_virtual, offset);
|
||||||
|
|
||||||
|
if (__base_info[i].__base_type->__do_upcast (dst, base, result2))
|
||||||
|
{
|
||||||
|
if (result2.base_type == nonvirtual_base_type && is_virtual)
|
||||||
|
result2.base_type = __base_info[i].__base_type;
|
||||||
|
if (contained_p (result2.part2dst) && !is_public)
|
||||||
|
result2.part2dst = __sub_kind (result2.part2dst & ~__contained_public_mask);
|
||||||
|
|
||||||
|
if (!result.base_type)
|
||||||
|
{
|
||||||
|
result = result2;
|
||||||
|
if (!contained_p (result.part2dst))
|
||||||
|
return true; // found ambiguously
|
||||||
|
|
||||||
|
if (result.part2dst & __contained_public_mask)
|
||||||
|
{
|
||||||
|
if (!(__flags & __non_diamond_repeat_mask))
|
||||||
|
return true; // cannot have an ambiguous other base
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!virtual_p (result.part2dst))
|
||||||
|
return true; // cannot have another path
|
||||||
|
if (!(__flags & __diamond_shaped_mask))
|
||||||
|
return true; // cannot have a more accessible path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (result.dst_ptr != result2.dst_ptr)
|
||||||
|
{
|
||||||
|
// Found an ambiguity.
|
||||||
|
result.dst_ptr = NULL;
|
||||||
|
result.part2dst = __contained_ambig;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (result.dst_ptr)
|
||||||
|
{
|
||||||
|
// Ok, found real object via a virtual path.
|
||||||
|
result.part2dst
|
||||||
|
= __sub_kind (result.part2dst | result2.part2dst);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Dealing with a null pointer, need to check vbase
|
||||||
|
// containing each of the two choices.
|
||||||
|
if (result2.base_type == nonvirtual_base_type
|
||||||
|
|| result.base_type == nonvirtual_base_type
|
||||||
|
|| !(*result2.base_type == *result.base_type))
|
||||||
|
{
|
||||||
|
// Already ambiguous, not virtual or via different virtuals.
|
||||||
|
// Cannot match.
|
||||||
|
result.part2dst = __contained_ambig;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
result.part2dst
|
||||||
|
= __sub_kind (result.part2dst | result2.part2dst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.part2dst != __unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
101
contrib/sdk/sources/libsupc++/vterminate.cc
Normal file
101
contrib/sdk/sources/libsupc++/vterminate.cc
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
// Verbose terminate_handler -*- C++ -*-
|
||||||
|
|
||||||
|
// Copyright (C) 2001, 2002, 2004, 2005, 2009, 2011 Free Software Foundation
|
||||||
|
//
|
||||||
|
// This file is part of the GNU ISO C++ Library. This library is free
|
||||||
|
// software; you can redistribute it and/or modify it under the
|
||||||
|
// terms of the GNU General Public License as published by the
|
||||||
|
// Free Software Foundation; either version 3, or (at your option)
|
||||||
|
// any later version.
|
||||||
|
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// Under Section 7 of GPL version 3, you are granted additional
|
||||||
|
// permissions described in the GCC Runtime Library Exception, version
|
||||||
|
// 3.1, as published by the Free Software Foundation.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License and
|
||||||
|
// a copy of the GCC Runtime Library Exception along with this program;
|
||||||
|
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <bits/c++config.h>
|
||||||
|
|
||||||
|
#if _GLIBCXX_HOSTED
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <exception>
|
||||||
|
#include <bits/exception_defines.h>
|
||||||
|
#include <cxxabi.h>
|
||||||
|
# include <cstdio>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace abi;
|
||||||
|
|
||||||
|
namespace __gnu_cxx
|
||||||
|
{
|
||||||
|
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
|
// A replacement for the standard terminate_handler which prints
|
||||||
|
// more information about the terminating exception (if any) on
|
||||||
|
// stderr.
|
||||||
|
void __verbose_terminate_handler()
|
||||||
|
{
|
||||||
|
static bool terminating;
|
||||||
|
if (terminating)
|
||||||
|
{
|
||||||
|
//fputs("terminate called recursively\n", stderr);
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
terminating = true;
|
||||||
|
|
||||||
|
// Make sure there was an exception; terminate is also called for an
|
||||||
|
// attempt to rethrow when there is no suitable exception.
|
||||||
|
type_info *t = __cxa_current_exception_type();
|
||||||
|
if (t)
|
||||||
|
{
|
||||||
|
// Note that "name" is the mangled name.
|
||||||
|
char const *name = t->name();
|
||||||
|
{
|
||||||
|
int status = -1;
|
||||||
|
char *dem = 0;
|
||||||
|
|
||||||
|
// dem = __cxa_demangle(name, 0, 0, &status);
|
||||||
|
|
||||||
|
// fputs("terminate called after throwing an instance of '", stderr);
|
||||||
|
// if (status == 0)
|
||||||
|
// fputs(dem, stderr);
|
||||||
|
// else
|
||||||
|
// fputs(name, stderr);
|
||||||
|
// fputs("'\n", stderr);
|
||||||
|
|
||||||
|
// if (status == 0)
|
||||||
|
// free(dem);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the exception is derived from std::exception, we can
|
||||||
|
// give more information.
|
||||||
|
__try { __throw_exception_again; }
|
||||||
|
#ifdef __EXCEPTIONS
|
||||||
|
__catch(const exception& exc)
|
||||||
|
{
|
||||||
|
char const *w = exc.what();
|
||||||
|
// fputs(" what(): ", stderr);
|
||||||
|
// fputs(w, stderr);
|
||||||
|
// fputs("\n", stderr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
__catch(...) { }
|
||||||
|
}
|
||||||
|
else;
|
||||||
|
// fputs("terminate called without an active exception\n", stderr);
|
||||||
|
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
_GLIBCXX_END_NAMESPACE_VERSION
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user