2016-01-13 75 views
2

我正在尋找問題。我看到這個鏈接https://hev.cc/2512.html這是做我完全一樣的東西,我想要的。但沒有解釋發生了什麼事情。我也困惑是否可以使用帶main()的共享庫來執行,如果是的話,怎麼辦?我可以猜想我必須給全球主要(),但不知道細節。任何進一步的參考和指導是非常讚賞如何使共享庫可執行

我的工作X86-64 64位的Ubuntu內核3.13

+0

什麼平臺你想做到這一點呢? – fuz

+0

添加了平臺和內核版本 – shami

回答

1

我不明白這對任何事物都有用。您可以始終使用與該庫鏈接的單獨二進制文件中的main獲得相同的功能。製作一個可以同時工作的單一文件,在「愚蠢的電腦技巧」領域是穩固的。即使它是一個測試工具或其他東西,我也可以看到嵌入庫中的main沒有任何好處。

可能有可能會有一些性能方面的原因,比如沒有函數調用經過PLT的間接。


在該示例中,共享庫也是一個有效的ELF可執行文件,因爲它有一個快速和骯髒的入口點從哪裏the ABI說,他們去抓住args作爲main(即從它們拷貝該堆棧進入寄存器)。它還安排正確設置ELF解釋器。它只能在x86-64上工作,因爲沒有爲其他平臺的init_args提供定義。

我很驚訝它的實際工作;我認爲通常的CRT(啓動)代碼確實需要stdio才能正常工作。它看起來像它不初始化extern char **environ;,因爲它只是變得argcargv從堆棧,不envp

無論如何,當作爲一個可執行文件運行,它必須是一個有效的動態鏈接可執行文件所需要的一切:它運行一些代碼和退出,一個解釋,並依賴於libc的入口點。 (ELF共享庫可以依賴於(即鏈接)其他ELF共享庫,就像可執行文件可以)。


當用作庫時,它只是作爲包含一些函數定義的普通庫工作。甚至沒有讓它作爲可執行文件(入口點和解釋器)工作的東西。

我不確定爲什麼您因爲main的多個定義沒有出錯,因爲它沒有被聲明爲"weak" symbol。我想只有在有一個未定義符號的引用時纔會查找共享庫定義。所以main()call.c用來代替main()libtest.so因爲main已經有一個定義鏈接看libtest之前。

3

這根本不是什麼明智的。

共享庫通常沒有它可以使用的任務,因爲它相當於main()函數。主要目標是允許對通用代碼操作進行單獨管理和實施,並且允許在運行該方式的系統上允許加載和共享單個代碼文件,從而減少使用它的應用程序代碼的內存開銷。

可執行文件被設計爲具有單一入口點,從該入口點執行與完成明確定義的任務有關的所有操作。不同的操作系統對該入口點有不同的要求。共享庫通常沒有類似的基礎功能。

因此,爲了(有用地)將共享庫轉換爲可執行文件,您還必須定義(並生成代碼)可從單個入口點啓動的任務。

您鏈接的代碼以源代碼開始,並顯式編碼通過入口點函數調用的main()。如果你沒有圖書館的源代碼,理論上你可以從共享庫中竊取一個新文件(在沒有安全功能的情況下在任何給定的操作系統中防止這種情況),但做一件奇怪的事情。

但實際上你不會以這種方式部署代碼。相反,您可以將共享庫編碼爲共享庫。如果你想執行一些任務,你將編寫一個單獨的可執行文件,鏈接到該庫和代碼。試圖將兩者聯繫在一起會破壞寫圖書館的目的,並扭曲圖書館和應用程序的結構,實施和維護。保持應用程序和庫的分離。

+0

我正在嘗試編寫以特殊方式加載二進制文件的引用監視器。共享庫在這種情況下是一個明智的解決方案。我對嗎?是的,你是正確的共享庫會生成守護進程來進一步限制加載進程的執行。 – shami

0
  • 使用示例創建共享動態庫。

假設用有三個文件分別是:sum.o mul.o和print.o

共享庫名稱 「libmno.so」

cc -shared -o libmno.so sum.o mul.o print.o 

並與

cc main.c ./libmno.so