青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

JonsenElizee

Software Developing Blog

"An idea is fragile . It can be killed by a scornful smile or a yawn .It can be mound down by irony and scared to death by a cold look."
"Most cultures throughout human history have not liked creative individuals .They ignore them or kill them.It is a very efficient way of stopping creativity."

------Advertising boss Charles Browe and Howard Gardner ,professor at Harvard

   :: 首頁 :: 新隨筆 ::  ::  :: 管理 ::
How does linux lib work?


用 Linux 進行動態(tài)加載

Linux 并不會自動為給定程序加載和鏈接庫,而是與應用程序本身共享該控制權。這個過程就稱為動態(tài)加載。使用動態(tài)加載,應用程序能夠先指定要加載的庫,然后將該庫作為一個可執(zhí)行文件來使用(即調用其中的函數(shù))。但是正如您在前面所了解到的,用于動態(tài)加載的共享庫與標準共享庫(ELF 共享對象)無異。事實上,ld-linux 動態(tài)鏈接器作為 ELF 加載器和解釋器,仍然會參與到這個過程中。

動態(tài)加載(Dynamic Loading,DL)API 就是為了動態(tài)加載而存在的,它允許共享庫對用戶空間程序可用。盡管非常小,但是這個 API 提供了所有需要的東西,而且很多困難的工作是在后臺完成的。表 1 展示了這個完整的 API。


表 1. Dl API
函數(shù) 描述
dlopen 使對象文件可被程序訪問
dlsym 獲取執(zhí)行了 dlopen 函數(shù)的對象文件中的符號的地址
dlerror 返回上一次出現(xiàn)錯誤的字符串錯誤
dlclose 關閉目標文件

該過程首先是調用 dlopen,提供要訪問的文件對象和模式。調用 dlopen 的結果是稍候要使用的對象的句柄。mode 參數(shù)通知動態(tài)鏈接器何時執(zhí)行再定位。有兩個可能的值。第一個是 RTLD_NOW,它表明動態(tài)鏈接器將會在調用 dlopen 時完成所有必要的再定位。第二個可選的模式是 RTLD_LAZY,它只在需要時執(zhí)行再定位。這是通過在內部使用動態(tài)鏈接器重定向所有尚未再定位的請求來完成的。這樣,動態(tài)鏈接器就能夠在請求時知曉何時發(fā)生了新的引用,而且再定位可以正常進行。后面的調用無需重復再定位過程。

還可以選擇另外兩種模式,它們可以按位 ORmode 參數(shù)中。RTLD_LOCAL 表明其他任何對象都無法使加載的共享對象的符號用于再定位過程。如果這正是您想要的的話(例如,為了讓共享的對象能夠調用原始進程映像中的符號),那就使用 RTLD_GLOBAL 吧。

dlopen 函數(shù)還會自動解析共享庫中的依賴項。這樣,如果您打開了一個依賴于其他共享庫的對象,它就會自動加載它們。函數(shù)返回一個句柄,該句柄用于后續(xù)的 API 調用。dlopen 的原型為:

#include <dlfcn.h>

void *dlopen( const char *file, int mode );

有了 ELF 對象的句柄,就可以通過調用 dlsym 來識別這個對象內的符號的地址了。該函數(shù)采用一個符號名稱,如對象內的一個函數(shù)的名稱。返回值為對象符號的解析地址:

void *dlsym( void *restrict handle, const char *restrict name );

如果調用該 API 時發(fā)生了錯誤,可以使用 dlerror 函數(shù)返回一個表示此錯誤的人類可讀的字符串。該函數(shù)沒有參數(shù),它會在發(fā)生前面的錯誤時返回一個字符串,在沒有錯誤發(fā)生時返回 NULL:

char *dlerror();

最后,如果無需再調用共享對象的話,應用程序可以調用 dlclose 來通知操作系統(tǒng)不再需要句柄和對象引用了。它完全是按引用來計數(shù)的,所以同一個共享對象的多個用戶相互間不會發(fā)生沖突(只要還有一個用戶在使用它,它就會待在內存中)。任何通過已關閉的對象的 dlsym 解析的符號都將不再可用。

char *dlclose( void *handle );





回頁首


動態(tài)加載示例

了 解了 API 之后,下面讓我們來看一看 DL API 的例子。在這個應用程序中,您主要實現(xiàn)了一個 shell,它允許操作員來指定庫、函數(shù)和參數(shù)。換句話說,也就是用戶能夠指定一個庫并調用該庫(先前未鏈接于該應用程序的)內的任意一個函數(shù)。首先使用 DL API 來解析該庫中的函數(shù),然后使用用戶定義的參數(shù)(用來發(fā)送結果)來調用它。清單 2 展示了完整的應用程序。


