簡體   English   中英

如何最好地在x86上為我的語言傳遞全局偏移表(GOT)?

[英]How can I best pass a Global Offset Table (GOT) for my language on x86?

我正在為我的語言編寫一個小型程序加載器,因為我放棄了對ELF格式的理解(在這樣做的同時,我最終可能會更好地理解它)。 我映射了內存中的文件,而燕尾服使之歡欣鼓舞。

我不想通過對其進行任何更改來阻礙程序的共享。 因此,我最終要做的事情與C和elf一樣:全局偏移表。

問題是:如何為程序傳遞GOT?

首先想到的是在寄存器或堆棧參數中給出它。 在寄存器中,它會很棒,但是x86會因為其寄存器數而延遲。 這可能意味着我將失去ebx或ebp或類似的東西。 在明智的架構中,這將是一個公平的權衡。 在x86中感覺有點失敗。

拆卸共享庫后,我發現gcc會將其作為IP相對地址來處理。 如果我這樣做,它將是:

    call 0
here:
    pop eax
    ; do something with [eax + (got - here) + index*4]

雖然,這在某種程度上讓人感到復雜。 我不喜歡這樣做。

還有其他想法嗎?

編輯:當要使用多個庫處理此問題時,我意識到:每個應用程序將有多個GOT,並且某些GOT的使用取決於我所在的代碼塊。因此,將GOT保留在單獨的寄存器中將需要一些我不知道的其他技巧。 我想知道當將GOT保留在寄存器中時,它們如何解決此問題。

您可以將段寄存器之一(或其基址)用作二進制映像的基址。 因此,您將參考全局數據,例如。 如FS:xxx。

這些寄存器是所謂的分段存儲器模型的剩余部分。 基本上,段是具有指定基數(和限制)的線性地址空間中的“窗口”,並且如果使用它們進行尋址(例如,如果地址為0010:00000001),則結果地址為(帶選擇器0010的段基數) )00000001。 段的基數(以及其他參數)存儲在描述符表中(其中有更多),這是內存中的特殊區域。 這些只能在內核模式下進行修改,Linux中有執行此操作的系統調用( modify_ldtarch_prctl )。 在64位模式下,情況要復雜一些。

有關參考,請參閱AMD64體系結構手冊 ,尤其是第2卷:系統編程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM