diff options
author | Frederic Konrad <konrad@adacore.com> | 2018-05-31 10:47:08 +0000 |
---|---|---|
committer | Pierre-Marie de Rodat <pmderodat@gcc.gnu.org> | 2018-05-31 10:47:08 +0000 |
commit | fe1db400ad466c7c62a37d89f51ee4474bdba214 (patch) | |
tree | 74fd38f91d3b24c2cd96bdde7db74f0ab08b9e44 | |
parent | 6ae40af30c0d2db1fe3d9610ade37004ee0c1d38 (diff) | |
download | gcc-fe1db400ad466c7c62a37d89f51ee4474bdba214.zip gcc-fe1db400ad466c7c62a37d89f51ee4474bdba214.tar.gz gcc-fe1db400ad466c7c62a37d89f51ee4474bdba214.tar.bz2 |
[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
-rw-r--r-- | gcc/ada/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/ada/tracebak.c | 34 |
2 files changed, 39 insertions, 1 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 47bf996..a68975b 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -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 diff --git a/gcc/ada/tracebak.c b/gcc/ada/tracebak.c index 1f41810..9918123 100644 --- a/gcc/ada/tracebak.c +++ b/gcc/ada/tracebak.c @@ -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__) |