2017-04-04 76 views
1

當我嘗試加載使用內在函數生成的某些密文時,出現段錯誤。我根本不明白這個錯誤。代碼示例:SSE segfault on _mm_store_si128

unsigned char c[177]; 
unsigned char m[161]; 
auth = _mm_setzero_si128(); 
unsigned char M_star[BLOCKSIZE]; 
__m128i tag = auth; 
for(i=0;i<numblocks_mes;++i) 
{ 
    M = _mm_load_si128(m+i*BLOCKSIZE); 
    idx = _mm_set_epi64x(zero,i); // both inputs are unsigned long long 
    tmp = encrypt_block(M,idx); 
    tag = _mm_xor_si128(tag,tmp); 
} 
if(fin_mes) 
{ 
    memcpy(M_star,m+numblocks_mes*BLOCKSIZE,fin_mes); 
    A_star[fin_mes] = 0x80; 
    memset(M_star+fin_mes+1,0,BLOCKSIZE-(fin_mes+1)); 
    M = _mm_load_si128(M_star); 
    idx = _mm_set_epi64x(tag_fin,numblocks_mes); // both inputs are unsigned long long 
    tmp = encrypt_block(M,idx); // Contains calls to AES 
    tag = _mm_xor_si128(tag,tmp); 
} 
// print128_asint(tag); 
tag = encrypt_block(tag,nonce); 
// Following line causes segfault 
_mm_store_si128((__m128i *)&c[numblocks_mes*BLOCKSIZE+fin_mes], tag); // numblocks_mes*BLOCKSIZE+fin_mes = 161 

我曾嘗試過其他類似的問題之前尋找,並試圖出來,但我沒有發現任何東西爲我工作。

+0

我忘了寫fin_mes是一個整數,它是1,BLOCKSIZE是16,numblocks_mes是10. –

+1

它可能是一個對齊問題? – unwind

回答

1

目標地址需要16字節對齊。由於c[]本身沒有特定的對齊方式,因此無法保證c內的任意偏移地址(即使這些偏移量是16的倍數)。

解決方法:使用_mm_storeu_si128而不是_mm_store_si128


請注意,您似乎也很幸運,負載從 mMstar - 你幾乎肯定會改變這些使用 _mm_loadu_si128

+1

非常感謝,它非常完美。看起來有更多的代碼需要經過和修復,因爲我不應該依賴運氣來讓我的代碼工作。 –

+1

是的,有兩種可能的方法:(a)確保所有的數據都是16字節對齊的(可能並不總是可能的)或(b)不對數據對齊做任何假設,並使用未對齊的加載/存儲。在較舊的體系結構中,使用未對齊的加載/存儲可能會造成嚴重的性能損失,但在最近/當前的體系結構中,它通常可以忽略不計。 –