mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-02 23:18:44 +00:00
Add error checks to Python objectifier (#281)
PYOBJ.COM was failing when statically analyzing _pyio.py in MODE=dbg because co_consts contained a big number, which dirtied the interpreter exception state. We now do comprehensive error checking w/ Python API. The -DSTACK_FRAME_UNLIMITED CPPFLAG has been removed from DES since its self test function has been fixed to use heap memory rather than making aggressive use of the stack. This change also fixes a regression with function tracing (the --ftrace flag a.k.a. ftrace_install() a.k.a. cosmo.ftrace) in ASAN build modes. Lastly, the _tracemalloc module should now always be available for use in MODE=dbg.
This commit is contained in:
parent
57f0eed382
commit
9cb54218ab
10 changed files with 323 additions and 422 deletions
|
@ -48,7 +48,8 @@ static int g_lastsymbol;
|
|||
static uint64_t laststamp;
|
||||
static struct SymbolTable *g_symbols;
|
||||
|
||||
forceinline int GetNestingLevelImpl(struct StackFrame *frame) {
|
||||
static privileged noinstrument noasan int GetNestingLevelImpl(
|
||||
struct StackFrame *frame) {
|
||||
int nesting = -2;
|
||||
while (frame) {
|
||||
++nesting;
|
||||
|
@ -57,7 +58,8 @@ forceinline int GetNestingLevelImpl(struct StackFrame *frame) {
|
|||
return MAX(0, nesting);
|
||||
}
|
||||
|
||||
forceinline int GetNestingLevel(struct StackFrame *frame) {
|
||||
static privileged noinstrument noasan int GetNestingLevel(
|
||||
struct StackFrame *frame) {
|
||||
int nesting;
|
||||
nesting = GetNestingLevelImpl(frame);
|
||||
if (nesting < g_skew) g_skew = nesting;
|
||||
|
|
2
third_party/mbedtls/aes.c
vendored
2
third_party/mbedtls/aes.c
vendored
|
@ -368,7 +368,7 @@ static uint32_t RCON[10];
|
|||
|
||||
static int aes_init_done;
|
||||
|
||||
static void aes_gen_tables( void )
|
||||
static noinline void aes_gen_tables( void )
|
||||
{
|
||||
int i, x, y, z;
|
||||
int pow[256];
|
||||
|
|
50
third_party/mbedtls/des.c
vendored
50
third_party/mbedtls/des.c
vendored
|
@ -15,6 +15,8 @@
|
|||
│ See the License for the specific language governing permissions and │
|
||||
│ limitations under the License. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "third_party/mbedtls/common.h"
|
||||
|
@ -835,16 +837,16 @@ static const unsigned char des3_test_cbc_enc[3][8] =
|
|||
int mbedtls_des_self_test( int verbose )
|
||||
{
|
||||
int i, j, u, v, ret = 0;
|
||||
mbedtls_des_context ctx;
|
||||
mbedtls_des3_context ctx3;
|
||||
mbedtls_des_context *ctx = gc(malloc(sizeof(mbedtls_des_context)));
|
||||
mbedtls_des3_context *ctx3 = gc(malloc(sizeof(mbedtls_des3_context)));
|
||||
unsigned char buf[8];
|
||||
#if defined(MBEDTLS_CIPHER_MODE_CBC)
|
||||
unsigned char prv[8];
|
||||
unsigned char iv[8];
|
||||
#endif
|
||||
|
||||
mbedtls_des_init( &ctx );
|
||||
mbedtls_des3_init( &ctx3 );
|
||||
mbedtls_des_init( ctx );
|
||||
mbedtls_des3_init( ctx3 );
|
||||
/*
|
||||
* ECB mode
|
||||
*/
|
||||
|
@ -863,27 +865,27 @@ int mbedtls_des_self_test( int verbose )
|
|||
switch( i )
|
||||
{
|
||||
case 0:
|
||||
mbedtls_des_setkey_dec( &ctx, des3_test_keys );
|
||||
mbedtls_des_setkey_dec( ctx, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
mbedtls_des_setkey_enc( &ctx, des3_test_keys );
|
||||
mbedtls_des_setkey_enc( ctx, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
|
||||
mbedtls_des3_set2key_dec( ctx3, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 3:
|
||||
mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
|
||||
mbedtls_des3_set2key_enc( ctx3, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 4:
|
||||
mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
|
||||
mbedtls_des3_set3key_dec( ctx3, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 5:
|
||||
mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
|
||||
mbedtls_des3_set3key_enc( ctx3, des3_test_keys );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -893,9 +895,9 @@ int mbedtls_des_self_test( int verbose )
|
|||
for( j = 0; j < 100; j++ )
|
||||
{
|
||||
if( u == 0 )
|
||||
mbedtls_des_crypt_ecb( &ctx, buf, buf );
|
||||
mbedtls_des_crypt_ecb( ctx, buf, buf );
|
||||
else
|
||||
mbedtls_des3_crypt_ecb( &ctx3, buf, buf );
|
||||
mbedtls_des3_crypt_ecb( ctx3, buf, buf );
|
||||
}
|
||||
|
||||
if( ( v == MBEDTLS_DES_DECRYPT &&
|
||||
|
@ -938,27 +940,27 @@ int mbedtls_des_self_test( int verbose )
|
|||
switch( i )
|
||||
{
|
||||
case 0:
|
||||
mbedtls_des_setkey_dec( &ctx, des3_test_keys );
|
||||
mbedtls_des_setkey_dec( ctx, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
mbedtls_des_setkey_enc( &ctx, des3_test_keys );
|
||||
mbedtls_des_setkey_enc( ctx, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
mbedtls_des3_set2key_dec( &ctx3, des3_test_keys );
|
||||
mbedtls_des3_set2key_dec( ctx3, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 3:
|
||||
mbedtls_des3_set2key_enc( &ctx3, des3_test_keys );
|
||||
mbedtls_des3_set2key_enc( ctx3, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 4:
|
||||
mbedtls_des3_set3key_dec( &ctx3, des3_test_keys );
|
||||
mbedtls_des3_set3key_dec( ctx3, des3_test_keys );
|
||||
break;
|
||||
|
||||
case 5:
|
||||
mbedtls_des3_set3key_enc( &ctx3, des3_test_keys );
|
||||
mbedtls_des3_set3key_enc( ctx3, des3_test_keys );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -970,9 +972,9 @@ int mbedtls_des_self_test( int verbose )
|
|||
for( j = 0; j < 100; j++ )
|
||||
{
|
||||
if( u == 0 )
|
||||
mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
|
||||
mbedtls_des_crypt_cbc( ctx, v, 8, iv, buf, buf );
|
||||
else
|
||||
mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
|
||||
mbedtls_des3_crypt_cbc( ctx3, v, 8, iv, buf, buf );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -982,9 +984,9 @@ int mbedtls_des_self_test( int verbose )
|
|||
unsigned char tmp[8];
|
||||
|
||||
if( u == 0 )
|
||||
mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
|
||||
mbedtls_des_crypt_cbc( ctx, v, 8, iv, buf, buf );
|
||||
else
|
||||
mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
|
||||
mbedtls_des3_crypt_cbc( ctx3, v, 8, iv, buf, buf );
|
||||
|
||||
memcpy( tmp, prv, 8 );
|
||||
memcpy( prv, buf, 8 );
|
||||
|
@ -1015,8 +1017,8 @@ int mbedtls_des_self_test( int verbose )
|
|||
mbedtls_printf( "\n" );
|
||||
|
||||
exit:
|
||||
mbedtls_des_free( &ctx );
|
||||
mbedtls_des3_free( &ctx3 );
|
||||
mbedtls_des_free( ctx );
|
||||
mbedtls_des3_free( ctx3 );
|
||||
|
||||
return( ret );
|
||||
}
|
||||
|
|
4
third_party/mbedtls/mbedtls.mk
vendored
4
third_party/mbedtls/mbedtls.mk
vendored
|
@ -58,10 +58,6 @@ o/$(MODE)/third_party/mbedtls/everest.o: \
|
|||
OVERRIDE_CFLAGS += \
|
||||
-O3
|
||||
|
||||
o/$(MODE)/third_party/mbedtls/des.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-DSTACK_FRAME_UNLIMITED
|
||||
|
||||
o/$(MODE)/third_party/mbedtls/bigmul4.o \
|
||||
o/$(MODE)/third_party/mbedtls/bigmul6.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
|
|
313
third_party/python/Modules/_tracemalloc.c
vendored
313
third_party/python/Modules/_tracemalloc.c
vendored
File diff suppressed because it is too large
Load diff
2
third_party/python/Objects/obmalloc.c
vendored
2
third_party/python/Objects/obmalloc.c
vendored
|
@ -85,7 +85,7 @@ static void* _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize);
|
|||
static void _PyObject_Free(void *ctx, void *p);
|
||||
static void* _PyObject_Realloc(void *ctx, void *ptr, size_t size);
|
||||
|
||||
#else
|
||||
#else
|
||||
/* in MODE=asan, no pymalloc, so use macro */
|
||||
#define _PyObject_Malloc(ctx, size) _PyMem_RawMalloc((ctx), (size))
|
||||
#define _PyObject_Calloc(ctx, nelem, elsize) _PyMem_RawCalloc((ctx), (nelem), (elsize))
|
||||
|
|
13
third_party/python/Objects/tupleobject.c
vendored
13
third_party/python/Objects/tupleobject.c
vendored
|
@ -159,18 +159,23 @@ PyTuple_Size(PyObject *op)
|
|||
return Py_SIZE(op);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns object at position 𝑖 in the tuple pointed to by 𝑝.
|
||||
*
|
||||
* @return borrowed reference, or NULL if 𝑖 is out of bounds
|
||||
*/
|
||||
PyObject *
|
||||
PyTuple_GetItem(PyObject *op, Py_ssize_t i)
|
||||
PyTuple_GetItem(PyObject *p, Py_ssize_t i)
|
||||
{
|
||||
if (!PyTuple_Check(op)) {
|
||||
if (!PyTuple_Check(p)) {
|
||||
PyErr_BadInternalCall();
|
||||
return NULL;
|
||||
}
|
||||
if (i < 0 || i >= Py_SIZE(op)) {
|
||||
if (i < 0 || i >= Py_SIZE(p)) {
|
||||
PyErr_SetString(PyExc_IndexError, "tuple index out of range");
|
||||
return NULL;
|
||||
}
|
||||
return ((PyTupleObject *)op) -> ob_item[i];
|
||||
return ((PyTupleObject *)p) -> ob_item[i];
|
||||
}
|
||||
|
||||
int
|
||||
|
|
119
third_party/python/Objects/unicodeobject.c
vendored
119
third_party/python/Objects/unicodeobject.c
vendored
|
@ -55,6 +55,38 @@ PYTHON_PROVIDE("_string.formatter_parser");
|
|||
|
||||
#include "third_party/python/Objects/stringlib/eq.inc"
|
||||
|
||||
/**
|
||||
* @fileoverview Unicode Objects
|
||||
*
|
||||
* Since the implementation of PEP 393 in Python 3.3, Unicode objects
|
||||
* internally use a variety of representations, in order to allow
|
||||
* handling the complete range of Unicode characters while staying
|
||||
* memory efficient. There are special cases for strings where all code
|
||||
* points are below 128, 256, or 65536; otherwise, code points must be
|
||||
* below 1114112 (which is the full Unicode range).
|
||||
*
|
||||
* Py_UNICODE* and UTF-8 representations are created on demand and
|
||||
* cached in the Unicode object. The Py_UNICODE* representation is
|
||||
* deprecated and inefficient.
|
||||
*
|
||||
* Due to the transition between the old APIs and the new APIs, Unicode
|
||||
* objects can internally be in two states depending on how they were
|
||||
* created:
|
||||
*
|
||||
* * “canonical” Unicode objects are all objects created by a
|
||||
* non-deprecated Unicode API. They use the most efficient
|
||||
* representation allowed by the implementation.
|
||||
*
|
||||
* * “legacy” Unicode objects have been created through one of the
|
||||
* deprecated APIs (typically PyUnicode_FromUnicode()) and only bear
|
||||
* the Py_UNICODE* representation; you will have to call
|
||||
* PyUnicode_READY() on them before calling any other API.
|
||||
*
|
||||
* The “legacy” Unicode object will be removed in Python 3.12 with
|
||||
* deprecated APIs. All Unicode objects will be “canonical” since then.
|
||||
* See PEP 623 for more information.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Unicode implementation based on original code by Fredrik Lundh,
|
||||
|
@ -2989,6 +3021,71 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return value: New reference.
|
||||
*
|
||||
* Take a C printf()-style format string and a variable number of
|
||||
* arguments, calculate the size of the resulting Python Unicode string
|
||||
* and return a string with the values formatted into it. The variable
|
||||
* arguments must be C types and must correspond exactly to the format
|
||||
* characters in the format ASCII-encoded string. The following format
|
||||
* characters are allowed:
|
||||
*
|
||||
* Format Type Comment
|
||||
* %% n/a The literal % character.
|
||||
* %c int A single character, represented as a C int.
|
||||
* %d int Equivalent to printf("%d")
|
||||
* %u unsigned int Equivalent to printf("%u")
|
||||
* %ld long Equivalent to printf("%ld")
|
||||
* %li long Equivalent to printf("%li")
|
||||
* %lu unsigned long Equivalent to printf("%lu")
|
||||
* %lld long long Equivalent to printf("%lld")
|
||||
* %lli long long Equivalent to printf("%lli")
|
||||
* %llu unsigned long long Equivalent to printf("%llu")
|
||||
* %zd Py_ssize_t Equivalent to printf("%zd")
|
||||
* %zi Py_ssize_t Equivalent to printf("%zi")
|
||||
* %zu size_t Equivalent to printf("%zu")
|
||||
* %i int Equivalent to printf("%i")
|
||||
* %x int Equivalent to printf("%x")
|
||||
* %s const char* A null-terminated C character array.
|
||||
* The hex representation of a C pointer.
|
||||
* Mostly equivalent to printf("%p")
|
||||
* %p const void* except that it is guaranteed to start
|
||||
* with the literal 0x regardless of what
|
||||
* the platform’s printf yields.
|
||||
* %A PyObject* The result of calling ascii().
|
||||
* %U PyObject* A Unicode object.
|
||||
* A Unicode object (which may be NULL)
|
||||
* %V PyObject*, const and a null-terminated C character array
|
||||
* char* as a second parameter (which will be
|
||||
* used, if the first parameter is NULL).
|
||||
* %S PyObject* The result of calling PyObject_Str().
|
||||
* %R PyObject* The result of calling PyObject_Repr().
|
||||
*
|
||||
* An unrecognized format character causes all the rest of the format
|
||||
* string to be copied as-is to the result string, and any extra
|
||||
* arguments discarded.
|
||||
*
|
||||
* Note
|
||||
*
|
||||
* The width formatter unit is number of characters rather than bytes.
|
||||
* The precision formatter unit is number of bytes for "%s" and "%V" (if
|
||||
* the PyObject* argument is NULL), and a number of characters for "%A",
|
||||
* "%U", "%S", "%R" and "%V" (if the PyObject* argument is not NULL).
|
||||
*
|
||||
* 1(1,2,3,4,5,6,7,8,9,10,11,12,13)
|
||||
*
|
||||
* For integer specifiers (d, u, ld, li, lu, lld, lli, llu,
|
||||
* zd, zi, zu, i, x): the 0-conversion flag has effect even
|
||||
* when a precision is given.
|
||||
*
|
||||
* Changed in version 3.2: Support for "%lld" and "%llu" added.
|
||||
*
|
||||
* Changed in version 3.3: Support for "%li", "%lli" and "%zi" added.
|
||||
*
|
||||
* Changed in version 3.4: Support width and precision formatter for
|
||||
* "%s", "%A", "%U", "%V", "%S", "%R" added.
|
||||
*/
|
||||
PyObject *
|
||||
PyUnicode_FromFormat(const char *format, ...)
|
||||
{
|
||||
|
@ -4063,7 +4160,20 @@ PyUnicode_FSDecoder(PyObject* arg, void* addr)
|
|||
return Py_CLEANUP_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns pointer to the UTF-8 encoding of the Unicode object, and
|
||||
* store the size of the encoded representation (in bytes) in size. The
|
||||
* size argument can be NULL; in this case no size will be stored. The
|
||||
* returned buffer always has an extra null byte appended (not included
|
||||
* in size), regardless of whether there are any other null code points.
|
||||
*
|
||||
* In the case of an error, NULL is returned with an exception set and
|
||||
* no size is stored.
|
||||
*
|
||||
* This caches the UTF-8 representation of the string in the Unicode
|
||||
* object, and subsequent calls will return a pointer to the same
|
||||
* buffer. The caller is not responsible for deallocating the buffer.
|
||||
*/
|
||||
char *
|
||||
PyUnicode_AsUTF8AndSize(PyObject *unicode, Py_ssize_t *psize)
|
||||
{
|
||||
|
@ -5294,6 +5404,13 @@ PyUnicode_EncodeUTF8(const Py_UNICODE *s,
|
|||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes Unicode object using UTF-8 and return the result as Python
|
||||
* bytes object. Error handling is “strict”. Return NULL if an exception
|
||||
* was raised by the codec.
|
||||
*
|
||||
* @return new reference
|
||||
*/
|
||||
PyObject *
|
||||
PyUnicode_AsUTF8String(PyObject *unicode)
|
||||
{
|
||||
|
|
224
third_party/python/pyobj.c
vendored
224
third_party/python/pyobj.c
vendored
|
@ -24,6 +24,7 @@
|
|||
#include "libc/elf/def.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
|
@ -49,6 +50,7 @@
|
|||
#include "third_party/python/Include/objimpl.h"
|
||||
#include "third_party/python/Include/opcode.h"
|
||||
#include "third_party/python/Include/pydebug.h"
|
||||
#include "third_party/python/Include/pyerrors.h"
|
||||
#include "third_party/python/Include/pylifecycle.h"
|
||||
#include "third_party/python/Include/pymacro.h"
|
||||
#include "third_party/python/Include/pythonrun.h"
|
||||
|
@ -286,7 +288,7 @@ GetOpts(int argc, char *argv[])
|
|||
break;
|
||||
case 'Y':
|
||||
yoinks.p = realloc(yoinks.p, ++yoinks.n * sizeof(*yoinks.p));
|
||||
yoinks.p[yoinks.n - 1] = strdup(optarg);
|
||||
yoinks.p[yoinks.n - 1] = xstrdup(optarg);
|
||||
break;
|
||||
case 'n':
|
||||
exit(0);
|
||||
|
@ -333,7 +335,7 @@ GetZipFile(void)
|
|||
if (*path_prefix) {
|
||||
zipfile = gc(xjoinpaths(path_prefix, zipfile));
|
||||
}
|
||||
return strdup(zipfile);
|
||||
return xstrdup(zipfile);
|
||||
}
|
||||
|
||||
static char *
|
||||
|
@ -390,11 +392,11 @@ GetParent2(void)
|
|||
}
|
||||
|
||||
static char *
|
||||
GetModSibling(const char *rel, int chomp)
|
||||
GetModSibling(const char *rel, long chomp)
|
||||
{
|
||||
char *p, *mod, *sib;
|
||||
mod = Dotify(xstripexts(StripComponents(pyfile, strip_components)));
|
||||
while (chomp--) {
|
||||
while (chomp-- > 0) {
|
||||
if ((p = strrchr(mod, '.'))) {
|
||||
*p = 0;
|
||||
} else {
|
||||
|
@ -405,10 +407,10 @@ GetModSibling(const char *rel, int chomp)
|
|||
if (*mod) {
|
||||
sib = xstrcat(mod, '.', rel);
|
||||
} else {
|
||||
sib = strdup(rel);
|
||||
sib = xstrdup(rel);
|
||||
}
|
||||
} else {
|
||||
sib = strdup(mod);
|
||||
sib = xstrdup(mod);
|
||||
}
|
||||
free(mod);
|
||||
return sib;
|
||||
|
@ -470,15 +472,17 @@ Provide(const char *modname, const char *global)
|
|||
free(imp);
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
Analyze(const char *modname, PyObject *code, struct Interner *globals)
|
||||
{
|
||||
int rc;
|
||||
bool istry;
|
||||
unsigned a;
|
||||
size_t i, j, n;
|
||||
char *p, *mod, *imp;
|
||||
int x, y, op, arg, rel;
|
||||
PyObject *co_code, *co_names, *co_consts, *name, *cnst, *iter, *item;
|
||||
PyObject *co_code, *co_names, *co_consts, *name, *iter, *item;
|
||||
rc = 0;
|
||||
mod = 0;
|
||||
istry = rel = 0;
|
||||
assert(PyCode_Check(code));
|
||||
|
@ -487,7 +491,7 @@ Analyze(const char *modname, PyObject *code, struct Interner *globals)
|
|||
co_consts = ((PyCodeObject *)code)->co_consts;
|
||||
n = PyBytes_GET_SIZE(co_code);
|
||||
p = PyBytes_AS_STRING(co_code);
|
||||
for (a = i = 0; i + 2 <= n; i += 2) {
|
||||
for (a = i = 0; !rc && i + 2 <= n; i += 2) {
|
||||
x = p[i + 0] & 255;
|
||||
y = p[i + 1] & 255;
|
||||
a = a << 8 | y;
|
||||
|
@ -501,60 +505,80 @@ Analyze(const char *modname, PyObject *code, struct Interner *globals)
|
|||
istry = false;
|
||||
break;
|
||||
case LOAD_CONST:
|
||||
if (PyLong_Check((cnst = PyTuple_GetItem(co_consts, arg)))) {
|
||||
rel = PyLong_AsLong(cnst);
|
||||
if ((item = PyTuple_GetItem(co_consts, arg))) {
|
||||
if (PyLong_Check(item)) {
|
||||
if ((rel = PyLong_AsLong(item)) == -1) {
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
break;
|
||||
case IMPORT_NAME:
|
||||
free(mod);
|
||||
name = PyUnicode_AsUTF8String(PyTuple_GetItem(co_names, arg));
|
||||
if (*PyBytes_AS_STRING(name)) {
|
||||
if (rel) {
|
||||
mod = GetModSibling(PyBytes_AS_STRING(name), rel);
|
||||
} else {
|
||||
mod = strdup(PyBytes_AS_STRING(name));
|
||||
}
|
||||
if (!IsIgnoredModule(mod)) {
|
||||
if (istry) {
|
||||
Yoink(mod);
|
||||
if (((item = PyTuple_GetItem(co_names, arg)) &&
|
||||
(name = PyUnicode_AsUTF8String(item)))) {
|
||||
free(mod);
|
||||
if (*PyBytes_AS_STRING(name)) {
|
||||
if (rel) {
|
||||
mod = GetModSibling(PyBytes_AS_STRING(name), rel);
|
||||
} else {
|
||||
Forcepull(mod);
|
||||
mod = xstrdup(PyBytes_AS_STRING(name));
|
||||
}
|
||||
if (!IsIgnoredModule(mod)) {
|
||||
if (istry) {
|
||||
Yoink(mod);
|
||||
} else {
|
||||
Forcepull(mod);
|
||||
}
|
||||
}
|
||||
} else if (IsDot()) {
|
||||
if (rel) {
|
||||
mod = GetModSibling(0, rel);
|
||||
} else {
|
||||
mod = GetParent();
|
||||
}
|
||||
}
|
||||
} else if (IsDot()) {
|
||||
if (rel) {
|
||||
mod = GetModSibling(0, rel);
|
||||
} else {
|
||||
mod = GetParent();
|
||||
mod = 0;
|
||||
}
|
||||
Py_DECREF(name);
|
||||
} else {
|
||||
mod = 0;
|
||||
rc = -1;
|
||||
}
|
||||
Py_DECREF(name);
|
||||
break;
|
||||
case IMPORT_FROM:
|
||||
name = PyUnicode_AsUTF8String(PyTuple_GetItem(co_names, arg));
|
||||
if (mod) {
|
||||
imp = xstrcat(mod, '.', PyBytes_AS_STRING(name));
|
||||
} else {
|
||||
imp = strdup(PyBytes_AS_STRING(name));
|
||||
}
|
||||
if (!IsIgnoredModule(imp)) {
|
||||
if (istry) {
|
||||
Yoink(imp);
|
||||
if (((item = PyTuple_GetItem(co_names, arg)) &&
|
||||
(name = PyUnicode_AsUTF8String(item)))) {
|
||||
if (mod) {
|
||||
imp = xstrcat(mod, '.', PyBytes_AS_STRING(name));
|
||||
} else {
|
||||
Forcepull(imp);
|
||||
imp = xstrdup(PyBytes_AS_STRING(name));
|
||||
}
|
||||
if (!IsIgnoredModule(imp)) {
|
||||
if (istry) {
|
||||
Yoink(imp);
|
||||
} else {
|
||||
Forcepull(imp);
|
||||
}
|
||||
}
|
||||
Py_DECREF(name);
|
||||
free(imp);
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
Py_DECREF(name);
|
||||
free(imp);
|
||||
break;
|
||||
case STORE_NAME:
|
||||
case STORE_GLOBAL:
|
||||
if (globals) {
|
||||
name = PyUnicode_AsUTF8String(PyTuple_GetItem(co_names, arg));
|
||||
intern(globals, PyBytes_AS_STRING(name));
|
||||
Py_DECREF(name);
|
||||
if (((item = PyTuple_GetItem(co_names, arg)) &&
|
||||
(name = PyUnicode_AsUTF8String(item)))) {
|
||||
intern(globals, PyBytes_AS_STRING(name));
|
||||
Py_DECREF(name);
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -563,33 +587,46 @@ Analyze(const char *modname, PyObject *code, struct Interner *globals)
|
|||
a = 0;
|
||||
}
|
||||
free(mod);
|
||||
iter = PyObject_GetIter(co_consts);
|
||||
while ((item = PyIter_Next(iter))) {
|
||||
if (PyCode_Check(item)) {
|
||||
Analyze(modname, item, 0);
|
||||
if (!rc) {
|
||||
if ((iter = PyObject_GetIter(co_consts))) {
|
||||
while (!rc && (item = PyIter_Next(iter))) {
|
||||
if (PyCode_Check(item)) {
|
||||
rc |= Analyze(modname, item, 0);
|
||||
}
|
||||
Py_DECREF(item);
|
||||
}
|
||||
Py_DECREF(iter);
|
||||
if (!rc && PyErr_Occurred()) {
|
||||
rc = -1;
|
||||
}
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
Py_DECREF(item);
|
||||
}
|
||||
Py_DECREF(iter);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
AnalyzeModule(const char *modname)
|
||||
{
|
||||
int rc;
|
||||
char *p;
|
||||
struct Interner *globals;
|
||||
globals = newinterner();
|
||||
intern(globals, "__file__");
|
||||
Analyze(modname, code, globals);
|
||||
for (p = globals->p; *p; p += strlen(p) + 1) {
|
||||
Provide(modname, p);
|
||||
if (!(rc = Analyze(modname, code, globals))) {
|
||||
for (p = globals->p; *p; p += strlen(p) + 1) {
|
||||
Provide(modname, p);
|
||||
}
|
||||
}
|
||||
freeinterner(globals);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
Objectify(void)
|
||||
{
|
||||
int rc;
|
||||
bool ispkg;
|
||||
size_t i, n;
|
||||
char header[12];
|
||||
|
@ -603,8 +640,7 @@ Objectify(void)
|
|||
if ((!(code = Py_CompileStringExFlags(pydata, synfile, Py_file_input,
|
||||
NULL, optimize)) ||
|
||||
!(marsh = PyMarshal_WriteObjectToString(code, Py_MARSHAL_VERSION)))) {
|
||||
PyErr_Print();
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
assert(PyBytes_CheckExact(marsh));
|
||||
mardata = PyBytes_AS_STRING(marsh);
|
||||
|
@ -637,56 +673,62 @@ Objectify(void)
|
|||
elfwriter_align(elf, 1, 0);
|
||||
elfwriter_startsection(elf, ".yoink", SHT_PROGBITS,
|
||||
SHF_ALLOC | SHF_EXECINSTR);
|
||||
AnalyzeModule(modname);
|
||||
if (*path_prefix && !IsDot()) {
|
||||
elfwriter_yoink(elf, gc(xstrcat(path_prefix, "/")), STB_GLOBAL);
|
||||
}
|
||||
if (strchr(modname, '.')) {
|
||||
Forcepull(gc(GetParent2()));
|
||||
}
|
||||
for (i = 0; i < yoinks.n; ++i) {
|
||||
elfwriter_yoink(elf, yoinks.p[i], STB_GLOBAL);
|
||||
}
|
||||
if (insertrunner) {
|
||||
elfwriter_yoink(elf, "RunPythonModule", STB_GLOBAL);
|
||||
} else if (insertlauncher) {
|
||||
elfwriter_yoink(elf, "LaunchPythonModule", STB_GLOBAL);
|
||||
}
|
||||
if (isunittest) {
|
||||
elfwriter_yoink(elf, "testlib_quota_handlers", STB_GLOBAL);
|
||||
}
|
||||
elfwriter_finishsection(elf);
|
||||
if (insertrunner || insertlauncher) {
|
||||
n = strlen(modname) + 1;
|
||||
elfwriter_align(elf, 1, 0);
|
||||
elfwriter_startsection(elf, ".rodata.str1.1", SHT_PROGBITS,
|
||||
SHF_ALLOC | SHF_MERGE | SHF_STRINGS);
|
||||
memcpy(elfwriter_reserve(elf, n), modname, n);
|
||||
elfwriter_appendsym(elf, "kLaunchPythonModuleName",
|
||||
ELF64_ST_INFO(STB_GLOBAL, STT_OBJECT),
|
||||
STV_DEFAULT, 0, n);
|
||||
elfwriter_commit(elf, n);
|
||||
if (!(rc = AnalyzeModule(modname))) {
|
||||
if (*path_prefix && !IsDot()) {
|
||||
elfwriter_yoink(elf, gc(xstrcat(path_prefix, "/")), STB_GLOBAL);
|
||||
}
|
||||
if (strchr(modname, '.')) {
|
||||
Forcepull(gc(GetParent2()));
|
||||
}
|
||||
for (i = 0; i < yoinks.n; ++i) {
|
||||
elfwriter_yoink(elf, yoinks.p[i], STB_GLOBAL);
|
||||
}
|
||||
if (insertrunner) {
|
||||
elfwriter_yoink(elf, "RunPythonModule", STB_GLOBAL);
|
||||
} else if (insertlauncher) {
|
||||
elfwriter_yoink(elf, "LaunchPythonModule", STB_GLOBAL);
|
||||
}
|
||||
if (isunittest) {
|
||||
elfwriter_yoink(elf, "testlib_quota_handlers", STB_GLOBAL);
|
||||
}
|
||||
elfwriter_finishsection(elf);
|
||||
if (insertrunner || insertlauncher) {
|
||||
n = strlen(modname) + 1;
|
||||
elfwriter_align(elf, 1, 0);
|
||||
elfwriter_startsection(elf, ".rodata.str1.1", SHT_PROGBITS,
|
||||
SHF_ALLOC | SHF_MERGE | SHF_STRINGS);
|
||||
memcpy(elfwriter_reserve(elf, n), modname, n);
|
||||
elfwriter_appendsym(elf, "kLaunchPythonModuleName",
|
||||
ELF64_ST_INFO(STB_GLOBAL, STT_OBJECT),
|
||||
STV_DEFAULT, 0, n);
|
||||
elfwriter_commit(elf, n);
|
||||
elfwriter_finishsection(elf);
|
||||
}
|
||||
}
|
||||
elfwriter_close(elf);
|
||||
freeinterner(forcepulls);
|
||||
freeinterner(yoinked);
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int rc;
|
||||
int ec;
|
||||
GetOpts(argc, argv);
|
||||
Py_NoUserSiteDirectory++;
|
||||
Py_NoSiteFlag++;
|
||||
Py_IgnoreEnvironmentFlag++;
|
||||
Py_FrozenFlag++;
|
||||
_Py_InitializeEx_Private(1, 0);
|
||||
rc = Objectify();
|
||||
if (!Objectify()) {
|
||||
ec = 0;
|
||||
} else {
|
||||
PyErr_Print();
|
||||
ec = 1;
|
||||
}
|
||||
Py_XDECREF(marsh);
|
||||
Py_XDECREF(code);
|
||||
Py_Finalize();
|
||||
return rc;
|
||||
if (Py_FinalizeEx() < 0 && !ec) ec = 120;
|
||||
return ec;
|
||||
}
|
||||
|
|
|
@ -464,7 +464,7 @@
|
|||
((not (eq 0 (logand 8 arg)))
|
||||
(cosmo--assembly (setq arg (logand (lognot 8)))
|
||||
"V=1 OVERRIDE_COPTS='-fverbose-asm -fsanitize=address'"))
|
||||
(t (cosmo--assembly arg "V=1 OVERRIDE_COPTS='' CPPFLAGS='-DSTACK_FRAME_UNLIMITED'"))))
|
||||
(t (cosmo--assembly arg "V=1 OVERRIDE_COPTS='' CPPFLAGS=''"))))
|
||||
|
||||
(defun cosmo-assembly-native (arg)
|
||||
(interactive "P")
|
||||
|
@ -472,11 +472,11 @@
|
|||
(cond ((not (eq 0 (logand 8 arg)))
|
||||
(cosmo--assembly
|
||||
(setq arg (logand (lognot 8)))
|
||||
"V=1 CCFLAGS=--verbose COPTS='$(IEEE_MATH)' CPPFLAGS='-DSTACK_FRAME_UNLIMITED' TARGET_ARCH='-march=k8'")) ;; znver2
|
||||
"V=1 CCFLAGS=--verbose COPTS='$(IEEE_MATH)' CPPFLAGS='' TARGET_ARCH='-march=k8'")) ;; znver2
|
||||
(t
|
||||
(cosmo--assembly
|
||||
arg
|
||||
"V=1 CCFLAGS=--verbose COPTS='$(MATHEMATICAL) -O3' CPPFLAGS='-DSTACK_FRAME_UNLIMITED' TARGET_ARCH='-march=k8'")))) ;; znver2
|
||||
"V=1 CCFLAGS=--verbose COPTS='$(MATHEMATICAL) -O3' CPPFLAGS='' TARGET_ARCH='-march=k8'")))) ;; znver2
|
||||
|
||||
(defun cosmo-assembly-icelake (arg)
|
||||
(interactive "P")
|
||||
|
@ -484,15 +484,15 @@
|
|||
(cond ((not (eq 0 (logand 8 arg)))
|
||||
(cosmo--assembly
|
||||
(setq arg (logand (lognot 8)))
|
||||
"V=1 CCFLAGS=--verbose COPTS='$(MATHEMATICAL) -O3' CPPFLAGS='-DSTACK_FRAME_UNLIMITED' TARGET_ARCH='-march=icelake-client'"))
|
||||
"V=1 CCFLAGS=--verbose COPTS='$(MATHEMATICAL) -O3' CPPFLAGS='' TARGET_ARCH='-march=icelake-client'"))
|
||||
(t
|
||||
(cosmo--assembly
|
||||
arg
|
||||
"V=1 CCFLAGS=--verbose COPTS='$(MATHEMATICAL) -O3' CPPFLAGS='-DSTACK_FRAME_UNLIMITED' TARGET_ARCH='-march=icelake-client'"))))
|
||||
"V=1 CCFLAGS=--verbose COPTS='$(MATHEMATICAL) -O3' CPPFLAGS='' TARGET_ARCH='-march=icelake-client'"))))
|
||||
|
||||
(defun cosmo-assembly-balanced (arg)
|
||||
(interactive "P")
|
||||
(cosmo--assembly (or arg 5) "CFLAGS='-O2 -ftrapv' CPPFLAGS='-DSTACK_FRAME_UNLIMITED'"))
|
||||
(cosmo--assembly (or arg 5) "CFLAGS='-O2 -ftrapv' CPPFLAGS=''"))
|
||||
|
||||
(defun cosmo-mca (arg)
|
||||
(interactive "P")
|
||||
|
|
Loading…
Add table
Reference in a new issue