_dl_open() >> dl_open_worker() 2532 static void 2533 dl_open_worker (void *a) 2534 { …………………….. 2547 args->map = new = _dl_map_object (NULL, file, 0, lt_loaded, 0, mode);
| 这里就是调用_dl_map_object 来把文档映射到内存中。原来的函数要从不同的路径搜索动态链接库文档,还要和SONAME(这是动态链接库文档在运行时的别名)比较,这些内容我在这里都删除了。
_dl_open() >> dl_open_worker() >> _dl_map_object() 1693 struct link_map * 1694 internal_function 1695 _dl_map_object (struct link_map *loader, const char *name, int preloaded, 1696 int type, int trace_mode, int mode) 1697 { 1698 int fd; 1699 char *realname; 1700 char *name_copy; 1701 struct link_map *l; 1702 struct filebuf fb; 1703 1704 1705 /* Look for this name among those already loaded. */ 1706 for (l = GL(dl_loaded); l; l = l->l_next) 1707 { 1708 if (!_dl_name_match_p (name, l)) ……………. 1721 return l; 1722 } 1723 1724 fd = open_path (name, namelen, preloaded, &env_path_list, 1725 &realname, &fb); 1726 1727 l = _dl_new_object (name_copy, name, type, loader); 1728 1729 return _dl_map_object_from_fd (name, fd, &fb, realname, loader, type, mode); 1730 1731 1732 }/*end of _dl_map_object*/
|
这里先在已被加载的一个动态链接库的链中搜索,在1706和1721行中就是作这一件事。想起来也很简单,因为可能在一个可执行文档依赖好几个动态链接库。而其中有几个动态链接库或许都依赖于同一个动态链接文档,可能早就加载了这样一个动态链接库,就是这样的情况了。
下面open_path是个关键,这里要指出的是env_path_list得到的方式有几种,一是在系统环境变量,二就是 DT_RUNPATH所指的节中的字符串(参见下面的附录),更有更复杂的,是从其他要加载这个动态链接库文档的动态链接库中得到的环境变量-------这些问题我们都不说明了。
_dl_open() >> dl_open_worker() >> _dl_map_object() >> open_path() 1289 static int open_path (const char *name, size_t namelen, int preloaded, 1290 struct r_search_path_struct *sps, char **realname, 1291 struct filebuf *fbp) 1292 1293 { 1294 struct r_search_path_elem **dirs = sps->dirs; 1295 char *buf; 1296 int fd = -1; 1297 const char *current_what = NULL; 1298 int any = 0; 1299 1300 buf = alloca (max_dirnamelen max_capstrlen namelen); 1301 1302 do 1303 { 1304 struct r_search_path_elem *this_dir = *dirs; 1305 size_t buflen = 0; ……………… 1310 struct stat64 st; 1311 1312 1313 edp = (char *) __mempcpy (buf, this_dir->dirname, this_dir->dirnamelen); 1314 for (cnt = 0; fd == -1 && cnt < ncapstr; cnt) 1315 { 1316 /* Skip this directory if we know it does not exist. */ 1317 if (this_dir->status[cnt] == nonexisting) 1318 continue; 1319 1320 buflen = ((char *) __mempcpy (__mempcpy (edp, capstr[cnt].str, 1321 capstr[cnt].len), name, namelen)- buf); 1322 1323 1324 fd = open_verify (buf, fbp); 1325 1326 1327 __xstat64 (_STAT_VER, buf, &st); 1328 1329 1341 } 1342 ……………. 1358 }
|
在这上面的alloc是在栈上分配空间的函数,这样就不用担心在函数结束的时候出现内存泄漏的情况(好的程式员真的要对内存的分配熟谙于心)。1313行就是把r_search_path_elem的dirname copy过来,而在1320至1321行的内容就是为这个路径加上最后的'/'路径分隔号,而capstr就是根据不同的操作系统和体系得到的路径分隔号。这其实是个很好的例子,因为__memcpy返回的参数是dest string所copy的最后的一个字节的地址,所以每copy之后就会得到新的地址,假如用strncpy来写的话,就要用这样的方法
strncpy(edp, capstr[cnt].str, capstr[cnt].len); edp =capstr[cnt].len; strncpy(edp,name, namelen); edp =namelen; buflen=edp-buf;
|
这就要用四句,而这里用了一句就能够了。
下面的open_verify是打开这个buf所指的文档名,fbp是从这个文档得到的文档开时1024字节的内容,并对文档的有效性进行检查,这里最主要的是ELF_IMAGIC核对。假如成功,就返回一个大于-1的文档描述符。整个open_path就这样完成了打开文档的方法。
_dl_new_object是个分配struct link_map* 数据结构并填充一些最基本的参数。
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!
| | 版权所有 西部数码(www.west263.com)
CopyRight (c) 2002~2007 west263.com all right reserved.
公司地址:四川成都市万和路90号天象大厦4楼 邮编:610031
电话总机:028-86263408 86263960 86264018 86267838 86262244 86263408 售前咨询:总机转201 202 203 204 205 206 207 208 售后服务:总机转211
212 213 214 217 218 晚上0点以后拔分机225 |
|
财务咨询:总机转224
223 传真:028-86264041 财务QQ: 635483282
售前咨询QQ: 327314358 241975952 275026793 408235859 2182518 499513144 售后服务QQ: 634349278 809071471 307742704 512359778 287976517 363783715 在线咨询
《中华人民共和国增值电信业务经营许可证》编号:川B2-20030065号
|