預處理器將無法找出結構偏移量,因此沒有任何宏魔法單獨爲您轉儲偏移量。
如果您正在構建嵌入式目標,您可能會創建.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
或某些這樣的值,以使兩個編譯器以相同格式發出整數。
'stddef.h'中有一個宏'offsetof()'。請參閱https://en.wikipedia.org/wiki/Offsetof – cdarke
每個對象中的DWARF信息都會有(如果啓用了調試信息)。但它需要一些解析來提取數據。 – kaylum
您可以確定爲您的結構設置「包」寬度,並在兩個項目上強制使用相同的值。 – LPs