diff -r 40ce5f4b8835 Include/asdl.h --- a/Include/asdl.h Mon Nov 02 09:17:08 2015 -0800 +++ b/Include/asdl.h Tue Nov 03 10:22:35 2015 +0200 @@ -17,12 +17,12 @@ typedef struct { Py_ssize_t size; - void *elements[1]; + void *elements[1] Py_VARIABLE_SIZE; } asdl_seq; typedef struct { Py_ssize_t size; - int elements[1]; + int elements[1] Py_VARIABLE_SIZE; } asdl_int_seq; asdl_seq *_Py_asdl_seq_new(Py_ssize_t size, PyArena *arena); diff -r 40ce5f4b8835 Include/bytesobject.h --- a/Include/bytesobject.h Mon Nov 02 09:17:08 2015 -0800 +++ b/Include/bytesobject.h Tue Nov 03 10:22:35 2015 +0200 @@ -31,7 +31,7 @@ typedef struct { PyObject_VAR_HEAD Py_hash_t ob_shash; - char ob_sval[1]; + char ob_sval[1] Py_VARIABLE_SIZE; /* Invariants: * ob_sval contains space for 'ob_size+1' elements. @@ -52,9 +52,9 @@ PyAPI_FUNC(PyObject *) PyBytes_FromString(const char *); PyAPI_FUNC(PyObject *) PyBytes_FromObject(PyObject *); PyAPI_FUNC(PyObject *) PyBytes_FromFormatV(const char*, va_list) - Py_GCC_ATTRIBUTE((format(printf, 1, 0))); + Py_GCC_ATTRIBUTE((format(printf, 1, 0))); PyAPI_FUNC(PyObject *) PyBytes_FromFormat(const char*, ...) - Py_GCC_ATTRIBUTE((format(printf, 1, 2))); + Py_GCC_ATTRIBUTE((format(printf, 1, 2))); PyAPI_FUNC(Py_ssize_t) PyBytes_Size(PyObject *); PyAPI_FUNC(char *) PyBytes_AsString(PyObject *); PyAPI_FUNC(PyObject *) PyBytes_Repr(PyObject *, int); @@ -72,8 +72,8 @@ int use_bytearray); #endif PyAPI_FUNC(PyObject *) PyBytes_DecodeEscape(const char *, Py_ssize_t, - const char *, Py_ssize_t, - const char *); + const char *, Py_ssize_t, + const char *); /* Macro, trading safety for speed */ #ifndef Py_LIMITED_API @@ -125,10 +125,10 @@ /* Flags used by string formatting */ #define F_LJUST (1<<0) -#define F_SIGN (1<<1) +#define F_SIGN (1<<1) #define F_BLANK (1<<2) -#define F_ALT (1<<3) -#define F_ZERO (1<<4) +#define F_ALT (1<<3) +#define F_ZERO (1<<4) #ifndef Py_LIMITED_API /* The _PyBytesWriter structure is big: it contains an embeded "stack buffer". diff -r 40ce5f4b8835 Include/frameobject.h --- a/Include/frameobject.h Mon Nov 02 09:17:08 2015 -0800 +++ b/Include/frameobject.h Tue Nov 03 10:22:35 2015 +0200 @@ -49,7 +49,7 @@ int f_iblock; /* index in f_blockstack */ char f_executing; /* whether the frame is still executing */ PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */ - PyObject *f_localsplus[1]; /* locals+stack, dynamically sized */ + PyObject *f_localsplus[1] Py_VARIABLE_SIZE; /* locals+stack, dynamically sized */ } PyFrameObject; diff -r 40ce5f4b8835 Include/longintrepr.h --- a/Include/longintrepr.h Mon Nov 02 09:17:08 2015 -0800 +++ b/Include/longintrepr.h Tue Nov 03 10:22:35 2015 +0200 @@ -50,22 +50,22 @@ typedef PY_INT32_T sdigit; /* signed variant of digit */ typedef PY_UINT64_T twodigits; typedef PY_INT64_T stwodigits; /* signed variant of twodigits */ -#define PyLong_SHIFT 30 -#define _PyLong_DECIMAL_SHIFT 9 /* max(e such that 10**e fits in a digit) */ -#define _PyLong_DECIMAL_BASE ((digit)1000000000) /* 10 ** DECIMAL_SHIFT */ +#define PyLong_SHIFT 30 +#define _PyLong_DECIMAL_SHIFT 9 /* max(e such that 10**e fits in a digit) */ +#define _PyLong_DECIMAL_BASE ((digit)1000000000) /* 10 ** DECIMAL_SHIFT */ #elif PYLONG_BITS_IN_DIGIT == 15 typedef unsigned short digit; typedef short sdigit; /* signed variant of digit */ typedef unsigned long twodigits; typedef long stwodigits; /* signed variant of twodigits */ -#define PyLong_SHIFT 15 -#define _PyLong_DECIMAL_SHIFT 4 /* max(e such that 10**e fits in a digit) */ -#define _PyLong_DECIMAL_BASE ((digit)10000) /* 10 ** DECIMAL_SHIFT */ +#define PyLong_SHIFT 15 +#define _PyLong_DECIMAL_SHIFT 4 /* max(e such that 10**e fits in a digit) */ +#define _PyLong_DECIMAL_BASE ((digit)10000) /* 10 ** DECIMAL_SHIFT */ #else #error "PYLONG_BITS_IN_DIGIT should be 15 or 30" #endif -#define PyLong_BASE ((digit)1 << PyLong_SHIFT) -#define PyLong_MASK ((digit)(PyLong_BASE - 1)) +#define PyLong_BASE ((digit)1 << PyLong_SHIFT) +#define PyLong_MASK ((digit)(PyLong_BASE - 1)) #if PyLong_SHIFT % 5 != 0 #error "longobject.c requires that PyLong_SHIFT be divisible by 5" @@ -73,12 +73,12 @@ /* Long integer representation. The absolute value of a number is equal to - SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i) + SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i) Negative numbers are represented with ob_size < 0; zero is represented by ob_size == 0. In a normalized number, ob_digit[abs(ob_size)-1] (the most significant digit) is never zero. Also, in all cases, for all valid i, - 0 <= ob_digit[i] <= MASK. + 0 <= ob_digit[i] <= MASK. The allocation function takes care of allocating extra memory so that ob_digit[0] ... ob_digit[abs(ob_size)-1] are actually available. @@ -87,8 +87,8 @@ */ struct _longobject { - PyObject_VAR_HEAD - digit ob_digit[1]; + PyObject_VAR_HEAD + digit ob_digit[1] Py_VARIABLE_SIZE; }; PyAPI_FUNC(PyLongObject *) _PyLong_New(Py_ssize_t); diff -r 40ce5f4b8835 Include/memoryobject.h --- a/Include/memoryobject.h Mon Nov 02 09:17:08 2015 -0800 +++ b/Include/memoryobject.h Tue Nov 03 10:22:35 2015 +0200 @@ -60,7 +60,7 @@ Py_ssize_t exports; /* number of buffer re-exports */ Py_buffer view; /* private copy of the exporter's view */ PyObject *weakreflist; - Py_ssize_t ob_array[1]; /* shape, strides, suboffsets */ + Py_ssize_t ob_array[1] Py_VARIABLE_SIZE; /* shape, strides, suboffsets */ } PyMemoryViewObject; #endif diff -r 40ce5f4b8835 Include/object.h --- a/Include/object.h Mon Nov 02 09:17:08 2015 -0800 +++ b/Include/object.h Tue Nov 03 10:22:35 2015 +0200 @@ -115,8 +115,8 @@ } PyVarObject; #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt) -#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) -#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size) +#define Py_TYPE(ob) (((PyObject*)Py_INIT_BOUNDS(ob))->ob_type) +#define Py_SIZE(ob) (((PyVarObject*)Py_INIT_BOUNDS(ob))->ob_size) /********************* String Literals ****************************************/ /* This structure helps managing static strings. The basic usage goes like this: @@ -780,7 +780,7 @@ #define Py_DECREF(op) \ do { \ - PyObject *_py_decref_tmp = (PyObject *)(op); \ + PyObject *_py_decref_tmp = (PyObject *)Py_INIT_BOUNDS(op); \ if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ --(_py_decref_tmp)->ob_refcnt != 0) \ _Py_CHECK_REFCNT(_py_decref_tmp) \ diff -r 40ce5f4b8835 Include/objimpl.h --- a/Include/objimpl.h Mon Nov 02 09:17:08 2015 -0800 +++ b/Include/objimpl.h Tue Nov 03 10:22:35 2015 +0200 @@ -344,7 +344,7 @@ #define Py_VISIT(op) \ do { \ if (op) { \ - int vret = visit((PyObject *)(op), arg); \ + int vret = visit((PyObject *)Py_INIT_BOUNDS(op), arg); \ if (vret) \ return vret; \ } \ diff -r 40ce5f4b8835 Include/pyport.h --- a/Include/pyport.h Mon Nov 02 09:17:08 2015 -0800 +++ b/Include/pyport.h Tue Nov 03 10:22:35 2015 +0200 @@ -570,18 +570,18 @@ #define HAVE_PY_SET_53BIT_PRECISION 1 #define _Py_SET_53BIT_PRECISION_HEADER \ unsigned int old_fpcr, new_fpcr -#define _Py_SET_53BIT_PRECISION_START \ - do { \ - __asm__ ("fmove.l %%fpcr,%0" : "=g" (old_fpcr)); \ - /* Set double precision / round to nearest. */ \ - new_fpcr = (old_fpcr & ~0xf0) | 0x80; \ - if (new_fpcr != old_fpcr) \ - __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (new_fpcr)); \ +#define _Py_SET_53BIT_PRECISION_START \ + do { \ + __asm__ ("fmove.l %%fpcr,%0" : "=g" (old_fpcr)); \ + /* Set double precision / round to nearest. */ \ + new_fpcr = (old_fpcr & ~0xf0) | 0x80; \ + if (new_fpcr != old_fpcr) \ + __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (new_fpcr)); \ } while (0) -#define _Py_SET_53BIT_PRECISION_END \ - do { \ - if (new_fpcr != old_fpcr) \ - __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (old_fpcr)); \ +#define _Py_SET_53BIT_PRECISION_END \ + do { \ + if (new_fpcr != old_fpcr) \ + __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (old_fpcr)); \ } while (0) #endif @@ -897,4 +897,24 @@ #endif /* _MSC_VER >= 1900 */ #endif /* Py_BUILD_CORE */ +/* + * Check for MPX support. GCC 5.2 or higher is needed for the MPX bnd_legacy + * attribute to be supported. + */ + +#if defined(__GNUC__) && ((__GNUC__ >= 6) || \ + (__GNUC__ == 5) && (__GNUC_MINOR__ >= 2)) && \ + defined(Py_INTEL_MPX) +#define Py_BND_LEGACY __attribute__((bnd_legacy)) +#define Py_VARIABLE_SIZE __attribute__((bnd_variable_size)) +#define Py_INIT_BOUNDS(p) __bnd_init_ptr_bounds(p) +#define Py_SET_PTR_BOUNDS(p, size) __bnd_set_ptr_bounds(p, size) +#define Py_MPX_ENABLED +#else +#define Py_BND_LEGACY +#define Py_VARIABLE_SIZE +#define Py_INIT_BOUNDS(p) (p) +#define Py_SET_PTR_BOUNDS(p, size) (p) +#endif + #endif /* Py_PYPORT_H */ diff -r 40ce5f4b8835 Include/tupleobject.h --- a/Include/tupleobject.h Mon Nov 02 09:17:08 2015 -0800 +++ b/Include/tupleobject.h Tue Nov 03 10:22:35 2015 +0200 @@ -24,7 +24,7 @@ #ifndef Py_LIMITED_API typedef struct { PyObject_VAR_HEAD - PyObject *ob_item[1]; + PyObject *ob_item[1] Py_VARIABLE_SIZE; /* ob_item contains space for 'ob_size' elements. * Items must normally not be NULL, except during construction when diff -r 40ce5f4b8835 Makefile.pre.in --- a/Makefile.pre.in Mon Nov 02 09:17:08 2015 -0800 +++ b/Makefile.pre.in Tue Nov 03 10:22:35 2015 +0200 @@ -80,6 +80,7 @@ # Use it when a compiler flag should _not_ be part of the distutils CFLAGS # once Python is installed (Issue #21121). CONFIGURE_CFLAGS_NODIST=@CFLAGS_NODIST@ +CONFIGURE_LDFLAGS_NODIST=@LDFLAGS_NODIST@ CONFIGURE_CPPFLAGS= @CPPFLAGS@ CONFIGURE_LDFLAGS= @LDFLAGS@ # Avoid assigning CFLAGS, LDFLAGS, etc. so users can use them on the @@ -91,7 +92,7 @@ # be able to build extension modules using the directories specified in the # environment variables PY_CPPFLAGS= $(BASECPPFLAGS) -I. -IInclude -I$(srcdir)/Include $(CONFIGURE_CPPFLAGS) $(CPPFLAGS) -PY_LDFLAGS= $(CONFIGURE_LDFLAGS) $(LDFLAGS) +PY_LDFLAGS= $(CONFIGURE_LDFLAGS) $(LDFLAGS) $(CONFIGURE_LDFLAGS_NODIST) NO_AS_NEEDED= @NO_AS_NEEDED@ LDLAST= @LDLAST@ SGI_ABI= @SGI_ABI@ diff -r 40ce5f4b8835 Modules/_ctypes/ctypes.h --- a/Modules/_ctypes/ctypes.h Mon Nov 02 09:17:08 2015 -0800 +++ b/Modules/_ctypes/ctypes.h Tue Nov 03 10:22:35 2015 +0200 @@ -67,7 +67,7 @@ PyObject *restype; SETFUNC setfunc; ffi_type *ffi_restype; - ffi_type *atypes[1]; + ffi_type *atypes[1] Py_VARIABLE_SIZE; } CThunkObject; extern PyTypeObject PyCThunk_Type; #define CThunk_CheckExact(v) ((v)->ob_type == &PyCThunk_Type) diff -r 40ce5f4b8835 Modules/_tracemalloc.c --- a/Modules/_tracemalloc.c Mon Nov 02 09:17:08 2015 -0800 +++ b/Modules/_tracemalloc.c Tue Nov 03 10:22:35 2015 +0200 @@ -72,7 +72,7 @@ typedef struct { Py_uhash_t hash; int nframe; - frame_t frames[1]; + frame_t frames[1] Py_VARIABLE_SIZE; } traceback_t; #define TRACEBACK_SIZE(NFRAME) \ diff -r 40ce5f4b8835 Modules/expat/xmlparse.c --- a/Modules/expat/xmlparse.c Mon Nov 02 09:17:08 2015 -0800 +++ b/Modules/expat/xmlparse.c Tue Nov 03 10:22:35 2015 +0200 @@ -24,6 +24,7 @@ #include "ascii.h" #include "expat.h" +#include "pyport.h" #ifdef XML_UNICODE #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX @@ -217,7 +218,7 @@ typedef struct block { struct block *next; int size; - XML_Char s[1]; + XML_Char s[1] Py_VARIABLE_SIZE; } BLOCK; typedef struct { diff -r 40ce5f4b8835 Modules/mathmodule.c --- a/Modules/mathmodule.c Mon Nov 02 09:17:08 2015 -0800 +++ b/Modules/mathmodule.c Tue Nov 03 10:22:35 2015 +0200 @@ -863,7 +863,7 @@ OverflowError. */ -static PyObject * +Py_BND_LEGACY static PyObject * math_1(PyObject *arg, double (*func) (double), int can_overflow) { return math_1_to_whatever(arg, func, PyFloat_FromDouble, can_overflow); @@ -875,7 +875,7 @@ return math_1_to_whatever(arg, func, PyLong_FromDouble, can_overflow); } -static PyObject * +Py_BND_LEGACY static PyObject * math_2(PyObject *args, double (*func) (double, double), char *funcname) { PyObject *ox, *oy; diff -r 40ce5f4b8835 Modules/sre.h --- a/Modules/sre.h Mon Nov 02 09:17:08 2015 -0800 +++ b/Modules/sre.h Tue Nov 03 10:22:35 2015 +0200 @@ -36,7 +36,7 @@ int isbytes; /* pattern type (1 - bytes, 0 - string, -1 - None) */ /* pattern code */ Py_ssize_t codesize; - SRE_CODE code[1]; + SRE_CODE code[1] Py_VARIABLE_SIZE; } PatternObject; #define PatternObject_GetCode(o) (((PatternObject*)(o))->code) @@ -49,7 +49,7 @@ Py_ssize_t pos, endpos; /* current target slice */ Py_ssize_t lastindex; /* last index marker seen by the engine (-1 if none) */ Py_ssize_t groups; /* number of groups (start/end marks) */ - Py_ssize_t mark[1]; + Py_ssize_t mark[1] Py_VARIABLE_SIZE; } MatchObject; typedef unsigned int (*SRE_TOLOWER_HOOK)(unsigned int ch); diff -r 40ce5f4b8835 Modules/sre_lib.h --- a/Modules/sre_lib.h Mon Nov 02 09:17:08 2015 -0800 +++ b/Modules/sre_lib.h Tue Nov 03 10:22:35 2015 +0200 @@ -189,7 +189,7 @@ LOCAL(Py_ssize_t) SRE(match)(SRE_STATE* state, SRE_CODE* pattern, int match_all); -LOCAL(Py_ssize_t) +Py_BND_LEGACY LOCAL(Py_ssize_t) SRE(count)(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount) { SRE_CODE chr; diff -r 40ce5f4b8835 Modules/winreparse.h --- a/Modules/winreparse.h Mon Nov 02 09:17:08 2015 -0800 +++ b/Modules/winreparse.h Tue Nov 03 10:22:35 2015 +0200 @@ -23,7 +23,7 @@ USHORT PrintNameOffset; USHORT PrintNameLength; ULONG Flags; - WCHAR PathBuffer[1]; + WCHAR PathBuffer[1] Py_VARIABLE_SIZE; } SymbolicLinkReparseBuffer; struct { @@ -31,11 +31,11 @@ USHORT SubstituteNameLength; USHORT PrintNameOffset; USHORT PrintNameLength; - WCHAR PathBuffer[1]; + WCHAR PathBuffer[1] Py_VARIABLE_SIZE; } MountPointReparseBuffer; struct { - UCHAR DataBuffer[1]; + UCHAR DataBuffer[1] Py_VARIABLE_SIZE; } GenericReparseBuffer; }; } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; diff -r 40ce5f4b8835 Objects/dict-common.h --- a/Objects/dict-common.h Mon Nov 02 09:17:08 2015 -0800 +++ b/Objects/dict-common.h Tue Nov 03 10:22:35 2015 +0200 @@ -16,7 +16,7 @@ Py_ssize_t dk_size; dict_lookup_func dk_lookup; Py_ssize_t dk_usable; - PyDictKeyEntry dk_entries[1]; + PyDictKeyEntry dk_entries[1] Py_VARIABLE_SIZE; }; #endif diff -r 40ce5f4b8835 Objects/dictobject.c --- a/Objects/dictobject.c Mon Nov 02 09:17:08 2015 -0800 +++ b/Objects/dictobject.c Tue Nov 03 10:22:35 2015 +0200 @@ -802,6 +802,9 @@ assert(PyUnicode_CheckExact(key) || mp->ma_keys->dk_lookup == lookdict); Py_INCREF(value); MAINTAIN_TRACKING(mp, key, value); +#ifdef Py_MPX_ENABLED + value_addr = Py_INIT_BOUNDS(value_addr); +#endif old_value = *value_addr; if (old_value != NULL) { assert(ep->me_key != NULL && ep->me_key != dummy); @@ -1083,6 +1086,9 @@ return NULL; } } +#ifdef Py_MPX_ENABLED + value_addr = (PyObject **)Py_INIT_BOUNDS(value_addr); +#endif return *value_addr; } @@ -1585,7 +1591,7 @@ static void dict_dealloc(PyDictObject *mp) { - PyObject **values = mp->ma_values; + PyObject **values = Py_INIT_BOUNDS(mp->ma_values); PyDictKeysObject *keys = mp->ma_keys; Py_ssize_t i, n; PyObject_GC_UnTrack(mp); @@ -1784,12 +1790,12 @@ offset = sizeof(PyObject *); } else { - value_ptr = &ep[0].me_value; + value_ptr = Py_INIT_BOUNDS(&ep[0].me_value); offset = sizeof(PyDictKeyEntry); } for (i = 0, j = 0; i < size; i++) { if (*value_ptr != NULL) { - PyObject *key = ep[i].me_key; + PyObject *key = Py_INIT_BOUNDS(ep[i].me_key); Py_INCREF(key); PyList_SET_ITEM(v, j, key); j++; @@ -1880,11 +1886,11 @@ ep = mp->ma_keys->dk_entries; size = DK_SIZE(mp->ma_keys); if (mp->ma_values) { - value_ptr = mp->ma_values; + value_ptr = Py_INIT_BOUNDS(mp->ma_values); offset = sizeof(PyObject *); } else { - value_ptr = &ep[0].me_value; + value_ptr = Py_INIT_BOUNDS(&ep[0].me_value); offset = sizeof(PyDictKeyEntry); } for (i = 0, j = 0; i < size; i++) { diff -r 40ce5f4b8835 Objects/listobject.c --- a/Objects/listobject.c Mon Nov 02 09:17:08 2015 -0800 +++ b/Objects/listobject.c Tue Nov 03 10:22:35 2015 +0200 @@ -310,7 +310,7 @@ /* Methods */ -static void +Py_BND_LEGACY static void list_dealloc(PyListObject *op) { Py_ssize_t i; @@ -1055,7 +1055,7 @@ Even in case of error, the output slice will be some permutation of the input (nothing is lost or duplicated). */ -static int +Py_BND_LEGACY static int binarysort(sortslice lo, PyObject **hi, PyObject **start) { Py_ssize_t k; @@ -2211,7 +2211,7 @@ return NULL; } -static int +Py_BND_LEGACY static int list_traverse(PyListObject *o, visitproc visit, void *arg) { Py_ssize_t i; diff -r 40ce5f4b8835 Objects/longobject.c --- a/Objects/longobject.c Mon Nov 02 09:17:08 2015 -0800 +++ b/Objects/longobject.c Tue Nov 03 10:22:35 2015 +0200 @@ -415,6 +415,9 @@ } res = -1; +#ifdef Py_MPX_ENABLED + v = Py_INIT_BOUNDS(v); +#endif i = Py_SIZE(v); switch (i) { @@ -517,7 +520,7 @@ return -1; } - v = (PyLongObject *)vv; + v = (PyLongObject *)Py_INIT_BOUNDS(vv); i = Py_SIZE(v); switch (i) { case -1: return -(sdigit)v->ob_digit[0]; @@ -572,7 +575,7 @@ return (unsigned long)-1; } - v = (PyLongObject *)vv; + v = (PyLongObject *)Py_INIT_BOUNDS(vv); i = Py_SIZE(v); x = 0; if (i < 0) { @@ -850,7 +853,7 @@ return (PyObject *)long_normalize(v); } -int +Py_BND_LEGACY int _PyLong_AsByteArray(PyLongObject* v, unsigned char* bytes, size_t n, int little_endian, int is_signed) @@ -2089,6 +2092,10 @@ PyObject *strobj; Py_ssize_t slen; +#ifdef Py_MPX_ENABLED + str = __bnd_init_ptr_bounds(str); +#endif + if ((base != 0 && base < 2) || base > 36) { PyErr_SetString(PyExc_ValueError, "int() arg 2 must be >= 2 and <= 36"); @@ -4679,7 +4686,7 @@ n = Py_SIZE(tmp); if (n < 0) n = -n; - newobj = (PyLongObject *)type->tp_alloc(type, n); + newobj = (PyLongObject *)Py_INIT_BOUNDS(type->tp_alloc(type, n)); if (newobj == NULL) { Py_DECREF(tmp); return NULL; diff -r 40ce5f4b8835 Objects/memoryobject.c --- a/Objects/memoryobject.c Mon Nov 02 09:17:08 2015 -0800 +++ b/Objects/memoryobject.c Tue Nov 03 10:22:35 2015 +0200 @@ -964,7 +964,7 @@ typedef struct { Py_buffer view; - Py_ssize_t array[1]; + Py_ssize_t array[1] Py_VARIABLE_SIZE; } Py_buffer_full; int diff -r 40ce5f4b8835 Objects/object.c --- a/Objects/object.c Mon Nov 02 09:17:08 2015 -0800 +++ b/Objects/object.c Tue Nov 03 10:22:35 2015 +0200 @@ -1055,7 +1055,7 @@ if (descr != NULL) { f = descr->ob_type->tp_descr_get; if (f != NULL && PyDescr_IsData(descr)) { - res = f(descr, obj, (PyObject *)obj->ob_type); + res = f(descr, obj, (PyObject *)Py_INIT_BOUNDS(obj->ob_type)); goto done; } } @@ -1230,7 +1230,7 @@ /* Test a value used as condition, e.g., in a for or if statement. Return -1 if an error occurred */ -int +Py_BND_LEGACY int PyObject_IsTrue(PyObject *v) { Py_ssize_t res; diff -r 40ce5f4b8835 Objects/obmalloc.c --- a/Objects/obmalloc.c Mon Nov 02 09:17:08 2015 -0800 +++ b/Objects/obmalloc.c Tue Nov 03 10:22:35 2015 +0200 @@ -722,7 +722,7 @@ #define DUMMY_SIZE_IDX 0xffff /* size class of newly cached pools */ /* Round pointer P down to the closest pool-aligned address <= P, as a poolp */ -#define POOL_ADDR(P) ((poolp)_Py_ALIGN_DOWN((P), POOL_SIZE)) +#define POOL_ADDR(P) ((poolp)_Py_ALIGN_DOWN((Py_INIT_BOUNDS(P)), POOL_SIZE)) /* Return total number of blocks in pool of size index I, as a uint. */ #define NUMBLOCKS(I) ((uint)(POOL_SIZE - POOL_OVERHEAD) / INDEX2SIZE(I)) @@ -1208,7 +1208,7 @@ UNLOCK(); if (use_calloc) memset(bp, 0, nbytes); - return (void *)bp; + return (void *)Py_SET_PTR_BOUNDS(bp, nbytes); } /* * Reached the end of the free list, try to extend it. @@ -1222,7 +1222,7 @@ UNLOCK(); if (use_calloc) memset(bp, 0, nbytes); - return (void *)bp; + return (void *)Py_SET_PTR_BOUNDS(bp, nbytes); } /* Pool is full, unlink from used pools. */ next = pool->nextpool; @@ -1232,7 +1232,7 @@ UNLOCK(); if (use_calloc) memset(bp, 0, nbytes); - return (void *)bp; + return (void *)Py_SET_PTR_BOUNDS(bp, nbytes); } /* There isn't a pool of the right size class immediately @@ -1313,7 +1313,7 @@ UNLOCK(); if (use_calloc) memset(bp, 0, nbytes); - return (void *)bp; + return (void *)Py_SET_PTR_BOUNDS(bp, nbytes); } /* * Initialize the pool header, set up the free list to @@ -1330,7 +1330,7 @@ UNLOCK(); if (use_calloc) memset(bp, 0, nbytes); - return (void *)bp; + return (void *)Py_SET_PTR_BOUNDS(bp, nbytes); } /* Carve off a new pool. */ @@ -1427,6 +1427,9 @@ * list in any case). */ assert(pool->ref.count > 0); /* else it was empty */ +#ifdef Py_MPX_ENABLED + p = Py_INIT_BOUNDS(p); +#endif *(block **)p = lastfree = pool->freeblock; pool->freeblock = (block *)p; if (lastfree) { @@ -1659,7 +1662,7 @@ /* It's the same, * or shrinking and new/old > 3/4. */ - return p; + return Py_SET_PTR_BOUNDS(p, nbytes); } size = nbytes; } @@ -1668,7 +1671,7 @@ memcpy(bp, p, size); _PyObject_Free(ctx, p); } - return bp; + return Py_SET_PTR_BOUNDS(bp, nbytes); } #ifdef WITH_VALGRIND redirect: diff -r 40ce5f4b8835 Objects/typeobject.c --- a/Objects/typeobject.c Mon Nov 02 09:17:08 2015 -0800 +++ b/Objects/typeobject.c Tue Nov 03 10:22:35 2015 +0200 @@ -886,7 +886,7 @@ return rtn; } -static PyObject * +Py_BND_LEGACY static PyObject * type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *obj; @@ -1742,7 +1742,7 @@ to_merge is the declared list of bases. */ - bases = type->tp_bases; + bases = Py_INIT_BOUNDS(type->tp_bases); n = PyTuple_GET_SIZE(bases); to_merge = PyList_New(n+1); diff -r 40ce5f4b8835 Objects/unicodeobject.c --- a/Objects/unicodeobject.c Mon Nov 02 09:17:08 2015 -0800 +++ b/Objects/unicodeobject.c Tue Nov 03 10:22:35 2015 +0200 @@ -2083,12 +2083,13 @@ PyObject* _PyUnicode_FromASCII(const char *buffer, Py_ssize_t size) { - const unsigned char *s = (const unsigned char *)buffer; + const unsigned char *s = (const unsigned char *)Py_INIT_BOUNDS(buffer); PyObject *unicode; + if (size == 1) { #ifdef Py_DEBUG assert((unsigned char)s[0] < 128); -#endif +#endif return get_latin1_char(s[0]); } unicode = PyUnicode_New(size, 127); @@ -7956,7 +7957,7 @@ PyObject_HEAD unsigned char level1[32]; int count2, count3; - unsigned char level23[1]; + unsigned char level23[1] Py_VARIABLE_SIZE; }; static PyObject* diff -r 40ce5f4b8835 Parser/grammar.c --- a/Parser/grammar.c Mon Nov 02 09:17:08 2015 -0800 +++ b/Parser/grammar.c Tue Nov 03 10:22:35 2015 +0200 @@ -79,7 +79,7 @@ s->s_arc = (arc *)PyObject_REALLOC(s->s_arc, sizeof(arc) * (s->s_narcs + 1)); if (s->s_arc == NULL) Py_FatalError("no mem to resize arc list in addarc"); - a = &s->s_arc[s->s_narcs++]; + a = Py_INIT_BOUNDS(&s->s_arc[s->s_narcs++]); a->a_lbl = lbl; a->a_arrow = to; } diff -r 40ce5f4b8835 Python/ast.c --- a/Python/ast.c Mon Nov 02 09:17:08 2015 -0800 +++ b/Python/ast.c Tue Nov 03 10:22:35 2015 +0200 @@ -4870,7 +4870,7 @@ decoded Python string object. If the string is an f-string, set *fmode and return the unparsed string object. */ -static PyObject * +Py_BND_LEGACY static PyObject * parsestr(struct compiling *c, const node *n, int *bytesmode, int *fmode) { size_t len; diff -r 40ce5f4b8835 Python/dtoa.c --- a/Python/dtoa.c Mon Nov 02 09:17:08 2015 -0800 +++ b/Python/dtoa.c Tue Nov 03 10:22:35 2015 +0200 @@ -330,7 +330,7 @@ Bigint { struct Bigint *next; int k, maxwds, sign, wds; - ULong x[1]; + ULong x[1] Py_VARIABLE_SIZE; }; typedef struct Bigint Bigint; @@ -446,7 +446,7 @@ #endif /* Py_USING_MEMORY_DEBUGGER */ -#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ +#define Bcopy(x,y) memcpy((char *)Py_INIT_BOUNDS(&x->sign), (char *)Py_INIT_BOUNDS(&y->sign), \ y->wds*sizeof(Long) + 2*sizeof(int)) /* Multiply a Bigint b by m and add a. Either modifies b in place and returns diff -r 40ce5f4b8835 Python/pyhash.c --- a/Python/pyhash.c Mon Nov 02 09:17:08 2015 -0800 +++ b/Python/pyhash.c Tue Nov 03 10:22:35 2015 +0200 @@ -372,7 +372,7 @@ PY_UINT64_T k0 = _le64toh(_Py_HashSecret.siphash.k0); PY_UINT64_T k1 = _le64toh(_Py_HashSecret.siphash.k1); PY_UINT64_T b = (PY_UINT64_T)src_sz << 56; - const PY_UINT64_T *in = (PY_UINT64_T*)src; + const PY_UINT64_T *in = (PY_UINT64_T*)Py_INIT_BOUNDS(src); PY_UINT64_T v0 = k0 ^ 0x736f6d6570736575ULL; PY_UINT64_T v1 = k1 ^ 0x646f72616e646f6dULL; @@ -393,7 +393,7 @@ } t = 0; - pt = (PY_UINT8_T *)&t; + pt = (PY_UINT8_T *)Py_INIT_BOUNDS(&t); m = (PY_UINT8_T *)in; switch (src_sz) { case 7: pt[6] = m[6]; diff -r 40ce5f4b8835 configure --- a/configure Mon Nov 02 09:17:08 2015 -0800 +++ b/configure Tue Nov 03 10:22:35 2015 +0200 @@ -664,6 +664,7 @@ LIBTOOL_CRUFT OTHER_LIBTOOL_OPT UNIVERSAL_ARCH_FLAGS +LDFLAGS_NODIST CFLAGS_NODIST BASECFLAGS OPT @@ -806,6 +807,7 @@ enable_shared enable_profiling with_pydebug +with_mpx with_hash_algorithm with_address_sanitizer with_libs @@ -1485,6 +1487,8 @@ compiler --with-suffix=.exe set executable suffix --with-pydebug build with Py_DEBUG defined + --with-mpx Enable Intel MPX (Memory Protection Extensions) + feature. Disabled by default. --with-hash-algorithm=[fnv|siphash24] select hash algorithm --with-address-sanitizer @@ -6437,6 +6441,52 @@ fi +# Check for --with-mpx +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-mpx" >&5 +$as_echo_n "checking for --with-mpx... " >&6; } + +# Check whether --with-mpx was given. +if test "${with_mpx+set}" = set; then : + withval=$with_mpx; +if test "$withval" != no +then + mpx_compatible=false + if [ "$CC" = "gcc" ] + then + CC_MAJOR_VERSION=$(gcc -dumpversion | cut -f1 -d.) + CC_MINOR_VERSION=$(gcc -dumpversion | cut -f2 -d.) + if [ "$CC_MAJOR_VERSION" -ge "5" ] + then + mpx_compatible=true + if [ "$CC_MAJOR_VERSION" -eq "5" ] && [ "$CC_MINOR_VERSION" -lt "2" ] + then + mpx_compatible=false + fi + fi + fi + + if [ "$mpx_compatible" = "false" ] + then + as_fn_error $? "MPX feature can only be used with gcc 5.2 and higher" "$LINENO" 5 + else + +$as_echo "#define Py_INTEL_MPX 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; }; + CFLAGS_NODIST="$CFLAGS_NODIST -fcheck-pointer-bounds -mmpx" + LDFLAGS_NODIST="$LDFLAGS_NODIST -fcheck-pointer-bounds -mmpx -static-libmpx" + OPT="-g -O0 -Wall $STRICT_PROTO" + fi +else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + # Enable PGO flags. # Extract the first word of "llvm-profdata", so it can be a program name with args. set dummy llvm-profdata; ac_word=$2 @@ -6578,6 +6628,7 @@ + # The -arch flags for universal builds on OSX UNIVERSAL_ARCH_FLAGS= diff -r 40ce5f4b8835 configure.ac --- a/configure.ac Mon Nov 02 09:17:08 2015 -0800 +++ b/configure.ac Tue Nov 03 10:22:35 2015 +0200 @@ -1218,6 +1218,43 @@ fi], [AC_MSG_RESULT(no)]) +# Check for --with-mpx +AC_MSG_CHECKING(for --with-mpx) +AC_ARG_WITH(mpx, + AS_HELP_STRING([--with-mpx], [Enable Intel MPX (Memory Protection Extensions) + feature. Disabled by default.]), +[ +if test "$withval" != no +then + mpx_compatible=false + if [[ "$CC" = "gcc" ]] + then + CC_MAJOR_VERSION=$(gcc -dumpversion | cut -f1 -d.) + CC_MINOR_VERSION=$(gcc -dumpversion | cut -f2 -d.) + if [[ "$CC_MAJOR_VERSION" -ge "5" ]] + then + mpx_compatible=true + if [[ "$CC_MAJOR_VERSION" -eq "5" ]] && [[ "$CC_MINOR_VERSION" -lt "2" ]] + then + mpx_compatible=false + fi + fi + fi + + if [[ "$mpx_compatible" = "false" ]] + then + AC_MSG_ERROR([MPX feature can only be used with gcc 5.2 and higher]) + else + AC_DEFINE(Py_INTEL_MPX, 1, [Define if you want to build an MPX instrumented interpreter.]) + AC_MSG_RESULT(yes); + CFLAGS_NODIST="$CFLAGS_NODIST -fcheck-pointer-bounds -mmpx" + LDFLAGS_NODIST="$LDFLAGS_NODIST -fcheck-pointer-bounds -mmpx -static-libmpx" + OPT="-g -O0 -Wall $STRICT_PROTO" + fi +else AC_MSG_RESULT(no) +fi], +[AC_MSG_RESULT(no)]) + # Enable PGO flags. AC_SUBST(PGO_PROF_GEN_FLAG) AC_SUBST(PGO_PROF_USE_FLAG) @@ -1327,6 +1364,7 @@ AC_SUBST(BASECFLAGS) AC_SUBST(CFLAGS_NODIST) +AC_SUBST(LDFLAGS_NODIST) # The -arch flags for universal builds on OSX UNIVERSAL_ARCH_FLAGS= diff -r 40ce5f4b8835 pyconfig.h.in --- a/pyconfig.h.in Mon Nov 02 09:17:08 2015 -0800 +++ b/pyconfig.h.in Tue Nov 03 10:22:35 2015 +0200 @@ -1239,6 +1239,9 @@ externally defined: 0 */ #undef Py_HASH_ALGORITHM +/* Define if you want to build an MPX instrumented interpreter. */ +#undef Py_INTEL_MPX + /* assume C89 semantics that RETSIGTYPE is always void */ #undef RETSIGTYPE