2016-09-13 37 views
0

Linux內核中是否有任何需要有效用戶空間堆棧的內容?也就是說,如果我要編寫一個程序,只能訪問數據段中的固定內存位置,或者只使用寄存器進行一些計算,我是否可以安全地將堆棧指針設置爲0或另一個無效地址,甚至可以一個有效的地址,而不必擔心那裏的內存被覆蓋?Linux是否需要用戶空間堆棧?

  • 我認爲硬件中斷可以很好地處理,因爲它們可以在任何時候發生,並且內核在處理這些中斷時不會對用戶空間的狀態做出假設。
  • 雖然在映射頁面發生故障呢?
  • 如何進行系統調用?當然不是通過libc,而是直接通過?

附加問題:有人知道有關其他操作系統的問題的答案,例如: MacOS X,BSD,Windows?

+0

爲什麼你認爲堆棧這樣的負擔? *「如果我要編寫一個程序......」* - 爲什麼不嘗試編寫這樣一個不重要的程序來查看這是否可能? *「我安全地將堆棧指針設置爲0 ...」* - 除非你破解內核,否則*你希望這樣做?僅供參考許多處理器體系結構和C語言(以及其他高級語言)都需要堆棧,因此它不僅僅是Linux操作系統。 IOW C和Linux通常僅用於具有硬件堆棧支持的處理器。 – sawdust

+0

@sawdust在評論中很難回答你所有的問題。我不能僅僅測試它,因爲這並不能保證我所做的事實際上是允許的;它可能恰好適用於我的測試,並打破下一個內核版本或體系結構。堆棧指針可以通過'movq $ 0,%rsp'進行簡單的修改,不需要內核入侵。 x86只需要一個用於ISR的堆棧,這與用戶空間無關(當然,您不能推/ pop/call/ret)。另外,我知道C,但那不是我的問題。我詢問_kernel_是否需要一個有效的_user space_堆棧。 –

+0

爲了給出更多的上下文:我不一定要完全避免堆棧(儘管這將是一個有趣的實驗)。我正在考慮使用適合當前線程/光纖的最大調用圖的正確大小的非常小的堆棧。這意味着堆棧有時可能完全滿,並且不一定在頁面邊界上結束。我想確定內核可以處理這種情況。也許用不同的方式來解釋這個問題:Linux內核是否需要用戶空間來遵循特定的ABI? –

回答

1

我懷疑任何人都可以很有信心地告訴你,但我會採取刺。

我的猜測是,在技術上沒有堆棧運行是可行的,但獲得正確的細節將是非常困難的。

中斷和異常(例如,頁面錯誤)應將寄存器保存到內核堆棧而不是用戶空間堆棧,因此這沒有問題。如果直接在彙編中編碼,系統調用甚至應該可以工作(除非你在32位模式下運行並且使用5個以上的參數,在這種情況下,第六個在用戶堆棧上,但你仍然可以很容易地修復它)。 gdb希望你的堆棧安排如此。

其他事情要考慮:

通常,您被分配在啓動時堆棧區域。不確定;你可以通過適當的鏈接器指令來改變它。堆棧區域通常配置爲向下生長。當地址不在任何當前分配的區域中時出現頁面錯誤時,假定要生成堆棧區域。錯誤地址不得少於sp(即esp/rsp)(少於64K軟件)的值。我想這不是一個問題,如果你不使用堆棧。

當您調用clone系統調用來創建一個新任務(線程)時,您爲新任務提供了一個堆棧指針。我不確定內核究竟做了什麼,看起來只是填入新任務中的sp寄存器(如果它不爲零)。這導致我...

clone系統調用和其他一些沒有很好地指定。 libc中嵌入了許多魔術來正確處理forkpthread_create等等。如果你想創建額外的線程,你必須知道這個魔法並自己實現它。

信號處理希望能夠將參數推送到用戶空間堆棧。我不認爲你可以在沒有堆棧的情況下使用信號 - 或者至少它會非常複雜。

+0

因此,看起來我只是需要對內核有信心,而不是做出意想不到的事情。至少Linux有一個永不破壞用戶空間的策略。感謝你提醒我關於clone()和朋友的特殊待遇,這是我不得不留意的事情。對於信號處理程序,可以用'sigaltstack(2)'設置一個備用棧。 –