diff options
| author | Robert Richter <robert.richter@amd.com> | 2009-06-10 21:47:10 +0200 | 
|---|---|---|
| committer | Robert Richter <robert.richter@amd.com> | 2009-06-10 21:47:10 +0200 | 
| commit | 0886751c5d8b19fcee2e65d34ae21c9111e652a9 (patch) | |
| tree | 015e8c2b3d44d46e9e8fccd016340c51bc876d3b /scripts/mod | |
| parent | 7e4e0bd50e80df2fe5501f48f872448376cdd997 (diff) | |
| parent | 07a2039b8eb0af4ff464efd3dfd95de5c02648c6 (diff) | |
Merge commit 'v2.6.30' into oprofile/master
Diffstat (limited to 'scripts/mod')
| -rw-r--r-- | scripts/mod/modpost.c | 100 | 
1 files changed, 54 insertions, 46 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 8d46ea7d671..161b7846733 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -384,11 +384,19 @@ static int parse_elf(struct elf_info *info, const char *filename)  		return 0;  	}  	/* Fix endianness in ELF header */ -	hdr->e_shoff    = TO_NATIVE(hdr->e_shoff); -	hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx); -	hdr->e_shnum    = TO_NATIVE(hdr->e_shnum); -	hdr->e_machine  = TO_NATIVE(hdr->e_machine); -	hdr->e_type     = TO_NATIVE(hdr->e_type); +	hdr->e_type      = TO_NATIVE(hdr->e_type); +	hdr->e_machine   = TO_NATIVE(hdr->e_machine); +	hdr->e_version   = TO_NATIVE(hdr->e_version); +	hdr->e_entry     = TO_NATIVE(hdr->e_entry); +	hdr->e_phoff     = TO_NATIVE(hdr->e_phoff); +	hdr->e_shoff     = TO_NATIVE(hdr->e_shoff); +	hdr->e_flags     = TO_NATIVE(hdr->e_flags); +	hdr->e_ehsize    = TO_NATIVE(hdr->e_ehsize); +	hdr->e_phentsize = TO_NATIVE(hdr->e_phentsize); +	hdr->e_phnum     = TO_NATIVE(hdr->e_phnum); +	hdr->e_shentsize = TO_NATIVE(hdr->e_shentsize); +	hdr->e_shnum     = TO_NATIVE(hdr->e_shnum); +	hdr->e_shstrndx  = TO_NATIVE(hdr->e_shstrndx);  	sechdrs = (void *)hdr + hdr->e_shoff;  	info->sechdrs = sechdrs; @@ -402,13 +410,16 @@ static int parse_elf(struct elf_info *info, const char *filename)  	/* Fix endianness in section headers */  	for (i = 0; i < hdr->e_shnum; i++) { -		sechdrs[i].sh_type   = TO_NATIVE(sechdrs[i].sh_type); -		sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset); -		sechdrs[i].sh_size   = TO_NATIVE(sechdrs[i].sh_size); -		sechdrs[i].sh_link   = TO_NATIVE(sechdrs[i].sh_link); -		sechdrs[i].sh_name   = TO_NATIVE(sechdrs[i].sh_name); -		sechdrs[i].sh_info   = TO_NATIVE(sechdrs[i].sh_info); -		sechdrs[i].sh_addr   = TO_NATIVE(sechdrs[i].sh_addr); +		sechdrs[i].sh_name      = TO_NATIVE(sechdrs[i].sh_name); +		sechdrs[i].sh_type      = TO_NATIVE(sechdrs[i].sh_type); +		sechdrs[i].sh_flags     = TO_NATIVE(sechdrs[i].sh_flags); +		sechdrs[i].sh_addr      = TO_NATIVE(sechdrs[i].sh_addr); +		sechdrs[i].sh_offset    = TO_NATIVE(sechdrs[i].sh_offset); +		sechdrs[i].sh_size      = TO_NATIVE(sechdrs[i].sh_size); +		sechdrs[i].sh_link      = TO_NATIVE(sechdrs[i].sh_link); +		sechdrs[i].sh_info      = TO_NATIVE(sechdrs[i].sh_info); +		sechdrs[i].sh_addralign = TO_NATIVE(sechdrs[i].sh_addralign); +		sechdrs[i].sh_entsize   = TO_NATIVE(sechdrs[i].sh_entsize);  	}  	/* Find symbol table. */  	for (i = 1; i < hdr->e_shnum; i++) { @@ -716,41 +727,37 @@ int match(const char *sym, const char * const pat[])  /* sections that we do not want to do full section mismatch check on */  static const char *section_white_list[] = -	{ ".debug*", ".stab*", ".note*", ".got*", ".toc*", NULL }; +{ +	".comment*", +	".debug*", +	".mdebug*",        /* alpha, score, mips etc. */ +	".pdr",            /* alpha, score, mips etc. */ +	".stab*", +	".note*", +	".got*", +	".toc*", +	NULL +};  /* - * Is this section one we do not want to check? - * This is often debug sections. - * If we are going to check this section then - * test if section name ends with a dot and a number. - * This is used to find sections where the linker have - * appended a dot-number to make the name unique. + * This is used to find sections missing the SHF_ALLOC flag.   * The cause of this is often a section specified in assembler - * without "ax" / "aw" and the same section used in .c - * code where gcc add these. + * without "ax" / "aw".   */ -static int check_section(const char *modname, const char *sec) -{ -	const char *e = sec + strlen(sec) - 1; -	if (match(sec, section_white_list)) -		return 1; - -	if (*e && isdigit(*e)) { -		/* consume all digits */ -		while (*e && e != sec && isdigit(*e)) -			e--; -		if (*e == '.' && !strstr(sec, ".linkonce")) { -			warn("%s (%s): unexpected section name.\n" -			     "The (.[number]+) following section name are " -			     "ld generated and not expected.\n" -			     "Did you forget to use \"ax\"/\"aw\" " -			     "in a .S file?\n" -			     "Note that for example <linux/init.h> contains\n" -			     "section definitions for use in .S files.\n\n", -			     modname, sec); -		} +static void check_section(const char *modname, struct elf_info *elf, +                          Elf_Shdr *sechdr) +{ +	const char *sec = sech_name(elf, sechdr); + +	if (sechdr->sh_type == SHT_PROGBITS && +	    !(sechdr->sh_flags & SHF_ALLOC) && +	    !match(sec, section_white_list)) { +		warn("%s (%s): unexpected non-allocatable section.\n" +		     "Did you forget to use \"ax\"/\"aw\" in a .S file?\n" +		     "Note that for example <linux/init.h> contains\n" +		     "section definitions for use in .S files.\n\n", +		     modname, sec);  	} -	return 0;  } @@ -928,8 +935,7 @@ static int section_mismatch(const char *fromsec, const char *tosec)   *           *probe_one, *_console, *_timer   *   * Pattern 3: - *   Whitelist all refereces from .text.head to .init.data - *   Whitelist all refereces from .text.head to .init.text + *   Whitelist all references from .head.text to any init section   *   * Pattern 4:   *   Some symbols belong to init section but still it is ok to reference @@ -1359,7 +1365,7 @@ static void section_rela(const char *modname, struct elf_info *elf,  	fromsec = sech_name(elf, sechdr);  	fromsec += strlen(".rela");  	/* if from section (name) is know good then skip it */ -	if (check_section(modname, fromsec)) +	if (match(fromsec, section_white_list))  		return;  	for (rela = start; rela < stop; rela++) { @@ -1403,7 +1409,7 @@ static void section_rel(const char *modname, struct elf_info *elf,  	fromsec = sech_name(elf, sechdr);  	fromsec += strlen(".rel");  	/* if from section (name) is know good then skip it */ -	if (check_section(modname, fromsec)) +	if (match(fromsec, section_white_list))  		return;  	for (rel = start; rel < stop; rel++) { @@ -1466,6 +1472,7 @@ static void check_sec_ref(struct module *mod, const char *modname,  	/* Walk through all sections */  	for (i = 0; i < elf->hdr->e_shnum; i++) { +		check_section(modname, elf, &elf->sechdrs[i]);  		/* We want to process only relocation sections and not .init */  		if (sechdrs[i].sh_type == SHT_RELA)  			section_rela(modname, elf, &elf->sechdrs[i]); @@ -1990,6 +1997,7 @@ static void read_markers(const char *fname)  		if (!mod->skip)  			add_marker(mod, marker, fmt);  	} +	release_file(file, size);  	return;  fail:  	fatal("parse error in markers list file\n");  | 
