public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Sam Ravnborg <sam@ravnborg.org>
To: Keith Owens <kaos@ocs.com.au>, LKML <linux-kernel@vger.kernel.org>
Subject: Re: Check for references to discarded sections during build time
Date: Sun, 5 Feb 2006 01:20:16 +0100	[thread overview]
Message-ID: <20060205002016.GA6105@mars.ravnborg.org> (raw)
In-Reply-To: <20060204225025.GA21292@mars.ravnborg.org>

On Sat, Feb 04, 2006 at 11:50:25PM +0100, Sam Ravnborg wrote:
> Hi Keith.
> 
> While doing some other modpost.c changes I thought about the
> possibility to do the reference_init check during the modpost stage - so
> it is done early and author can catch warning when he made the error.
> Attached is first cut.
> 
> It does a much more lousy job than reference_init because it identifies
> the module and not the .o file. I hope to later identify the function
> where the illegal reference hapens.
> 
> I have only run it on a subset of the kernel and it found a few
> warnings in ide-core.o + one warning in net/drivers/drgs.o.
> I have not investigated if this is false positives yet.
> 
> make allmodconfig running in background - will check the result when I
> wake up again.

That spew out several screenfull of stuff...
So far by looking only positives..

Heading for a business trip and vacation the next 2 weeks so do not
expect much response...

	Sam

Corrected patch below:

diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index d901095..01b482d 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -451,6 +451,101 @@ static char *get_modinfo(void *modinfo, 
 	return NULL;
 }
 
+/**
+ * Is this section a true init section?
+ **/
+static int is_init_section(const char *name)
+{
+	if (strcmp(name, ".init") == 0)
+		return 1;
+	if (strncmp(name, ".init.", strlen(".init.")) == 0)
+		return 1;
+	return 0;
+}
+
+/**
+ * Check name - identify sections which is discarded by vmlinux
+ * after module is loaded. Here we are fine referencing __init.
+ **/
+static int is_ref_init_ok(const char *name)
+{
+	const char **s;
+	/* Absolute section names */
+	const char *namelist1[] = {
+		".init",
+		".stab",
+		".rodata",
+		".text.lock",
+		".pci_fixup_header",
+		".pci_fixup_final",
+		".pdr",
+		"__param",
+		NULL
+	};
+	/* Start of section names */
+	const char *namelist2[] = {
+		".init.",
+		".altinstructions",
+		".eh_frame",
+		".debug",
+		NULL
+	};
+	
+	for (s = namelist1; *s; s++)
+		if (strcmp(*s, name) == 0)
+			return 1;
+	for (s = namelist2; *s; s++)	
+		if (strncmp(*s, name, strlen(*s)) == 0)
+			return 1;
+	return 0;
+}
+
+/**
+ * Walk through all sections.
+ * All sections with references to a section identified as "init"
+ * needs to be int too - otherwise we have a reference to code marked
+ * __init and which is discarded by vmlinux
+ **/
+static void handle_checkinitref(struct module *mod, const char *modname, struct elf_info *elf)
+{
+	int i;
+	Elf_Sym  *sym;
+	Elf_Ehdr *hdr = elf->hdr;
+	Elf_Shdr *sechdrs = elf->sechdrs;
+	const char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+		
+	/* Walk through all sections */
+	for (i = 0; i < hdr->e_shnum; i++) {
+		const char *name = secstrings + sechdrs[i].sh_name + strlen(".rela");
+		/* We want to process only relocation sections and not .init */
+		if (is_ref_init_ok(name) || (sechdrs[i].sh_type != SHT_RELA))
+			continue;
+		Elf_Rela *rela;
+		Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset;
+		Elf_Rela *stop  = (void*)start + sechdrs[i].sh_size;
+
+		for (rela = start; rela < stop; rela++) {
+			Elf_Rela r;
+			const char *symname;
+			r.r_offset = TO_NATIVE(rela->r_offset);
+			r.r_info   = TO_NATIVE(rela->r_info);
+			sym = elf->symtab_start + ELF_R_SYM(r.r_info);
+			/* Skip special sections */
+			if (sym->st_shndx >= SHN_LORESERVE)
+				continue;
+			symname = secstrings + sechdrs[sym->st_shndx].sh_name;
+
+			if (is_init_section(symname)) {
+				warn("%s: Reference to %s section from "
+				     "offset 0x%lx within section %s\n",
+				     modname, symname,
+				     (long)r.r_offset, 
+				     name);
+			}
+		}
+	}
+}
+
 static void read_symbols(char *modname)
 {
 	const char *symname;
@@ -476,6 +571,7 @@ static void read_symbols(char *modname)
 		handle_modversions(mod, &info, sym, symname);
 		handle_moddevtable(mod, &info, sym, symname);
 	}
+	handle_checkinitref(mod, modname, &info);
 
 	version = get_modinfo(info.modinfo, info.modinfo_len, "version");
 	if (version)
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index c0de7b9..f7126c1 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -19,6 +19,9 @@
 #define ELF_ST_BIND ELF32_ST_BIND
 #define ELF_ST_TYPE ELF32_ST_TYPE
 
+#define Elf_Rela    Elf32_Rela
+#define ELF_R_SYM   ELF32_R_SYM
+#define ELF_R_TYPE  ELF32_R_TYPE
 #else
 
 #define Elf_Ehdr    Elf64_Ehdr 
@@ -27,6 +30,9 @@
 #define ELF_ST_BIND ELF64_ST_BIND
 #define ELF_ST_TYPE ELF64_ST_TYPE
 
+#define Elf_Rela    Elf64_Rela
+#define ELF_R_SYM   ELF64_R_SYM
+#define ELF_R_TYPE  ELF64_R_TYPE
 #endif
 
 #if KERNEL_ELFDATA != HOST_ELFDATA


  reply	other threads:[~2006-02-05  0:20 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-02-04 22:50 Check for references to discarded sections during build time Sam Ravnborg
2006-02-05  0:20 ` Sam Ravnborg [this message]
2006-02-06 14:31   ` Keith Owens
2006-02-06 19:20     ` Sam Ravnborg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20060205002016.GA6105@mars.ravnborg.org \
    --to=sam@ravnborg.org \
    --cc=kaos@ocs.com.au \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox