pkarashchenko commented on pull request #5251:
URL: https://github.com/apache/incubator-nuttx/pull/5251#issuecomment-1014942062


   > I think the bug is that some architectures do not support dereferencing a 
pointer to an unaligned address. Packing the structs will create more of those, 
won't it?
   
   The case is that packing for Ethernet packet structure will not impact on 
unaligned addresses, but should fix the cases when 16 or 32 bit types are 
accessed with instructions that require addresses to be aligned.
   Similar is available for Ethernet header in Linux 
https://github.com/spotify/linux/blob/master/include/linux/if_ether.h
   Here is some example test1.c:
   ```
   #include <stdint.h>
   
   struct eth_hdr_s
   {
     uint8_t  dest[6]; /* Ethernet destination address (6 bytes) */
     uint8_t  src[6];  /* Ethernet source address (6 bytes) */
     uint16_t type;    /* Type code (2 bytes) */
   };
   
   struct packed_eth_hdr_s
   {
     uint8_t  dest[6]; /* Ethernet destination address (6 bytes) */
     uint8_t  src[6];  /* Ethernet source address (6 bytes) */
     uint16_t type;    /* Type code (2 bytes) */
   } __attribute__ ((packed));
   
   uint8_t pkt[128];
   
   #define BUF ((struct eth_hdr_s *)pkt)
   #define BUF_PACKED ((struct packed_eth_hdr_s *)pkt)
   
   int f(void)
   {
     if (BUF->type == 0x0008)
     {
       return 0;
     }
   
     return 1;
   }
   
   int f_packed(void)
   {
     if (BUF_PACKED->type == 0x0008)
     {
       return 0;
     }
   
     return 1;
   }
   ```
   It is compiled with `arm-none-eabi-gcc -save-temps -Wall -Wextra -c 
-mcpu=cortex-m0 -mthumb -mfloat-abi=soft test1.c` and generates the next output:
   ```
        .cpu cortex-m0
        .arch armv6s-m
        .fpu softvfp
        .eabi_attribute 20, 1
        .eabi_attribute 21, 1
        .eabi_attribute 23, 3
        .eabi_attribute 24, 1
        .eabi_attribute 25, 1
        .eabi_attribute 26, 1
        .eabi_attribute 30, 6
        .eabi_attribute 34, 0
        .eabi_attribute 18, 4
        .file   "test1.c"
        .text
        .global pkt
        .bss
        .align  2
        .type   pkt, %object
        .size   pkt, 128
   pkt:
        .space  128
        .text
        .align  1
        .global f
        .syntax unified
        .code   16
        .thumb_func
        .type   f, %function
   f:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 1, uses_anonymous_args = 0
        push    {r7, lr}
        add     r7, sp, #0
        ldr     r3, .L4
        ldrh    r3, [r3, #12]
        cmp     r3, #8
        bne     .L2
        movs    r3, #0
        b       .L3
   .L2:
        movs    r3, #1
   .L3:
        movs    r0, r3
        mov     sp, r7
        @ sp needed
        pop     {r7, pc}
   .L5:
        .align  2
   .L4:
        .word   pkt
        .size   f, .-f
        .align  1
        .global f_packed
        .syntax unified
        .code   16
        .thumb_func
        .type   f_packed, %function
   f_packed:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 1, uses_anonymous_args = 0
        push    {r7, lr}
        add     r7, sp, #0
        ldr     r3, .L9
        ldrb    r2, [r3, #12]
        ldrb    r3, [r3, #13]
        lsls    r3, r3, #8
        orrs    r3, r2
        uxth    r3, r3
        cmp     r3, #8
        bne     .L7
        movs    r3, #0
        b       .L8
   .L7:
        movs    r3, #1
   .L8:
        movs    r0, r3
        mov     sp, r7
        @ sp needed
        pop     {r7, pc}
   .L10:
        .align  2
   .L9:
        .word   pkt
        .size   f_packed, .-f_packed
        .ident  "GCC: (GNU Arm Embedded Toolchain 10.3-2021.10) 10.3.1 20210824 
(release)"
   ```
   So in case is struct is unpacked we are getting `ldrh` instruction that 
expects 16 bit alignment of `.L4`
   ```
        ldr     r3, .L4
        ldrh    r3, [r3, #12]
        cmp     r3, #8
   ```
   In case if packed is used we are getting:
   ```
        ldr     r3, .L9
        ldrb    r2, [r3, #12]
        ldrb    r3, [r3, #13]
        lsls    r3, r3, #8
        orrs    r3, r2
        uxth    r3, r3
        cmp     r3, #8
   ```
   So `.L9` can have any alignment and the value is reassembled using multiple 
`ldrb` instructions, byte-shift and "or".
   
   But somehow @ptka reports that it does not work in his case.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to