Jan Rinze wrote:
> Pedro Alves wrote:
>> Yes there is.  Fix the software that is making the problem trigger.
>> 10 years ago, having a handler was the only way to go, but nowadays
>> I guess most problems are solved now.
>> The most problematic constructs where things like:
>>
>> char* buf = <...>;
>> *(unsigned long*)buf = 0xfeedf00d;
>>
>> where buf may not be 32-bit aligned.  The portable way to fix this
>> is to use memcpy.  (The compiler is allowed to inline the memcpy.)
>>
>> I'm not advocating for removing
>> the handler, though.
>>
>>     
>
> On x86 the above is perfectly valid and therefore gcc does a 4 byte
> write. This should not be a memcpy however unless the data is already
> somewhere in the memory. Any long variable should be able to be written
> anywhere in memory.. the problem is that when the data is only in a
> temporary register things go wrong. Any other assingment will be just a
> memcpy anyway.. This means that the programmer should take extra care
> about how to interact directly with memory. For people used to
> programming on x86 platforms this will be rather hard to do
> consistently. this really is a fundamental ARM issue.
> On Alpha there have been similar troubles. 
>
>   

It should be a memcpy, or copy byte by byte manually.  The compiler is 
allowed to
optimize the memcpy.  Eg, if the memory size passed is constant, and small
enough, the copy could be optimize to a load store op.

>>> Some programs rely on the 'x86' memory-access methods and will fail on
>>> ARM platforms. The most recent ARM gcc compilers will by default
>>> generate byte-by-byte memory access for packed structures. That should
>>> remove the necessity for an unaligned memory trap handler.
>>>
>>>       
>> Right.  The problem still happens when you lose packedness information, like
>>
>> struct packed_s
>> {
>>     char a;
>>     int b;
>> } __attribute__((packed));
>>
>>
>> struct packed_s* p;
>>
>> int* pp = (int*)p->b;
>>
>> Here pp is a pointer to an int, and knows nothing about the fact that
>> p->b may be unaligned.
>>     
>
> the above code is perfectly valid for x86.. For compatibility a handler
> could help out here. Just to keep the code from breaking.
> Best practice however dictates that the above is not the right way to do
> these things especially when looking at cross platform compatibility.
> Unfortunately 90% of al programmers have not programmed on a platform
> different from the x86.. (i have had the privillege to program on sparc,
> PA-risc, Alpha, x86, 68000, and ARM. Each has its own peculiarities..)  
> in the world of open source these alignment problems have been fixed
> only in the kernel of Linux and a few projects.. keeping in the line of
> best-practices has been in favour of the ARM platforms lately but this
> is in my experience only in the last few years..
>   

It is mostly a difference between CISC/RISC.  I too have used many other 
processors
other than x86, like h8, sparc, 68000, of course ARM and some other 
microcontrollers.
In fact, x86 is the one I used the less.

Your statement would better be written as: The above code *happens* to be
valid fox x86.  The thing is, we're are stepping out of the c standard by
using __attribute__((packed)).  Then later we assign an aligned address 
to an aligned
pointer ( int* pp = (int*)&p->b ), and then we dereference that pointer, 
gcc is allowed
to generate instructions as if the address was really aligned, because 
that was what you told
him to (int*).  This could be mitigated if there was a _packed pointer 
in gcc like there
is in the ARM compiler.  Remember that it is always the stepping a bit 
out of the
C standard, and assuming platform features that gets us into these 
situations.
> I understand. the sad thing is that gcc can keep people from doing
> things in a platform dependant way.. 
> from the back of my mind, I read somewhere:
> "C gives you enough rope to hang yourself with."
>   
Yeah, you just have to make sure you never put it around your neck :)


>>     
>>> Speed is as always a problem when exception-handling needs to take over
>>> to ensure proper execution of programs. (All floating-point instructions
>>> will be handled by the undefined instruction handler... ) But you should
>>> keep in mind that many other processors have similar solutions to
>>> architectural problems.
>>> Some PowerPC processor have special handlers for instructions that are
>>> not built into the processor. These get emulated in some sort of
>>> firmware. Also intel processors have similar solutions.
>>>
>>> for some interesting reading:
>>> http://netwinder.osuosl.org/users/b/brianbr/public_html/alignment.html
>>> http://www.aleph1.co.uk/node/294?PHPSESSID=af8de6d053f7342c8bfb27c86dee2817
>>>
>>> both articles are very similar but the last one also adresses the debate
>>> that somehow still lingers about speed versus compatibility.
>>>
>>>       
>>>> - implements very rudimentary support for SIGSEGV.
>>>>         
>>> I have not checked the code yet but alignment faults are not
>>> segmentation faults (data-aborts) i.i.r.c. and it generates SIGBUS under
>>> linux if configured to do so. Eventually the processor can be configured
>>> to ignore alignment errors which makes it more an OS related issue.
>>> Things get even more complicated when the alignment eror co-incides with
>>> a data-abort in the alignment handler..
>>>
>>>       
>> Right.  The handler catches more than alignment faults.  It maps windows
>> exceptions to unix signals.  SIGSEGV happens to be the one I remembered
>> trying :)
>>     
>
> The handler should specifically check if the alignment fault bit is set.
> it might mistake a data-abort for a segmentation fault..
>   