清單 2. 使用 DL API 的 Shell
	
#include <stdio.h>
#include <dlfcn.h>
#include <string.h>

#define MAX_STRING 80


void invoke_method( char *lib, char *method, float argument )
{
void *dl_handle;
float (*func)(float);
char *error;

/* Open the shared object */
dl_handle = dlopen( lib, RTLD_LAZY );
if (!dl_handle) {
printf( "!!! %s\n", dlerror() );
return;
}

/* Resolve the symbol (method) from the object */
func = dlsym( dl_handle, method );
error = dlerror();
if (error != NULL) {
printf( "!!! %s\n", error );
return;
}

/* Call the resolved method and print the result */
printf(" %f\n", (*func)(argument) );

/* Close the object */
dlclose( dl_handle );

return;
}


int main( int argc, char *argv[] )
{
char line[MAX_STRING+1];
char lib[MAX_STRING+1];
char method[MAX_STRING+1];
float argument;

while (1) {

printf("> ");

line[0]=0;
fgets( line, MAX_STRING, stdin);

if (!strncmp(line, "bye", 3)) break;

sscanf( line, "%s %s %f", lib, method, &argument);

invoke_method( lib, method, argument );

}

}

要構建這個應用程序,需要通過 GNU Compiler Collection(GCC)使用如下的編譯行。選項 -rdynamic 用來通知鏈接器將所有符號添加到動態(tài)符號表中(目的是能夠通過使用 dlopen 來實現(xiàn)向后跟蹤)。-ldl 表明一定要將 dllib 鏈接于該程序。

gcc -rdynamic -o dl dl.c -ldl

再回到 清單 2main 函數(shù)僅充當解釋器,解析來自輸入行的三個參數(shù)(庫名、函數(shù)名和浮點參數(shù))。如果出現(xiàn) bye 的話,應用程序就會退出。否則的話,這三個參數(shù)就會傳遞給使用 DL API 的 invoke_method 函數(shù)。

首先調用 dlopen 來訪問目標文件。如果返回 NULL 句柄,表示無法找到對象,過程結束。否則的話,將會得到對象的一個句柄,可以進一步詢問對象。然后使用 dlsym API 函數(shù),嘗試解析新打開的對象文件中的符號。您將會得到一個有效的指向該符號的指針,或者是得到一個 NULL 并返回一個錯誤。

在 ELF 對象中解析了符號后,下一步就只需要調用函數(shù)。要注意一下這個代碼和前面討論的動態(tài)鏈接的差別。在這個例子中,您強行將目標文件中的符號地址用作函數(shù)指 針,然后調用它。而在前面的例子是將對象名作為函數(shù),由動態(tài)鏈接器來確保符號指向正確的位置。雖然動態(tài)鏈接器能夠為您做所有麻煩的工作,但這個方法會讓您 構建出極其動態(tài)的應用程序,它們可以再運行時被擴展。

調用 ELF 對象中的目標函數(shù)后,通過調用 dlclose 來關閉對它的訪問。

清 單 3 展示了一個如何使用這個測試程序的例子。在這個例子中,首先編譯程序而后執(zhí)行它。接著調用了 math 庫(libm.so)中的幾個函數(shù)。完成演示后,程序現(xiàn)在能夠用動態(tài)加載來調用共享對象(庫)中的任意函數(shù)了。這是一個很強大的功能,通過它還能夠給程序 擴充新的功能。


清單 3. 使用簡單的程序來調用庫函數(shù)
	
mtj@camus:~/dl$ gcc -rdynamic -o dl dl.c -ldl
mtj@camus:~/dl$ ./dl
> libm.so cosf 0.0
1.000000
> libm.so sinf 0.0
0.000000
> libm.so tanf 1.0
1.557408
> bye
mtj@camus:~/dl$





回頁首


工具

Linux 提供了很多種查看和解析 ELF 對象(包括共享庫)的工具。其中最有用的一個當屬 ldd 命令,您可以使用它來發(fā)送共享庫依賴項。例如,在 dl 應用程序上使用 ldd 命令會顯示如下內容:

mtj@camus:~/dl$ ldd dl
linux-gate.so.1 => (0xffffe000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7fdb000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7eac000)
/lib/ld-linux.so.2 (0xb7fe7000)
mtj@camus:~/dl$

ldd 所告訴您的是:該 ELF 映像依賴于 linux-gate.so(一個特殊的共享對象,它處理系統(tǒng)調用,它在文件系統(tǒng)中無關聯(lián)文件)、libdl.so(DL API)、GNU C 庫(libc.so)以及 Linux 動態(tài)加載器(因為它里面有共享庫依賴項)。

readelf 命令是一個有很多特性的實用程序,它讓您能夠解析和讀取 ELF 對象。readelf 有一個有趣的用途,就是用來識別對象內可再定位的項。對于我們這個簡單的程序來說(清單 2 展示的程序),您可以看到需要再定位的符號為:

mtj@camus:~/dl$ readelf -r dl

Relocation section '.rel.dyn' at offset 0x520 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
08049a3c 00001806 R_386_GLOB_DAT 00000000 __gmon_start__
08049a78 00001405 R_386_COPY 08049a78 stdin

Relocation section '.rel.plt' at offset 0x530 contains 8 entries:
Offset Info Type Sym.Value Sym. Name
08049a4c 00000207 R_386_JUMP_SLOT 00000000 dlsym
08049a50 00000607 R_386_JUMP_SLOT 00000000 fgets
08049a54 00000b07 R_386_JUMP_SLOT 00000000 dlerror
08049a58 00000c07 R_386_JUMP_SLOT 00000000 __libc_start_main
08049a5c 00000e07 R_386_JUMP_SLOT 00000000 printf
08049a60 00001007 R_386_JUMP_SLOT 00000000 dlclose
08049a64 00001107 R_386_JUMP_SLOT 00000000 sscanf
08049a68 00001907 R_386_JUMP_SLOT 00000000 dlopen
mtj@camus:~/dl$

從這個列表中,您可以看到各種各樣的需要再定位(到 libc.so)的 C 庫調用,包括對 DL API(libdl.so)的調用。函數(shù) __libc_start_main 是一個 C 庫函數(shù),它優(yōu)先于程序的 main 函數(shù)(一個提供必要初始化的 shell)而被調用。

其他操作對象文件的實用程序包括:objdump,它展示了關于對象文件的信息;nm,它列出來自對象文件(包括調試信息)的符號。還可以將 EFL 程序作為參數(shù),直接調用 Linux 動態(tài)鏈接器,從而手動啟動映像:

mtj@camus:~/dl$ /lib/ld-linux.so.2 ./dl
> libm.so expf 0.0
1.000000
>

另外,可以使用 ld-linux.so 的 --list 選項來羅列 ELF 映像的依賴項(ldd 命令也如此)。切記,它僅僅是一個用戶空間程序,是由內核在需要時引導的。


posted on 2010-10-01 02:10 JonsenElizee 閱讀(545) 評論(0)  編輯 收藏 引用 所屬分類: Linux.Basic
By JonsenElizee
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            性欧美激情精品| 性欧美xxxx大乳国产app| 欧美成人精品1314www| 欧美一区二区三区婷婷月色 | 亚洲一区二区成人| 亚洲午夜久久久久久尤物| 一区二区免费在线播放| 亚洲午夜女主播在线直播| 亚洲欧美卡通另类91av| 欧美在线视频不卡| 久久综合给合久久狠狠狠97色69| 老司机免费视频一区二区| 亚洲天堂激情| 久久免费视频在线观看| 亚洲男人影院| 久久精品国产99| 免费在线观看日韩欧美| 欧美日韩三级视频| 国产精品综合| 亚洲成人在线网站| 亚洲一区二区久久| 欧美在线一区二区三区| 麻豆精品视频在线观看| 91久久精品国产91久久性色tv| 亚洲成人在线网| 日韩视频中文字幕| 欧美在线影院| 欧美日韩国产二区| 国产精品视频在线观看| 亚洲欧洲一区二区在线播放| 国内精品免费午夜毛片| 日韩视频免费观看高清完整版| 亚洲一区二区三区精品视频| 久久久久国产一区二区三区四区| 欧美夫妇交换俱乐部在线观看| 中文在线资源观看视频网站免费不卡| 久久国产精品久久久久久| 欧美xart系列高清| 国产欧美日韩三区| 在线天堂一区av电影| 久久免费少妇高潮久久精品99| 亚洲精品美女久久7777777| 欧美亚洲系列| 欧美特黄a级高清免费大片a级| 亚洲高清av在线| 久久九九热re6这里有精品| 99香蕉国产精品偷在线观看| 欧美福利视频| 亚洲成人在线网站| 久久天天躁夜夜躁狠狠躁2022| 中日韩美女免费视频网址在线观看| 久久在线免费视频| 好吊视频一区二区三区四区| 午夜精品久久久久久久| 亚洲人成人99网站| 欧美凹凸一区二区三区视频| 激情视频一区二区| 欧美影院一区| 日韩一区二区精品视频| 欧美a级一区二区| 黑人一区二区三区四区五区| 香蕉久久夜色精品| 一本色道久久综合| 欧美日韩综合精品| 一区二区三区.www| 一本一本久久| 国产精品久久久久久亚洲毛片 | 你懂的国产精品| 久久er精品视频| 好吊色欧美一区二区三区视频| 欧美一区在线视频| 午夜视频精品| 国产欧美一区二区精品婷婷| 亚洲一区二区三区乱码aⅴ蜜桃女| 亚洲精品一区二区在线观看| 欧美久久电影| 亚洲综合精品四区| 香蕉乱码成人久久天堂爱免费 | 亚洲黄色免费网站| 欧美大片在线观看| 欧美大学生性色视频| 一区二区电影免费在线观看| 亚洲毛片在线观看| 国产精品久久久91| 久久日韩精品| 亚洲高清av| 欧美一级网站| 欧美一区二区三区四区高清 | 午夜精品久久久久久久99樱桃| 国产精品久久久久国产a级| 亚洲欧美精品suv| 性色av一区二区三区红粉影视| 尤物yw午夜国产精品视频| 亚洲高清一区二| 欧美日韩国产一区精品一区| 欧美专区在线播放| 欧美xart系列在线观看| 亚洲欧美日韩国产一区| 久久久久91| 一区二区高清在线观看| 欧美在线观看视频在线| 日韩视频在线你懂得| 亚洲在线网站| 亚洲精品日韩在线观看| 午夜精品福利视频| 日韩午夜av| 久久本道综合色狠狠五月| 亚洲激情视频在线观看| 亚洲免费一在线| 亚洲精品资源| 新片速递亚洲合集欧美合集| 亚洲精品四区| 久久精品国产一区二区电影| 国产精品99久久久久久宅男| 久久爱另类一区二区小说| 亚洲午夜精品福利| 美女网站在线免费欧美精品| 午夜视频在线观看一区二区三区 | 亚洲精品影院在线观看| 亚洲欧美经典视频| 日韩一区二区高清| 久久综合九九| 久久久999精品视频| 国产精品成人一区二区网站软件| 欧美成人嫩草网站| 国产一区二区三区奇米久涩| 99精品国产在热久久下载| 亚洲欧洲精品一区二区三区| 欧美一区二区观看视频| 亚洲在线视频一区| 欧美二区乱c少妇| 玖玖在线精品| 国产日韩欧美一区在线 | 久久裸体视频| 久久精品夜色噜噜亚洲a∨| 欧美日韩精品一区视频| 欧美激情精品| 亚洲激情av| 欧美高清视频在线| 亚洲国产视频直播| 亚洲精品久久久久久久久久久久| 亚洲精品视频在线观看网站 | 免费久久99精品国产| 欧美视频专区一二在线观看| 最新亚洲一区| 日韩午夜av电影| 欧美精品二区| 亚洲精品在线电影| 9l国产精品久久久久麻豆| 免费一级欧美片在线播放| 欧美大片在线影院| 亚洲日本aⅴ片在线观看香蕉| 老司机凹凸av亚洲导航| 欧美激情精品| 一区二区三区不卡视频在线观看| 欧美激情视频网站| 亚洲精品久久久久久久久久久久久| 亚洲精品美女久久7777777| 欧美国产第一页| 亚洲精品男同| 欧美伊人精品成人久久综合97| 国产欧亚日韩视频| 久久久久久九九九九| 欧美激情一区二区三区蜜桃视频 | 最近中文字幕日韩精品| 99精品视频网| 国产精品欧美久久| 欧美在线观看网址综合| 欧美激情中文不卡| 亚洲视频在线观看三级| 国产麻豆午夜三级精品| 久久久久久久高潮| av成人手机在线| 久久蜜桃香蕉精品一区二区三区| 最新国产乱人伦偷精品免费网站| 欧美美女视频| 欧美伊人精品成人久久综合97| 欧美激情中文不卡| 欧美一区二区在线免费观看| 伊人狠狠色丁香综合尤物| 欧美另类69精品久久久久9999| 亚洲欧美成人一区二区三区| 欧美成人午夜激情在线| 亚洲男人av电影| 亚洲国产美女| 国产精品综合视频| 欧美成人性网| 欧美中文字幕第一页| 亚洲狼人综合| 麻豆精品视频在线观看| 亚洲综合视频网| 亚洲国产国产亚洲一二三| 国产精品日韩专区| 欧美成人一品| 久久久久久久久一区二区| 亚洲少妇一区| 亚洲精品久久7777| 亚洲福利视频网| 久久中文在线| 欧美中文字幕视频在线观看|