[Bug c/57862] invalid read struct uint32_t member (ARMV5)

2013-08-21 Thread rearnsha at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57862

Richard Earnshaw rearnsha at gcc dot gnu.org changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

--- Comment #8 from Richard Earnshaw rearnsha at gcc dot gnu.org ---
As Mikael says, this is undefined behaviour.


[Bug c/57862] invalid read struct uint32_t member (ARMV5)

2013-07-10 Thread mendola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57862

--- Comment #4 from Gaetano Mendola mendola at gmail dot com ---
At this point I'm very puzzled. The fact I have to use memcpy instead of an
assignment for sake of portability is plain wrong.

Consider that only looking at:

  struct in_addr myInAddr;
  myInAddr.s_addr = theIpHeader-daddr;

I have no idea if the theIpHeader pointer was the result of a malloc or the
result of an assignment with a not aligned offset. Unless of course I inspect
the pointer value. 

The entire application (my application) suppose, as I think it should, that an
assignment of a value retrieved from a structure member is correctly done, note
that I'm not relying if this is done with 1 bus access, 2 or whatever. 

I'm going to put 2 in /proc/cpu/alignment and considering it as a kernel
configuration problem. 

btw clang behaves correctly even with a kernel not well configured.


[Bug c/57862] invalid read struct uint32_t member (ARMV5)

2013-07-10 Thread mikpe at it dot uu.se
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57862

--- Comment #5 from Mikael Pettersson mikpe at it dot uu.se ---
Your test case contains this:

===snip===
struct iphdr
  {
...
  };
...
int main()
{
  char thePacket[1518];
  memset(thePacket, 0, 1518);

  thePacket[30] = 1;
  thePacket[31] = 2;
  thePacket[32] = 3;
  thePacket[33] = 4;

  struct ether_header* theEthHeader = (struct ether_header*)(thePacket);

  struct iphdr* theIpHeader = (struct iphdr*)((const unsigned
char*)(theEthHeader) + 14);

  struct in_addr myInAddr;
  myInAddr.s_addr = theIpHeader-daddr;
===snip===

The alignment of thePacket is arbitrary, so the alignment of theIpHeader is
unknown, and struct iphdr is not declared with attribute packed.  The final
load may therefore be misaligned.


[Bug c/57862] invalid read struct uint32_t member (ARMV5)

2013-07-10 Thread mendola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57862

--- Comment #6 from Gaetano Mendola mendola at gmail dot com ---
That's clear to me.

I'm writing in C not in assembler, what I'm trying to understand is if I have
to
threat the following code:

  struct in_addr myInAddr;
  myInAddr.s_addr = theIpHeader-daddr;

as not portable, where myInAddr.s_addr and theIpHeader-daddr are of the same
type. I'm not a c-standard lawyer but I'm hard believing that in the standard
that assignment is marked as: undefined behaviour unless you use memcpy.

And again printf-ing the two values, both are reported on screen as the same
number but the bytes behind that area of memory do not contain the same values.


[Bug c/57862] invalid read struct uint32_t member (ARMV5)

2013-07-10 Thread mikpe at it dot uu.se
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57862

--- Comment #7 from Mikael Pettersson mikpe at it dot uu.se ---
(In reply to Gaetano Mendola from comment #6)
   struct in_addr myInAddr;
   myInAddr.s_addr = theIpHeader-daddr;
 
 as not portable, where myInAddr.s_addr and theIpHeader-daddr are of the
 same type. I'm not a c-standard lawyer but I'm hard believing that in the
 standard
 that assignment is marked as: undefined behaviour unless you use memcpy.

The assignment is immaterial, it's the load (theIpHeader-daddr) that's
problematic because the base pointer (theIpHeader) is not correctly aligned for
its declared type (struct iphdr).


[Bug c/57862] invalid read struct uint32_t member (ARMV5)

2013-07-09 Thread mikpe at it dot uu.se
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57862

--- Comment #1 from Mikael Pettersson mikpe at it dot uu.se ---
This has all the indications of a mis-aligned memory access.  Since you're on
Linux, please make sure that the 'User faults' field in /proc/cpu/alignment
shows a value of 2 (fixup) or 3 (fixup+warn).  You can 'echo 3 
/proc/cpu/alignment'
in your startup scripts to ensure this setting, or you can hack it into the
kernel source's arch/arm/mm/alignment.c (which is what I do).


[Bug c/57862] invalid read struct uint32_t member (ARMV5)

2013-07-09 Thread mendola at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57862

--- Comment #2 from Gaetano Mendola mendola at gmail dot com ---
I had 0. Putting 2 or 3 fixed the problem. Now my question is: who is faulty? 
Kernel configuration on this platform, the architecture, the compiler or even
me ?
BTW, compiling that code with clang even with 0 in /proc/cpu/alignment gives
the right result.


[Bug c/57862] invalid read struct uint32_t member (ARMV5)

2013-07-09 Thread mikpe at it dot uu.se
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57862

--- Comment #3 from Mikael Pettersson mikpe at it dot uu.se ---
(In reply to Gaetano Mendola from comment #2)
 who is faulty? 
 Kernel configuration on this platform, the architecture, the compiler or
 even me ?

All of the above.  The architecture for getting mis-alignment very very wrong,
the kernel for not enforcing correct handling of alignment faults, the compiler
for sometimes generating mis-aligned accesses where the original code had none
(there are PRs about that affecting at least ARM and I believe also SPARC), and
your code for (apparently) having a load from a mis-aligned address where
portable code should use memcpy() (the fact that memcpy() didn't help you is a
consequence of one of those PRs).

My ARMv5TE box' /proc/cpu/alignment currently reads

User:   100669

all of which come from gcc's own test suite.  That's just so wrong.