我正在使用 GCC 為 ARM Cortex M3 編譯程式。
我的程式導致出現硬故障,我正在嘗試對其進行故障排除。
GCC 版本是,10.3.1但我也用舊版本(即9.2)確認了這一點。
僅當啟用優化 ( -O3)時才會發生硬故障。
有問題的函式如下:
void XTEA_decrypt(XTEA_t * xtea, uint32_t data[2])
{
uint32_t d0 = data[0];
uint32_t d1 = data[1];
uint32_t sum = XTEA_DELTA * XTEA_NUMBER_OF_ROUNDS;
for (int i = XTEA_NUMBER_OF_ROUNDS; i != 0; i--)
{
d1 -= (((d0 << 4) ^ (d0 >> 5)) d0) ^ (sum xtea->key[(sum >> 11) & 3]);
sum -= XTEA_DELTA;
d0 -= (((d1 << 4) ^ (d1 >> 5)) d1) ^ (sum xtea->key[sum & 3]);
}
data[0] = d0;
data[1] = d1;
}
我注意到故障發生在:
data[0] = d0;
拆開這個,給我:
49 data[0] = d0;
0000f696: lsrs r0, r3, #5
0000f698: eor.w r0, r0, r3, lsl #4
0000f69c: add r0, r3
0000f69e: ldr.w r12, [sp, #4]
0000f6a2: eors r5, r0
0000f6a4: subs r2, r2, r5
0000f6a6: strd r2, r3, [r12]
0000f6aa: add sp, #12
0000f6ac: ldmia.w sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc}
0000f6b0: ldr r3, [sp, #576] ; 0x240
0000f6b2: b.n 0xfda4 <parseNode 232>
違規行特別是:
0000f6a6: strd r2, r3, [r12]
GCC 生成的代碼使用了未對齊的記憶體地址strd,這在我的架構中是不允許的。
如何解決這個問題?
這是編譯器錯誤,還是代碼以某種方式混淆了 GCC?
在 GCC 中是否有任何標志可以改變這種行為?
The aforementioned function belongs to an external library, so I cannot modify it.
However, I prefer a solution that makes GCC produce the correct instructions, instead of modifying the code, as I need to ensure that this bug will actually be fixed, and it is not lurking elsewhere in the code.
UPDATE
Following the recommendations in the comments, I was suspecting that the function itself is called with unaligned data.
I checked the whole stack frame, all previous function calls, and my code does not contain casts, unaligned indexes in buffers etc, in contrast to what I had in mind initially.
The problem is that the buffer itself is unaligned, as it is defined as:
typedef struct {
uint32_t var1;
uint32_t var2;
uint8_t var3;
uint8_t buffer[BUFFER_SIZE];
uint16_t var4;
// More variables here...
} HDLC_t;
(And later cast to uint32_t by the external library).
Swapping places between var3 and buffer solves the issue.
The thing is that again this struct is defined in a library that is not in my control.
So, can GCC detect this issue between the libraries, and either align the data, or warn me of the issue?
uj5u.com熱心網友回復:
那么,GCC 能否檢測到庫之間的這個問題,并對齊資料或警告我這個問題?
是的,它可以,它確實并且必須這樣做才能符合 C 標準。如果您在默認設定下運行 gcc 并嘗試將uint8_t指標(HDLC_t buffer成員)傳遞給需要 的函式,則會發生這種情況uint32_t [2]:
警告:從不兼容的指標型別 [-Wincompatible-pointer-types] 傳遞“XTEA_decrypt”的引數 2
這是一個約束違規,意味著代碼是無效的 C 并且編譯器已經告訴你了。請參閱C 編譯器發現錯誤時必須做什么?-pedantic-errors如果您希望阻止 gcc C 從無效的 C 代碼中生成二進制可執行檔案,則可以打開。
至于如何修復代碼,如果您堅持下去struct:memcpy將buffer成員放入一個臨時uint32_t [2]陣列,然后將其傳遞給函式。
您也可以將 struct 成員宣告為,_Alignas(uint32_t) uint8_t buffer[100];但是如果您可以修改該結構,您最好重新排列它,因為_Alignas會插入 3 個浪費的填充位元組。
uj5u.com熱心網友回復:
最簡單的方法是對齊data到 8 位元組。
您應該像這樣宣告陣列:
__attribute__((aligned(8))) uint32_t data[2];
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/324804.html
