2016-09-27 1 views
0

GCC를 사용하고 있으며 링커에서 사용자 정의 섹션의 다른 파일에서 데이터 객체 배열을 만들려고합니다. 여기 링커에서 섹션에 추가 패딩을 추가합니까?

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

내 데이터 구조입니다 : 내가 링커 스크립트에이 섹션을 추가 한 I는 64 비트 플랫폼에서 오전

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

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))); 

gcc가 자동으로 패드 가까운 높은 64 바이트 주소로 각 구조체하려면 및 (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 
관련 문제