The alignment case (EXCEPTION_DATATYPE_MISALIGNMENT) is handled specially.
LDR and STR ops to unaligned addresses are emulated with memcpy.  Hummm, 
if another insn
causes the misaligment, it is then not handled on the mapping table, it 
should be.

Here is the current mapping table:

struct exception_map_t __exception_map[] =
{
  { STATUS_ACCESS_VIOLATION,         SIGSEGV,  "Access Violation" },
  { STATUS_ILLEGAL_INSTRUCTION,      SIGILL, "Illegal Instruction"},
  { STATUS_PRIVILEGED_INSTRUCTION,   SIGILL, "Privileged Instruction" },
  /*      { (unsigned long)STATUS_NONCONTINUABLE_EXCEPTION, NOSIG,   
SIG_DIE }, */
  /*      { (unsigned long)STATUS_INVALID_DISPOSITION,      NOSIG,   
SIG_DIE }, */
  { STATUS_INTEGER_DIVIDE_BY_ZERO,   SIGFPE, "Integer divide by zero" },
  { STATUS_FLOAT_DENORMAL_OPERAND,   SIGFPE, "Float denormal operand" },
  { STATUS_FLOAT_DIVIDE_BY_ZERO,     SIGFPE, "Float divide by zero" },
  { STATUS_FLOAT_INEXACT_RESULT,     SIGFPE, "Float inexact result" },
  { STATUS_FLOAT_INVALID_OPERATION,  SIGFPE, "Float invalid operation" },
  { STATUS_FLOAT_OVERFLOW,           SIGFPE, "Float overflow" },
  { STATUS_FLOAT_STACK_CHECK,        SIGFPE, "Float stack check" },
  { STATUS_FLOAT_UNDERFLOW,          SIGFPE, "Float underflow" },
  /*      { (unsigned long)STATUS_INTEGER_DIVIDE_BY_ZERO,   NOSIG }, */
  /*      { (unsigned long)STATUS_STACK_OVERFLOW,           NOSIG } */
};




>>     
>>> Not sure what was meant here but proper SEGV signals etc. would be very
>>> nice to have.
>>>
>>>       
>> What do you mean by proper?  You should be able to have a signal handler
>> being called on an SEGV, but don't expect core dump support :)
>>
>>     
>
> A long time ago I had written some virtual memory methods and
> single-step methods for ARM under linux. Those bits can only work if a
> signal handler can be installed with the full sigset and so on.
> I may have overlooked the recent development with cegcc but I had not
> been able to use such methods with cegcc yet.
>   
>   

You would have to do that with Windows exceptions or with the
Windows debug API, which itself works hand in hand with SEH.

Nothing has happened in cegcc regarding to signals for a long time.  We only
support very simple things, and only in process.  Also, I believe there 
are problems
of reentrancy of cegcc.dll, and problems of handling signals while the 
thread
is inside a syscall.  All these things are taken care of my cygwin.  To make
it work correctly, they had to come up with a very complicated scheme.  
The thing is
Cygwin is GPL, so I've avoided looking at their code the most I could.  
Nowadays
I don't use cegcc for any of my projects.  I've switched them all to 
mingw32ce.
I suggest everyone do the same, as what cegcc offers is not sooo much.
Maybe someday someone will really port cygwin.dll to Windows CE.  Well,
some things would be very difficult on CE <= 5, but on 6 it starts to
look possible, due to the new memory layout changes.

>>>> (Any brave soul to implement proper ARM WinCE SEH
>>>> support on gcc ?)
>>>>         
>>> Forgive my lack of knowledge her but what is SEH?
>>>       
>> Structured Exception Handling.  __try/__catch/__finally that
>> also works on C.  gcc must be the only compiler for windows that doesn't
>> support it.  The OS implements half of it.  Google is your friend.  :)
>>     
>
> Structured exception handling is not part of C but of C++. Unfortunately
> Microsoft has the habit of reinventing standards and have implemented
> this in their C compilers.. try the DCE exception handling and you will
> discover that it is exactly that which I missed in the signal handling.
> By using setjmp etc. these things can be nicely implemented.
>
>   
SEH is not part of C++.  It is part of the OS, and therefore language 
agnostic.  It just happens
that MSVC implements standard c++ exceptions on top of SEH, and adds 
__try/__finally as
language sugar for C and C++.  In x86, SEH is similar in concept to most 
sjlj (setjmp/longjmp)
schemes, but on RISC archs (ARM/SH) and on x64, it is table based, much like
DWARF exception handling is.

> guess we cannot change how WinCE behaves, only work within its
> parameters.
>
>   
SEH exists in all forms of Windows, not just CE.  There is a Google 
Summer of Code project
to work on SEH on x86 support for gcc.  I guess the we could share with that
work the syntax and the semantics of the language extensions, the 
backend and
table generation would be very different.  I'm waiting for someone to do 
it for x64, and then
port it to ARM would be easier, as it is similar.  :)

Cheers,
Pedro Alves



-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Cegcc-devel mailing list
Cegcc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/cegcc-devel

Reply via email to