public inbox for crossgcc@sourceware.org
 help / color / mirror / Atom feed
* Compiler Memory Alignment Issue
@ 2012-02-02 18:15 Richard Koch
  2012-02-02 23:09 ` Martin Guy
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Richard Koch @ 2012-02-02 18:15 UTC (permalink / raw)
  To: crossgcc


Hello List,

I'm seeing an alignment issue when I'm incrementing a pointer.

Using the program below I found that the cross compiler I built from
crosstools-ng-1.13.3, interprets the "*(ptr + 1)" as adding 1 BYTE to ptr. It should
know that ptr is declared as a pointer to an integer and interpret "*(ptr + 1)"
as adding 4 BYTES to ptr.

An older cross compiler from Technologics, crosstool-linux-gnueabi-2005q3-2, doesn't
exhibit this problem and interprets the pointer addition correctly. So does the
native gcc on the target. I would prefer to use crosstools-ng.

The target is a Technologics TS-7350 ARM920T (EP9302).

I'm wondering if there may be something I haven't set properly in the crosstool-ng's
configuration?

The configuration file I'm using can be seen here:

    http://home.comcast.net/~n1gp/ct_config

PROGRAM:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main()
{
        unsigned char buffer[8], i;
        int *ptr = (int *) buffer;

        printf("size of int is: %d\n", sizeof(int));
        memset(buffer, 0xff, sizeof buffer);

        *(ptr + 1) = 0x1234;

        for (i=0; i<(sizeof(buffer) +1); i++)
                printf("buffer[%d]=%x\n", i, buffer[i]);
}


RESULTS WITH crosstool-linux-gnueabi-2005q3-2:

size of int is: 4
buffer[0]=ff
buffer[1]=ff
buffer[2]=ff
buffer[3]=ff
buffer[4]=34
buffer[5]=12
buffer[6]=0
buffer[7]=0
buffer[8]=0

RESULTS WITH crosstools-ng:

size of int is: 4
buffer[0]=ff
buffer[1]=34
buffer[2]=12
buffer[3]=0
buffer[4]=0
buffer[5]=ff
buffer[6]=ff
buffer[7]=ff
buffer[8]=8

Thanks,

Rick


 		 	   		  

--
For unsubscribe information see http://sourceware.org/lists.html#faq

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Compiler Memory Alignment Issue
  2012-02-02 18:15 Compiler Memory Alignment Issue Richard Koch
@ 2012-02-02 23:09 ` Martin Guy
  2012-02-02 23:26 ` Rod Nussbaumer
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 10+ messages in thread
From: Martin Guy @ 2012-02-02 23:09 UTC (permalink / raw)
  To: Richard Koch; +Cc: crossgcc

On 2 February 2012 19:15, Richard Koch <n1gp@hotmail.com> wrote:
> I'm seeing an alignment issue when I'm incrementing a pointer.

> The target is a Technologics TS-7350 ARM920T (EP9302).

Ah, my favourite processor :)

> I'm wondering if there may be something I haven't set properly in the crosstool-ng's
> configuration?

I see

Target options -> Floating point -> hardware(FPU) which should almost
certainly be "softfp" as I doubt MaverickCrunch FPU code generation
works. That should also allow you to link objects with standard Debian
or whatever - it certainly won't work with the arm hardfloat ports
like debian armhf, which neds a VFP FPU.

Let me know if that makes any difference.

    M

--
For unsubscribe information see http://sourceware.org/lists.html#faq

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Compiler Memory Alignment Issue
  2012-02-02 18:15 Compiler Memory Alignment Issue Richard Koch
  2012-02-02 23:09 ` Martin Guy
@ 2012-02-02 23:26 ` Rod Nussbaumer
  2012-02-03  9:52 ` Martin Guy
  2012-02-03 10:16 ` Bob Dunlop
  3 siblings, 0 replies; 10+ messages in thread
From: Rod Nussbaumer @ 2012-02-02 23:26 UTC (permalink / raw)
  To: Richard Koch; +Cc: crossgcc

Richard:

It probably doesn't cause the result you're seeing, but the size of your 
buffer[] (8 bytes) is one byte smaller than that which you are reading 
and printing (9 bytes: 0 - 8).

> PROGRAM:
>
> #include<stdlib.h>
> #include<stdio.h>
> #include<string.h>
> #include<unistd.h>
>
> int main()
> {
>          unsigned char buffer[8], i;
>          int *ptr = (int *) buffer;
>
>          printf("size of int is: %d\n", sizeof(int));
>          memset(buffer, 0xff, sizeof buffer);
>
>          *(ptr + 1) = 0x1234;
>
>          for (i=0; i<(sizeof(buffer) +1); i++)
>                  printf("buffer[%d]=%x\n", i, buffer[i]);
> }
>
>


--
For unsubscribe information see http://sourceware.org/lists.html#faq

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Compiler Memory Alignment Issue
  2012-02-02 18:15 Compiler Memory Alignment Issue Richard Koch
  2012-02-02 23:09 ` Martin Guy
  2012-02-02 23:26 ` Rod Nussbaumer
@ 2012-02-03  9:52 ` Martin Guy
  2012-02-03 10:16 ` Bob Dunlop
  3 siblings, 0 replies; 10+ messages in thread
From: Martin Guy @ 2012-02-03  9:52 UTC (permalink / raw)
  To: Richard Koch; +Cc: crossgcc

On 2 February 2012 19:15, Richard Koch <n1gp@hotmail.com> wrote:
> know that ptr is declared as a pointer to an integer and interpret "*(ptr + 1)"
> as adding 4 BYTES to ptr.
>         unsigned char buffer[8], i;
>         int *ptr = (int *) buffer;
>
>         printf("size of int is: %d\n", sizeof(int));
>         memset(buffer, 0xff, sizeof buffer);
>
>         *(ptr + 1) = 0x1234;
>
>         for (i=0; i<(sizeof(buffer) +1); i++)
>                 printf("buffer[%d]=%x\n", i, buffer[i]);
> }
>
>
> RESULTS WITH crosstool-linux-gnueabi-2005q3-2:
>
> size of int is: 4
> buffer[0]=ff
> buffer[1]=ff
> buffer[2]=ff
> buffer[3]=ff
> buffer[4]=34
> buffer[5]=12
> buffer[6]=0
> buffer[7]=0
> buffer[8]=0
>
> RESULTS WITH crosstools-ng:
>
> size of int is: 4
> buffer[0]=ff
> buffer[1]=34
> buffer[2]=12
> buffer[3]=0
> buffer[4]=0
> buffer[5]=ff
> buffer[6]=ff
> buffer[7]=ff
> buffer[8]=8


I can reproduce your first result with gcc.4,4 and your second result
with gcc-4.3 (plain native debian compilers), which corresponds to the
gcc version you are using in crosstool.

The problem is that your char buffer is not word-aligned, so you can't
poke ints into it with predictable results.  On ARM a nonaligned word
access writes into *(int*)(char *)ptr & ~3) and the value it writes is
byte-rotated in such a way as to write the least significant byte into
*(char *)ptr.
It looks like, in your failing case, that the bottom two bits of the
address of buffer[0] are 1 and 1.

The results also depend on the setting of /pro/cpu/alignment. The
default value of 0 gives the above behaviour,
  echo 4 > /proc/cpu/alignment
will cause a fatal signal on misaligned word accesses and
  echo 2 > /proc/cpu/alignment
will trap the misaligned access in the kernel and do what you are
expecting (i386- and vax-like behaviour).

A more robust solution would be to declare
char buffer[8] __attribute__ ((aligned (sizeof(int))));
or
int buffer[2];

A further test you can run to verify whether it is the compiler bug
you suspect or an alignment issue is to disassemble the object code
with
  arm-linux-gnueabi-objdump -d a.out | less
(or whatever your toolchain is called) to check whether it is adding
one or four to the pointer.

     M

--
For unsubscribe information see http://sourceware.org/lists.html#faq

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Compiler Memory Alignment Issue
  2012-02-02 18:15 Compiler Memory Alignment Issue Richard Koch
                   ` (2 preceding siblings ...)
  2012-02-03  9:52 ` Martin Guy
@ 2012-02-03 10:16 ` Bob Dunlop
  2012-02-03 13:21   ` Yann E. MORIN
  3 siblings, 1 reply; 10+ messages in thread
From: Bob Dunlop @ 2012-02-03 10:16 UTC (permalink / raw)
  To: crossgcc

On Thu, Feb 02 at 01:15, Richard Koch wrote:
> 
> Hello List,
> 
> I'm seeing an alignment issue when I'm incrementing a pointer.
...

It's not specifically ct-ng at fault but the compiler.

I can reproduce the problem if I build Gcc 3.3.3 but not with my regular
build (4.4.4).

> I'm wondering if there may be something I haven't set properly in the crosstool-ng's
> configuration?

Try a more recent compiler version.


-- 
        Bob Dunlop

--
For unsubscribe information see http://sourceware.org/lists.html#faq

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Compiler Memory Alignment Issue
  2012-02-03 10:16 ` Bob Dunlop
