Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libc] Add proper alloca to OpenWatcom C library #2123

Merged
merged 2 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions libc/include/alloca.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef __ALLOCA_H
#define __ALLOCA_H
/*
* Stack-checking alloca for GCC and OWC
*/

// void *alloca(size_t);

#define alloca(s) (__stackavail(__ALLOCA_ALIGN(s))? \
__alloca(__ALLOCA_ALIGN(s)): (void *)0)

#define __ALLOCA_ALIGN(s) (((s)+(sizeof(int)-1))&~(sizeof(int)-1))

#ifdef __GNUC__
/* The compiler auto-aligns the stack from the parameter somewhat strangely:
* 0 -> 0, 1 -> 2, 2 -> 4, 3 -> 4, 4 -> 6 etc.
* Thus, __stackavail should check for two more bytes available than asked for.
*/
#define __alloca(s) __builtin_alloca(s)
#define __stackavail(s) 0 /* temp no stack checking */
#endif

#ifdef __WATCOMC__
int __stackavail(unsigned int size);
#pragma aux __stackavail "*" __modify __nomemory

extern void __based(__segname("_STACK")) *__alloca(unsigned int __size);
#pragma aux __alloca = \
"sub sp,ax" \
__parm __nomemory [__ax] \
__value [__sp] \
__modify __exact __nomemory [__sp]

#endif


#endif
1 change: 0 additions & 1 deletion libc/include/malloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ void *malloc(size_t);
void free(void *);
void *realloc(void *, size_t);
void *calloc(size_t elm, size_t sz);
void *alloca(size_t);

#ifdef __LIBC__
/*
Expand Down
1 change: 1 addition & 0 deletions libc/include/stdlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <features.h>
#include <sys/types.h>
#include <malloc.h>
#include <alloca.h>
#include <arch/divmod.h>

/* Don't overwrite user definitions of NULL */
Expand Down
13 changes: 2 additions & 11 deletions libc/watcom/syscall/crt0.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,8 @@ int __argc;
char **__argv;
char *__program_filename;
char **environ;
unsigned int __stacklow;
unsigned char _HShift = 12; /* huge pointer support required by pia.asm */

static unsigned int _SP(void);
#pragma aux _SP = __value [__sp]

/* called by alloca() to check stack available */
unsigned int stackavail(void)
{
return (_SP() - __stacklow);
}
unsigned int __stacklow; /* lowest valid SP value */
unsigned char _HShift = 12; /* huge pointer support required by pia.asm */

#if defined(__SMALL__) || defined(__MEDIUM__) /* near data models */
/* no argv/environ rewrite */
Expand Down
69 changes: 69 additions & 0 deletions libc/watcom/syscall/stackcheck.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Open Watcom C stack checking helper routines
*
* 4 Dec 2024 Greg Haerr
*/

#include <sys/cdefs.h>
#include <alloca.h>
#include <unistd.h>

extern unsigned int __stacklow;

#define errmsg(str) write(STDERR_FILENO, str, sizeof(str) - 1)

static unsigned int __SP(void);
#pragma aux __SP = __value [__sp]

static void stack_alloca_warning(void)
{
errmsg("ALLOCA FAIL, INCREASE STACK\n");
}

/*
* Return true if stack can be extended by size bytes,
* called by alloca() to check stack available.
*/
#pragma aux __stackavail "*"
int __stackavail(unsigned int size)
{
unsigned int remaining = __SP() - __stacklow;

if ((int)remaining >= 0 && remaining >= size)
return 1;
stack_alloca_warning();
return 0;
}

#if LATER
static void stack_overflow(void)
{
errmsg("STACK OVERFLOW\n");
}

static void stack_overlimit(void)
{
errmsg("STACK OVER LIMIT\n");
}
#endif

/*
* Check if size bytes can be allocated from stack,
* called from function prologue when -fstack-check set.
*/
#pragma aux __STK "*"
void __STK(unsigned int size)
{
unsigned int remaining = __SP() - __stacklow;
unsigned int curbreak;

if ((int)remaining >= 0 && remaining >= size)
return;
curbreak = (unsigned int)sbrk(0); /* NOTE syscall here will cause SIGSEGV sent */
#if LATER
if (__SP() < curbreak)
stack_overflow();
else
stack_overlimit();
#endif
}
Loading