Skip to content

Commit b7962b3

Browse files
stefanordanglin44
andcommitted
GH-139914: On HPPA, the stack grows up
Adapted from a patch for Python 3.14 submitted to the Debian BTS by John https://bugs.debian.org/1105111#20 Co-authored-by: John David Anglin <[email protected]>
1 parent bb85af3 commit b7962b3

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

Include/internal/pycore_ceval.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,11 @@ extern void _PyEval_DeactivateOpCache(void);
217217
static inline int _Py_MakeRecCheck(PyThreadState *tstate) {
218218
uintptr_t here_addr = _Py_get_machine_stack_pointer();
219219
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
220+
#ifdef __hppa__
221+
return here_addr > _tstate->c_stack_soft_limit;
222+
#else
220223
return here_addr < _tstate->c_stack_soft_limit;
224+
#endif
221225
}
222226

223227
// Export for '_json' shared extension, used via _Py_EnterRecursiveCall()
@@ -249,7 +253,11 @@ static inline int _Py_ReachedRecursionLimit(PyThreadState *tstate) {
249253
uintptr_t here_addr = _Py_get_machine_stack_pointer();
250254
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
251255
assert(_tstate->c_stack_hard_limit != 0);
256+
#ifdef __hppa__
257+
return here_addr >= _tstate->c_stack_soft_limit;
258+
#else
252259
return here_addr <= _tstate->c_stack_soft_limit;
260+
#endif
253261
}
254262

255263
static inline void _Py_LeaveRecursiveCall(void) {

Python/ceval.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,21 +347,33 @@ _Py_ReachedRecursionLimitWithMargin(PyThreadState *tstate, int margin_count)
347347
{
348348
uintptr_t here_addr = _Py_get_machine_stack_pointer();
349349
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
350+
#ifdef __hppa__
351+
if (here_addr <= _tstate->c_stack_soft_limit - margin_count * _PyOS_STACK_MARGIN_BYTES) {
352+
#else
350353
if (here_addr > _tstate->c_stack_soft_limit + margin_count * _PyOS_STACK_MARGIN_BYTES) {
354+
#endif
351355
return 0;
352356
}
353357
if (_tstate->c_stack_hard_limit == 0) {
354358
_Py_InitializeRecursionLimits(tstate);
355359
}
360+
#ifdef __hppa__
361+
return here_addr > _tstate->c_stack_soft_limit - margin_count * _PyOS_STACK_MARGIN_BYTES;
362+
#else
356363
return here_addr <= _tstate->c_stack_soft_limit + margin_count * _PyOS_STACK_MARGIN_BYTES;
364+
#endif
357365
}
358366

359367
void
360368
_Py_EnterRecursiveCallUnchecked(PyThreadState *tstate)
361369
{
362370
uintptr_t here_addr = _Py_get_machine_stack_pointer();
363371
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
372+
#ifdef __hppa__
373+
if (here_addr > _tstate->c_stack_hard_limit) {
374+
#else
364375
if (here_addr < _tstate->c_stack_hard_limit) {
376+
#endif
365377
Py_FatalError("Unchecked stack overflow.");
366378
}
367379
}
@@ -491,12 +503,22 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate)
491503
#ifdef _Py_THREAD_SANITIZER
492504
// Thread sanitizer crashes if we use more than half the stack.
493505
uintptr_t stacksize = top - base;
506+
#ifdef __hppa__
507+
top -= stacksize/2;
508+
#else
494509
base += stacksize/2;
510+
#endif
495511
#endif
496512
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
513+
#ifdef __hppa__
514+
_tstate->c_stack_top = base;
515+
_tstate->c_stack_hard_limit = top - _PyOS_STACK_MARGIN_BYTES;
516+
_tstate->c_stack_soft_limit = top - _PyOS_STACK_MARGIN_BYTES * 2;
517+
#else
497518
_tstate->c_stack_top = top;
498519
_tstate->c_stack_hard_limit = base + _PyOS_STACK_MARGIN_BYTES;
499520
_tstate->c_stack_soft_limit = base + _PyOS_STACK_MARGIN_BYTES * 2;
521+
#endif
500522
}
501523

502524
/* The function _Py_EnterRecursiveCallTstate() only calls _Py_CheckRecursiveCall()
@@ -508,9 +530,15 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where)
508530
uintptr_t here_addr = _Py_get_machine_stack_pointer();
509531
assert(_tstate->c_stack_soft_limit != 0);
510532
assert(_tstate->c_stack_hard_limit != 0);
533+
#ifdef __hppa__
534+
if (here_addr > _tstate->c_stack_hard_limit) {
535+
/* Overflowing while handling an overflow. Give up. */
536+
int kbytes_used = (int)(here_addr - _tstate->c_stack_top)/1024;
537+
#else
511538
if (here_addr < _tstate->c_stack_hard_limit) {
512539
/* Overflowing while handling an overflow. Give up. */
513540
int kbytes_used = (int)(_tstate->c_stack_top - here_addr)/1024;
541+
#endif
514542
char buffer[80];
515543
snprintf(buffer, 80, "Unrecoverable stack overflow (used %d kB)%s", kbytes_used, where);
516544
Py_FatalError(buffer);
@@ -519,7 +547,11 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where)
519547
return 0;
520548
}
521549
else {
550+
#ifdef __hppa__
551+
int kbytes_used = (int)(here_addr - _tstate->c_stack_top)/1024;
552+
#else
522553
int kbytes_used = (int)(_tstate->c_stack_top - here_addr)/1024;
554+
#endif
523555
tstate->recursion_headroom++;
524556
_PyErr_Format(tstate, PyExc_RecursionError,
525557
"Stack overflow (used %d kB)%s",

0 commit comments

Comments
 (0)