@ 2012-02-03 13:21   ` Yann E. MORIN
  2012-02-03 14:14     ` Johannes Stezenbach
  0 siblings, 1 reply; 10+ messages in thread
From: Yann E. MORIN @ 2012-02-03 13:21 UTC (permalink / raw)
  To: crossgcc; +Cc: Bob Dunlop, Richard Koch

Richard, Bob, All,

On Friday 03 February 2012 11:16:27 Bob Dunlop wrote:
> On Thu, Feb 02 at 01:15, Richard Koch wrote:
> > I'm seeing an alignment issue when I'm incrementing a pointer.

I Just tried your .config and your sample C code, and it seems to work here
(with the buffer overflow fixed):

$ arm-none-linux-gnueabi-gcc -o ess ess.c
$ qemu-arm -L ..../arm-none-linux-gnueabi/sysroot ./ess
size of int is: 4
buffer[0]=ff
buffer[1]=ff
buffer[2]=ff
buffer[3]=ff
buffer[4]=34
buffer[5]=12
buffer[6]=0
buffer[7]=0

The assembly code corresponding to the assignment is (from gdb's disas /m):
14          *(ptr + 1) = 0x1234;
   0x00008400 <+56>:    ldr     r3, [r11, #-16]
   0x00008404 <+60>:    add     r2, r3, #4
   0x00008408 <+64>:    mov     r3, #4608       ; 0x1200
   0x0000840c <+68>:    add     r3, r3, #52     ; 0x34
   0x00008410 <+72>:    str     r3, [r2]

As you can see for @0x8404, an offset of #4 is added to the address of the
array.

Regards,
Yann E. MORIN.

-- 
.-----------------.--------------------.------------------.--------------------.
|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +0/33 662376056 | Software  Designer | \ / CAMPAIGN     |   ^                |
| --==< O_o >==-- '------------.-------:  X  AGAINST      |  /e\  There is no  |
| http://ymorin.is-a-geek.org/ | (*_*) | / \ HTML MAIL    |  """  conspiracy.  |
'------------------------------'-------'------------------'--------------------'

--
For unsubscribe information see http://sourceware.org/lists.html#faq

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Compiler Memory Alignment Issue
  2012-02-03 13:21   ` Yann E. MORIN
@ 2012-02-03 14:14     ` Johannes Stezenbach
  2012-02-03 14:23       ` Yann E. MORIN
  2012-02-03 15:13       ` Richard Koch
  0 siblings, 2 replies; 10+ messages in thread
From: Johannes Stezenbach @ 2012-02-03 14:14 UTC (permalink / raw)
  To: Yann E. MORIN; +Cc: crossgcc, Bob Dunlop, Richard Koch, Martin Guy

Hi Yann,

On Fri, Feb 03, 2012 at 02:21:23PM +0100, Yann E. MORIN wrote:
> On Friday 03 February 2012 11:16:27 Bob Dunlop wrote:
> > On Thu, Feb 02 at 01:15, Richard Koch wrote:
> > > I'm seeing an alignment issue when I'm incrementing a pointer.
> 
> I Just tried your .config and your sample C code, and it seems to work here
> (with the buffer overflow fixed):

As Martin Guy pointed out the issue may be caused
by wrong alignment.  In fact the behaviour of the code
is undefined according to C99 if buffer is not suitably aligned:
https://www.securecoding.cert.org/confluence/display/seccode/EXP36-C.+Do+not+convert+pointers+into+more+strictly+aligned+pointer+types

I'd suggest to add a printf for the buffer address.

For ARM, unaligned access is supported for ARMv6+, in ARMv5
unaligned write is UNPREDICTABLE (unaligned read is
defined as rotated read from aligned address).
Not sure what's the default CPU for qemu-arm but
Richard has ARMv5.  I know Linux on ARM926EJ-S can
fix it up in sw like Martin described, but I'm not
sure every ARMv5 CPU supports alignment trap.


Johannes

--
For unsubscribe information see http://sourceware.org/lists.html#faq

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Compiler Memory Alignment Issue
  2012-02-03 14:14     ` Johannes Stezenbach
@ 2012-02-03 14:23       ` Yann E. MORIN
  2012-02-03 20:41         ` Johannes Stezenbach
  2012-02-03 15:13       ` Richard Koch
  1 sibling, 1 reply; 10+ messages in thread
From: Yann E. MORIN @ 2012-02-03 14:23 UTC (permalink / raw)
  To: crossgcc; +Cc: Johannes Stezenbach, Bob Dunlop, Richard Koch, Martin Guy

Johannes, Richard, Bob, Martin, All,

On Friday 03 February 2012 15:13:59 Johannes Stezenbach wrote:
> On Fri, Feb 03, 2012 at 02:21:23PM +0100, Yann E. MORIN wrote:
> > On Friday 03 February 2012 11:16:27 Bob Dunlop wrote:
> > > On Thu, Feb 02 at 01:15, Richard Koch wrote:
> > > > I'm seeing an alignment issue when I'm incrementing a pointer.
> > 
> > I Just tried your .config and your sample C code, and it seems to work here
> > (with the buffer overflow fixed):
> 
> As Martin Guy pointed out the issue may be caused
> by wrong alignment.  In fact the behaviour of the code
> is undefined according to C99 if buffer is not suitably aligned:
> https://www.securecoding.cert.org/confluence/display/seccode/EXP36-C.+Do+not+convert+pointers+into+more+strictly+aligned+pointer+types

Indeed, but with the same .config (ie the same compiler settings), and the
same code, I get a correct result, where Richard does not.

Regards,
Yann E. MORIN.

-- 
.-----------------.--------------------.------------------.--------------------.
|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +0/33 662376056 | Software  Designer | \ / CAMPAIGN     |   ^                |
| --==< O_o >==-- '------------.-------:  X  AGAINST      |  /e\  There is no  |
| http://ymorin.is-a-geek.org/ | (*_*) | / \ HTML MAIL    |  """  conspiracy.  |
'------------------------------'-------'------------------'--------------------'

--
For unsubscribe information see http://sourceware.org/lists.html#faq

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: Compiler Memory Alignment Issue
  2012-02-03 14:14     ` Johannes Stezenbach
  2012-02-03 14:23       ` Yann E. MORIN
@ 2012-02-03 15:13       ` Richard Koch
  1 sibling, 0 replies; 10+ messages in thread
From: Richard Koch @ 2012-02-03 15:13 UTC (permalink / raw)
  To: crossgcc



Yann, Johannes, Bob, Martin, All,

Thank you for all your information. I have updated to
C-compiler 4.4.4 and am no longer seeing the alignment
issue.

I have also tried the suggestion to update /proc/cpu/alignment
and that works as well with the older compiler.

I will point out to the developers in my group to try to use
"compliant" coding methods when casting between types.

Thanks again.

-Rick Koch

----------------------------------------
> Date: Fri, 3 Feb 2012 15:13:59 +0100

> From: js@sig21.net

> To: yann.morin.1998@free.fr

> CC: crossgcc@sourceware.org; bob.dunlop@xyzzy.org.uk; n1gp@hotmail.com; martinwguy@gmail.com

> Subject: Re: Compiler Memory Alignment Issue

>

> Hi Yann,

>

> On Fri, Feb 03, 2012 at 02:21:23PM +0100, Yann E. MORIN wrote:

> > On Friday 03 February 2012 11:16:27 Bob Dunlop wrote:

> > > On Thu, Feb 02 at 01:15, Richard Koch wrote:

> > > > I'm seeing an alignment issue when I'm incrementing a pointer.

> >

> > I Just tried your .config and your sample C code, and it seems to work here

> > (with the buffer overflow fixed):

>

> As Martin Guy pointed out the issue may be caused

> by wrong alignment. In fact the behaviour of the code

> is undefined according to C99 if buffer is not suitably aligned:

> https://www.securecoding.cert.org/confluence/display/seccode/EXP36-C.+Do+not+convert+pointers+into+more+strictly+aligned+pointer+types

>

> I'd suggest to add a printf for the buffer address.

>

> For ARM, unaligned access is supported for ARMv6+, in ARMv5

> unaligned write is UNPREDICTABLE (unaligned read is

> defined as rotated read from aligned address).

> Not sure what's the default CPU for qemu-arm but

> Richard has ARMv5. I know Linux on ARM926EJ-S can

> fix it up in sw like Martin described, but I'm not

> sure every ARMv5 CPU supports alignment trap.

>

>

> Johannes

 		 	   		  

--
For unsubscribe information see http://sourceware.org/lists.html#faq

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Compiler Memory Alignment Issue
  2012-02-03 14:23       ` Yann E. MORIN
@ 2012-02-03 20:41         ` Johannes Stezenbach
  0 siblings, 0 replies; 10+ messages in thread
From: Johannes Stezenbach @ 2012-02-03 20:41 UTC (permalink / raw)
  To: Yann E. MORIN; +Cc: crossgcc, Bob Dunlop, Richard Koch, Martin Guy

On Fri, Feb 03, 2012 at 03:23:33PM +0100, Yann E. MORIN wrote:
> On Friday 03 February 2012 15:13:59 Johannes Stezenbach wrote:
> > On Fri, Feb 03, 2012 at 02:21:23PM +0100, Yann E. MORIN wrote:
> > > On Friday 03 February 2012 11:16:27 Bob Dunlop wrote:
> > > > On Thu, Feb 02 at 01:15, Richard Koch wrote:
> > > > > I'm seeing an alignment issue when I'm incrementing a pointer.
> > > 
> > > I Just tried your .config and your sample C code, and it seems to work here
> > > (with the buffer overflow fixed):
> > 
> > As Martin Guy pointed out the issue may be caused
> > by wrong alignment.  In fact the behaviour of the code
> > is undefined according to C99 if buffer is not suitably aligned:
> > https://www.securecoding.cert.org/confluence/display/seccode/EXP36-C.+Do+not+convert+pointers+into+more+strictly+aligned+pointer+types
> 
> Indeed, but with the same .config (ie the same compiler settings), and the
> same code, I get a correct result, where Richard does not.

Richard has real hardware (ARMv5, Technologics TS-7350 ARM920T).
Since unaligned writes are undefined in ARMv5 qemu-arm is free
to do whatever it wants -- if you don't know what the hw
would do you can't emulate it 100%, I think.


Johannes

--
For unsubscribe information see http://sourceware.org/lists.html#faq

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2012-02-03 20:41 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-02 18:15 Compiler Memory Alignment Issue Richard Koch
2012-02-02 23:09 ` Martin Guy
2012-02-02 23:26 ` Rod Nussbaumer
2012-02-03  9:52 ` Martin Guy
2012-02-03 10:16 ` Bob Dunlop
2012-02-03 13:21   ` Yann E. MORIN
2012-02-03 14:14     ` Johannes Stezenbach
2012-02-03 14:23       ` Yann E. MORIN
2012-02-03 20:41         ` Johannes Stezenbach
2012-02-03 15:13       ` Richard Koch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).