Skip to content

Commit 96e5156

Browse files
stefanordanglin44
andcommitted
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 <dave.anglin@bell.net>
1 parent bb85af3 commit 96e5156

2 files changed

Lines changed: 42 additions & 0 deletions

File tree

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: 34 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
}
@@ -471,7 +483,11 @@ hardware_stack_limits(uintptr_t *top, uintptr_t *base)
471483
}
472484
if (err == 0) {
473485
*base = ((uintptr_t)stack_addr) + guard_size;
486+
#ifdef __hppa__
487+
*top = (uintptr_t)stack_addr;
488+
#else
474489
*top = (uintptr_t)stack_addr + stack_size;
490+
#endif
475491
return;
476492
}
477493
# endif
@@ -491,12 +507,20 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate)
491507
#ifdef _Py_THREAD_SANITIZER
492508
// Thread sanitizer crashes if we use more than half the stack.
493509
uintptr_t stacksize = top - base;
510+
#ifndef __hppa__
494511
base += stacksize/2;
512+
#endif
495513
#endif
496514
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
515+
#ifdef __hppa__
516+
_tstate->c_stack_top = base + stacksize/2;
517+
_tstate->c_stack_hard_limit = base + stacksize + _PyOS_STACK_MARGIN_BYTES;
518+
_tstate->c_stack_soft_limit = base + +stacksize + _PyOS_STACK_MARGIN_BYTES * 2;
519+
#else
497520
_tstate->c_stack_top = top;
498521
_tstate->c_stack_hard_limit = base + _PyOS_STACK_MARGIN_BYTES;
499522
_tstate->c_stack_soft_limit = base + _PyOS_STACK_MARGIN_BYTES * 2;
523+
#endif
500524
}
501525

502526
/* The function _Py_EnterRecursiveCallTstate() only calls _Py_CheckRecursiveCall()
@@ -508,9 +532,15 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where)
508532
uintptr_t here_addr = _Py_get_machine_stack_pointer();
509533
assert(_tstate->c_stack_soft_limit != 0);
510534
assert(_tstate->c_stack_hard_limit != 0);
535+
#ifdef __hppa__
536+
if (here_addr > _tstate->c_stack_hard_limit) {
537+
/* Overflowing while handling an overflow. Give up. */
538+
int kbytes_used = (int)(here_addr - _tstate->c_stack_top)/1024;
539+
#else
511540
if (here_addr < _tstate->c_stack_hard_limit) {
512541
/* Overflowing while handling an overflow. Give up. */
513542
int kbytes_used = (int)(_tstate->c_stack_top - here_addr)/1024;
543+
#endif
514544
char buffer[80];
515545
snprintf(buffer, 80, "Unrecoverable stack overflow (used %d kB)%s", kbytes_used, where);
516546
Py_FatalError(buffer);
@@ -519,7 +549,11 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where)
519549
return 0;
520550
}
521551
else {
552+
#ifdef __hppa__
553+
int kbytes_used = (int)(here_addr - _tstate->c_stack_top)/1024;
554+
#else
522555
int kbytes_used = (int)(_tstate->c_stack_top - here_addr)/1024;
556+
#endif
523557
tstate->recursion_headroom++;
524558
_PyErr_Format(tstate, PyExc_RecursionError,
525559
"Stack overflow (used %d kB)%s",

0 commit comments

Comments
 (0)