[Ada] Fix __gnat_backtrace for VxWorks7 on x86

A STORAGE ERROR is raised in __gnat_backtrace:

adainit: 0x00400DBC

Execution of ce.vxe terminated by unhandled exception
raised STORAGE_ERROR : SIGSEGV: possible stack overflow
Call stack traceback locations:
0x4082f1 0x408323 0x4080c9

It was passing with vxsim because the WRS_RTP_BASE is set to a different
place hence the (CURRENT) < (TOP_STACK) was stopping the backtrace at the
right time. So let's stop at the main symbol when RTS=rtp.

2018-05-31  Frederic Konrad  <konrad@adacore.com>

gcc/ada/

	* tracebak.c (STOP_FRAME): Harden condition.
	(is_return_from, EXTRA_STOP_CONDITION): New helpers for VxWorks in RTP
	mode.

From-SVN: r261010
This commit is contained in:
Frederic Konrad 2018-05-31 10:47:08 +00:00 committed by Pierre-Marie de Rodat
parent 6ae40af30c
commit fe1db400ad
2 changed files with 39 additions and 1 deletions

View File

@ -1,3 +1,9 @@
2018-05-31 Frederic Konrad <konrad@adacore.com>
* tracebak.c (STOP_FRAME): Harden condition.
(is_return_from, EXTRA_STOP_CONDITION): New helpers for VxWorks in RTP
mode.
2018-05-31 Ed Schonberg <schonberg@adacore.com>
* checks.adb (Apply_Discriminant_Check): Do not apply discriminant

View File

@ -478,10 +478,11 @@ struct layout
#define PC_ADJUST -2
#define STOP_FRAME(CURRENT, TOP_STACK) \
(IS_BAD_PTR((long)(CURRENT)) \
|| (void *) (CURRENT) < (TOP_STACK) \
|| IS_BAD_PTR((long)(CURRENT)->return_address) \
|| (CURRENT)->return_address == 0 \
|| (void *) ((CURRENT)->next) < (TOP_STACK) \
|| (void *) (CURRENT) < (TOP_STACK))
|| EXTRA_STOP_CONDITION(CURRENT))
#define BASE_SKIP (1+FRAME_LEVEL)
@ -504,6 +505,37 @@ struct layout
|| ((*((ptr) - 1) & 0xff) == 0xff) \
|| (((*(ptr) & 0xd0ff) == 0xd0ff))))
#if defined (__vxworks) && defined (__RTP__)
/* For VxWorks following backchains past the "main" frame gets us into the
kernel space, where it can't be dereferenced. So lets stop at the main
symbol. */
extern void main();
static int
is_return_from(void *symbol_addr, void *ret_addr)
{
int ret = 0;
char *ptr = (char *)ret_addr;
if ((*(ptr - 5) & 0xff) == 0xe8)
{
/* call addr16 E8 xx xx xx xx */
int32_t offset = *(int32_t *)(ptr - 4);
ret = (ptr + offset) == symbol_addr;
}
/* Others not implemented yet... But it is very likely that call addr16
is used here. */
return ret;
}
#define EXTRA_STOP_CONDITION(CURRENT) \
(is_return_from(&main, (CURRENT)->return_address))
#else /* not (defined (__vxworks) && defined (__RTP__)) */
#define EXTRA_STOP_CONDITION(CURRENT) (0)
#endif /* not (defined (__vxworks) && defined (__RTP__)) */
/*----------------------------- qnx ----------------------------------*/
#elif defined (__QNX__)