FazJaxton
FazJaxton

Reputation: 7914

Linker adds extra padding in section?

I am using GCC and am trying to get the linker to create an array of data objects from different files in a custom section. I have added this section to the linker script:

.mydata :
{
  __mydata_start = .;
  KEEP (*(.mydata))
  __mydata_end = .;
}

Here is my data structure:

struct my_type_t {
    unsigned char a;
    size_t b;
    void *c;
    const void *d;
    const void *e;
    const char *f;
};

I am on a 64-bit platform, and sizeof(struct my_type_t) gives 48. However, the linker seems to want to align these structures to 64-bytes.

My declarations:

struct my_type_t a1 __attribute__((section(".mydata"))) = {
    1, 2, (void *)3, (void *)4, (void *)5, (void *)6,
};
struct my_type_t a2 __attribute__((section(".mydata"))) = {
    7, 8, (void *)9, (void *)10, (void *)11, (void *)12,
};

Linker output:

$ gcc -o ldtest ldtest.c -Wl,-Tlink.ld
$ objcopy -Obinary -j .mydata ldtest mydata
$ hd mydata
00000000  01 00 00 00 00 00 00 00  02 00 00 00 00 00 00 00  |................|
00000010  03 00 00 00 00 00 00 00  04 00 00 00 00 00 00 00  |................|
00000020  05 00 00 00 00 00 00 00  06 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000040  07 00 00 00 00 00 00 00  08 00 00 00 00 00 00 00  |................|
00000050  09 00 00 00 00 00 00 00  0a 00 00 00 00 00 00 00  |................|
00000060  0b 00 00 00 00 00 00 00  0c 00 00 00 00 00 00 00  |................|

If I instead declare it as an array:

struct my_type_t a1[2] __attribute__((section(".mydata"))) = {
    {
    1, 2, (void *)3, (void *)4, (void *)5, (void *)6,
    },
    {
    7, 8, (void *)9, (void *)10, (void *)11, (void *)12,
    },
};

There is no padding, as expected:

00000000  01 00 00 00 00 00 00 00  02 00 00 00 00 00 00 00  |................|
00000010  03 00 00 00 00 00 00 00  04 00 00 00 00 00 00 00  |................|
00000020  05 00 00 00 00 00 00 00  06 00 00 00 00 00 00 00  |................|
00000030  07 00 00 00 00 00 00 00  08 00 00 00 00 00 00 00  |................|
00000040  09 00 00 00 00 00 00 00  0a 00 00 00 00 00 00 00  |................|
00000050  0b 00 00 00 00 00 00 00  0c 00 00 00 00 00 00 00  |................|

Why is the linker adding extra padding beyond what the compiler thinks is necessary, and how can I get rid of it?

Upvotes: 0

Views: 2204

Answers (1)

Tomas Skäre
Tomas Skäre

Reputation: 184

I don't know why it wants it aligned on 64-byte, but you can do:

struct my_type_t {
    unsigned char a;
    size_t b;
    void *c;
    const void *d;
    const void *e;
    const char *f;
} __attribute__ ((aligned (64)));

To make gcc automatically pad each struct to the nearest higher 64-byte address and make sizeof(struct my_type_t) also include the padding. This makes operations like this work correctly:

struct my_type_t *s = &__mydata_start;
s++; // Jump to next entry
s[0]; // First entry
s[1]; // Second entry

Upvotes: 0

Related Questions