[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [XEN] Make labels _start, _end, _stext, _etext, _sinittext, _einittext generic.



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxxx
# Date 1167868407 0
# Node ID 60f91c9f1a248491e2f216d009a27a4c7e5e67d4
# Parent  bf25488db8ebbc513d7f20e12a514691e54b6436
[XEN] Make labels _start,_end,_stext,_etext,_sinittext,_einittext generic.
Also sync the tools/symbol.c symbol table generator with Linux.
Make section names generic (e.e.g, .init.text, .init.data, ...).
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/ia64/xen/xenmisc.c    |   20 -
 xen/arch/powerpc/setup.c       |   13 -
 xen/arch/powerpc/xen.lds.S     |    4 
 xen/arch/x86/boot/x86_32.S     |    2 
 xen/arch/x86/boot/x86_64.S     |    2 
 xen/arch/x86/traps.c           |   20 -
 xen/arch/x86/x86_32/xen.lds.S  |   17 -
 xen/arch/x86/x86_64/xen.lds.S  |   17 -
 xen/common/kexec.c             |    6 
 xen/common/symbols.c           |    6 
 xen/include/asm-ia64/init.h    |   25 --
 xen/include/asm-powerpc/init.h |   19 -
 xen/include/asm-x86/config.h   |    4 
 xen/include/asm-x86/init.h     |   25 --
 xen/include/xen/init.h         |   19 +
 xen/include/xen/kernel.h       |   17 +
 xen/include/xen/symbols.h      |    5 
 xen/tools/symbols.c            |  471 ++++++++++-------------------------------
 18 files changed, 193 insertions(+), 499 deletions(-)

diff -r bf25488db8eb -r 60f91c9f1a24 xen/arch/ia64/xen/xenmisc.c
--- a/xen/arch/ia64/xen/xenmisc.c       Wed Jan 03 14:08:42 2007 +0000
+++ b/xen/arch/ia64/xen/xenmisc.c       Wed Jan 03 23:53:27 2007 +0000
@@ -55,26 +55,6 @@ is_platform_hp_ski(void)
 }
 
 struct pt_regs *guest_cpu_user_regs(void) { return vcpu_regs(current); }
-
-///////////////////////////////
-// from arch/ia64/traps.c
-///////////////////////////////
-
-int is_kernel_text(unsigned long addr)
-{
-       extern char _stext[], _etext[];
-       if (addr >= (unsigned long) _stext &&
-           addr <= (unsigned long) _etext)
-           return 1;
-
-       return 0;
-}
-
-unsigned long kernel_text_end(void)
-{
-       extern char _etext[];
-       return (unsigned long) _etext;
-}
 
 ///////////////////////////////
 // from common/keyhandler.c
diff -r bf25488db8eb -r 60f91c9f1a24 xen/arch/powerpc/setup.c
--- a/xen/arch/powerpc/setup.c  Wed Jan 03 14:08:42 2007 +0000
+++ b/xen/arch/powerpc/setup.c  Wed Jan 03 23:53:27 2007 +0000
@@ -91,19 +91,6 @@ static struct domain *idle_domain;
 
 volatile struct processor_area * volatile global_cpu_table[NR_CPUS];
 
