Jump to page: 1 2 3
Thread overview
Exceptions in ARM
Jan 01, 2014
Timo Sintonen
Jan 01, 2014
Iain Buclaw
Jan 01, 2014
Timo Sintonen
Jan 02, 2014
Timo Sintonen
Jan 05, 2014
Timo Sintonen
Jan 05, 2014
Johannes Pfau
Jan 05, 2014
Timo Sintonen
Jan 08, 2014
Timo Sintonen
Jan 08, 2014
Iain Buclaw
Jan 08, 2014
Johannes Pfau
Jan 08, 2014
Timo Sintonen
Jan 08, 2014
Mike
Feb 28, 2014
Timo Sintonen
Mar 01, 2014
Mike
Mar 01, 2014
Timo Sintonen
Mar 01, 2014
Mike
Mar 01, 2014
Timo Sintonen
Mar 01, 2014
Mike
Mar 01, 2014
Johannes Pfau
Mar 01, 2014
Timo Sintonen
Mar 01, 2014
Johannes Pfau
Mar 02, 2014
Timo Sintonen
Mar 02, 2014
Johannes Pfau
Mar 02, 2014
Timo Sintonen
Mar 07, 2014
Johannes Pfau
Mar 08, 2014
Timo Sintonen
Mar 09, 2014
Timo Sintonen
Mar 09, 2014
Mike
Mar 09, 2014
Johannes Pfau
Jan 01, 2014
Johannes Pfau
January 01, 2014
I started to update minlibd with gdc head from last saturday. While testing if exceptions work, the program just stops and does not reach catch or abort.

Before investigating further, I want to ask the status of arm exceptions: are they known to work, known not to work or is the status just unknown?

Does anybody know if there are any good articles of exceptions and unwinding in gcc or in general?


January 01, 2014
On 1 Jan 2014 14:05, "Timo Sintonen" <t.sintonen@luukku.com> wrote:
>
> I started to update minlibd with gdc head from last saturday. While
testing if exceptions work, the program just stops and does not reach catch or abort.
>
> Before investigating further, I want to ask the status of arm exceptions:
are they known to work, known not to work or is the status just unknown?
>
> Does anybody know if there are any good articles of exceptions and
unwinding in gcc or in general?
>

How are exceptions implemented in minilibd? I assume that you don't use/copy from the gdc compiler runtime folders (rt.* and gcc.*)


January 01, 2014
On Wednesday, 1 January 2014 at 15:19:01 UTC, Iain Buclaw wrote:
> On 1 Jan 2014 14:05, "Timo Sintonen" <t.sintonen@luukku.com> wrote:
>>
>> I started to update minlibd with gdc head from last saturday. While
> testing if exceptions work, the program just stops and does not reach catch
> or abort.
>>
>> Before investigating further, I want to ask the status of arm exceptions:
> are they known to work, known not to work or is the status just unknown?
>>
>> Does anybody know if there are any good articles of exceptions and
> unwinding in gcc or in general?
>>
>
> How are exceptions implemented in minilibd? I assume that you don't
> use/copy from the gdc compiler runtime folders (rt.* and gcc.*)

I do not have my own code here. I just add those files that are needed to link the test program. Currently I have rt/deh.d, gcc/deh.d, gcc/unwind/pe.d, gcc/unwind/arm.d and core/exception.d

Meanwhile I found an exception abi documentation from arm:
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038a/IHI0038A_ehabi.pdf
and now I know a little how this is supposed to work.

By looking the asm I think that at the throw point it generates the exception object and then the unwind_control_block struct and then calls _Unwind_Resume. The unwind tables have already been in linker script. Then the unwind system should at some point call the personality functions in gcc/deh.d.

Maybe I have to check if there is meaningful data in the unwind tables and if the personality functions ever get called.
January 01, 2014
Am Wed, 01 Jan 2014 14:02:42 +0000
schrieb "Timo Sintonen" <t.sintonen@luukku.com>:

> I started to update minlibd with gdc head from last saturday. While testing if exceptions work, the program just stops and does not reach catch or abort.
> 
> Before investigating further, I want to ask the status of arm exceptions: are they known to work, known not to work or is the status just unknown?

They work just as well on ARM/linux/glibc as on x86/glibc/linux. (Exception chaining isn't working on any architecture, IIRC).

There's a problem with nothrow functions on ARM though: GDC currently
marks nothrow functions with TREE_NOTHROW. However, if such a functions
throws an Error (which is legal in D) the program crashes. The
solution is not setting TREE_NOTHROW, see here:
https://github.com/jpf91/GDC/commit/935198bda01ada89d946ee28819253cca872bea5

> 
> Does anybody know if there are any good articles of exceptions and unwinding in gcc or in general?
> 
> 

The keywords here are 'dwarf exceptions' and 'sjlj exceptions' (or setjump/longjump exceptions) and you probably want 'dwarf exceptions'.

http://gcc.gnu.org/ml/gcc/2002-07/msg00391.html
January 02, 2014
I have fond one thing that confuses me. I have defined ARM_EABI_UNWINDER but gcc/deh.d has checks for GNU_ARM_EABI_Unwinder. Is this what I should have? When using this I get an error in line 116: static assert ( 8 == 4 ) is false.
January 05, 2014
On Thursday, 2 January 2014 at 06:54:18 UTC, Timo Sintonen wrote:
> I have fond one thing that confuses me. I have defined ARM_EABI_UNWINDER but gcc/deh.d has checks for GNU_ARM_EABI_Unwinder. Is this what I should have? When using this I get an error in line 116: static assert ( 8 == 4 ) is false.

I think that this code in gcc/deh.d line 105 may not get it right

 // To place 'obj' behing unwindHeader.
  enum UNWIND_PAD = (Phase1Info.sizeof + Object.sizeof)
    % _Unwind_Exception.alignof;

  static if (UNWIND_PAD > 0)
    byte[UNWIND_PAD] _pad;

  Object obj;

  // The exception object must be directly behind unwindHeader.
  // (See build_exception_object.)
  static assert(unwindHeader.offsetof - obj.offsetof == obj.sizeof);

  // The generic exception header
  _Unwind_Exception unwindHeader;


Its purpose seems to add padding so that obj is aligned at the end of align block just before unwindHeader.

Fitst, if I uderstand correct, the amount to pad should be align - modulo, not modulo. The current code happens to work anyway if align is 8 and modulo is 0 or 4 which is usually the case.

Second, When I define GNU_ARM_EABI_Unwinder, the assertion fails. Nothing changes in calculation of UNWIND_PAD but the alignment is not correct and the assert fails. With this define the whole size of struct if 96 bytes and 40 bytes without. Something is aligned differently such a way that this calculation cannot find it. I can not print offsetof with pragma msg so I do not know what happens.

January 05, 2014
Am Sun, 05 Jan 2014 08:26:16 +0000
schrieb "Timo Sintonen" <t.sintonen@luukku.com>:

> On Thursday, 2 January 2014 at 06:54:18 UTC, Timo Sintonen wrote:
> > I have fond one thing that confuses me. I have defined ARM_EABI_UNWINDER but gcc/deh.d has checks for GNU_ARM_EABI_Unwinder. Is this what I should have? When using this I get an error in line 116: static assert ( 8 == 4 ) is false.
> 
> I think that this code in gcc/deh.d line 105 may not get it right
> 
>   // To place 'obj' behing unwindHeader.
>    enum UNWIND_PAD = (Phase1Info.sizeof + Object.sizeof)
>      % _Unwind_Exception.alignof;
> 
>    static if (UNWIND_PAD > 0)
>      byte[UNWIND_PAD] _pad;
> 
>    Object obj;
> 
>    // The exception object must be directly behind unwindHeader.
>    // (See build_exception_object.)
>    static assert(unwindHeader.offsetof - obj.offsetof ==
> obj.sizeof);
> 
>    // The generic exception header
>    _Unwind_Exception unwindHeader;
> 
> 
> Its purpose seems to add padding so that obj is aligned at the end of align block just before unwindHeader.
> 
> Fitst, if I uderstand correct, the amount to pad should be align - modulo, not modulo. The current code happens to work anyway if align is 8 and modulo is 0 or 4 which is usually the case.
> 
> Second, When I define GNU_ARM_EABI_Unwinder, the assertion fails. Nothing changes in calculation of UNWIND_PAD but the alignment is not correct and the assert fails. With this define the whole size of struct if 96 bytes and 40 bytes without. Something is aligned differently such a way that this calculation cannot find it. I can not print offsetof with pragma msg so I do not know what happens.
> 

I should really start pushing my local ARM changes upstream. Here's a
fix for the EABI unwinder:
https://github.com/jpf91/GDC/commit/262e432e95cbe31a6764cd337f64022a56011eda

IIRC I also thought the code in gcc/deh.d wasn't correct. As it wouldn't work for the eabi unwinder anyway (no Phase1Info member) I didn't investigate that though.
January 05, 2014
On Sunday, 5 January 2014 at 10:06:48 UTC, Johannes Pfau wrote:

> I should really start pushing my local ARM changes upstream. Here's a
> fix for the EABI unwinder:
> https://github.com/jpf91/GDC/commit/262e432e95cbe31a6764cd337f64022a56011eda
>
> IIRC I also thought the code in gcc/deh.d wasn't correct. As it wouldn't
> work for the eabi unwinder anyway (no Phase1Info member) I didn't
> investigate that though.

Meanwhile I got it to pass with this:
align(8) int _pad;

Exceptions still not working, but this is a start
January 08, 2014
On Sunday, 5 January 2014 at 10:21:36 UTC, Timo Sintonen wrote:
> On Sunday, 5 January 2014 at 10:06:48 UTC, Johannes Pfau wrote:
>
>> I should really start pushing my local ARM changes upstream. Here's a
>> fix for the EABI unwinder:
>> https://github.com/jpf91/GDC/commit/262e432e95cbe31a6764cd337f64022a56011eda
>>
>> IIRC I also thought the code in gcc/deh.d wasn't correct. As it wouldn't
>> work for the eabi unwinder anyway (no Phase1Info member) I didn't
>> investigate that though.
>
> Meanwhile I got it to pass with this:
> align(8) int _pad;
>
Exceptions still not working. The code call the unwind routine in libgcc but that never calls back to personality routine. Neither it resumes to the error callback nor abort.

There are several addresses in tables like the call to cleanup code and jump to the catch routine. Are they called in libgcc side or in personality routine? I was just wondering if thumb mode has been taken into account.

Cortex processors have only the 16 bit 'thumb' instruction set. This is indicated by setting the lsb of the address to 1 in any address that is used in jumps or calls or any address loads to pc. If the lsb is 0 it will result to illegal instruction fault in Cortex.

When compiling with -mthumb the compiler always sets this bit for any address and there is a separate libgcc for thumb mode. When calculating address offsets from exception tables the compiler can not know they are used as jump addresses. It may be possible that callback functions are called in wrong mode.

Any thoughts?
January 08, 2014
On 8 January 2014 08:37, Timo Sintonen <t.sintonen@luukku.com> wrote:
> On Sunday, 5 January 2014 at 10:21:36 UTC, Timo Sintonen wrote:
>>
>> On Sunday, 5 January 2014 at 10:06:48 UTC, Johannes Pfau wrote:
>>
>>> I should really start pushing my local ARM changes upstream. Here's a fix for the EABI unwinder:
>>>
>>> https://github.com/jpf91/GDC/commit/262e432e95cbe31a6764cd337f64022a56011eda
>>>
>>> IIRC I also thought the code in gcc/deh.d wasn't correct. As it wouldn't work for the eabi unwinder anyway (no Phase1Info member) I didn't investigate that though.
>>
>>
>> Meanwhile I got it to pass with this:
>> align(8) int _pad;
>>
> Exceptions still not working. The code call the unwind routine in libgcc but that never calls back to personality routine. Neither it resumes to the error callback nor abort.
>

Hmm, could maybe try some alignment test:

struct test
{
  byte space;
  byte[0] end;
}

struct OurUnwindException
{
...
  enum UNWIND_PAD = (Object.sizeof < test.sizeof)
      ? test.sizeof - Object.sizeof : 0;

  byte[UNWIND_PAD] _pad;

  Object obj;
...
}

Will have to take a relook at the unwind code again sometime incase there has been changes since it was last updated.

Regards
Iain
« First   ‹ Prev
1 2 3