[Bug c/57862] invalid read struct uint32_t member (ARMV5)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57862 Richard Earnshaw changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID --- Comment #8 from Richard Earnshaw --- As Mikael says, this is undefined behaviour.
[Bug c/57862] invalid read struct uint32_t member (ARMV5)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57862 --- Comment #7 from Mikael Pettersson --- (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)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57862 --- Comment #6 from Gaetano Mendola --- 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)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57862 --- Comment #5 from Mikael Pettersson --- 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)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57862 --- Comment #4 from Gaetano Mendola --- 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)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57862 --- Comment #3 from Mikael Pettersson --- (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.
[Bug c/57862] invalid read struct uint32_t member (ARMV5)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57862 --- Comment #2 from Gaetano Mendola --- 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)
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57862 --- Comment #1 from Mikael Pettersson --- 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).