Re: [Patch][arm] Enable return code with semi-hosting SYS_EXIT_EXTENDED
Matthew Malcomson <[email protected]>
| Newsgroups | gmane.comp.lib.newlib |
|---|---|
| Message-ID | <[email protected]> |
On 20/11/18 11:16, Richard Earnshaw (lists) wrote:
> On 16/11/2018 18:48, Matthew Malcomson wrote:
>> The _exit function currently passes -1 as a "sig" to the _kill function as an
>> invalid signal number so that _kill can distinguish between an abort and a
>> standard exit.
>>
>> For boards using the SYS_EXIT_EXTENDED semi-hosting operation to return a
>> status code, this means that the "status" paramter to _exit is ignored and the
>> return code is always -1.
>> https://developer.arm.com/docs/100863/latest/semihosting-operations/sys_exit_extended-0x20
>>
>> This patch puts shared code between _kill and _exit into a new function
>> _kill_shared that takes the semi-hosting "reason" to use (if semi-hosting is
>> available) as an argument.
>>
>> For semi-hosting _kill_shared provides that "reason".
>>
>> Without the "sig" argument being used to distinguish between a normal and
>> abnormal exit, the _exit function can provide the return code to be used if the
>> SYS_EXIT_EXTENDED operation is available.
>>
>> Hence the exit code can be returned.
>>
>> Tested with gcc testsuite on arm-none-eabi and no issues.
>> Ok for master?
>>
>> PS. I don't have commit rights so if OK can someone commit for me?
> This change needs to be applied to the similar code in newlib's sys
> directory as well. PLEASE keep this in sync.
>
> R.
Thanks for pointing that out, and thanks for the help in testing too.
The patch applying this same change to the sys/ directory is attached.
If OK could someone commit for me? I don't have commit rights.
Regards,
Matthew
#### Patch inlined for ease of reply ###
diff --git a/newlib/libc/sys/arm/syscalls.c b/newlib/libc/sys/arm/syscalls.c
index 87ddca7..b521074 100644
--- a/newlib/libc/sys/arm/syscalls.c
+++ b/newlib/libc/sys/arm/syscalls.c
@@ -30,7 +30,7 @@ int _stat (const char *, struct stat *);
int _fstat (int, struct stat *);
void * _sbrk (ptrdiff_t);
pid_t _getpid (void);
-int _kill (int, int) __attribute__((__noreturn__));
+int _kill (int, int);
void _exit (int);
int _close (int);
int _swiclose (int);
@@ -49,6 +49,7 @@ static int error (int);
static int get_errno (void);
static int remap_handle (int);
static int findslot (int);
+static int _kill_shared (int, int, int)
__attribute__((__noreturn__));
/* Register name faking - works in collusion with the linker. */
register char * stack_ptr asm ("sp");
@@ -424,21 +425,35 @@ _close (int file)
return wrap (_swiclose (file));
}
-int
-_kill (int pid, int sig)
+static int
+_kill_shared (int pid, int sig, int reason)
{
- (void)pid; (void)sig;
+ (void) pid; (void) sig;
#ifdef ARM_RDI_MONITOR
/* Note: The pid argument is thrown away. */
- switch (sig) {
- case SIGABRT:
- do_AngelSWI (AngelSWI_Reason_ReportException,
- (void *) ADP_Stopped_RunTimeError);
- __builtin_unreachable();
- default:
- do_AngelSWI (AngelSWI_Reason_ReportException,
- (void *) ADP_Stopped_ApplicationExit);
- }
+ int block[2];
+ block[1] = sig;
+ block[0] = reason;
+ int insn;
+
+#if SEMIHOST_V2
+ if (_has_ext_exit_extended ())
+ {
+ 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
asm ("swi %a0" :: "i" (SWI_Exit));
#endif
@@ -446,15 +461,24 @@ _kill (int pid, int sig)
__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
_exit (int status)
{
- /* There is only one SWI for both _exit and _kill. For _exit, call
- the SWI with the second argument set to -1, an invalid value for
- signum, so that the SWI handler can distinguish the two calls.
- Note: The RDI implementation of _kill throws away both its
- arguments. */
- _kill(status, -1);
+ /* The same SWI is used for both _exit and _kill.
+ For _exit, call the SWI with "reason" set to
ADP_Stopped_ApplicationExit
+ to mark a standard exit.
+ Note: The RDI implementation of _kill_shared throws away all its
+ arguments and all implementations ignore the first argument. */
+ _kill_shared (-1, status, ADP_Stopped_ApplicationExit);
}
pid_t
--
2.7.4
0001-newlib-arm-Builtin-enable-return-code-with-SYS_EXIT_.patch
(text/x-patch, 3.5 KB)
From 306eed5cb6acd8a52b40f3e86f0a9ec9e1c09eb2 Mon Sep 17 00:00:00 2001 From: Matthew Malcomson <[email protected]> Date: Fri, 16 Nov 2018 11:45:48 +0000 Subject: [PATCH] [newlib][arm] 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. --- newlib/libc/sys/arm/syscalls.c | 62 +++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/newlib/libc/sys/arm/syscalls.c b/newlib/libc/sys/arm/syscalls.c index 87ddca7..b521074 100644 --- a/newlib/libc/sys/arm/syscalls.c +++ b/newlib/libc/sys/arm/syscalls.c @@ -30,7 +30,7 @@ int _stat (const char *, struct stat *); int _fstat (int, struct stat *); void * _sbrk (ptrdiff_t); pid_t _getpid (void); -int _kill (int, int) __attribute__((__noreturn__)); +int _kill (int, int); void _exit (int); int _close (int); int _swiclose (int); @@ -49,6 +49,7 @@ static int error (int); static int get_errno (void); static int remap_handle (int); static int findslot (int); +static int _kill_shared (int, int, int) __attribute__((__noreturn__)); /* Register name faking - works in collusion with the linker. */ register char * stack_ptr asm ("sp"); @@ -424,21 +425,35 @@ _close (int file) return wrap (_swiclose (file)); } -int -_kill (int pid, int sig) +static int +_kill_shared (int pid, int sig, int reason) { - (void)pid; (void)sig; + (void) pid; (void) sig; #ifdef ARM_RDI_MONITOR /* Note: The pid argument is thrown away. */ - switch (sig) { - case SIGABRT: - do_AngelSWI (AngelSWI_Reason_ReportException, - (void *) ADP_Stopped_RunTimeError); - __builtin_unreachable(); - default: - do_AngelSWI (AngelSWI_Reason_ReportException, - (void *) ADP_Stopped_ApplicationExit); - } + int block[2]; + block[1] = sig; + block[0] = reason; + int insn; + +#if SEMIHOST_V2 + if (_has_ext_exit_extended ()) + { + 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 asm ("swi %a0" :: "i" (SWI_Exit)); #endif @@ -446,15 +461,24 @@ _kill (int pid, int sig) __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 _exit (int status) { - /* There is only one SWI for both _exit and _kill. For _exit, call - the SWI with the second argument set to -1, an invalid value for - signum, so that the SWI handler can distinguish the two calls. - Note: The RDI implementation of _kill throws away both its - arguments. */ - _kill(status, -1); + /* The same SWI is used for both _exit and _kill. + For _exit, call the SWI with "reason" set to ADP_Stopped_ApplicationExit + to mark a standard exit. + Note: The RDI implementation of _kill_shared throws away all its + arguments and all implementations ignore the first argument. */ + _kill_shared (-1, status, ADP_Stopped_ApplicationExit); } pid_t -- 2.7.4