一個多月沒有寫 blog 了...並不是沒有東西想寫,而是剛好換了新工作,並且接了幾個有時程壓力的任務,所以每天都累得跟狗一樣... :P
Anyway,趁今天早點下班,將一個工作上遇到的連結問題紀錄一下,或許對某些朋友剛好有幫助。問題是這樣的,在某個使用 MIPS GNU toolchain 的環境中,原本一份可以順利編譯的 code ,今天加了一點 code 後,突然出現了連結錯誤:
Anyway,趁今天早點下班,將一個工作上遇到的連結問題紀錄一下,或許對某些朋友剛好有幫助。問題是這樣的,在某個使用 MIPS GNU toolchain 的環境中,原本一份可以順利編譯的 code ,今天加了一點 code 後,突然出現了連結錯誤:
relocation truncated to fit: R_MIPS_GPREL16 against `no symbol'大家似乎都第一次遇到這個錯誤,google 一陣子找不太到直接解法,但是隱約看到有人提到跟 small data section、register GP 有關,記得在 See MIPS Run 中有描述過類似的句子,翻開教科書(chapter 2),果然提到 GP 可能會被利用來作為快速的 addressing 方式,但由於要在一個指令作完 addressing ,所以只能用到一個 32 bits 指令的 16 bits,所以如果是以 GP-relative relative addressing 方式來作 relocation ,就必須注意資料必須在 GP 的前後 32KB 的範圍。也就是說,我們有兩種解法:
- 檢查 toolchain 將哪些 sections 的存取或指令用了 GP-relative addressing,然後改寫 linker script 將這些 sections 與 script 中的 _gp 排近一點(在 reset.S 之類的地方通常會拿 _gp 當作 GP 的值)。
- 利用編譯選項 -G0,使其不要產生 small data section,而這看起來似乎就是靜態連結時的唯一一種會用的 GP-relative addressing 的 section 。
我們採用方法1,因為方法2似乎有人有遇過不少問題,為了避免又撞到這類 link error 問題,先用安全點的作法。:-)
留言
張貼留言