rt-thread装载共享目标文件的过程源码分析
在http://blog.csdn.net/flydream0/article/details/8684811一文中已对rrt-thread的moudle源码进行分析,在讲到rt_module_load函数时,程序将对两个类型的elf文件进行分别处理,共享目标文件将用_load_shared_object函数来处理,而可重定位文件则用_load_relocated_object函数来处理,由于要了解这两个函数的具体过程,必须先熟悉了解elf文件格式(参考:http://blog.csdn.net/flydream0/article/details/8719036)。这里假设你已非常了解elf文件格式的前提下说深入分析_load_shared_object函数的源码,让你了彻底了解rt-thread是如何输入一个共享目标文件。
_load_relocated_object函数大体分为四个步骤:
- 分配内存并初始化。根据输入目标文件的顺序,以段(segment)为单位将它们拼装起来并映射到module->module_space内存空间。对module->module_space的内容某些位置根据重定位信息进行修改。生成最终的符号表。
for (i=0, count=0; i<shdr[index].sh_size/sizeof(Elf32_Sym); i++)扫描所有导出符号 { rt_size_t length; if ((ELF_ST_BIND(symtab[i].st_info) != STB_GLOBAL) || (ELF_ST_TYPE(symtab[i].st_info) != STT_FUNC)) continue; length = rt_strlen((const char *)(strtab + symtab[i].st_name)) + 1;//符号名长度 module->symtab[count].addr = (void *)(module->module_space + symtab[i].st_value);//设置符号地址 module->symtab[count].name = rt_malloc(length);//设置符号名 rt_memset((void *)module->symtab[count].name, 0, length); rt_memcpy((void *)module->symtab[count].name, strtab + symtab[i].st_name, length); count ++; }
从上面可以看出,导出符号表的过程其实是找出.dynsym节区,因为此节区包含了所有链表符号,但并是不所有符号都是需要导出的,只在标志为全局的符号,且此符号类型为函数的符号才是需要导出的。最后将此类型的全局函数全部导出到模块对应的符号表内。
rt-thread装载共享文件的过程分析完毕!