Tuesday Jul 17, 2007

Data Alignment Issue


If a data structure will be used in both a 32bits binary and a 64bits
binary, e.g., an ioctl structure which is passed from a 32bit
application to the 64bit kernel, then we need to consider the code
alignment issue. Because:

  •   The structure size might be different for a same structure.
  •   The offset of each structure member might be different for a same
    structure.

The alignment can be decided by compiler options. The default compiler behavior will conform to the top rule: all structure members must start at its alignment addresses, and, the whole structure should start at the alignment address of its largest member.
For example, uint16_t will always start at even address, uint32_t will always align at 4 bytes boundary, etc. There are also some points as following:

  1.  

    The whole structure's size will be according to the biggest member's
    alignment. e.g., if the biggest member is uint32_t, then the whole
    sizeof(struct) will be divided exactly by 4bytes.

  2.  

    If there are "long", "pointer", or "long double" types in the
    structure
    members, then the alignment in 32bit and 64bit binaries will be
    different. Because they are different length. For example, if there is
    a pointer in a structure, then, in a 32bits binary, it aligns at 4
    bytes
    address; in a 64bits binary, it aligns at 8 bytes address.

  3.  

    The max alignment of 32bits binary is 32bits, The max alignment of
    64bits binary is 64bits. So, if there is a "long long" in a 32bits
    binary, it aligns at 4 bytes address; however, the same type aligns at
    8 bytes address in a 64bits binary.

  4.  

    "enum" type is considered as uint_t.

Code alignment feature can be disabled by setting specific compiler options, such as, gcc -fpack-struct, which will remove the code alignment feature, that is, there are no gaps between structure members.

And "pack" pragma can also do the same job, details refer to the related section of "C User's Guide". Note that the pragma might cause problems on different hardware platforms.

The following table is comparing the data types between 32bits and 64bits binaries.

C Type                      ILP32                LP64
 

char                            8                    8
  short                          16                   16
  int                              32                   32
  long                           32                   64
  long long                   64                   64
  float                           32                   32
  double                       64                   64
  long double               96                   128
  pointer                      32                   64


-----------------------------
An data structure Example:


    typedef enum list {

        a0 = 0,

        a1 = 1,

        a2 = 2,

    } list_t;


    struct align {

        uint16_t a;

        uint8_t  b;

        list_t    list;

        uint8_t    c;  

        uint8_t    d;  

    } sa;


offset_a=fffffd7fffdff954, offset_b=fffffd7fffdff956,
offset_list=fffffd7fffdff958, offset_c=fffffd7fffdff95c,
offset_d=fffffd7fffdff95d, sizeof_allign=12

About

Colin Zou is a software engineer enjoying improving operating systems. Besides sitting at a computer all day like a dull boy, he also likes hiking and the activities on the beach.

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today