2017-04-12 62 views
0

我想弄清楚重定位是如何工作的,但我似乎無法擺脫困境。 This document描述了重定位ELF文件時可能遇到的不同類型。在ARM Cortex-M3上的ELF重定位

例如,我們以R_ARM_ALU_SB_G0_NC(#70)爲例。

  • 類型:靜態
  • 類:ARM,描述了被搬遷的地點類型(我不明白)
  • 操作:((S + A)| T) - B(S))

我猜數學表達式是我正在尋找的操作。但是,我並不完全理解這如何適合我的功能。 其中重定位發生的方法,如下所示:

int elfloader_arch_relocate(int input_fd, struct elfloader_output *output, 
    unsigned int sectionoffset, char *sectionaddr, struct elf32_rela *rela, char *addr) 

input_fd對於ELF文件的文件描述符,*output被寫入輸出段時使用的,sectionoffset是文件偏移量,重定位可以發現,*sectionaddr是段開始地址(絕對運行時間),*addr是重定位地址。 32位重定位結構看起來像這樣

struct elf32_rela { 
    elf32_addr r_offset; 
    elf32_word r_info; 
    elf32_sword r_addend; 
}; 

在上述26中提到document的命名法是說明頁:

  • S(單獨使用時)是符號的地址。
  • A是重新安置的加數。
  • 如果目標符號S具有類型STT_FUNC並且符號尋址Thumb指令,則T爲1;否則爲0。
  • B(S)是輸出段定義符號

所以我的問題是,其在重定位函數的參數的對應於式中所使用的那些的尋址原點?

+0

你在哪裏做重定位,你有一個在cortex-m3上有一個elf分析器的操作系統嗎? –

+0

我正在使用Contiki OS 2.7,因此我只需要編寫一些與處理器相關的函數,如'elfloader_arch_relocate()' – boortmans

+0

我不清楚您是在實現_linker_還是_loader_。鏈接器作爲編譯的最後階段運行,將「目標文件」轉換爲「可執行文件」和「共享庫」。加載程序作爲執行的第一階段運行,以便在將可執行程序和共享庫引入內存時「修復」它們。鏈接器必須處理比裝載器更多的重定位類型。請說出你的意思。 – zwol

回答

0

如果我讀這個權利,我不知道我,它是這樣的:

  • Saddr
  • B(S)sectionaddr
  • Arela->r_addend
  • T可能可從rela->r_info中的信息推導出;如果不是,我不知道你需要看什麼。

這是一個非常複雜的重定位。考慮從簡單的開始(如R_ARM_ABS16)。在一個動態加載器中,你應該不是而是必須實現你鏈接的規範中的所有重定位類型,只有一小部分。如果您似乎需要大量的重定位類型,這可能是因爲您試圖將未鏈接的目標文件提供給動態裝載程序;您應該使用現有的ARM鏈接器將它們轉換爲共享對象。 (使用GNU工具鏈,你如何做到這一點的第一個近似值是gcc -shared foo.o -o foo.so。)

爲架構拆除現有動態加載器通常是一個很好的計劃;在這些事情的代碼中往往會隱藏許多無證的智慧。例如,這裏是GNU libc's ld.so's ARM relocator。 (LGPL)

+0

當我測試當前的實現時,出現一個關於不支持的重定位類型(#70)的錯誤。那麼通過使用更簡單的重定位可以克服這個錯誤嗎? – boortmans

+0

從長遠來看,儘管您仍然在實施這個實現,但您仍然可以測試逐漸增加複雜性的共享對象。 – zwol

+0

(可能你試圖將一個未鏈接的對象文件提供給一個加載器,這不是首先應該工作的東西,請參閱這個問題的評論。) – zwol

相關問題