linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Keith Owens <kaos@ocs.com.au>
To: linux-kernel@vger.kernel.org
Subject: [RFC] 2.5.8 sort kernel tables
Date: Thu, 18 Apr 2002 19:46:26 +1000	[thread overview]
Message-ID: <1589.1019123186@ocs3.intra.ocs.com.au> (raw)

The use of __init and __exit sections breaks the assumption that tables
such as __ex_table are sorted, it has already broken the dbe table in
mips on 2.5.  This patch against 2.5.8 adds a generic sort routine and
sorts the i386 exception table.

This sorting needs to be extended to several other tables, to all
architectures, to modutils (insmod loads some of these tables for
modules) and back ported to 2.4.  Before I spend the rest of the time,
any objections?

ndex: 8.1/init/main.c
--- 8.1/init/main.c Mon, 15 Apr 2002 13:28:23 +1000 kaos (linux-2.5/w/d/29_main.c 1.16 444)
+++ 8.1(w)/init/main.c Thu, 18 Apr 2002 19:36:40 +1000 kaos (linux-2.5/w/d/29_main.c 1.16 444)
@@ -257,6 +257,56 @@ static void __init parse_options(char *l
 	envp_init[envs+1] = NULL;
 }
 
+/* Quick and dirty bubble sort to ensure that certain kernel tables really are
+ * sorted.  Various kernel tables, in particular the exception entries, are
+ * assumed to be in ascending order.  These tables are built by the linker from
+ * sections in each object.  The linker is not a problem, it appends entries to
+ * the tables as each object is added to vmlinux.  However the use of __init and
+ * __exit in objects can break the ordering, within each object the entries are
+ * in order, the linker appends them in order but the entries are not in order
+ * across objects.
+ *
+ * Do not assume that the table from the linker is correct, sort it at boot
+ * time.  Since 90%+ of the entries will be sorted, a bubble sort is good
+ * enough, it only runs once per table per boot.  The sort only does binary
+ * keys and only sorts in ascending order.
+ */
+
+void __init sort_table(void *table, size_t entry_size, size_t entries, size_t key_size, size_t key_offset)
+{
+	char *a, *b;
+	int i, j, changed = 1;
+	char save[entry_size];
+	a = (char *)table;
+	if (key_size != 4 && key_size != 8) {
+		printk(KERN_ERR "sort_table key_size %d is incorrect\n", key_size);
+		return;
+	}
+	for (i = 0; i < entries && changed; a += entry_size, ++i) {
+		changed = 0;
+		b = a + entry_size;
+		for (j = i + 1; j < entries; b += entry_size, ++j) {
+			if (key_size == 4) {
+				if (*((__u32 *)(b+key_offset-entry_size)) >
+				    *((__u32 *)(b+key_offset))) {
+					memcpy(save, b, entry_size);
+					memcpy(b, b-entry_size, entry_size);
+					memcpy(b-entry_size, save, entry_size);
+					changed = 1;
+				}
+			}
+			else {
+				if (*((__u64 *)(b+key_offset-entry_size)) >
+				    *((__u64 *)(b+key_offset))) {
+					memcpy(save, b, entry_size);
+					memcpy(b, b-entry_size, entry_size);
+					memcpy(b-entry_size, save, entry_size);
+					changed = 1;
+				}
+			}
+		}
+	}
+}
 
 extern void setup_arch(char **);
 extern void cpu_idle(void);
@@ -343,6 +393,7 @@ asmlinkage void __init start_kernel(void
  */
 	lock_kernel();
 	printk(linux_banner);
+	sort_arch_tables();
 	setup_arch(&command_line);
 	setup_per_cpu_areas();
 	printk("Kernel command line: %s\n", saved_command_line);
Index: 8.1/arch/i386/mm/extable.c
--- 8.1/arch/i386/mm/extable.c Sat, 24 Nov 2001 05:28:08 +1100 kaos (linux-2.5/b/b/41_extable.c 1.1 444)
+++ 8.1(w)/arch/i386/mm/extable.c Thu, 18 Apr 2002 19:37:50 +1000 kaos (linux-2.5/b/b/41_extable.c 1.1 444)
@@ -31,6 +31,14 @@ search_one_table(const struct exception_
         return 0;
 }
 
+void __init sort_arch_tables(void)
+{
+	sort_table((void *) __start___ex_table, sizeof(*__start___ex_table),
+			__stop___ex_table - __start___ex_table,
+			sizeof(__start___ex_table->insn),
+			offsetof(typeof(*__start___ex_table), insn));
+}
+
 extern spinlock_t modlist_lock;
 
 unsigned long
Index: 8.1/include/linux/kernel.h
--- 8.1/include/linux/kernel.h Sat, 09 Feb 2002 15:37:49 +1100 kaos (linux-2.5/v/d/17_kernel.h 1.4 444)
+++ 8.1(w)/include/linux/kernel.h Thu, 18 Apr 2002 18:38:26 +1000 kaos (linux-2.5/v/d/17_kernel.h 1.4 444)
@@ -95,6 +95,9 @@ extern const char *print_tainted(void);
 #define TAINT_FORCED_MODULE		(1<<1)
 #define TAINT_UNSAFE_SMP		(1<<2)
 
+extern void sort_arch_tables(void);
+extern void sort_table(void *table, size_t entry_size, size_t entries, size_t key_size, size_t key_offset);
+
 #if DEBUG
 #define pr_debug(fmt,arg...) \
 	printk(KERN_DEBUG fmt,##arg)


             reply	other threads:[~2002-04-18  9:46 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-04-18  9:46 Keith Owens [this message]
2002-04-18 10:21 ` [RFC] 2.5.8 sort kernel tables Matthias Andree
2002-04-18 10:32   ` Keith Owens
2002-04-18 10:52   ` Alan Cox
2002-04-18 13:02 ` Paul Mackerras
2002-04-18 15:38   ` Keith Owens
2002-04-18 15:52     ` Russell King
2002-04-18 16:09       ` Keith Owens
2002-04-18 13:59 ` William Lee Irwin III
2002-04-18 18:16   ` Kai Henningsen
2002-04-18 18:24     ` William Lee Irwin III
2002-04-19 11:46     ` David Weinehall
2002-04-18 20:20   ` Oliver Xymoron
2002-04-19  4:59     ` Matt
2002-04-19 13:45     ` Jamie Lokier
2002-04-19 13:46     ` Jamie Lokier
2002-04-19 14:25       ` Oliver Xymoron
2002-04-19 15:16         ` Tobias Wollgam
     [not found] <1589.1019123186@ocs3.intra.ocs.com.au.suse.lists.linux.kernel>
     [not found] ` <15550.50131.489249.256007@nanango.paulus.ozlabs.org.suse.lists.linux.kernel>
2002-04-18 17:51   ` Andi Kleen
2002-04-18 23:17     ` Keith Owens
2002-04-19 11:38 Randal, Phil
2002-04-20  5:19 ` Keith Owens
2002-04-20  8:50   ` Alan Cox
2002-04-20  9:40     ` Keith Owens

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=1589.1019123186@ocs3.intra.ocs.com.au \
    --to=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;
as well as URLs for NNTP newsgroup(s).