2015-09-21 72 views
3

我想爲我的Infiniband ConnectX-3卡構建/刻錄最新的Mellanox Flexboot固件。但是,Mellanox沒有提供二進制形式的最新版本。但是他們會提供源代碼。這是嚴格別名規則中斷的有效代碼修復嗎?

不幸的是,當我試圖編譯它,我得到以下錯誤:

net/udp/dhcp.c: In function 'start_dhcp': 
net/udp/dhcp.c:1361:3: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing] 
    seed += *((uint32_t *)&netdev->ll_addr[j]); 
^
cc1: all warnings being treated as errors 
make: *** [bin/dhcp.o] Error 1 
make: *** Waiting for unfinished jobs.... 
Build failed! 

看代碼,下面塊是問題。特別是種子系。這是因爲嚴格的別名開啓了,我們試圖訪問另一種類型。

/** 
* Having both i and j , makes the code more robust 
* in the improbable case that MAX_LL_ADDR_LEN is not a 
* multiple of 4 bytes. 
*/ 
for (i = 0, j = 0; i < (MAX_LL_ADDR_LEN >> 2); ++i, j += 4){ 
    seed += *((uint32_t *)&netdev->ll_addr[j]); 
} 

我的修復使它編譯。

for (i = 0, j = 0; i < (MAX_LL_ADDR_LEN >> 2); ++i, j += 4){ 
    uint32_t s; 
    memcpy(&s, &netdev->ll_addr[j], 4); 
    seed += s; 
} 

但是在我燒它之前,這實際上是否相等?我認爲它應該是,但我只是想在燃燒這麼重要的東西之前再次發表意見。

FYI: ll_addr被定義爲:

#define MAX_LL_ADDR_LEN 20 

... 

/** Link-layer address 
* 
* This is the current link-layer address assigned to the  
* device. It can be changed at runtime. 
*/ 
uint8_t ll_addr[MAX_LL_ADDR_LEN]; 

種子以後這裏使用:

dhcp->xid = random (seed); 

/* Store DHCP transaction ID for fakedhcp code */ 
dhcp_last_xid = dhcp->xid; 

所以,在我看來這個種子東西只是用來播種隨機數發生器。我不確定他們種下它的方式是非常好的主意,但毫無疑問,它不應該傷害事情,我認爲即使它給出了不同的答案,我的解決方法也應該沒問題。所以謝謝大家的答案。

+3

它們應該是,如果原始代碼實際工作。如果'uint32_t'具有更嚴格的對齊規則,底部的代碼甚至可以工作,而頂部的代碼可能不會。還要確保字段以相同的順序存儲字節,而磁盤或網絡中的哪些數據可能不是。如果我對可移植性或編碼風格很迂腐,我可能會建議將魔術數字4改爲「sizeof」。 – Davislor

+2

這看起來很像黑客。他們應該使用正確的(去)序列化。很可能還有其他這樣的結構。 – Olaf

+0

它看起來像是一個硬件地址,可能我訪問它的方式很好。它應該等同於我想的以前的hacky代碼。 – Matt

回答

2

在這種情況下,只要ll_addrchar的數組,就是安全的。 j的增量保證增量一次只能執行四個字節,即uint32_t的寬度。

在這種情況下,最好使用原始實現並忽略錯誤,特別是如果代碼是在C99之前編寫的。

Lorehead對於字節順序也很有幫助。

相關問題