Skip to content

Commit 5f0a5ec

Browse files
committed
Fix startup code when compiling without optimizations
When compiling without optimizations, the "bp" variable may not be in a register, and we cannot access it after calling Mshrink()/setstack().
1 parent 6a67088 commit 5f0a5ec

File tree

1 file changed

+44
-11
lines changed

1 file changed

+44
-11
lines changed

mintlib/crtinit.c

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,16 @@ static long parseargs(BASEPAGE *);
9191
*/
9292
static char *acc_argv[] = { "", NULL }; /* no name and no arguments */
9393

94+
/*
95+
* A frame-pointer is useless here,
96+
* because we change the stack inside those functions.
97+
*/
98+
#pragma GCC optimize "-fomit-frame-pointer"
99+
94100
void
95101
_acc_main(void)
96102
{
97-
char *s;
103+
char *s;
98104

99105
if (_stksize == 0 || _stksize == -1L)
100106
_stksize = MINKEEP;
@@ -111,6 +117,9 @@ _acc_main(void)
111117
s = (char *)Malloc(_stksize);
112118
_setstack(s + _stksize);
113119

120+
/* local variables must not be accessed after this point,
121+
because we just changed the stack */
122+
114123
/* this is an accessory */
115124
_app = 0;
116125

@@ -123,17 +132,20 @@ _acc_main(void)
123132
#endif
124133

125134
_main(__libc_argc, __libc_argv, environ);
126-
/*NOTREACHED*/
135+
__builtin_unreachable();
127136
}
128137

138+
/* because we change the stack in this function */
139+
#pragma GCC optimize "-fno-defer-pop"
140+
129141
void
130142
_crtinit(void)
131143
{
132144
extern void etext(void); /* a "function" to fake out pc-rel addressing */
133145

134-
register BASEPAGE *bp;
135-
register long m;
136-
register long freemem;
146+
BASEPAGE *bp;
147+
long m;
148+
long freemem;
137149
char *s;
138150

139151
/* its an application */
@@ -192,31 +204,52 @@ _crtinit(void)
192204
if (((long)bp + m) > ((long)bp->p_hitpa - MINFREE))
193205
goto notenough;
194206

195-
/* set up the new stack to bp + m */
196-
_setstack((char *)bp + m);
197-
198-
/* shrink the TPA */
199-
(void)Mshrink(bp, m);
200-
201207
/* keep length of program area */
202208
_PgmSize = m;
203209

204210
/* start profiling, if we were linked with gcrt0.o */
205211
_monstartup((void *)bp->p_tbase, (void *)((long)etext - 1));
206212

213+
/*
214+
* shrink the TPA,
215+
* and set up the new stack to bp + m.
216+
* Instead of calling Mshrink() and _setstack, this is done inline here,
217+
* because we cannot access the bp parameter after changing the stack anymore.
218+
*/
219+
__asm__ __volatile__(
220+
"\tmovel %0,%%d0\n"
221+
"\taddl %1,%%d0\n"
222+
"\tsubl #64,%%d0\n" /* push some unused space for buggy OS */
223+
"\tmovel %%d0,%%sp\n"/* set up the new stack to bp + m */
224+
"\tmove.l %1,-(%%sp)\n"
225+
"\tmove.l %0,-(%%sp)\n"
226+
"\tclr.w -(%%sp)\n"
227+
"\tmove.w #0x4a,-(%%sp)\n" /* Mshrink */
228+
"\ttrap #1\n"
229+
"\tlea 12(%%sp),%%sp\n"
230+
: /* no outputs */
231+
: "r"(bp), "r"(m)
232+
: "d0", "d1", "d2", "a0", "a1", "a2", "cc" AND_MEMORY
233+
);
234+
235+
/* local variables must not be accessed after this point,
236+
because we just changed the stack */
237+
207238
#ifdef __GCC_HAVE_INITFINI_ARRAY_SUPPORT
208239
/* main() won't call __main() for global constructors, so do it here. */
209240
__main();
210241
#endif
211242

212243
_main(__libc_argc, __libc_argv, environ);
213244
/* not reached normally */
245+
__builtin_unreachable();
214246

215247
notenough:
216248
(void) Cconws("Fatal error: insufficient memory\r\n");
217249
(void) Cconws("Hint: either decrease stack size using 'stack' command (not recomended)\r\n" \
218250
" or increase TPA_INITIALMEM value in mint.cnf.\r\n");
219251
Pterm(-1);
252+
__builtin_unreachable();
220253
}
221254

222255
/*

0 commit comments

Comments
 (0)