diff options
Diffstat (limited to 'scripts/mod/file2alias.c')
| -rw-r--r-- | scripts/mod/file2alias.c | 60 | 
1 files changed, 56 insertions, 4 deletions
| diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index d0de2a2c3a2d..8e730ccc3f2b 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -46,11 +46,37 @@ struct devtable {  	void *function;  }; +#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[]; -#define ___cat(a,b) a ## b -#define __cat(a,b) ___cat(a,b) +#endif /* __MACH__ */  #if __GNUC__ == 3 && __GNUC_MINOR__ < 3  # define __used			__attribute__((__unused__)) @@ -65,8 +91,8 @@ extern struct devtable *__start___devtable[], *__stop___devtable[];  						(type *)NULL,		\  						(char *)NULL)),		\  		sizeof(type), (function) };				\ -	static struct devtable *__attribute__((section("__devtable"))) \ -		__used __cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__) +	static struct devtable *SECTION(__devtable) __used \ +		__cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__)  #define ADD(str, sep, cond, field)                              \  do {                                                            \ @@ -1003,6 +1029,31 @@ static int do_amba_entry(const char *filename,  }  ADD_TO_DEVTABLE("amba", struct amba_id, do_amba_entry); +/* LOOKS like x86cpu:vendor:VVVV:family:FFFF:model:MMMM:feature:*,FEAT,* + * All fields are numbers. It would be nicer to use strings for vendor + * and feature, but getting those out of the build system here is too + * complicated. + */ + +static int do_x86cpu_entry(const char *filename, struct x86_cpu_id *id, +			   char *alias) +{ +	id->feature = TO_NATIVE(id->feature); +	id->family = TO_NATIVE(id->family); +	id->model = TO_NATIVE(id->model); +	id->vendor = TO_NATIVE(id->vendor); + +	strcpy(alias, "x86cpu:"); +	ADD(alias, "vendor:",  id->vendor != X86_VENDOR_ANY, id->vendor); +	ADD(alias, ":family:", id->family != X86_FAMILY_ANY, id->family); +	ADD(alias, ":model:",  id->model  != X86_MODEL_ANY,  id->model); +	strcat(alias, ":feature:*"); +	if (id->feature != X86_FEATURE_ANY) +		sprintf(alias + strlen(alias), "%04X*", id->feature); +	return 1; +} +ADD_TO_DEVTABLE("x86cpu", struct x86_cpu_id, do_x86cpu_entry); +  /* Does namelen bytes of name exactly match the symbol? */  static bool sym_is(const char *name, unsigned namelen, const char *symbol)  { @@ -1080,6 +1131,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,  		do_pnp_card_entries(symval, sym->st_size, mod);  	else {  		struct devtable **p; +		INIT_SECTION(__devtable);  		for (p = __start___devtable; p < __stop___devtable; p++) {  			if (sym_is(name, namelen, (*p)->device_id)) { |