2016-09-27 15 views
0

私はGCCを使用しており、リンカがカスタムセクションの異なるファイルからデータオブジェクトの配列を作成しようとしています。私は、リンカスクリプトにこのセクションを追加しました:ここリンカはセクションに余分な埋め込みを追加しますか?

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

は私のデータ構造である:

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

私は64ビットプラットフォーム上で午前、そしてsizeof(struct my_type_t)はしかし、48を与え、リンカがいるようですこれらの構造体を64バイトに整列させたい

マイ宣言:

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, 
}; 

リンカ出力:

$ 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 |................| 

私の代わりに、配列として宣言した場合:

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, 
    }, 
}; 

は予想通り、パディングはありません。

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 |................| 

リンカーは、コンパイラが必要と考える以上の余分な埋め込みを追加する理由は何ですか?どうすれば取り除くことができますか?

+1

「リンカが余分な埋め込みを追加する理由は何ですか?」 - なぜそうではありませんか?規格には、異なるオブジェクトの特定の配置についての要件はありません。準拠したCコードとは無関係です。 "それを取り除く方法"に関して、あなたはすでに答えを持っています。私は問題を見ません。 – Olaf

+0

私が指定したように、これらのオブジェクトは異なるファイルにあるので、それらの配列を作成することはできません。しかし、私はそれらをCコードの配列として扱いたい。 Cはサイズが48だと思うので、最初のものへのポインタをインクリメントすると、次のものの先頭ではなく、パディングを指します。 – FazJaxton

+0

"しかし、私はそれらをCコードの配列として扱いたい" - それは未定義の動作です。 XY問題のような音。異なるアプローチが必要です(例:ポインタのテーブル。 – Olaf

答えて

0

それが64バイトに揃えたい理由を私は知らないが、あなたは行うことができます(

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

を最寄りの上位64バイトのアドレスにgccを自動的にパッド各構造体を作成およびsizeofを作成するにはstruct my_type_t)にもパディングが含まれています。これにより、次のような操作が正しく行われます。

struct my_type_t *s = &__mydata_start; 
s++; // Jump to next entry 
s[0]; // First entry 
s[1]; // Second entry 
関連する問題