This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
Re: [ECOS] Calling exit in a Redboot standalone Arm program
- From: Pierre Habraken <Pierre dot Habraken at imag dot fr>
- To: ecos-patches at sources dot redhat dot com
- Date: Mon, 05 May 2003 15:21:55 +0200
- Subject: Re: [ECOS] Calling exit in a Redboot standalone Arm program
- Organization: Université Joseph Fourier
--
________________________________________________________________________
Pierre HABRAKEN - mailto:Pierre.Habraken@imag.fr
Tél: 04 76 82 72 83 - Fax: 04 76 82 72 87
IMAG-LSR BP72 38402 SAINT MARTIN D'HERES Cedex
________________________________________________________________________
2003-05-05 Pierre Habraken <Pierre.Habraken@imag.fr>
* cdl/redboot.cdl: Added option
CYGOPT_REDBOOT_BSP_SYSCALLS_EXIT_WITHOUT_TRAP for enabling (possibly
single shot) programs to exit and return a termination status as
their normal behavior (i.e. without raising a SIGTRAP).
* src/syscall.c (__do_syscall, return_from_stub): Added conditionally
compiled code to SYS_exit for returning to RedBoot main loop without
raising a SIGTRAP, even when the calling program is not being
debugged (use of a trampoline function suggested by Mark Salter).
* src/main.c (cyg_start, call_breakpoint): Added code (following
Jonathan Larmour's and Mark Salter's suggestions) to RedBoot main
loop: a (context) savepoint is created before the thread of control
is transferred to gdb stubs (through a trampoline procedure). This
savepoint enables the stubs to return control back to the main loop
by calling the return_to_redboot procedure (macro
CYGACC_CALL_IF_MONITOR_RETURN). Procedure go_trampoline and variables
go_saved_context and go_return_status have been respectively renamed
to trampoline, saved_context and return_status.
--- redboot/current/cdl/redboot.cdl.inst Fri May 2 16:51:42 2003
+++ redboot/current/cdl/redboot.cdl Mon May 5 15:01:13 2003
@@ -841,6 +841,15 @@
display "Does the HAL support 'gprof' profiling?"
no_define
}
+
+ cdl_option CYGOPT_REDBOOT_BSP_SYSCALLS_EXIT_WITHOUT_TRAP {
+ display "Do not raise SIGTRAP when program exits"
+ default_value 0
+ description "
+ For some (single shot) newlib based programs,
+ exiting and returning a termination status may be
+ the normal expected behavior."
+ }
}
cdl_component CYGOPT_REDBOOT_FIS_ZLIB_COMMON_BUFFER {
--- redboot/current/src/syscall.c.inst Fri Jan 31 17:46:00 2003
+++ redboot/current/src/syscall.c Mon May 5 13:24:36 2003
@@ -424,6 +424,13 @@
#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
+// Trampoline for returning to RedBoot
+static void
+return_from_stub(int exit_status)
+{
+ CYGACC_CALL_IF_MONITOR_RETURN(exit_status);
+}
+
//
// Generic syscall handler.
//
@@ -632,12 +639,19 @@
case SYS_exit:
if (gdb_active) {
+#ifdef CYGOPT_REDBOOT_BSP_SYSCALLS_EXIT_WITHOUT_TRAP
+ __send_exit_status((int)arg1);
+ }
+ set_pc((target_register_t)return_from_stub);
+ err = arg1;
+#else
*sig = SIGTRAP;
err = func;
} else {
- CYGACC_CALL_IF_MONITOR_RETURN(arg1);
- // never returns
+ set_pc((target_register_t)return_from_stub);
+ err = arg1;
}
+#endif // CYGOPT_REDBOOT_BSP_SYSCALLS_EXIT_WITHOUT_TRAP
break;
default:
--- redboot/current/src/main.c.inst Mon Mar 3 18:49:40 2003
+++ redboot/current/src/main.c Mon May 5 13:09:29 2003
@@ -76,9 +76,21 @@
// Builtin Self Test (BIST)
externC void bist(void);
-// Return path for code run from a go command
+// Path to code run from a go command or to GDB stubs
+static void trampoline(unsigned long entry);
+
+// Return path for code run from a go command or for GDB stubs
static void return_to_redboot(int status);
+// Wrapper to breakpoint()
+static void call_breakpoint(void);
+
+// Address of area where current context is saved before executing
+// trampoline procedure
+static void * saved_context;
+
+// Status returned after trampoline execution
+static int return_status;
// CLI command processing (defined in this file)
RedBoot_cmd("version",
@@ -171,6 +183,17 @@
mon_write_char(c);
}
+// Wrapper to breakpoint()
+static void
+call_breakpoint(void)
+{
+#ifdef HAL_ARCH_PROGRAM_NEW_STACK
+ HAL_ARCH_PROGRAM_NEW_STACK(breakpoint);
+#else
+ breakpoint(); // get GDB stubs started, with a proper environment, etc.
+#endif
+}
+
//
// This is the main entry point for RedBoot
//
@@ -312,11 +335,15 @@
}
CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
-#ifdef HAL_ARCH_PROGRAM_NEW_STACK
- HAL_ARCH_PROGRAM_NEW_STACK(breakpoint);
-#else
- breakpoint(); // Get GDB stubs started, with a proper environment, etc.
-#endif
+
+ // set up a temporary context that will take us to the
+ // trampoline
+ HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end,
+ call_breakpoint, trampoline, 0);
+
+ // switch context to trampoline (get GDB stubs started)
+ HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end);
+
dbgchan = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
CYGACC_CALL_IF_SET_CONSOLE_COMM(dbgchan);
} else
@@ -384,11 +411,8 @@
return;
}
-static void * go_saved_context;
-static int go_return_status;
-
static void
-go_trampoline(unsigned long entry)
+trampoline(unsigned long entry)
{
typedef void code_fun(void);
code_fun *fun = (code_fun *)entry;
@@ -408,8 +432,8 @@
{
CYGARC_HAL_SAVE_GP();
- go_return_status = status;
- HAL_THREAD_LOAD_CONTEXT(&go_saved_context);
+ return_status = status;
+ HAL_THREAD_LOAD_CONTEXT(&saved_context);
// never returns
// need this to balance above CYGARC_HAL_SAVE_GP on
@@ -470,10 +494,10 @@
HAL_DCACHE_INVALIDATE_ALL();
// set up a temporary context that will take us to the trampoline
- HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end, entry, go_trampoline, 0);
+ HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end, entry, trampoline, 0);
// switch context to trampoline
- HAL_THREAD_SWITCH_CONTEXT(&go_saved_context, &workspace_end);
+ HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end);
// we get back here by way of return_to_redboot()
@@ -487,7 +511,7 @@
HAL_RESTORE_INTERRUPTS(oldints);
- diag_printf("\nProgram completed with status %d\n", go_return_status);
+ diag_printf("\nProgram completed with status %d\n", return_status);
}
#ifdef HAL_PLATFORM_RESET