Browse Source

extract module symbol via elf file instead of using RTM_EXPORT declare

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1214 bbd45198-f89e-11dd-88c7-29a3b14d5316
qiuyiuestc 14 years ago
parent
commit
848a08f62e
1 changed files with 63 additions and 14 deletions
  1. 63 14
      src/module.c

+ 63 - 14
src/module.c

@@ -251,11 +251,10 @@ static void rt_module_init_object_container(struct rt_module* module)
  */
  */
 rt_module_t rt_module_load(const rt_uint8_t* name, void* module_ptr)
 rt_module_t rt_module_load(const rt_uint8_t* name, void* module_ptr)
 {
 {
-	rt_uint32_t index;
-	rt_uint32_t module_size = 0;
+	rt_uint8_t *ptr = RT_NULL;
 	rt_module_t module = RT_NULL;
 	rt_module_t module = RT_NULL;
-	rt_uint8_t *ptr, *strtab;
 	rt_bool_t linked = RT_FALSE;
 	rt_bool_t linked = RT_FALSE;
+	rt_uint32_t index, module_size = 0;
 
 
 	rt_kprintf("rt_module_load: %s\n", name);
 	rt_kprintf("rt_module_load: %s\n", name);
 
 
@@ -327,11 +326,13 @@ rt_module_t rt_module_load(const rt_uint8_t* name, void* module_ptr)
 			rt_uint32_t i, nr_reloc;
 			rt_uint32_t i, nr_reloc;
 			Elf32_Sym *symtab;
 			Elf32_Sym *symtab;
 			Elf32_Rel *rel;
 			Elf32_Rel *rel;
+			rt_uint8_t *strtab;
+			static rt_bool_t unsolved = RT_FALSE;
 
 
 			/* get relocate item */
 			/* get relocate item */
 			rel = (Elf32_Rel *) ((rt_uint8_t*)module_ptr + shdr[index].sh_offset);
 			rel = (Elf32_Rel *) ((rt_uint8_t*)module_ptr + shdr[index].sh_offset);
 
 
-			/* locate .rel.plt and .rel.dyn */
+			/* locate .rel.plt and .rel.dyn section */
 			symtab =(Elf32_Sym *) ((rt_uint8_t*)module_ptr + shdr[shdr[index].sh_link].sh_offset);
 			symtab =(Elf32_Sym *) ((rt_uint8_t*)module_ptr + shdr[shdr[index].sh_link].sh_offset);
 			strtab = (rt_uint8_t*) module_ptr + shdr[shdr[shdr[index].sh_link].sh_link].sh_offset;
 			strtab = (rt_uint8_t*) module_ptr + shdr[shdr[shdr[index].sh_link].sh_link].sh_offset;
  			nr_reloc = (rt_uint32_t) (shdr[index].sh_size / sizeof(Elf32_Rel));
  			nr_reloc = (rt_uint32_t) (shdr[index].sh_size / sizeof(Elf32_Rel));
@@ -344,12 +345,7 @@ rt_module_t rt_module_load(const rt_uint8_t* name, void* module_ptr)
 				rt_kprintf("relocate symbol %s shndx %d\n", strtab + sym->st_name, sym->st_shndx);
 				rt_kprintf("relocate symbol %s shndx %d\n", strtab + sym->st_name, sym->st_shndx);
 #endif
 #endif
 				if((sym->st_shndx != SHT_NULL) || (ELF_ST_BIND(sym->st_info) == STB_LOCAL))	
 				if((sym->st_shndx != SHT_NULL) || (ELF_ST_BIND(sym->st_info) == STB_LOCAL))	
-				{	
-					rt_module_arm_relocate(
-						module, 
-						rel, 
-						(Elf32_Addr)(module->module_space + sym->st_value));
-				}
+					rt_module_arm_relocate(module, rel,  (Elf32_Addr)(module->module_space + sym->st_value));
 				else if(!linked)
 				else if(!linked)
 				{
 				{
 					Elf32_Addr addr;
 					Elf32_Addr addr;
@@ -361,17 +357,64 @@ rt_module_t rt_module_load(const rt_uint8_t* name, void* module_ptr)
 					if (addr == 0)
 					if (addr == 0)
 					{
 					{
 						rt_kprintf("can't find %s in kernel symbol table\n", strtab + sym->st_name);
 						rt_kprintf("can't find %s in kernel symbol table\n", strtab + sym->st_name);
-						rt_object_delete(&(module->parent));
-						rt_free(module);
-						return RT_NULL;
+						unsolved = RT_TRUE;
 					}	
 					}	
-					rt_module_arm_relocate(module, rel, addr);
+					else rt_module_arm_relocate(module, rel, addr);
 				}
 				}
 				rel ++;
 				rel ++;
 			}
 			}
