Builtin enable return code with SYS_EXIT_EXTENDED

A previous commit introduced the ability to use the semi-hosting
SYS_EXIT_EXTENDED operation to libgloss, this commit adds the same
ability to the sys/arm/ backend so that building newlib only will
provide the same capabilities.
This commit is contained in:
Matthew Malcomson 2018-11-16 11:45:48 +00:00 committed by Jeff Johnston
parent 7e72be1c39
commit 2d6b71ee6d

View File

@ -30,7 +30,7 @@ int _stat (const char *, struct stat *);
int _fstat (int, struct stat *); int _fstat (int, struct stat *);
void * _sbrk (ptrdiff_t); void * _sbrk (ptrdiff_t);
pid_t _getpid (void); pid_t _getpid (void);
int _kill (int, int) __attribute__((__noreturn__)); int _kill (int, int);
void _exit (int); void _exit (int);
int _close (int); int _close (int);
int _swiclose (int); int _swiclose (int);
@ -49,6 +49,7 @@ static int error (int);
static int get_errno (void); static int get_errno (void);
static int remap_handle (int); static int remap_handle (int);
static int findslot (int); static int findslot (int);
static int _kill_shared (int, int, int) __attribute__((__noreturn__));
/* Register name faking - works in collusion with the linker. */ /* Register name faking - works in collusion with the linker. */
register char * stack_ptr asm ("sp"); register char * stack_ptr asm ("sp");
@ -424,21 +425,35 @@ _close (int file)
return wrap (_swiclose (file)); return wrap (_swiclose (file));
} }
int static int
_kill (int pid, int sig) _kill_shared (int pid, int sig, int reason)
{ {
(void) pid; (void) sig; (void) pid; (void) sig;
#ifdef ARM_RDI_MONITOR #ifdef ARM_RDI_MONITOR
/* Note: The pid argument is thrown away. */ /* Note: The pid argument is thrown away. */
switch (sig) { int block[2];
case SIGABRT: block[1] = sig;
do_AngelSWI (AngelSWI_Reason_ReportException, block[0] = reason;
(void *) ADP_Stopped_RunTimeError); int insn;
__builtin_unreachable();
default: #if SEMIHOST_V2
do_AngelSWI (AngelSWI_Reason_ReportException, if (_has_ext_exit_extended ())
(void *) ADP_Stopped_ApplicationExit); {
insn = AngelSWI_Reason_ReportExceptionExtended;
} }
else
#endif
{
insn = AngelSWI_Reason_ReportException;
}
#if SEMIHOST_V2
if (_has_ext_exit_extended ())
do_AngelSWI (insn, block);
else
#endif
do_AngelSWI (insn, (void*)block[0]);
#else #else
asm ("swi %a0" :: "i" (SWI_Exit)); asm ("swi %a0" :: "i" (SWI_Exit));
#endif #endif
@ -446,15 +461,24 @@ _kill (int pid, int sig)
__builtin_unreachable(); __builtin_unreachable();
} }
int
_kill (int pid, int sig)
{
if (sig == SIGABRT)
_kill_shared (pid, sig, ADP_Stopped_RunTimeError);
else
_kill_shared (pid, sig, ADP_Stopped_ApplicationExit);
}
void void
_exit (int status) _exit (int status)
{ {
/* There is only one SWI for both _exit and _kill. For _exit, call /* The same SWI is used for both _exit and _kill.
the SWI with the second argument set to -1, an invalid value for For _exit, call the SWI with "reason" set to ADP_Stopped_ApplicationExit
signum, so that the SWI handler can distinguish the two calls. to mark a standard exit.
Note: The RDI implementation of _kill throws away both its Note: The RDI implementation of _kill_shared throws away all its
arguments. */ arguments and all implementations ignore the first argument. */
_kill(status, -1); _kill_shared (-1, status, ADP_Stopped_ApplicationExit);
} }
pid_t pid_t