-int is_kernel_text(unsigned long addr)
-{
-    if (addr >= (unsigned long) &_start &&
-        addr <= (unsigned long) &_etext)
-        return 1;
-    return 0;
-}
-
-unsigned long kernel_text_end(void)
-{
-    return (unsigned long) &_etext;
-}
-
 static void __init do_initcalls(void)
 {
     initcall_t *call;
diff -r bf25488db8eb -r 60f91c9f1a24 xen/arch/powerpc/xen.lds.S
--- a/xen/arch/powerpc/xen.lds.S        Wed Jan 03 14:08:42 2007 +0000
+++ b/xen/arch/powerpc/xen.lds.S        Wed Jan 03 23:53:27 2007 +0000
@@ -113,10 +113,10 @@ SECTIONS
 
   . = ALIGN(32);
   __setup_start = .;
-  .setup.init : { *(.setup.init) }
+  .init.setup : { *(.init.setup) }
   __setup_end = .;
   __initcall_start = .;
-  .initcall.init : { *(.initcall.init) }
+  .initcall.init : { *(.initcall1.init) }
   __initcall_end = .;
   __inithcall_start = .;
   .inithcall.text : { *(.inithcall.text) }
diff -r bf25488db8eb -r 60f91c9f1a24 xen/arch/x86/boot/x86_32.S
--- a/xen/arch/x86/boot/x86_32.S        Wed Jan 03 14:08:42 2007 +0000
+++ b/xen/arch/x86/boot/x86_32.S        Wed Jan 03 23:53:27 2007 +0000
@@ -11,8 +11,6 @@
         .text
 
 ENTRY(start)
-ENTRY(stext)
-ENTRY(_stext)
         jmp __start
 
         .align 4
diff -r bf25488db8eb -r 60f91c9f1a24 xen/arch/x86/boot/x86_64.S
--- a/xen/arch/x86/boot/x86_64.S        Wed Jan 03 14:08:42 2007 +0000
+++ b/xen/arch/x86/boot/x86_64.S        Wed Jan 03 23:53:27 2007 +0000
@@ -14,8 +14,6 @@
 #define SYM_PHYS(sym) (sym - __PAGE_OFFSET)
 
 ENTRY(start)
-ENTRY(stext)
-ENTRY(_stext)
         jmp __start
 
         .org    0x004
diff -r bf25488db8eb -r 60f91c9f1a24 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Wed Jan 03 14:08:42 2007 +0000
+++ b/xen/arch/x86/traps.c      Wed Jan 03 23:53:27 2007 +0000
@@ -115,22 +115,6 @@ integer_param("debug_stack_lines", debug
 #define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)regs->rsp)
 #endif
 
-int is_kernel_text(unsigned long addr)
-{
-    extern char _stext, _etext;
-    if (addr >= (unsigned long) &_stext &&
-        addr <= (unsigned long) &_etext)
-        return 1;
-    return 0;
-
-}
-
-unsigned long kernel_text_end(void)
-{
-    extern char _etext;
-    return (unsigned long) &_etext;
-}
-
 static void show_guest_stack(struct cpu_user_regs *regs)
 {
     int i;
@@ -187,7 +171,7 @@ static void show_trace(struct cpu_user_r
     while ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) != 0 )
     {
         addr = *stack++;
-        if ( is_kernel_text(addr) )
+        if ( is_kernel_text(addr) || is_kernel_inittext(addr) )
         {
             printk("[<%p>]", _p(addr));
             print_symbol(" %s\n   ", addr);
@@ -316,7 +300,7 @@ void show_stack_overflow(unsigned long e
     while ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) != 0 )
     {
         addr = *stack++;
-        if ( is_kernel_text(addr) )
+        if ( is_kernel_text(addr) || is_kernel_inittext(addr) )
         {
             printk("%p: [<%p>]", stack, _p(addr));
             print_symbol(" %s\n   ", addr);
diff -r bf25488db8eb -r 60f91c9f1a24 xen/arch/x86/x86_32/xen.lds.S
--- a/xen/arch/x86/x86_32/xen.lds.S     Wed Jan 03 14:08:42 2007 +0000
+++ b/xen/arch/x86/x86_32/xen.lds.S     Wed Jan 03 23:53:27 2007 +0000
@@ -19,7 +19,8 @@ SECTIONS
 SECTIONS
 {
   . = 0xFF000000 + 0x100000;
-  _text = .;                   /* Text and read-only data */
+  _start = .;
+  _stext = .;                  /* Text and read-only data */
   .text : {
        *(.text)
        *(.fixup)
@@ -51,14 +52,16 @@ SECTIONS
 
   . = ALIGN(4096);             /* Init code and data */
   __init_begin = .;
-  .text.init : { *(.text.init) } :text
-  .data.init : { *(.data.init) } :text
+  _sinittext = .;
+  .init.text : { *(.init.text) } :text
+  _einittext = .;
+  .init.data : { *(.init.data) } :text
   . = ALIGN(32);
   __setup_start = .;
-  .setup.init : { *(.setup.init) } :text
+  .init.setup : { *(.init.setup) } :text
   __setup_end = .;
   __initcall_start = .;
-  .initcall.init : { *(.initcall.init) } :text
+  .initcall.init : { *(.initcall1.init) } :text
   __initcall_end = .;
   . = ALIGN(PAGE_SIZE);
   __init_end = .;
@@ -80,8 +83,8 @@ SECTIONS
 
   /* Sections to be discarded */
   /DISCARD/ : {
-       *(.text.exit)
-       *(.data.exit)
+       *(.exit.text)
+       *(.exit.data)
        *(.exitcall.exit)
        }
 
diff -r bf25488db8eb -r 60f91c9f1a24 xen/arch/x86/x86_64/xen.lds.S
--- a/xen/arch/x86/x86_64/xen.lds.S     Wed Jan 03 14:08:42 2007 +0000
+++ b/xen/arch/x86/x86_64/xen.lds.S     Wed Jan 03 23:53:27 2007 +0000
@@ -17,7 +17,8 @@ SECTIONS
 SECTIONS
 {
   . = 0xFFFF830000100000;
-  _text = .;                   /* Text and read-only data */
+  _start = .;
+  _stext = .;                  /* Text and read-only data */
   .text : {
        *(.text)
        *(.fixup)
@@ -49,14 +50,16 @@ SECTIONS
 
   . = ALIGN(4096);             /* Init code and data */
   __init_begin = .;
-  .text.init : { *(.text.init) } :text
-  .data.init : { *(.data.init) } :text
+  _sinittext = .;
+  .init.text : { *(.init.text) } :text
+  _einittext = .;
+  .init.data : { *(.init.data) } :text
   . = ALIGN(32);
   __setup_start = .;
-  .setup.init : { *(.setup.init) } :text
+  .init.setup : { *(.init.setup) } :text
   __setup_end = .;
   __initcall_start = .;
-  .initcall.init : { *(.initcall.init) } :text
+  .initcall.init : { *(.initcall1.init) } :text
   __initcall_end = .;
   . = ALIGN(PAGE_SIZE);
   __init_end = .;
@@ -78,8 +81,8 @@ SECTIONS
 
   /* Sections to be discarded */
   /DISCARD/ : {
-       *(.text.exit)
-       *(.data.exit)
+       *(.exit.text)
+       *(.exit.data)
        *(.exitcall.exit)
        }
 
diff -r bf25488db8eb -r 60f91c9f1a24 xen/common/kexec.c
--- a/xen/common/kexec.c        Wed Jan 03 14:08:42 2007 +0000
+++ b/xen/common/kexec.c        Wed Jan 03 23:53:27 2007 +0000
@@ -150,12 +150,10 @@ static int kexec_get_reserve(xen_kexec_r
     return 0;
 }
 
-extern unsigned long _text;
-
 static int kexec_get_xen(xen_kexec_range_t *range)
 {
-    range->start = virt_to_maddr(&_text);
-    range->size = (unsigned long)&_end - (unsigned long)&_text;
+    range->start = virt_to_maddr(_start);
+    range->size = (unsigned long)_end - (unsigned long)_start;
     return 0;
 }
 
diff -r bf25488db8eb -r 60f91c9f1a24 xen/common/symbols.c
--- a/xen/common/symbols.c      Wed Jan 03 14:08:42 2007 +0000
+++ b/xen/common/symbols.c      Wed Jan 03 23:53:27 2007 +0000
@@ -12,6 +12,7 @@
 
 #include <xen/config.h>
 #include <xen/symbols.h>
+#include <xen/kernel.h>
 #include <xen/init.h>
 #include <xen/lib.h>
 #include <xen/string.h>
@@ -99,7 +100,7 @@ const char *symbols_lookup(unsigned long
     namebuf[KSYM_NAME_LEN] = 0;
     namebuf[0] = 0;
 
-    if (!is_kernel_text(addr))
+    if (!is_kernel_text(addr) && !is_kernel_inittext(addr))
         return NULL;
 
         /* do a binary search on the sorted symbols_addresses array */
@@ -130,7 +131,8 @@ const char *symbols_lookup(unsigned long
 
     /* if we found no next symbol, we use the end of the section */
     if (!symbol_end)
-        symbol_end = kernel_text_end();
+        symbol_end = is_kernel_inittext(addr) ?
+            (unsigned long)_einittext : (unsigned long)_etext;
 
     *symbolsize = symbol_end - symbols_addresses[low];
     *offset = addr - symbols_addresses[low];
diff -r bf25488db8eb -r 60f91c9f1a24 xen/include/asm-ia64/init.h
--- a/xen/include/asm-ia64/init.h       Wed Jan 03 14:08:42 2007 +0000
+++ b/xen/include/asm-ia64/init.h       Wed Jan 03 23:53:27 2007 +0000
@@ -1,29 +1,4 @@
 #ifndef _XEN_ASM_INIT_H
 #define _XEN_ASM_INIT_H
 
-/*
- * Mark functions and data as being only used at initialization
- * or exit time.
- */
-#define __init       \
-    __attribute__ ((__section__ (".init.text")))
-#define __exit       \
-    __attribute_used__ __attribute__ ((__section__(".text.exit")))
-#define __initdata   \
-    __attribute__ ((__section__ (".init.data")))
-#define __exitdata   \
-    __attribute_used__ __attribute__ ((__section__ (".data.exit")))
-#define __initsetup  \
-    __attribute_used__ __attribute__ ((__section__ (".init.setup")))
-#define __init_call  \
-    __attribute_used__ __attribute__ ((__section__ (".initcall1.init")))
-#define __exit_call  \
-    __attribute_used__ __attribute__ ((__section__ (".exitcall.exit")))
-
-/* For assembly routines
-#define __INIT         .section        ".text.init","ax"
-#define __FINIT                .previous
-#define __INITDATA     .section        ".data.init","aw"
-*/
-
 #endif /* _XEN_ASM_INIT_H */
diff -r bf25488db8eb -r 60f91c9f1a24 xen/include/asm-powerpc/init.h
--- a/xen/include/asm-powerpc/init.h    Wed Jan 03 14:08:42 2007 +0000
+++ b/xen/include/asm-powerpc/init.h    Wed Jan 03 23:53:27 2007 +0000
@@ -21,25 +21,6 @@
 #ifndef _XEN_ASM_INIT_H
 #define _XEN_ASM_INIT_H
 
-/*
- * Mark functions and data as being only used at initialization
- * or exit time.
- */
-#define __init       \
-    __attribute__ ((__section__ (".init.text")))
-#define __exit       \
-    __attribute_used__ __attribute__ ((__section__(".text.exit")))
-#define __initdata   \
-    __attribute__ ((__section__ (".init.data")))
-#define __exitdata   \
-    __attribute_used__ __attribute__ ((__section__ (".data.exit")))
-#define __initsetup  \
-    __attribute_used__ __attribute__ ((__section__ (".setup.init")))
-#define __init_call  \
-    __attribute_used__ __attribute__ ((__section__ (".initcall.init")))
-#define __exit_call  \
-    __attribute_used__ __attribute__ ((__section__ (".exitcall.exit")))
-
 struct cpu_user_regs;
 typedef void (*hcall_handler_t)(struct cpu_user_regs *regs);
 
diff -r bf25488db8eb -r 60f91c9f1a24 xen/include/asm-x86/config.h
--- a/xen/include/asm-x86/config.h      Wed Jan 03 14:08:42 2007 +0000
+++ b/xen/include/asm-x86/config.h      Wed Jan 03 23:53:27 2007 +0000
@@ -83,10 +83,6 @@
 #define DEBUG_STACK_SIZE 8192
 
 #define CONFIG_DMA_BITSIZE 30
-
-#ifndef __ASSEMBLY__
-extern unsigned long _end; /* standard ELF symbol */
-#endif /* __ASSEMBLY__ */
 
 #if defined(__x86_64__)
 
diff -r bf25488db8eb -r 60f91c9f1a24 xen/include/asm-x86/init.h
--- a/xen/include/asm-x86/init.h        Wed Jan 03 14:08:42 2007 +0000
+++ b/xen/include/asm-x86/init.h        Wed Jan 03 23:53:27 2007 +0000
@@ -1,29 +1,4 @@
 #ifndef _XEN_ASM_INIT_H
 #define _XEN_ASM_INIT_H
 
-/*
- * Mark functions and data as being only used at initialization
- * or exit time.
- */
-#define __init       \
-    __attribute__ ((__section__ (".init.text")))
-#define __exit       \
-    __attribute_used__ __attribute__ ((__section__(".text.exit")))
-#define __initdata   \
-    __attribute__ ((__section__ (".init.data")))
-#define __exitdata   \
-    __attribute_used__ __attribute__ ((__section__ (".data.exit")))
-#define __initsetup  \
-    __attribute_used__ __attribute__ ((__section__ (".setup.init")))
-#define __init_call  \
-    __attribute_used__ __attribute__ ((__section__ (".initcall.init")))
-#define __exit_call  \
-    __attribute_used__ __attribute__ ((__section__ (".exitcall.exit")))
-
-/* For assembly routines
-#define __INIT         .section        ".text.init","ax"
-#define __FINIT                .previous
-#define __INITDATA     .section        ".data.init","aw"
-*/
-
 #endif /* _XEN_ASM_INIT_H */
diff -r bf25488db8eb -r 60f91c9f1a24 xen/include/xen/init.h
--- a/xen/include/xen/init.h    Wed Jan 03 14:08:42 2007 +0000
+++ b/xen/include/xen/init.h    Wed Jan 03 23:53:27 2007 +0000
@@ -3,6 +3,25 @@
 
 #include <xen/config.h>
 #include <asm/init.h>
+
+/*
+ * Mark functions and data as being only used at initialization
+ * or exit time.
+ */
+#define __init       \
+    __attribute__ ((__section__ (".init.text")))
+#define __exit       \
+    __attribute_used__ __attribute__ ((__section__(".exit.text")))
+#define __initdata   \
+    __attribute__ ((__section__ (".init.data")))
+#define __exitdata   \
+    __attribute_used__ __attribute__ ((__section__ (".exit.data")))
+#define __initsetup  \
+    __attribute_used__ __attribute__ ((__section__ (".init.setup")))
+#define __init_call  \
+    __attribute_used__ __attribute__ ((__section__ (".initcall1.init")))
+#define __exit_call  \
+    __attribute_used__ __attribute__ ((__section__ (".exitcall.exit")))
 
 /* These macros are used to mark some functions or 
  * initialized data (doesn't apply to uninitialized data)
diff -r bf25488db8eb -r 60f91c9f1a24 xen/include/xen/kernel.h
--- a/xen/include/xen/kernel.h  Wed Jan 03 14:08:42 2007 +0000
+++ b/xen/include/xen/kernel.h  Wed Jan 03 23:53:27 2007 +0000
@@ -56,6 +56,23 @@
        1;                                      \
 })
 
+extern char _start[], _end[];
+#define is_kernel(p) ({                         \
+    char *__p = (char *)(unsigned long)(p);     \
+    (__p >= _start) && (__p <= _end);           \
+})
+
+extern char _stext[], _etext[];
+#define is_kernel_text(p) ({                    \
+    char *__p = (char *)(unsigned long)(p);     \
+    (__p >= _stext) && (__p <= _etext);         \
+})
+
+extern char _sinittext[], _einittext[];
+#define is_kernel_inittext(p) ({                \
+    char *__p = (char *)(unsigned long)(p);     \
+    (__p >= _sinittext) && (__p <= _einittext); \
+})
 
 #endif /* _LINUX_KERNEL_H */
 
diff -r bf25488db8eb -r 60f91c9f1a24 xen/include/xen/symbols.h
--- a/xen/include/xen/symbols.h Wed Jan 03 14:08:42 2007 +0000
+++ b/xen/include/xen/symbols.h Wed Jan 03 23:53:27 2007 +0000
@@ -6,9 +6,6 @@
 
 #define KSYM_NAME_LEN 127
 
-extern int is_kernel_text(unsigned long addr);
-extern unsigned long kernel_text_end(void);
-
 /* Lookup an address. */
 const char *symbols_lookup(unsigned long addr,
                            unsigned long *symbolsize,
@@ -16,7 +13,7 @@ const char *symbols_lookup(unsigned long
                            char *namebuf);
 
 /* Replace "%s" in format with address, if found */
-extern void __print_symbol(const char *fmt, unsigned long address);
+void __print_symbol(const char *fmt, unsigned long address);
 
 /* This macro allows us to keep printk typechecking */
 static void __check_printsym_format(const char *fmt, ...)
diff -r bf25488db8eb -r 60f91c9f1a24 xen/tools/symbols.c
--- a/xen/tools/symbols.c       Wed Jan 03 14:08:42 2007 +0000
+++ b/xen/tools/symbols.c       Wed Jan 03 23:53:27 2007 +0000
@@ -5,7 +5,7 @@
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
- * Usage: nm -n <object-file> | scripts/symbols [--all-symbols] > symbols.S
+ * Usage: nm -n vmlinux | scripts/symbols [--all-symbols] > symbols.S
  *
  * ChangeLog:
  *
@@ -24,75 +24,37 @@
  *
  */
 
+#define _GNU_SOURCE
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
 
-/* maximum token length used. It doesn't pay to increase it a lot, because
- * very long substrings probably don't repeat themselves too often. */
-#define MAX_TOK_SIZE           11
 #define KSYM_NAME_LEN          127
 
-/* we use only a subset of the complete symbol table to gather the token count,
- * to speed up compression, at the expense of a little compression ratio */
-#define WORKING_SET            1024
-
-/* first find the best token only on the list of tokens that would profit more
- * than GOOD_BAD_THRESHOLD. Only if this list is empty go to the "bad" list.
- * Increasing this value will put less tokens on the "good" list, so the search
- * is faster. However, if the good list runs out of tokens, we must painfully
- * search the bad list. */
-#define GOOD_BAD_THRESHOLD     10
-
-/* token hash parameters */
-#define HASH_BITS              18
-#define HASH_TABLE_SIZE                (1 << HASH_BITS)
-#define HASH_MASK              (HASH_TABLE_SIZE - 1)
-#define HASH_BASE_OFFSET       2166136261U
-#define HASH_FOLD(a)           ((a)&(HASH_MASK))
-
-/* flags to mark symbols */
-#define SYM_FLAG_VALID         1
-#define SYM_FLAG_SAMPLED       2
 
 struct sym_entry {
        unsigned long long addr;
-       char type;
-       unsigned char flags;
-       unsigned char len;
+       unsigned int len;
        unsigned char *sym;
 };
 
 
 static struct sym_entry *table;
-static int size, cnt;
-static unsigned long long _stext, _etext;
+static unsigned int table_size, table_cnt;
+static unsigned long long _stext, _etext, _sinittext, _einittext, _sextratext, 
_eextratext;
 static int all_symbols = 0;
 static char symbol_prefix_char = '\0';
 
-struct token {
-       unsigned char data[MAX_TOK_SIZE];
-       unsigned char len;
-       /* profit: the number of bytes that could be saved by inserting this
-        * token into the table */
-       int profit;
-       struct token *next;     /* next token on the hash list */
-       struct token *right;    /* next token on the good/bad list */
-       struct token *left;    /* previous token on the good/bad list */
-       struct token *smaller; /* token that is less one letter than this one */
-       };
-
-struct token bad_head, good_head;
-struct token *hash_table[HASH_TABLE_SIZE];
+int token_profit[0x10000];
 
 /* the table that holds the result of the compression */
-unsigned char best_table[256][MAX_TOK_SIZE+1];
+unsigned char best_table[256][2];
 unsigned char best_table_len[256];
 
 
-static void
-usage(void)
+static void usage(void)
 {
        fprintf(stderr, "Usage: symbols [--all-symbols] 
[--symbol-prefix=<prefix char>] < in.map > out.S\n");
        exit(1);
@@ -102,21 +64,19 @@ usage(void)
  * This ignores the intensely annoying "mapping symbols" found
  * in ARM ELF files: $a, $t and $d.
  */
-static inline int
-is_arm_mapping_symbol(const char *str)
+static inline int is_arm_mapping_symbol(const char *str)
 {
        return str[0] == '$' && strchr("atd", str[1])
               && (str[2] == '\0' || str[2] == '.');
 }
 
-static int
-read_symbol(FILE *in, struct sym_entry *s)
+static int read_symbol(FILE *in, struct sym_entry *s)
 {
        char str[500];
-       char *sym;
+       char *sym, stype;
        int rc;
 
-       rc = fscanf(in, "%llx %c %499s\n", &s->addr, &s->type, str);
+       rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str);
        if (rc != 3) {
                if (rc != EOF) {
                        /* skip line */
@@ -135,7 +95,15 @@ read_symbol(FILE *in, struct sym_entry *
                _stext = s->addr;
        else if (strcmp(sym, "_etext") == 0)
                _etext = s->addr;
-       else if (toupper(s->type) == 'A')
+       else if (strcmp(sym, "_sinittext") == 0)
+               _sinittext = s->addr;
+       else if (strcmp(sym, "_einittext") == 0)
+               _einittext = s->addr;
+       else if (strcmp(sym, "_sextratext") == 0)
+               _sextratext = s->addr;
+       else if (strcmp(sym, "_eextratext") == 0)
+               _eextratext = s->addr;
+       else if (toupper(stype) == 'A')
        {
                /* Keep these useful absolute symbols */
                if (strcmp(sym, "__kernel_syscall_via_break") &&
@@ -145,22 +113,24 @@ read_symbol(FILE *in, struct sym_entry *
                        return -1;
 
        }
-       else if (toupper(s->type) == 'U' ||
+       else if (toupper(stype) == 'U' ||
                 is_arm_mapping_symbol(sym))
+               return -1;
+       /* exclude also MIPS ELF local symbols ($L123 instead of .L123) */
+       else if (str[0] == '$')
                return -1;
 
        /* include the type field in the symbol name, so that it gets
         * compressed together */
        s->len = strlen(str) + 1;
-       s->sym = (unsigned char *) malloc(s->len + 1);
+       s->sym = malloc(s->len + 1);
        strcpy((char *)s->sym + 1, str);
-       s->sym[0] = s->type;
+       s->sym[0] = stype;
 
        return 0;
 }
 
-static int
-symbol_valid(struct sym_entry *s)
+static int symbol_valid(struct sym_entry *s)
 {
        /* Symbols which vary between passes.  Passes 1 and 2 must have
         * identical symbol lists.  The symbols_* symbols below are only added
@@ -189,7 +159,9 @@ symbol_valid(struct sym_entry *s)
        /* if --all-symbols is not specified, then symbols outside the text
         * and inittext sections are discarded */
        if (!all_symbols) {
-               if (s->addr < _stext || s->addr > _etext)
+               if ((s->addr < _stext || s->addr > _etext)
+                   && (s->addr < _sinittext || s->addr > _einittext)
+                   && (s->addr < _sextratext || s->addr > _eextratext))
                        return 0;
                /* Corner case.  Discard any symbols with the same value as
                 * _etext _einittext or _eextratext; they can move between pass
@@ -197,7 +169,9 @@ symbol_valid(struct sym_entry *s)
                 * move then they may get dropped in pass 2, which breaks the
                 * symbols rules.
                 */
-               if (s->addr == _etext && strcmp((char *)s->sym + offset, 
"_etext"))
+               if ((s->addr == _etext && strcmp((char*)s->sym + offset, 
"_etext")) ||
+                   (s->addr == _einittext && strcmp((char*)s->sym + offset, 
"_einittext")) ||
+                   (s->addr == _eextratext && strcmp((char*)s->sym + offset, 
"_eextratext")))
                        return 0;
        }
 
@@ -212,20 +186,19 @@ symbol_valid(struct sym_entry *s)
        return 1;
 }
 
-static void
-read_map(FILE *in)
+static void read_map(FILE *in)
 {
        while (!feof(in)) {
-               if (cnt >= size) {
-                       size += 10000;
-                       table = realloc(table, sizeof(*table) * size);
+               if (table_cnt >= table_size) {
+                       table_size += 10000;
+                       table = realloc(table, sizeof(*table) * table_size);
                        if (!table) {
                                fprintf(stderr, "out of memory\n");
                                exit (1);
                        }
                }
-               if (read_symbol(in, &table[cnt]) == 0)
-                       cnt++;
+               if (read_symbol(in, &table[table_cnt]) == 0)
+                       table_cnt++;
        }
 }
 
@@ -269,10 +242,9 @@ static int expand_symbol(unsigned char *
        return total;
 }
 
-static void
-write_src(void)
-{
-       int i, k, off, valid;
+static void write_src(void)
+{
+       unsigned int i, k, off;
        unsigned int best_idx[256];
        unsigned int *markers;
        char buf[KSYM_NAME_LEN+1];
@@ -289,33 +261,24 @@ write_src(void)
        printf(".data\n");
 
        output_label("symbols_addresses");
-       valid = 0;
-       for (i = 0; i < cnt; i++) {
-               if (table[i].flags & SYM_FLAG_VALID) {
-                       printf("\tPTR\t%#llx\n", table[i].addr);
-                       valid++;
-               }
+       for (i = 0; i < table_cnt; i++) {
+               printf("\tPTR\t%#llx\n", table[i].addr);
        }
        printf("\n");
 
        output_label("symbols_num_syms");
-       printf("\tPTR\t%d\n", valid);
+       printf("\tPTR\t%d\n", table_cnt);
        printf("\n");
 
        /* table of offset markers, that give the offset in the compressed 
stream
         * every 256 symbols */
-       markers = (unsigned int *) malloc(sizeof(unsigned int)*((valid + 255) / 
256));
+       markers = (unsigned int *) malloc(sizeof(unsigned int) * ((table_cnt + 
255) / 256));
 
        output_label("symbols_names");
-       valid = 0;
        off = 0;
-       for (i = 0; i < cnt; i++) {
-
-               if (!(table[i].flags & SYM_FLAG_VALID))
-                       continue;
-
-               if ((valid & 0xFF) == 0)
-                       markers[valid >> 8] = off;
+       for (i = 0; i < table_cnt; i++) {
+               if ((i & 0xFF) == 0)
+                       markers[i >> 8] = off;
 
                printf("\t.byte 0x%02x", table[i].len);
                for (k = 0; k < table[i].len; k++)
@@ -323,12 +286,11 @@ write_src(void)
                printf("\n");
 
                off += table[i].len + 1;
-               valid++;
        }
        printf("\n");
 
        output_label("symbols_markers");
-       for (i = 0; i < ((valid + 255) >> 8); i++)
+       for (i = 0; i < ((table_cnt + 255) >> 8); i++)
                printf("\tPTR\t%d\n", markers[i]);
        printf("\n");
 
@@ -338,7 +300,7 @@ write_src(void)
        off = 0;
        for (i = 0; i < 256; i++) {
                best_idx[i] = off;
-               expand_symbol(best_table[i],best_table_len[i],buf);
+               expand_symbol(best_table[i], best_table_len[i], buf);
                printf("\t.asciz\t\"%s\"\n", buf);
                off += strlen(buf) + 1;
        }
@@ -353,153 +315,13 @@ write_src(void)
 
 /* table lookup compression functions */
 
-static inline unsigned int rehash_token(unsigned int hash, unsigned char data)
-{
-       return ((hash * 16777619) ^ data);
-}
-
-static unsigned int hash_token(unsigned char *data, int len)
-{
-       unsigned int hash=HASH_BASE_OFFSET;
-       int i;
-
-       for (i = 0; i < len; i++)
-               hash = rehash_token(hash, data[i]);
-
-       return HASH_FOLD(hash);
-}
-
-/* find a token given its data and hash value */
-static struct token *find_token_hash(unsigned char *data, int len, unsigned 
int hash)
-{
-       struct token *ptr;
-
-       ptr = hash_table[hash];
-
-       while (ptr) {
-               if ((ptr->len == len) && (memcmp(ptr->data, data, len) == 0))
-                       return ptr;
-               ptr=ptr->next;
-       }
-
-       return NULL;
-}
-
-static inline void insert_token_in_group(struct token *head, struct token *ptr)
-{
-       ptr->right = head->right;
-       ptr->right->left = ptr;
-       head->right = ptr;
-       ptr->left = head;
-}
-
-static inline void remove_token_from_group(struct token *ptr)
-{
-       ptr->left->right = ptr->right;
-       ptr->right->left = ptr->left;
-}
-
-
-/* build the counts for all the tokens that start with "data", and have lenghts
- * from 2 to "len" */
-static void learn_token(unsigned char *data, int len)
-{
-       struct token *ptr,*last_ptr;
-       int i, newprofit;
-       unsigned int hash = HASH_BASE_OFFSET;
-       unsigned int hashes[MAX_TOK_SIZE + 1];
-
-       if (len > MAX_TOK_SIZE)
-               len = MAX_TOK_SIZE;
-
-       /* calculate and store the hash values for all the sub-tokens */
-       hash = rehash_token(hash, data[0]);
-       for (i = 2; i <= len; i++) {
-               hash = rehash_token(hash, data[i-1]);
-               hashes[i] = HASH_FOLD(hash);
-       }
-
-       last_ptr = NULL;
-       ptr = NULL;
-
-       for (i = len; i >= 2; i--) {
-               hash = hashes[i];
-
-               if (!ptr) ptr = find_token_hash(data, i, hash);
-
-               if (!ptr) {
-                       /* create a new token entry */
-                       ptr = (struct token *) malloc(sizeof(*ptr));
-
-                       memcpy(ptr->data, data, i);
-                       ptr->len = i;
-
-                       /* when we create an entry, it's profit is 0 because
-                        * we also take into account the size of the token on
-                        * the compressed table. We then subtract 
GOOD_BAD_THRESHOLD
-                        * so that the test to see if this token belongs to
-                        * the good or bad list, is a comparison to zero */
-                       ptr->profit = -GOOD_BAD_THRESHOLD;
-
-                       ptr->next = hash_table[hash];
-                       hash_table[hash] = ptr;
-
-                       insert_token_in_group(&bad_head, ptr);
-
-                       ptr->smaller = NULL;
-               } else {
-                       newprofit = ptr->profit + (ptr->len - 1);
-                       /* check to see if this token needs to be moved to a
-                        * different list */
-                       if((ptr->profit < 0) && (newprofit >= 0)) {
-                               remove_token_from_group(ptr);
-                               insert_token_in_group(&good_head,ptr);
-                       }
-                       ptr->profit = newprofit;
-               }
-
-               if (last_ptr) last_ptr->smaller = ptr;
-               last_ptr = ptr;
-
-               ptr = ptr->smaller;
-       }
-}
-
-/* decrease the counts for all the tokens that start with "data", and have 
lenghts
- * from 2 to "len". This function is much simpler than learn_token because we 
have
- * more guarantees (tho tokens exist, the ->smaller pointer is set, etc.)
- * The two separate functions exist only because of compression performance */
-static void forget_token(unsigned char *data, int len)
-{
-       struct token *ptr;
-       int i, newprofit;
-       unsigned int hash=0;
-
-       if (len > MAX_TOK_SIZE) len = MAX_TOK_SIZE;
-
-       hash = hash_token(data, len);
-       ptr = find_token_hash(data, len, hash);
-
-       for (i = len; i >= 2; i--) {
-
-               newprofit = ptr->profit - (ptr->len - 1);
-               if ((ptr->profit >= 0) && (newprofit < 0)) {
-                       remove_token_from_group(ptr);
-                       insert_token_in_group(&bad_head, ptr);
-               }
-               ptr->profit=newprofit;
-
-               ptr=ptr->smaller;
-       }
-}
-
 /* count all the possible tokens in a symbol */
 static void learn_symbol(unsigned char *symbol, int len)
 {
        int i;
 
        for (i = 0; i < len - 1; i++)
-               learn_token(symbol + i, len - i);
+               token_profit[ symbol[i] + (symbol[i + 1] << 8) ]++;
 }
 
 /* decrease the count for all the possible tokens in a symbol */
@@ -508,117 +330,90 @@ static void forget_symbol(unsigned char 
        int i;
 
        for (i = 0; i < len - 1; i++)
-               forget_token(symbol + i, len - i);
-}
-
-/* set all the symbol flags and do the initial token count */
+               token_profit[ symbol[i] + (symbol[i + 1] << 8) ]--;
+}
+
+/* remove all the invalid symbols from the table and do the initial token 
count */
 static void build_initial_tok_table(void)
 {
-       int i, use_it, valid;
-
-       valid = 0;
-       for (i = 0; i < cnt; i++) {
-               table[i].flags = 0;
+       unsigned int i, pos;
+
+       pos = 0;
+       for (i = 0; i < table_cnt; i++) {
                if ( symbol_valid(&table[i]) ) {
-                       table[i].flags |= SYM_FLAG_VALID;
-                       valid++;
-               }
-       }
-
-       use_it = 0;
-       for (i = 0; i < cnt; i++) {
-
-               /* subsample the available symbols. This method is almost like
-                * a Bresenham's algorithm to get uniformly distributed samples
-                * across the symbol table */
-               if (table[i].flags & SYM_FLAG_VALID) {
-
-                       use_it += WORKING_SET;
-
-                       if (use_it >= valid) {
-                               table[i].flags |= SYM_FLAG_SAMPLED;
-                               use_it -= valid;
-                       }
-               }
-               if (table[i].flags & SYM_FLAG_SAMPLED)
-                       learn_symbol(table[i].sym, table[i].len);
-       }
+                       if (pos != i)
+                               table[pos] = table[i];
+                       learn_symbol(table[pos].sym, table[pos].len);
+                       pos++;
+               }
+       }
+       table_cnt = pos;
 }
 
 /* replace a given token in all the valid symbols. Use the sampled symbols
  * to update the counts */
-static void compress_symbols(unsigned char *str, int tlen, int idx)
-{
-       int i, len, learn, size;
-       unsigned char *p;
-
-       for (i = 0; i < cnt; i++) {
-
-               if (!(table[i].flags & SYM_FLAG_VALID)) continue;
+static void compress_symbols(unsigned char *str, int idx)
+{
+       unsigned int i, len, size;
+       unsigned char *p1, *p2;
+
+       for (i = 0; i < table_cnt; i++) {
 
                len = table[i].len;
-               learn = 0;
-               p = table[i].sym;
+               p1 = table[i].sym;
+
+               /* find the token on the symbol */
+               p2 = memmem(p1, len, str, 2);
+               if (!p2) continue;
+
+               /* decrease the counts for this symbol's tokens */
+               forget_symbol(table[i].sym, len);
+
+               size = len;
 
                do {
+                       *p2 = idx;
+                       p2++;
+                       size -= (p2 - p1);
+                       memmove(p2, p2 + 1, size);
+                       p1 = p2;
+                       len--;
+
+                       if (size < 2) break;
+
                        /* find the token on the symbol */
-                       p = (unsigned char *) strstr((char *) p, (char *) str);
-                       if (!p) break;
-
-                       if (!learn) {
-                               /* if this symbol was used to count, decrease 
it */
-                               if (table[i].flags & SYM_FLAG_SAMPLED)
-                                       forget_symbol(table[i].sym, len);
-                               learn = 1;
-                       }
-
-                       *p = idx;
-                       size = (len - (p - table[i].sym)) - tlen + 1;
-                       memmove(p + 1, p + tlen, size);
-                       p++;
-                       len -= tlen - 1;
-
-               } while (size >= tlen);
-
-               if(learn) {
-                       table[i].len = len;
-                       /* if this symbol was used to count, learn it again */
-                       if(table[i].flags & SYM_FLAG_SAMPLED)
-                               learn_symbol(table[i].sym, len);
-               }
+                       p2 = memmem(p1, size, str, 2);
+
+               } while (p2);
+
+               table[i].len = len;
+
+               /* increase the counts for this symbol's new tokens */
+               learn_symbol(table[i].sym, len);
        }
 }
 
 /* search the token with the maximum profit */
-static struct token *find_best_token(void)
-{
-       struct token *ptr,*best,*head;
-       int bestprofit;
+static int find_best_token(void)
+{
+       int i, best, bestprofit;
 
        bestprofit=-10000;
-
-       /* failsafe: if the "good" list is empty search from the "bad" list */
-       if(good_head.right == &good_head) head = &bad_head;
-       else head = &good_head;
-
-       ptr = head->right;
-       best = NULL;
-       while (ptr != head) {
-               if (ptr->profit > bestprofit) {
-                       bestprofit = ptr->profit;
-                       best = ptr;
-               }
-               ptr = ptr->right;
-       }
-
+       best = 0;
+
+       for (i = 0; i < 0x10000; i++) {
+               if (token_profit[i] > bestprofit) {
+                       best = i;
+                       bestprofit = token_profit[i];
+               }
+       }
        return best;
 }
 
 /* this is the core of the algorithm: calculate the "best" table */
 static void optimize_result(void)
 {
-       struct token *best;
-       int i;
+       int i, best;
 
        /* using the '\0' symbol last allows compress_symbols to use standard
         * fast string functions */
@@ -632,14 +427,12 @@ static void optimize_result(void)
                        best = find_best_token();
 
                        /* place it in the "best" table */
-                       best_table_len[i] = best->len;
-                       memcpy(best_table[i], best->data, best_table_len[i]);
-                       /* zero terminate the token so that we can use strstr
-                          in compress_symbols */
-                       best_table[i][best_table_len[i]]='\0';
+                       best_table_len[i] = 2;
+                       best_table[i][0] = best & 0xFF;
+                       best_table[i][1] = (best >> 8) & 0xFF;
 
                        /* replace this token in all the valid symbols */
-                       compress_symbols(best_table[i], best_table_len[i], i);
+                       compress_symbols(best_table[i], i);
                }
        }
 }
@@ -647,39 +440,28 @@ static void optimize_result(void)
 /* start by placing the symbols that are actually used on the table */
 static void insert_real_symbols_in_table(void)
 {
-       int i, j, c;
+       unsigned int i, j, c;
 
        memset(best_table, 0, sizeof(best_table));
        memset(best_table_len, 0, sizeof(best_table_len));
 
-       for (i = 0; i < cnt; i++) {
-               if (table[i].flags & SYM_FLAG_VALID) {
-                       for (j = 0; j < table[i].len; j++) {
-                               c = table[i].sym[j];
-                               best_table[c][0]=c;
-                               best_table_len[c]=1;
-                       }
+       for (i = 0; i < table_cnt; i++) {
+               for (j = 0; j < table[i].len; j++) {
+                       c = table[i].sym[j];
+                       best_table[c][0]=c;
+                       best_table_len[c]=1;
                }
        }
 }
 
 static void optimize_token_table(void)
 {
-       memset(hash_table, 0, sizeof(hash_table));
-
-       good_head.left = &good_head;
-       good_head.right = &good_head;
-
-       bad_head.left = &bad_head;
-       bad_head.right = &bad_head;
-
        build_initial_tok_table();
 
        insert_real_symbols_in_table();
 
        /* When valid symbol is not registered, exit to error */
-       if (good_head.left == good_head.right &&
-           bad_head.left == bad_head.right) {
+       if (!table_cnt) {
                fprintf(stderr, "No valid symbol.\n");
                exit(1);
        }
@@ -688,8 +470,7 @@ static void optimize_token_table(void)
 }
 
 
-int
-main(int argc, char **argv)
+int main(int argc, char **argv)
 {
        if (argc >= 2) {
                int i;

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.