+
+			if(unsolved) 
+			{
+				rt_object_delete(&(module->parent));
+				rt_free(module);
+				return RT_NULL;
+			}	
 		}
 		}
 	}
 	}
 
 
+	/* construct module symbol table */
+	for (index = 0; index < elf_module->e_shnum; index ++)
+	{	
+		/* find .dynsym section */
+		rt_uint8_t* shstrab = (rt_uint8_t*) module_ptr + shdr[elf_module->e_shstrndx].sh_offset;
+		if (rt_strcmp(shstrab + shdr[index].sh_name, ELF_DYNSYM) == 0) break;
+	}
+
+	/* found .dynsyn section */
+	if(index != elf_module->e_shnum)
+	{
+		int i, count = 0;
+		Elf32_Sym *symtab = RT_NULL;
+		rt_uint8_t *strtab  = RT_NULL;
+
+		symtab =(Elf32_Sym *) ((rt_uint8_t*)module_ptr + shdr[index].sh_offset);
+		strtab = (rt_uint8_t*) module_ptr + shdr[shdr[index].sh_link].sh_offset;			
+
+		for(i=0; i<shdr[index].sh_size/sizeof(Elf32_Sym); i++)
+		{
+			if((ELF_ST_BIND(symtab[i].st_info) == STB_GLOBAL) && (ELF_ST_TYPE(symtab[i].st_info) == STT_FUNC))
+				count++;
+		}
+
+		module->symtab = (struct rt_module_symtab*)rt_malloc(count * sizeof(struct rt_module_symtab));
+		module->nsym = count;
+		for(i=0, count=0; i<shdr[index].sh_size/sizeof(Elf32_Sym); i++)
+		{
+			if((ELF_ST_BIND(symtab[i].st_info) == STB_GLOBAL) && (ELF_ST_TYPE(symtab[i].st_info) == STT_FUNC))
+			{
+				rt_size_t length = rt_strlen(strtab + symtab[i].st_name) + 1;
+
+				module->symtab[count].addr = module->module_space + symtab[i].st_value; 
+				module->symtab[count].name = rt_malloc(length);
+				rt_memset(module->symtab[count].name, 0, length);
+				rt_memcpy(module->symtab[count].name, strtab + symtab[i].st_name, length);
+				count++;
+			}	
+		}	
+	}	
+	
+#if 0
 	/* construct module symbol table */
 	/* construct module symbol table */
 	for (index = 0; index < elf_module->e_shnum; index ++)
 	for (index = 0; index < elf_module->e_shnum; index ++)
 	{	
 	{	
@@ -382,6 +425,7 @@ rt_module_t rt_module_load(const rt_uint8_t* name, void* module_ptr)
 			module->nsym = shdr[index].sh_size / sizeof(struct rt_module_symtab);
 			module->nsym = shdr[index].sh_size / sizeof(struct rt_module_symtab);
 		}	
 		}	
 	}
 	}
+#endif
 
 
 	/* init module object container */
 	/* init module object container */
 	rt_module_init_object_container(module);
 	rt_module_init_object_container(module);
@@ -501,6 +545,7 @@ FINSH_FUNCTION_EXPORT_ALIAS(rt_module_open, exec, exec module from file);
  */
  */
 rt_err_t rt_module_unload(rt_module_t module)
 rt_err_t rt_module_unload(rt_module_t module)
 {
 {
+	int i;
 	struct rt_object* object;
 	struct rt_object* object;
 	struct rt_list_node *list;
 	struct rt_list_node *list;
 
 
@@ -696,6 +741,10 @@ rt_err_t rt_module_unload(rt_module_t module)
 	/* release module space memory */
 	/* release module space memory */
 	rt_free(module->module_space);
 	rt_free(module->module_space);
 
 
+	/* release module symbol table */
+	for(i=0; i<module->nsym; i++) rt_free(module->symtab[i].name);
+	if(module->symtab != RT_NULL) rt_free(module->symtab);
+	
 	/* delete module object */
 	/* delete module object */
 	rt_object_delete((rt_object_t)module);
 	rt_object_delete((rt_object_t)module);