mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	modpost: stop symbol preloading for modversion CRC
It is complicated to add mocked-up symbols for pre-handling CRC. Handle CRC after all the export symbols in the relevant module are registered. Call handle_modversion() after the handle_symbol() iteration. In some cases, I see atand-alone __crc_* without __ksymtab_*. For example, ARCH=arm allyesconfig produces __crc_ccitt_veneer and __crc_itu_t_veneer. I guess they come from crc_ccitt, crc_itu_t, respectively. Since __*_veneer are auto-generated symbols, just ignore them. Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
This commit is contained in:
		
							parent
							
								
									9bd2a099d7
								
							
						
					
					
						commit
						1743694eb2
					
				
					 1 changed files with 39 additions and 32 deletions
				
			
		|  | @ -169,7 +169,7 @@ struct symbol { | |||
| 	unsigned int vmlinux:1;    /* 1 if symbol is defined in vmlinux */ | ||||
| 	unsigned int kernel:1;     /* 1 if symbol is from kernel
 | ||||
| 				    *  (only for external modules) **/ | ||||
| 	unsigned int preloaded:1;  /* 1 if symbol from Module.symvers, or crc */ | ||||
| 	unsigned int preloaded:1;  /* 1 if symbol from Module.symvers */ | ||||
| 	unsigned int is_static:1;  /* 1 if symbol is not global */ | ||||
| 	enum export  export;       /* Type of export */ | ||||
| 	char name[0]; | ||||
|  | @ -410,16 +410,17 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod, | |||
| 	return s; | ||||
| } | ||||
| 
 | ||||
| static void sym_update_crc(const char *name, struct module *mod, | ||||
| 			   unsigned int crc, enum export export) | ||||
| static void sym_set_crc(const char *name, unsigned int crc) | ||||
| { | ||||
| 	struct symbol *s = find_symbol(name); | ||||
| 
 | ||||
| 	if (!s) { | ||||
| 		s = new_symbol(name, mod, export); | ||||
| 		/* Don't complain when we find it later. */ | ||||
| 		s->preloaded = 1; | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * Ignore stand-alone __crc_*, which might be auto-generated symbols | ||||
| 	 * such as __*_veneer in ARM ELF. | ||||
| 	 */ | ||||
| 	if (!s) | ||||
| 		return; | ||||
| 
 | ||||
| 	s->crc = crc; | ||||
| 	s->crc_valid = 1; | ||||
| } | ||||
|  | @ -683,12 +684,34 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname) | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void handle_modversion(const struct module *mod, | ||||
| 			      const struct elf_info *info, | ||||
| 			      const Elf_Sym *sym, const char *symname) | ||||
| { | ||||
| 	unsigned int crc; | ||||
| 
 | ||||
| 	if (sym->st_shndx == SHN_UNDEF) { | ||||
| 		warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n", | ||||
| 		     symname, mod->name, is_vmlinux(mod->name) ? "":".ko"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (sym->st_shndx == SHN_ABS) { | ||||
| 		crc = sym->st_value; | ||||
| 	} else { | ||||
| 		unsigned int *crcp; | ||||
| 
 | ||||
| 		/* symbol points to the CRC in the ELF object */ | ||||
| 		crcp = sym_get_data(info, sym); | ||||
| 		crc = TO_NATIVE(*crcp); | ||||
| 	} | ||||
| 	sym_set_crc(symname, crc); | ||||
| } | ||||
| 
 | ||||
| static void handle_symbol(struct module *mod, struct elf_info *info, | ||||
| 			  const Elf_Sym *sym, const char *symname) | ||||
| { | ||||
| 	unsigned int crc; | ||||
| 	enum export export; | ||||
| 	bool is_crc = false; | ||||
| 	const char *name; | ||||
| 
 | ||||
| 	if ((!is_vmlinux(mod->name) || mod->is_dot_o) && | ||||
|  | @ -697,21 +720,6 @@ static void handle_symbol(struct module *mod, struct elf_info *info, | |||
| 	else | ||||
| 		export = export_from_sec(info, get_secindex(info, sym)); | ||||
| 
 | ||||
| 	/* CRC'd symbol */ | ||||
| 	if (strstarts(symname, "__crc_")) { | ||||
| 		is_crc = true; | ||||
| 		crc = (unsigned int) sym->st_value; | ||||
| 		if (sym->st_shndx != SHN_UNDEF && sym->st_shndx != SHN_ABS) { | ||||
| 			unsigned int *crcp; | ||||
| 
 | ||||
| 			/* symbol points to the CRC in the ELF object */ | ||||
| 			crcp = sym_get_data(info, sym); | ||||
| 			crc = TO_NATIVE(*crcp); | ||||
| 		} | ||||
| 		sym_update_crc(symname + strlen("__crc_"), mod, crc, | ||||
| 				export); | ||||
| 	} | ||||
| 
 | ||||
| 	switch (sym->st_shndx) { | ||||
| 	case SHN_COMMON: | ||||
| 		if (strstarts(symname, "__gnu_lto_")) { | ||||
|  | @ -746,11 +754,6 @@ static void handle_symbol(struct module *mod, struct elf_info *info, | |||
| 		} | ||||
| #endif | ||||
| 
 | ||||
| 		if (is_crc) { | ||||
| 			const char *e = is_vmlinux(mod->name) ?"":".ko"; | ||||
| 			warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n", | ||||
| 			     symname + strlen("__crc_"), mod->name, e); | ||||
| 		} | ||||
| 		mod->unres = alloc_symbol(symname, | ||||
| 					  ELF_ST_BIND(sym->st_info) == STB_WEAK, | ||||
| 					  mod->unres); | ||||
|  | @ -2055,14 +2058,18 @@ static void read_symbols(const char *modname) | |||
| 		handle_moddevtable(mod, &info, sym, symname); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Apply symbol namespaces from __kstrtabns_<symbol> entries. */ | ||||
| 	for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { | ||||
| 		symname = remove_dot(info.strtab + sym->st_name); | ||||
| 
 | ||||
| 		/* Apply symbol namespaces from __kstrtabns_<symbol> entries. */ | ||||
| 		if (strstarts(symname, "__kstrtabns_")) | ||||
| 			sym_update_namespace(symname + strlen("__kstrtabns_"), | ||||
| 					     namespace_from_kstrtabns(&info, | ||||
| 								      sym)); | ||||
| 
 | ||||
| 		if (strstarts(symname, "__crc_")) | ||||
| 			handle_modversion(mod, &info, sym, | ||||
| 					  symname + strlen("__crc_")); | ||||
| 	} | ||||
| 
 | ||||
| 	// check for static EXPORT_SYMBOL_* functions && global vars
 | ||||
|  | @ -2476,7 +2483,7 @@ static void read_dump(const char *fname, unsigned int kernel) | |||
| 		s->kernel    = kernel; | ||||
| 		s->preloaded = 1; | ||||
| 		s->is_static = 0; | ||||
| 		sym_update_crc(symname, mod, crc, export_no(export)); | ||||
| 		sym_set_crc(symname, crc); | ||||
| 		sym_update_namespace(symname, namespace); | ||||
| 	} | ||||
| 	release_file(file, size); | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Masahiro Yamada
						Masahiro Yamada