diff options
Diffstat (limited to 'scripts/mod')
| -rw-r--r-- | scripts/mod/Makefile | 2 | ||||
| -rw-r--r-- | scripts/mod/file2alias.c | 149 | ||||
| -rw-r--r-- | scripts/mod/modpost.c | 114 | 
3 files changed, 114 insertions, 151 deletions
diff --git a/scripts/mod/Makefile b/scripts/mod/Makefile index a5b4af47987a..42c5d50f2bcc 100644 --- a/scripts/mod/Makefile +++ b/scripts/mod/Makefile @@ -4,8 +4,6 @@ OBJECT_FILES_NON_STANDARD := y  hostprogs-y	:= modpost mk_elfconfig  always		:= $(hostprogs-y) empty.o -CFLAGS_REMOVE_empty.o := $(ASM_MACRO_FLAGS) -  modpost-objs	:= modpost.o file2alias.o sumversion.o  devicetable-offsets-file := devicetable-offsets.h diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 28a61665bb9c..a37af7d71973 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -47,49 +47,9 @@ typedef struct {  struct devtable {  	const char *device_id; /* name of table, __mod_<name>__*_device_table. */  	unsigned long id_size; -	void *function; +	int (*do_entry)(const char *filename, void *symval, char *alias);  }; -#define ___cat(a,b) a ## b -#define __cat(a,b) ___cat(a,b) - -/* we need some special handling for this host tool running eventually on - * Darwin. The Mach-O section handling is a bit different than ELF section - * handling. The differnces in detail are: - *  a) we have segments which have sections - *  b) we need a API call to get the respective section symbols */ -#if defined(__MACH__) -#include <mach-o/getsect.h> - -#define INIT_SECTION(name)  do {					\ -		unsigned long name ## _len;				\ -		char *__cat(pstart_,name) = getsectdata("__TEXT",	\ -			#name, &__cat(name,_len));			\ -		char *__cat(pstop_,name) = __cat(pstart_,name) +	\ -			__cat(name, _len);				\ -		__cat(__start_,name) = (void *)__cat(pstart_,name);	\ -		__cat(__stop_,name) = (void *)__cat(pstop_,name);	\ -	} while (0) -#define SECTION(name)   __attribute__((section("__TEXT, " #name))) - -struct devtable **__start___devtable, **__stop___devtable; -#else -#define INIT_SECTION(name) /* no-op for ELF */ -#define SECTION(name)   __attribute__((section(#name))) - -/* We construct a table of pointers in an ELF section (pointers generally - * go unpadded by gcc).  ld creates boundary syms for us. */ -extern struct devtable *__start___devtable[], *__stop___devtable[]; -#endif /* __MACH__ */ - -#if !defined(__used) -# if __GNUC__ == 3 && __GNUC_MINOR__ < 3 -#  define __used			__attribute__((__unused__)) -# else -#  define __used			__attribute__((__used__)) -# endif -#endif -  /* Define a variable f that holds the value of field f of struct devid   * based at address m.   */ @@ -110,16 +70,6 @@ extern struct devtable *__start___devtable[], *__stop___devtable[];  #define DEF_FIELD_ADDR(m, devid, f) \  	DEF_FIELD_ADDR_VAR(m, devid, f, f) -/* Add a table entry.  We test function type matches while we're here. */ -#define ADD_TO_DEVTABLE(device_id, type, function) \ -	static struct devtable __cat(devtable,__LINE__) = {	\ -		device_id + 0*sizeof((function)((const char *)NULL,	\ -						(void *)NULL,		\ -						(char *)NULL)),		\ -		SIZE_##type, (function) };				\ -	static struct devtable *SECTION(__devtable) __used \ -		__cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__) -  #define ADD(str, sep, cond, field)                              \  do {                                                            \          strcat(str, sep);                                       \ @@ -439,7 +389,6 @@ static int do_hid_entry(const char *filename,  	return 1;  } -ADD_TO_DEVTABLE("hid", hid_device_id, do_hid_entry);  /* Looks like: ieee1394:venNmoNspNverN */  static int do_ieee1394_entry(const char *filename, @@ -464,7 +413,6 @@ static int do_ieee1394_entry(const char *filename,  	add_wildcard(alias);  	return 1;  } -ADD_TO_DEVTABLE("ieee1394", ieee1394_device_id, do_ieee1394_entry);  /* Looks like: pci:vNdNsvNsdNbcNscNiN. */  static int do_pci_entry(const char *filename, @@ -508,7 +456,6 @@ static int do_pci_entry(const char *filename,  	add_wildcard(alias);  	return 1;  } -ADD_TO_DEVTABLE("pci", pci_device_id, do_pci_entry);  /* looks like: "ccw:tNmNdtNdmN" */  static int do_ccw_entry(const char *filename, @@ -532,7 +479,6 @@ static int do_ccw_entry(const char *filename,  	add_wildcard(alias);  	return 1;  } -ADD_TO_DEVTABLE("ccw", ccw_device_id, do_ccw_entry);  /* looks like: "ap:tN" */  static int do_ap_entry(const char *filename, @@ -543,7 +489,6 @@ static int do_ap_entry(const char *filename,  	sprintf(alias, "ap:t%02X*", dev_type);  	return 1;  } -ADD_TO_DEVTABLE("ap", ap_device_id, do_ap_entry);  /* looks like: "css:tN" */  static int do_css_entry(const char *filename, @@ -554,7 +499,6 @@ static int do_css_entry(const char *filename,  	sprintf(alias, "css:t%01X", type);  	return 1;  } -ADD_TO_DEVTABLE("css", css_device_id, do_css_entry);  /* Looks like: "serio:tyNprNidNexN" */  static int do_serio_entry(const char *filename, @@ -574,7 +518,6 @@ static int do_serio_entry(const char *filename,  	add_wildcard(alias);  	return 1;  } -ADD_TO_DEVTABLE("serio", serio_device_id, do_serio_entry);  /* looks like: "acpi:ACPI0003" or "acpi:PNP0C0B" or "acpi:LNXVIDEO" or   *             "acpi:bbsspp" (bb=base-class, ss=sub-class, pp=prog-if) @@ -612,7 +555,6 @@ static int do_acpi_entry(const char *filename,  	}  	return 1;  } -ADD_TO_DEVTABLE("acpi", acpi_device_id, do_acpi_entry);  /* looks like: "pnp:dD" */  static void do_pnp_device_entry(void *symval, unsigned long size, @@ -736,7 +678,6 @@ static int do_pcmcia_entry(const char *filename,  	add_wildcard(alias);  	return 1;  } -ADD_TO_DEVTABLE("pcmcia", pcmcia_device_id, do_pcmcia_entry);  static int do_vio_entry(const char *filename, void *symval,  		char *alias) @@ -756,7 +697,6 @@ static int do_vio_entry(const char *filename, void *symval,  	add_wildcard(alias);  	return 1;  } -ADD_TO_DEVTABLE("vio", vio_device_id, do_vio_entry);  #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) @@ -829,7 +769,6 @@ static int do_input_entry(const char *filename, void *symval,  		do_input(alias, *swbit, 0, INPUT_DEVICE_ID_SW_MAX);  	return 1;  } -ADD_TO_DEVTABLE("input", input_device_id, do_input_entry);  static int do_eisa_entry(const char *filename, void *symval,  		char *alias) @@ -841,7 +780,6 @@ static int do_eisa_entry(const char *filename, void *symval,  		strcat(alias, "*");  	return 1;  } -ADD_TO_DEVTABLE("eisa", eisa_device_id, do_eisa_entry);  /* Looks like: parisc:tNhvNrevNsvN */  static int do_parisc_entry(const char *filename, void *symval, @@ -861,7 +799,6 @@ static int do_parisc_entry(const char *filename, void *symval,  	add_wildcard(alias);  	return 1;  } -ADD_TO_DEVTABLE("parisc", parisc_device_id, do_parisc_entry);  /* Looks like: sdio:cNvNdN. */  static int do_sdio_entry(const char *filename, @@ -878,7 +815,6 @@ static int do_sdio_entry(const char *filename,  	add_wildcard(alias);  	return 1;  } -ADD_TO_DEVTABLE("sdio", sdio_device_id, do_sdio_entry);  /* Looks like: ssb:vNidNrevN. */  static int do_ssb_entry(const char *filename, @@ -895,7 +831,6 @@ static int do_ssb_entry(const char *filename,  	add_wildcard(alias);  	return 1;  } -ADD_TO_DEVTABLE("ssb", ssb_device_id, do_ssb_entry);  /* Looks like: bcma:mNidNrevNclN. */  static int do_bcma_entry(const char *filename, @@ -914,7 +849,6 @@ static int do_bcma_entry(const char *filename,  	add_wildcard(alias);  	return 1;  } -ADD_TO_DEVTABLE("bcma", bcma_device_id, do_bcma_entry);  /* Looks like: virtio:dNvN */  static int do_virtio_entry(const char *filename, void *symval, @@ -930,7 +864,6 @@ static int do_virtio_entry(const char *filename, void *symval,  	add_wildcard(alias);  	return 1;  } -ADD_TO_DEVTABLE("virtio", virtio_device_id, do_virtio_entry);  /*   * Looks like: vmbus:guid @@ -953,7 +886,6 @@ static int do_vmbus_entry(const char *filename, void *symval,  	return 1;  } -ADD_TO_DEVTABLE("vmbus", hv_vmbus_device_id, do_vmbus_entry);  /* Looks like: rpmsg:S */  static int do_rpmsg_entry(const char *filename, void *symval, @@ -964,7 +896,6 @@ static int do_rpmsg_entry(const char *filename, void *symval,  	return 1;  } -ADD_TO_DEVTABLE("rpmsg", rpmsg_device_id, do_rpmsg_entry);  /* Looks like: i2c:S */  static int do_i2c_entry(const char *filename, void *symval, @@ -975,7 +906,6 @@ static int do_i2c_entry(const char *filename, void *symval,  	return 1;  } -ADD_TO_DEVTABLE("i2c", i2c_device_id, do_i2c_entry);  /* Looks like: spi:S */  static int do_spi_entry(const char *filename, void *symval, @@ -986,7 +916,6 @@ static int do_spi_entry(const char *filename, void *symval,  	return 1;  } -ADD_TO_DEVTABLE("spi", spi_device_id, do_spi_entry);  static const struct dmifield {  	const char *prefix; @@ -1041,7 +970,6 @@ static int do_dmi_entry(const char *filename, void *symval,  	strcat(alias, ":");  	return 1;  } -ADD_TO_DEVTABLE("dmi", dmi_system_id, do_dmi_entry);  static int do_platform_entry(const char *filename,  			     void *symval, char *alias) @@ -1050,7 +978,6 @@ static int do_platform_entry(const char *filename,  	sprintf(alias, PLATFORM_MODULE_PREFIX "%s", *name);  	return 1;  } -ADD_TO_DEVTABLE("platform", platform_device_id, do_platform_entry);  static int do_mdio_entry(const char *filename,  			 void *symval, char *alias) @@ -1075,7 +1002,6 @@ static int do_mdio_entry(const char *filename,  	return 1;  } -ADD_TO_DEVTABLE("mdio", mdio_device_id, do_mdio_entry);  /* Looks like: zorro:iN. */  static int do_zorro_entry(const char *filename, void *symval, @@ -1086,7 +1012,6 @@ static int do_zorro_entry(const char *filename, void *symval,  	ADD(alias, "i", id != ZORRO_WILDCARD, id);  	return 1;  } -ADD_TO_DEVTABLE("zorro", zorro_device_id, do_zorro_entry);  /* looks like: "pnp:dD" */  static int do_isapnp_entry(const char *filename, @@ -1102,7 +1027,6 @@ static int do_isapnp_entry(const char *filename,  		(function >> 12) & 0x0f, (function >> 8) & 0x0f);  	return 1;  } -ADD_TO_DEVTABLE("isapnp", isapnp_device_id, do_isapnp_entry);  /* Looks like: "ipack:fNvNdN". */  static int do_ipack_entry(const char *filename, @@ -1118,7 +1042,6 @@ static int do_ipack_entry(const char *filename,  	add_wildcard(alias);  	return 1;  } -ADD_TO_DEVTABLE("ipack", ipack_device_id, do_ipack_entry);  /*   * Append a match expression for a single masked hex digit. @@ -1189,7 +1112,6 @@ static int do_amba_entry(const char *filename,  	return 1;  } -ADD_TO_DEVTABLE("amba", amba_id, do_amba_entry);  /*   * looks like: "mipscdmm:tN" @@ -1205,7 +1127,6 @@ static int do_mips_cdmm_entry(const char *filename,  	sprintf(alias, "mipscdmm:t%02X*", type);  	return 1;  } -ADD_TO_DEVTABLE("mipscdmm", mips_cdmm_device_id, do_mips_cdmm_entry);  /* LOOKS like cpu:type:x86,venVVVVfamFFFFmodMMMM:feature:*,FEAT,*   * All fields are numbers. It would be nicer to use strings for vendor @@ -1230,7 +1151,6 @@ static int do_x86cpu_entry(const char *filename, void *symval,  		sprintf(alias + strlen(alias), "%04X*", feature);  	return 1;  } -ADD_TO_DEVTABLE("x86cpu", x86_cpu_id, do_x86cpu_entry);  /* LOOKS like cpu:type:*:feature:*FEAT* */  static int do_cpu_entry(const char *filename, void *symval, char *alias) @@ -1240,7 +1160,6 @@ static int do_cpu_entry(const char *filename, void *symval, char *alias)  	sprintf(alias, "cpu:type:*:feature:*%04X*", feature);  	return 1;  } -ADD_TO_DEVTABLE("cpu", cpu_feature, do_cpu_entry);  /* Looks like: mei:S:uuid:N:* */  static int do_mei_entry(const char *filename, void *symval, @@ -1259,7 +1178,6 @@ static int do_mei_entry(const char *filename, void *symval,  	return 1;  } -ADD_TO_DEVTABLE("mei", mei_cl_device_id, do_mei_entry);  /* Looks like: rapidio:vNdNavNadN */  static int do_rio_entry(const char *filename, @@ -1279,7 +1197,6 @@ static int do_rio_entry(const char *filename,  	add_wildcard(alias);  	return 1;  } -ADD_TO_DEVTABLE("rapidio", rio_device_id, do_rio_entry);  /* Looks like: ulpi:vNpN */  static int do_ulpi_entry(const char *filename, void *symval, @@ -1292,7 +1209,6 @@ static int do_ulpi_entry(const char *filename, void *symval,  	return 1;  } -ADD_TO_DEVTABLE("ulpi", ulpi_device_id, do_ulpi_entry);  /* Looks like: hdaudio:vNrNaN */  static int do_hda_entry(const char *filename, void *symval, char *alias) @@ -1309,7 +1225,6 @@ static int do_hda_entry(const char *filename, void *symval, char *alias)  	add_wildcard(alias);  	return 1;  } -ADD_TO_DEVTABLE("hdaudio", hda_device_id, do_hda_entry);  /* Looks like: sdw:mNpN */  static int do_sdw_entry(const char *filename, void *symval, char *alias) @@ -1324,7 +1239,6 @@ static int do_sdw_entry(const char *filename, void *symval, char *alias)  	add_wildcard(alias);  	return 1;  } -ADD_TO_DEVTABLE("sdw", sdw_device_id, do_sdw_entry);  /* Looks like: fsl-mc:vNdN */  static int do_fsl_mc_entry(const char *filename, void *symval, @@ -1336,7 +1250,6 @@ static int do_fsl_mc_entry(const char *filename, void *symval,  	sprintf(alias, "fsl-mc:v%08Xd%s", vendor, *obj_type);  	return 1;  } -ADD_TO_DEVTABLE("fslmc", fsl_mc_device_id, do_fsl_mc_entry);  /* Looks like: tbsvc:kSpNvNrN */  static int do_tbsvc_entry(const char *filename, void *symval, char *alias) @@ -1361,7 +1274,6 @@ static int do_tbsvc_entry(const char *filename, void *symval, char *alias)  	add_wildcard(alias);  	return 1;  } -ADD_TO_DEVTABLE("tbsvc", tb_service_id, do_tbsvc_entry);  /* Looks like: typec:idNmN */  static int do_typec_entry(const char *filename, void *symval, char *alias) @@ -1374,7 +1286,6 @@ static int do_typec_entry(const char *filename, void *symval, char *alias)  	return 1;  } -ADD_TO_DEVTABLE("typec", typec_device_id, do_typec_entry);  /* Does namelen bytes of name exactly match the symbol? */  static bool sym_is(const char *name, unsigned namelen, const char *symbol) @@ -1388,12 +1299,11 @@ static bool sym_is(const char *name, unsigned namelen, const char *symbol)  static void do_table(void *symval, unsigned long size,  		     unsigned long id_size,  		     const char *device_id, -		     void *function, +		     int (*do_entry)(const char *filename, void *symval, char *alias),  		     struct module *mod)  {  	unsigned int i;  	char alias[500]; -	int (*do_entry)(const char *, void *entry, char *alias) = function;  	device_id_check(mod->name, device_id, size, id_size, symval);  	/* Leave last one: it's the terminator. */ @@ -1407,6 +1317,48 @@ static void do_table(void *symval, unsigned long size,  	}  } +static const struct devtable devtable[] = { +	{"hid", SIZE_hid_device_id, do_hid_entry}, +	{"ieee1394", SIZE_ieee1394_device_id, do_ieee1394_entry}, +	{"pci", SIZE_pci_device_id, do_pci_entry}, +	{"ccw", SIZE_ccw_device_id, do_ccw_entry}, +	{"ap", SIZE_ap_device_id, do_ap_entry}, +	{"css", SIZE_css_device_id, do_css_entry}, +	{"serio", SIZE_serio_device_id, do_serio_entry}, +	{"acpi", SIZE_acpi_device_id, do_acpi_entry}, +	{"pcmcia", SIZE_pcmcia_device_id, do_pcmcia_entry}, +	{"vio", SIZE_vio_device_id, do_vio_entry}, +	{"input", SIZE_input_device_id, do_input_entry}, +	{"eisa", SIZE_eisa_device_id, do_eisa_entry}, +	{"parisc", SIZE_parisc_device_id, do_parisc_entry}, +	{"sdio", SIZE_sdio_device_id, do_sdio_entry}, +	{"ssb", SIZE_ssb_device_id, do_ssb_entry}, +	{"bcma", SIZE_bcma_device_id, do_bcma_entry}, +	{"virtio", SIZE_virtio_device_id, do_virtio_entry}, +	{"vmbus", SIZE_hv_vmbus_device_id, do_vmbus_entry}, +	{"rpmsg", SIZE_rpmsg_device_id, do_rpmsg_entry}, +	{"i2c", SIZE_i2c_device_id, do_i2c_entry}, +	{"spi", SIZE_spi_device_id, do_spi_entry}, +	{"dmi", SIZE_dmi_system_id, do_dmi_entry}, +	{"platform", SIZE_platform_device_id, do_platform_entry}, +	{"mdio", SIZE_mdio_device_id, do_mdio_entry}, +	{"zorro", SIZE_zorro_device_id, do_zorro_entry}, +	{"isapnp", SIZE_isapnp_device_id, do_isapnp_entry}, +	{"ipack", SIZE_ipack_device_id, do_ipack_entry}, +	{"amba", SIZE_amba_id, do_amba_entry}, +	{"mipscdmm", SIZE_mips_cdmm_device_id, do_mips_cdmm_entry}, +	{"x86cpu", SIZE_x86_cpu_id, do_x86cpu_entry}, +	{"cpu", SIZE_cpu_feature, do_cpu_entry}, +	{"mei", SIZE_mei_cl_device_id, do_mei_entry}, +	{"rapidio", SIZE_rio_device_id, do_rio_entry}, +	{"ulpi", SIZE_ulpi_device_id, do_ulpi_entry}, +	{"hdaudio", SIZE_hda_device_id, do_hda_entry}, +	{"sdw", SIZE_sdw_device_id, do_sdw_entry}, +	{"fslmc", SIZE_fsl_mc_device_id, do_fsl_mc_entry}, +	{"tbsvc", SIZE_tb_service_id, do_tbsvc_entry}, +	{"typec", SIZE_typec_device_id, do_typec_entry}, +}; +  /* Create MODULE_ALIAS() statements.   * At this time, we cannot write the actual output C source yet,   * so we write into the mod->dev_table_buf buffer. */ @@ -1460,13 +1412,14 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,  	else if (sym_is(name, namelen, "pnp_card"))  		do_pnp_card_entries(symval, sym->st_size, mod);  	else { -		struct devtable **p; -		INIT_SECTION(__devtable); +		int i; + +		for (i = 0; i < ARRAY_SIZE(devtable); i++) { +			const struct devtable *p = &devtable[i]; -		for (p = __start___devtable; p < __stop___devtable; p++) { -			if (sym_is(name, namelen, (*p)->device_id)) { -				do_table(symval, sym->st_size, (*p)->id_size, -					 (*p)->device_id, (*p)->function, mod); +			if (sym_is(name, namelen, p->device_id)) { +				do_table(symval, sym->st_size, p->id_size, +					 p->device_id, p->do_entry, mod);  				break;  			}  		} diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 0d998c54564d..0de2fb236640 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1163,6 +1163,14 @@ static const struct sectioncheck *section_mismatch(   *   fromsec = text section   *   refsymname = *.constprop.*   * + * Pattern 6: + *   Hide section mismatch warnings for ELF local symbols.  The goal + *   is to eliminate false positive modpost warnings caused by + *   compiler-generated ELF local symbol names such as ".LANCHOR1". + *   Autogenerated symbol names bypass modpost's "Pattern 2" + *   whitelisting, which relies on pattern-matching against symbol + *   names to work.  (One situation where gcc can autogenerate ELF + *   local symbols is when "-fsection-anchors" is used.)   **/  static int secref_whitelist(const struct sectioncheck *mismatch,  			    const char *fromsec, const char *fromsym, @@ -1201,9 +1209,37 @@ static int secref_whitelist(const struct sectioncheck *mismatch,  	    match(fromsym, optim_symbols))  		return 0; +	/* Check for pattern 6 */ +	if (strstarts(fromsym, ".L")) +		return 0; +  	return 1;  } +static inline int is_arm_mapping_symbol(const char *str) +{ +	return str[0] == '$' && strchr("axtd", str[1]) +	       && (str[2] == '\0' || str[2] == '.'); +} + +/* + * If there's no name there, ignore it; likewise, ignore it if it's + * one of the magic symbols emitted used by current ARM tools. + * + * Otherwise if find_symbols_between() returns those symbols, they'll + * fail the whitelist tests and cause lots of false alarms ... fixable + * only by merging __exit and __init sections into __text, bloating + * the kernel (which is especially evil on embedded platforms). + */ +static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym) +{ +	const char *name = elf->strtab + sym->st_name; + +	if (!name || !strlen(name)) +		return 0; +	return !is_arm_mapping_symbol(name); +} +  /**   * Find symbol based on relocation record info.   * In some cases the symbol supplied is a valid symbol so @@ -1229,6 +1265,8 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,  			continue;  		if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)  			continue; +		if (!is_valid_name(elf, sym)) +			continue;  		if (sym->st_value == addr)  			return sym;  		/* Find a symbol nearby - addr are maybe negative */ @@ -1247,30 +1285,6 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,  		return NULL;  } -static inline int is_arm_mapping_symbol(const char *str) -{ -	return str[0] == '$' && strchr("axtd", str[1]) -	       && (str[2] == '\0' || str[2] == '.'); -} - -/* - * If there's no name there, ignore it; likewise, ignore it if it's - * one of the magic symbols emitted used by current ARM tools. - * - * Otherwise if find_symbols_between() returns those symbols, they'll - * fail the whitelist tests and cause lots of false alarms ... fixable - * only by merging __exit and __init sections into __text, bloating - * the kernel (which is especially evil on embedded platforms). - */ -static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym) -{ -	const char *name = elf->strtab + sym->st_name; - -	if (!name || !strlen(name)) -		return 0; -	return !is_arm_mapping_symbol(name); -} -  /*   * Find symbols before or equal addr and after addr - in the section sec.   * If we find two symbols with equal offset prefer one with a valid name. @@ -2083,15 +2097,27 @@ static void check_for_unused(enum export exp, const char *m, const char *s)  	}  } -static void check_exports(struct module *mod) +static int check_exports(struct module *mod)  {  	struct symbol *s, *exp; +	int err = 0;  	for (s = mod->unres; s; s = s->next) {  		const char *basename;  		exp = find_symbol(s->name); -		if (!exp || exp->module == mod) +		if (!exp || exp->module == mod) { +			if (have_vmlinux && !s->weak) { +				if (warn_unresolved) { +					warn("\"%s\" [%s.ko] undefined!\n", +					     s->name, mod->name); +				} else { +					merror("\"%s\" [%s.ko] undefined!\n", +					       s->name, mod->name); +					err = 1; +				} +			}  			continue; +		}  		basename = strrchr(mod->name, '/');  		if (basename)  			basename++; @@ -2101,6 +2127,8 @@ static void check_exports(struct module *mod)  			check_for_gpl_usage(exp->export, basename, exp->name);  		check_for_unused(exp->export, basename, exp->name);  	} + +	return err;  }  static int check_modname_len(struct module *mod) @@ -2178,19 +2206,8 @@ static int add_versions(struct buffer *b, struct module *mod)  	for (s = mod->unres; s; s = s->next) {  		exp = find_symbol(s->name); -		if (!exp || exp->module == mod) { -			if (have_vmlinux && !s->weak) { -				if (warn_unresolved) { -					warn("\"%s\" [%s.ko] undefined!\n", -					     s->name, mod->name); -				} else { -					merror("\"%s\" [%s.ko] undefined!\n", -					       s->name, mod->name); -					err = 1; -				} -			} +		if (!exp || exp->module == mod)  			continue; -		}  		s->module = exp->module;  		s->crc_valid = exp->crc_valid;  		s->crc = exp->crc; @@ -2227,15 +2244,15 @@ static int add_versions(struct buffer *b, struct module *mod)  	return err;  } -static void add_depends(struct buffer *b, struct module *mod, -			struct module *modules) +static void add_depends(struct buffer *b, struct module *mod)  {  	struct symbol *s; -	struct module *m;  	int first = 1; -	for (m = modules; m; m = m->next) -		m->seen = is_vmlinux(m->name); +	/* Clear ->seen flag of modules that own symbols needed by this. */ +	for (s = mod->unres; s; s = s->next) +		if (s->module) +			s->module->seen = is_vmlinux(s->module->name);  	buf_printf(b, "\n");  	buf_printf(b, "static const char __module_depends[]\n"); @@ -2416,7 +2433,7 @@ int main(int argc, char **argv)  	struct ext_sym_list *extsym_iter;  	struct ext_sym_list *extsym_start = NULL; -	while ((opt = getopt(argc, argv, "i:I:e:mnsST:o:awM:K:E")) != -1) { +	while ((opt = getopt(argc, argv, "i:I:e:mnsST:o:awE")) != -1) {  		switch (opt) {  		case 'i':  			kernel_read = optarg; @@ -2482,12 +2499,6 @@ int main(int argc, char **argv)  	if (files_source)  		read_symbols_from_files(files_source); -	for (mod = modules; mod; mod = mod->next) { -		if (mod->skip) -			continue; -		check_exports(mod); -	} -  	err = 0;  	for (mod = modules; mod; mod = mod->next) { @@ -2499,12 +2510,13 @@ int main(int argc, char **argv)  		buf.pos = 0;  		err |= check_modname_len(mod); +		err |= check_exports(mod);  		add_header(&buf, mod);  		add_intree_flag(&buf, !external_module);  		add_retpoline(&buf);  		add_staging_flag(&buf, mod->name);  		err |= add_versions(&buf, mod); -		add_depends(&buf, mod, modules); +		add_depends(&buf, mod);  		add_moddevtable(&buf, mod);  		add_srcversion(&buf, mod);  | 
