2016-06-09 70 views
6

有沒有什麼方法可以看到C構造在構建期間如何打包?我已經通過幾個類似的帖子關於如何結構可以被封裝爲:查看C結構如何在構建時間內打包

但我不知道是否有生成的文件某種構建時,顯示我到底一個結構是如何打包的?我試着檢查鏈接器生成的映射文件,但它沒有這些信息。 PS:我試圖讓幾個微控制器通過UART相互通信,因爲一個是16位,其他是32位,我每次更新這些結構時都會碰到一些錯誤。

+3

'stddef.h'中有一個宏'offsetof()'。請參閱https://en.wikipedia.org/wiki/Offsetof – cdarke

+0

每個對象中的DWARF信息都會有(如果啓用了調試信息)。但它需要一些解析來提取數據。 – kaylum

+1

您可以確定爲您的結構設置「包」寬度,並在兩個項目上強制使用相同的值。 – LPs

回答

1

預處理器將無法找出結構偏移量,因此沒有任何宏魔法單獨爲您轉儲偏移量。

如果您正在構建嵌入式目標,您可能會創建.bin文件(而不是elf,coff,mach-o)。如果您使用每個目標編譯器在目標文件中創建一個偏移量數組,然後將其轉儲到bin文件,應該可以比較每個目標文件的bin文件。將構建時間檢查過程自動化將是一個好主意。

這裏是我談論的例子:

#include <stdint.h> 
#include <stddef.h> 
typedef struct s1{ 
    uint16_t f1; 
    uint32_t f2; 
    uint64_t f3; 
    int8_t f4[5]; 
    uint32_t f5[2]; 
}s1; 

#define o(f) ((int32_t)offsetof(s1,f)) 

int32_t offsets[]={ 
    o(f1), 
    o(f2), 
    o(f3), 
    o(f4), 
    o(f5) 
}; 

這只是創建偏移表。建立一個mipsel和x86_64並進行比較。下面是一個make文件:

T1:=x86_64-linux-gnu 
CC1:=$(T1)-gcc 
OBJCPY1:=$(T1)-objcopy 
T2:=mipsel-linux 
CC2:=$(T2)-gcc 
OBJCPY2:=$(T2)-objcopy 


.PHONY: all cmp clean hexdumps 

all: hexdumps 

hexdumps: hexdump.$(T1).txt hexdump.$(T2).txt 

hexdump.$(T1).txt: offsets.$(T1).bin 
    hexdump -C $< > [email protected] 

hexdump.$(T2).txt: offsets.$(T2).bin 
    hexdump -C $< > [email protected] 

offsets.$(T1).bin: offsets.$(T1).o 
    $(OBJCPY1) -j.data -O binary $< [email protected] 

offsets.$(T2).bin: offsets.$(T2).o 
    $(OBJCPY2) -j .data -O binary $< [email protected] 

offsets.$(T1).o: offsets.c 
    $(CC1) -Wall -c -o [email protected] $< 

offsets.$(T2).o: offsets.c 
    $(CC2) -Wall -c -o [email protected] $< 

clean: 
    -rm -f offsets.$(T1).o offsets.$(T2).o 
    -rm -f offsets.$(T1).bin offsets.$(T2).bin 
    -rm -f hexdump.$(T1).txt hexdump.$(T2).txt 

現在,比較偏移量是相當簡單:

[email protected] ~/se $ cat hexdump.mipsel-linux.txt 
00000000 00 00 00 00 04 00 00 00 08 00 00 00 10 00 00 00 |................| 
00000010 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 
00000020 
[email protected] ~/se $ cat hexdump.x86_64-linux-gnu.txt 
00000000 00 00 00 00 04 00 00 00 08 00 00 00 10 00 00 00 |................| 
00000010 18 00 00 00          |....| 
00000014 

了MIPS發出一個32字節的數據部分,而不是86 20字節。如果您將尺寸設置爲offsets,則應該可以使用cmp比較構建中的兩個尺寸。

如果您的目標具有不同的字尾,您可能需要將o宏更改爲使用ntohl或某些這樣的值,以使兩個編譯器以相同格式發出整數。