ia64/xen-unstable

changeset 13250:60f91c9f1a24

[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@xensource.com>
author kaf24@localhost.localdomain
date Wed Jan 03 23:53:27 2007 +0000 (2007-01-03)
parents bf25488db8eb
children bdbfbfdfbd64
files xen/arch/ia64/xen/xenmisc.c xen/arch/powerpc/setup.c xen/arch/powerpc/xen.lds.S xen/arch/x86/boot/x86_32.S xen/arch/x86/boot/x86_64.S xen/arch/x86/traps.c xen/arch/x86/x86_32/xen.lds.S xen/arch/x86/x86_64/xen.lds.S xen/common/kexec.c xen/common/symbols.c xen/include/asm-ia64/init.h xen/include/asm-powerpc/init.h xen/include/asm-x86/config.h xen/include/asm-x86/init.h xen/include/xen/init.h xen/include/xen/kernel.h xen/include/xen/symbols.h xen/tools/symbols.c
line diff
     1.1 --- a/xen/arch/ia64/xen/xenmisc.c	Wed Jan 03 14:08:42 2007 +0000
     1.2 +++ b/xen/arch/ia64/xen/xenmisc.c	Wed Jan 03 23:53:27 2007 +0000
     1.3 @@ -57,26 +57,6 @@ is_platform_hp_ski(void)
     1.4  struct pt_regs *guest_cpu_user_regs(void) { return vcpu_regs(current); }
     1.5  
     1.6  ///////////////////////////////
     1.7 -// from arch/ia64/traps.c
     1.8 -///////////////////////////////
     1.9 -
    1.10 -int is_kernel_text(unsigned long addr)
    1.11 -{
    1.12 -	extern char _stext[], _etext[];
    1.13 -	if (addr >= (unsigned long) _stext &&
    1.14 -	    addr <= (unsigned long) _etext)
    1.15 -	    return 1;
    1.16 -
    1.17 -	return 0;
    1.18 -}
    1.19 -
    1.20 -unsigned long kernel_text_end(void)
    1.21 -{
    1.22 -	extern char _etext[];
    1.23 -	return (unsigned long) _etext;
    1.24 -}
    1.25 -
    1.26 -///////////////////////////////
    1.27  // from common/keyhandler.c
    1.28  ///////////////////////////////
    1.29  void dump_pageframe_info(struct domain *d)
     2.1 --- a/xen/arch/powerpc/setup.c	Wed Jan 03 14:08:42 2007 +0000
     2.2 +++ b/xen/arch/powerpc/setup.c	Wed Jan 03 23:53:27 2007 +0000
     2.3 @@ -91,19 +91,6 @@ static struct domain *idle_domain;
     2.4  
     2.5  volatile struct processor_area * volatile global_cpu_table[NR_CPUS];
     2.6  
     2.7 -int is_kernel_text(unsigned long addr)
     2.8 -{
     2.9 -    if (addr >= (unsigned long) &_start &&
    2.10 -        addr <= (unsigned long) &_etext)
    2.11 -        return 1;
    2.12 -    return 0;
    2.13 -}
    2.14 -
    2.15 -unsigned long kernel_text_end(void)
    2.16 -{
    2.17 -    return (unsigned long) &_etext;
    2.18 -}
    2.19 -
    2.20  static void __init do_initcalls(void)
    2.21  {
    2.22      initcall_t *call;
     3.1 --- a/xen/arch/powerpc/xen.lds.S	Wed Jan 03 14:08:42 2007 +0000
     3.2 +++ b/xen/arch/powerpc/xen.lds.S	Wed Jan 03 23:53:27 2007 +0000
     3.3 @@ -113,10 +113,10 @@ SECTIONS
     3.4  
     3.5    . = ALIGN(32);
     3.6    __setup_start = .;
     3.7 -  .setup.init : { *(.setup.init) }
     3.8 +  .init.setup : { *(.init.setup) }
     3.9    __setup_end = .;
    3.10    __initcall_start = .;
    3.11 -  .initcall.init : { *(.initcall.init) }
    3.12 +  .initcall.init : { *(.initcall1.init) }
    3.13    __initcall_end = .;
    3.14    __inithcall_start = .;
    3.15    .inithcall.text : { *(.inithcall.text) }
     4.1 --- a/xen/arch/x86/boot/x86_32.S	Wed Jan 03 14:08:42 2007 +0000
     4.2 +++ b/xen/arch/x86/boot/x86_32.S	Wed Jan 03 23:53:27 2007 +0000
     4.3 @@ -11,8 +11,6 @@
     4.4          .text
     4.5  
     4.6  ENTRY(start)
     4.7 -ENTRY(stext)
     4.8 -ENTRY(_stext)
     4.9          jmp __start
    4.10  
    4.11          .align 4
     5.1 --- a/xen/arch/x86/boot/x86_64.S	Wed Jan 03 14:08:42 2007 +0000
     5.2 +++ b/xen/arch/x86/boot/x86_64.S	Wed Jan 03 23:53:27 2007 +0000
     5.3 @@ -14,8 +14,6 @@
     5.4  #define SYM_PHYS(sym) (sym - __PAGE_OFFSET)
     5.5  
     5.6  ENTRY(start)
     5.7 -ENTRY(stext)
     5.8 -ENTRY(_stext)
     5.9          jmp __start
    5.10  
    5.11          .org    0x004
     6.1 --- a/xen/arch/x86/traps.c	Wed Jan 03 14:08:42 2007 +0000
     6.2 +++ b/xen/arch/x86/traps.c	Wed Jan 03 23:53:27 2007 +0000
     6.3 @@ -115,22 +115,6 @@ integer_param("debug_stack_lines", debug
     6.4  #define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)regs->rsp)
     6.5  #endif
     6.6  
     6.7 -int is_kernel_text(unsigned long addr)
     6.8 -{
     6.9 -    extern char _stext, _etext;
    6.10 -    if (addr >= (unsigned long) &_stext &&
    6.11 -        addr <= (unsigned long) &_etext)
    6.12 -        return 1;
    6.13 -    return 0;
    6.14 -
    6.15 -}
    6.16 -
    6.17 -unsigned long kernel_text_end(void)
    6.18 -{
    6.19 -    extern char _etext;
    6.20 -    return (unsigned long) &_etext;
    6.21 -}
    6.22 -
    6.23  static void show_guest_stack(struct cpu_user_regs *regs)
    6.24  {
    6.25      int i;
    6.26 @@ -187,7 +171,7 @@ static void show_trace(struct cpu_user_r
    6.27      while ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) != 0 )
    6.28      {
    6.29          addr = *stack++;
    6.30 -        if ( is_kernel_text(addr) )
    6.31 +        if ( is_kernel_text(addr) || is_kernel_inittext(addr) )
    6.32          {
    6.33              printk("[<%p>]", _p(addr));
    6.34              print_symbol(" %s\n   ", addr);
    6.35 @@ -316,7 +300,7 @@ void show_stack_overflow(unsigned long e
    6.36      while ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) != 0 )
    6.37      {
    6.38          addr = *stack++;
    6.39 -        if ( is_kernel_text(addr) )
    6.40 +        if ( is_kernel_text(addr) || is_kernel_inittext(addr) )
    6.41          {
    6.42              printk("%p: [<%p>]", stack, _p(addr));
    6.43              print_symbol(" %s\n   ", addr);
     7.1 --- a/xen/arch/x86/x86_32/xen.lds.S	Wed Jan 03 14:08:42 2007 +0000
     7.2 +++ b/xen/arch/x86/x86_32/xen.lds.S	Wed Jan 03 23:53:27 2007 +0000
     7.3 @@ -19,7 +19,8 @@ PHDRS
     7.4  SECTIONS
     7.5  {
     7.6    . = 0xFF000000 + 0x100000;
     7.7 -  _text = .;			/* Text and read-only data */
     7.8 +  _start = .;
     7.9 +  _stext = .;			/* Text and read-only data */
    7.10    .text : {
    7.11  	*(.text)
    7.12  	*(.fixup)
    7.13 @@ -51,14 +52,16 @@ SECTIONS
    7.14  
    7.15    . = ALIGN(4096);		/* Init code and data */
    7.16    __init_begin = .;
    7.17 -  .text.init : { *(.text.init) } :text
    7.18 -  .data.init : { *(.data.init) } :text
    7.19 +  _sinittext = .;
    7.20 +  .init.text : { *(.init.text) } :text
    7.21 +  _einittext = .;
    7.22 +  .init.data : { *(.init.data) } :text
    7.23    . = ALIGN(32);
    7.24    __setup_start = .;
    7.25 -  .setup.init : { *(.setup.init) } :text
    7.26 +  .init.setup : { *(.init.setup) } :text
    7.27    __setup_end = .;
    7.28    __initcall_start = .;
    7.29 -  .initcall.init : { *(.initcall.init) } :text
    7.30 +  .initcall.init : { *(.initcall1.init) } :text
    7.31    __initcall_end = .;
    7.32    . = ALIGN(PAGE_SIZE);
    7.33    __init_end = .;
    7.34 @@ -80,8 +83,8 @@ SECTIONS
    7.35  
    7.36    /* Sections to be discarded */
    7.37    /DISCARD/ : {
    7.38 -	*(.text.exit)
    7.39 -	*(.data.exit)
    7.40 +	*(.exit.text)
    7.41 +	*(.exit.data)
    7.42  	*(.exitcall.exit)
    7.43  	}
    7.44  
     8.1 --- a/xen/arch/x86/x86_64/xen.lds.S	Wed Jan 03 14:08:42 2007 +0000
     8.2 +++ b/xen/arch/x86/x86_64/xen.lds.S	Wed Jan 03 23:53:27 2007 +0000
     8.3 @@ -17,7 +17,8 @@ PHDRS
     8.4  SECTIONS
     8.5  {
     8.6    . = 0xFFFF830000100000;
     8.7 -  _text = .;			/* Text and read-only data */
     8.8 +  _start = .;
     8.9 +  _stext = .;			/* Text and read-only data */
    8.10    .text : {
    8.11  	*(.text)
    8.12  	*(.fixup)
    8.13 @@ -49,14 +50,16 @@ SECTIONS
    8.14  
    8.15    . = ALIGN(4096);		/* Init code and data */
    8.16    __init_begin = .;
    8.17 -  .text.init : { *(.text.init) } :text
    8.18 -  .data.init : { *(.data.init) } :text
    8.19 +  _sinittext = .;
    8.20 +  .init.text : { *(.init.text) } :text
    8.21 +  _einittext = .;
    8.22 +  .init.data : { *(.init.data) } :text
    8.23    . = ALIGN(32);
    8.24    __setup_start = .;
    8.25 -  .setup.init : { *(.setup.init) } :text
    8.26 +  .init.setup : { *(.init.setup) } :text
    8.27    __setup_end = .;
    8.28    __initcall_start = .;
    8.29 -  .initcall.init : { *(.initcall.init) } :text
    8.30 +  .initcall.init : { *(.initcall1.init) } :text
    8.31    __initcall_end = .;
    8.32    . = ALIGN(PAGE_SIZE);
    8.33    __init_end = .;
    8.34 @@ -78,8 +81,8 @@ SECTIONS
    8.35  
    8.36    /* Sections to be discarded */
    8.37    /DISCARD/ : {
    8.38 -	*(.text.exit)
    8.39 -	*(.data.exit)
    8.40 +	*(.exit.text)
    8.41 +	*(.exit.data)
    8.42  	*(.exitcall.exit)
    8.43  	}
    8.44  
     9.1 --- a/xen/common/kexec.c	Wed Jan 03 14:08:42 2007 +0000
     9.2 +++ b/xen/common/kexec.c	Wed Jan 03 23:53:27 2007 +0000
     9.3 @@ -150,12 +150,10 @@ static int kexec_get_reserve(xen_kexec_r
     9.4      return 0;
     9.5  }
     9.6  
     9.7 -extern unsigned long _text;
     9.8 -
     9.9  static int kexec_get_xen(xen_kexec_range_t *range)
    9.10  {
    9.11 -    range->start = virt_to_maddr(&_text);
    9.12 -    range->size = (unsigned long)&_end - (unsigned long)&_text;
    9.13 +    range->start = virt_to_maddr(_start);
    9.14 +    range->size = (unsigned long)_end - (unsigned long)_start;
    9.15      return 0;
    9.16  }
    9.17  
    10.1 --- a/xen/common/symbols.c	Wed Jan 03 14:08:42 2007 +0000
    10.2 +++ b/xen/common/symbols.c	Wed Jan 03 23:53:27 2007 +0000
    10.3 @@ -12,6 +12,7 @@
    10.4  
    10.5  #include <xen/config.h>
    10.6  #include <xen/symbols.h>
    10.7 +#include <xen/kernel.h>
    10.8  #include <xen/init.h>
    10.9  #include <xen/lib.h>
   10.10  #include <xen/string.h>
   10.11 @@ -99,7 +100,7 @@ const char *symbols_lookup(unsigned long
   10.12      namebuf[KSYM_NAME_LEN] = 0;
   10.13      namebuf[0] = 0;
   10.14  
   10.15 -    if (!is_kernel_text(addr))
   10.16 +    if (!is_kernel_text(addr) && !is_kernel_inittext(addr))
   10.17          return NULL;
   10.18  
   10.19          /* do a binary search on the sorted symbols_addresses array */
   10.20 @@ -130,7 +131,8 @@ const char *symbols_lookup(unsigned long
   10.21  
   10.22      /* if we found no next symbol, we use the end of the section */
   10.23      if (!symbol_end)
   10.24 -        symbol_end = kernel_text_end();
   10.25 +        symbol_end = is_kernel_inittext(addr) ?
   10.26 +            (unsigned long)_einittext : (unsigned long)_etext;
   10.27  
   10.28      *symbolsize = symbol_end - symbols_addresses[low];
   10.29      *offset = addr - symbols_addresses[low];
    11.1 --- a/xen/include/asm-ia64/init.h	Wed Jan 03 14:08:42 2007 +0000
    11.2 +++ b/xen/include/asm-ia64/init.h	Wed Jan 03 23:53:27 2007 +0000
    11.3 @@ -1,29 +1,4 @@
    11.4  #ifndef _XEN_ASM_INIT_H
    11.5  #define _XEN_ASM_INIT_H
    11.6  
    11.7 -/*
    11.8 - * Mark functions and data as being only used at initialization
    11.9 - * or exit time.
   11.10 - */
   11.11 -#define __init       \
   11.12 -    __attribute__ ((__section__ (".init.text")))
   11.13 -#define __exit       \
   11.14 -    __attribute_used__ __attribute__ ((__section__(".text.exit")))
   11.15 -#define __initdata   \
   11.16 -    __attribute__ ((__section__ (".init.data")))
   11.17 -#define __exitdata   \
   11.18 -    __attribute_used__ __attribute__ ((__section__ (".data.exit")))
   11.19 -#define __initsetup  \
   11.20 -    __attribute_used__ __attribute__ ((__section__ (".init.setup")))
   11.21 -#define __init_call  \
   11.22 -    __attribute_used__ __attribute__ ((__section__ (".initcall1.init")))
   11.23 -#define __exit_call  \
   11.24 -    __attribute_used__ __attribute__ ((__section__ (".exitcall.exit")))
   11.25 -
   11.26 -/* For assembly routines
   11.27 -#define __INIT		.section	".text.init","ax"
   11.28 -#define __FINIT		.previous
   11.29 -#define __INITDATA	.section	".data.init","aw"
   11.30 -*/
   11.31 -
   11.32  #endif /* _XEN_ASM_INIT_H */
    12.1 --- a/xen/include/asm-powerpc/init.h	Wed Jan 03 14:08:42 2007 +0000
    12.2 +++ b/xen/include/asm-powerpc/init.h	Wed Jan 03 23:53:27 2007 +0000
    12.3 @@ -21,25 +21,6 @@
    12.4  #ifndef _XEN_ASM_INIT_H
    12.5  #define _XEN_ASM_INIT_H
    12.6  
    12.7 -/*
    12.8 - * Mark functions and data as being only used at initialization
    12.9 - * or exit time.
   12.10 - */
   12.11 -#define __init       \
   12.12 -    __attribute__ ((__section__ (".init.text")))
   12.13 -#define __exit       \
   12.14 -    __attribute_used__ __attribute__ ((__section__(".text.exit")))
   12.15 -#define __initdata   \
   12.16 -    __attribute__ ((__section__ (".init.data")))
   12.17 -#define __exitdata   \
   12.18 -    __attribute_used__ __attribute__ ((__section__ (".data.exit")))
   12.19 -#define __initsetup  \
   12.20 -    __attribute_used__ __attribute__ ((__section__ (".setup.init")))
   12.21 -#define __init_call  \
   12.22 -    __attribute_used__ __attribute__ ((__section__ (".initcall.init")))
   12.23 -#define __exit_call  \
   12.24 -    __attribute_used__ __attribute__ ((__section__ (".exitcall.exit")))
   12.25 -
   12.26  struct cpu_user_regs;
   12.27  typedef void (*hcall_handler_t)(struct cpu_user_regs *regs);
   12.28  
    13.1 --- a/xen/include/asm-x86/config.h	Wed Jan 03 14:08:42 2007 +0000
    13.2 +++ b/xen/include/asm-x86/config.h	Wed Jan 03 23:53:27 2007 +0000
    13.3 @@ -84,10 +84,6 @@
    13.4  
    13.5  #define CONFIG_DMA_BITSIZE 30
    13.6  
    13.7 -#ifndef __ASSEMBLY__
    13.8 -extern unsigned long _end; /* standard ELF symbol */
    13.9 -#endif /* __ASSEMBLY__ */
   13.10 -
   13.11  #if defined(__x86_64__)
   13.12  
   13.13  #define CONFIG_X86_64 1
    14.1 --- a/xen/include/asm-x86/init.h	Wed Jan 03 14:08:42 2007 +0000
    14.2 +++ b/xen/include/asm-x86/init.h	Wed Jan 03 23:53:27 2007 +0000
    14.3 @@ -1,29 +1,4 @@
    14.4  #ifndef _XEN_ASM_INIT_H
    14.5  #define _XEN_ASM_INIT_H
    14.6  
    14.7 -/*
    14.8 - * Mark functions and data as being only used at initialization
    14.9 - * or exit time.
   14.10 - */
   14.11 -#define __init       \
   14.12 -    __attribute__ ((__section__ (".init.text")))
   14.13 -#define __exit       \
   14.14 -    __attribute_used__ __attribute__ ((__section__(".text.exit")))
   14.15 -#define __initdata   \
   14.16 -    __attribute__ ((__section__ (".init.data")))
   14.17 -#define __exitdata   \
   14.18 -    __attribute_used__ __attribute__ ((__section__ (".data.exit")))
   14.19 -#define __initsetup  \
   14.20 -    __attribute_used__ __attribute__ ((__section__ (".setup.init")))
   14.21 -#define __init_call  \
   14.22 -    __attribute_used__ __attribute__ ((__section__ (".initcall.init")))
   14.23 -#define __exit_call  \
   14.24 -    __attribute_used__ __attribute__ ((__section__ (".exitcall.exit")))
   14.25 -
   14.26 -/* For assembly routines
   14.27 -#define __INIT		.section	".text.init","ax"
   14.28 -#define __FINIT		.previous
   14.29 -#define __INITDATA	.section	".data.init","aw"
   14.30 -*/
   14.31 -
   14.32  #endif /* _XEN_ASM_INIT_H */
    15.1 --- a/xen/include/xen/init.h	Wed Jan 03 14:08:42 2007 +0000
    15.2 +++ b/xen/include/xen/init.h	Wed Jan 03 23:53:27 2007 +0000
    15.3 @@ -4,6 +4,25 @@
    15.4  #include <xen/config.h>
    15.5  #include <asm/init.h>
    15.6  
    15.7 +/*
    15.8 + * Mark functions and data as being only used at initialization
    15.9 + * or exit time.
   15.10 + */
   15.11 +#define __init       \
   15.12 +    __attribute__ ((__section__ (".init.text")))
   15.13 +#define __exit       \
   15.14 +    __attribute_used__ __attribute__ ((__section__(".exit.text")))
   15.15 +#define __initdata   \
   15.16 +    __attribute__ ((__section__ (".init.data")))
   15.17 +#define __exitdata   \
   15.18 +    __attribute_used__ __attribute__ ((__section__ (".exit.data")))
   15.19 +#define __initsetup  \
   15.20 +    __attribute_used__ __attribute__ ((__section__ (".init.setup")))
   15.21 +#define __init_call  \
   15.22 +    __attribute_used__ __attribute__ ((__section__ (".initcall1.init")))
   15.23 +#define __exit_call  \
   15.24 +    __attribute_used__ __attribute__ ((__section__ (".exitcall.exit")))
   15.25 +
   15.26  /* These macros are used to mark some functions or 
   15.27   * initialized data (doesn't apply to uninitialized data)
   15.28   * as `initialization' functions. The kernel can take this
    16.1 --- a/xen/include/xen/kernel.h	Wed Jan 03 14:08:42 2007 +0000
    16.2 +++ b/xen/include/xen/kernel.h	Wed Jan 03 23:53:27 2007 +0000
    16.3 @@ -56,6 +56,23 @@
    16.4  	1;                                      \
    16.5  })
    16.6  
    16.7 +extern char _start[], _end[];
    16.8 +#define is_kernel(p) ({                         \
    16.9 +    char *__p = (char *)(unsigned long)(p);     \
   16.10 +    (__p >= _start) && (__p <= _end);           \
   16.11 +})
   16.12 +
   16.13 +extern char _stext[], _etext[];
   16.14 +#define is_kernel_text(p) ({                    \
   16.15 +    char *__p = (char *)(unsigned long)(p);     \
   16.16 +    (__p >= _stext) && (__p <= _etext);         \
   16.17 +})
   16.18 +
   16.19 +extern char _sinittext[], _einittext[];
   16.20 +#define is_kernel_inittext(p) ({                \
   16.21 +    char *__p = (char *)(unsigned long)(p);     \
   16.22 +    (__p >= _sinittext) && (__p <= _einittext); \
   16.23 +})
   16.24  
   16.25  #endif /* _LINUX_KERNEL_H */
   16.26  
    17.1 --- a/xen/include/xen/symbols.h	Wed Jan 03 14:08:42 2007 +0000
    17.2 +++ b/xen/include/xen/symbols.h	Wed Jan 03 23:53:27 2007 +0000
    17.3 @@ -6,9 +6,6 @@
    17.4  
    17.5  #define KSYM_NAME_LEN 127
    17.6  
    17.7 -extern int is_kernel_text(unsigned long addr);
    17.8 -extern unsigned long kernel_text_end(void);
    17.9 -
   17.10  /* Lookup an address. */
   17.11  const char *symbols_lookup(unsigned long addr,
   17.12                             unsigned long *symbolsize,
   17.13 @@ -16,7 +13,7 @@ const char *symbols_lookup(unsigned long
   17.14                             char *namebuf);
   17.15  
   17.16  /* Replace "%s" in format with address, if found */
   17.17 -extern void __print_symbol(const char *fmt, unsigned long address);
   17.18 +void __print_symbol(const char *fmt, unsigned long address);
   17.19  
   17.20  /* This macro allows us to keep printk typechecking */
   17.21  static void __check_printsym_format(const char *fmt, ...)
    18.1 --- a/xen/tools/symbols.c	Wed Jan 03 14:08:42 2007 +0000
    18.2 +++ b/xen/tools/symbols.c	Wed Jan 03 23:53:27 2007 +0000
    18.3 @@ -5,7 +5,7 @@
    18.4   * This software may be used and distributed according to the terms
    18.5   * of the GNU General Public License, incorporated herein by reference.
    18.6   *
    18.7 - * Usage: nm -n <object-file> | scripts/symbols [--all-symbols] > symbols.S
    18.8 + * Usage: nm -n vmlinux | scripts/symbols [--all-symbols] > symbols.S
    18.9   *
   18.10   * ChangeLog:
   18.11   *
   18.12 @@ -24,75 +24,37 @@
   18.13   *
   18.14   */
   18.15  
   18.16 +#define _GNU_SOURCE
   18.17 +
   18.18  #include <stdio.h>
   18.19  #include <stdlib.h>
   18.20  #include <string.h>
   18.21  #include <ctype.h>
   18.22  
   18.23 -/* maximum token length used. It doesn't pay to increase it a lot, because
   18.24 - * very long substrings probably don't repeat themselves too often. */
   18.25 -#define MAX_TOK_SIZE		11
   18.26  #define KSYM_NAME_LEN		127
   18.27  
   18.28 -/* we use only a subset of the complete symbol table to gather the token count,
   18.29 - * to speed up compression, at the expense of a little compression ratio */
   18.30 -#define WORKING_SET		1024
   18.31 -
   18.32 -/* first find the best token only on the list of tokens that would profit more
   18.33 - * than GOOD_BAD_THRESHOLD. Only if this list is empty go to the "bad" list.
   18.34 - * Increasing this value will put less tokens on the "good" list, so the search
   18.35 - * is faster. However, if the good list runs out of tokens, we must painfully
   18.36 - * search the bad list. */
   18.37 -#define GOOD_BAD_THRESHOLD	10
   18.38 -
   18.39 -/* token hash parameters */
   18.40 -#define HASH_BITS		18
   18.41 -#define HASH_TABLE_SIZE		(1 << HASH_BITS)
   18.42 -#define HASH_MASK		(HASH_TABLE_SIZE - 1)
   18.43 -#define HASH_BASE_OFFSET	2166136261U
   18.44 -#define HASH_FOLD(a)		((a)&(HASH_MASK))
   18.45 -
   18.46 -/* flags to mark symbols */
   18.47 -#define SYM_FLAG_VALID		1
   18.48 -#define SYM_FLAG_SAMPLED	2
   18.49  
   18.50  struct sym_entry {
   18.51  	unsigned long long addr;
   18.52 -	char type;
   18.53 -	unsigned char flags;
   18.54 -	unsigned char len;
   18.55 +	unsigned int len;
   18.56  	unsigned char *sym;
   18.57  };
   18.58  
   18.59  
   18.60  static struct sym_entry *table;
   18.61 -static int size, cnt;
   18.62 -static unsigned long long _stext, _etext;
   18.63 +static unsigned int table_size, table_cnt;
   18.64 +static unsigned long long _stext, _etext, _sinittext, _einittext, _sextratext, _eextratext;
   18.65  static int all_symbols = 0;
   18.66  static char symbol_prefix_char = '\0';
   18.67  
   18.68 -struct token {
   18.69 -	unsigned char data[MAX_TOK_SIZE];
   18.70 -	unsigned char len;
   18.71 -	/* profit: the number of bytes that could be saved by inserting this
   18.72 -	 * token into the table */
   18.73 -	int profit;
   18.74 -	struct token *next;	/* next token on the hash list */
   18.75 -	struct token *right;	/* next token on the good/bad list */
   18.76 -	struct token *left;    /* previous token on the good/bad list */
   18.77 -	struct token *smaller; /* token that is less one letter than this one */
   18.78 -	};
   18.79 -
   18.80 -struct token bad_head, good_head;
   18.81 -struct token *hash_table[HASH_TABLE_SIZE];
   18.82 +int token_profit[0x10000];
   18.83  
   18.84  /* the table that holds the result of the compression */
   18.85 -unsigned char best_table[256][MAX_TOK_SIZE+1];
   18.86 +unsigned char best_table[256][2];
   18.87  unsigned char best_table_len[256];
   18.88  
   18.89  
   18.90 -static void
   18.91 -usage(void)
   18.92 +static void usage(void)
   18.93  {
   18.94  	fprintf(stderr, "Usage: symbols [--all-symbols] [--symbol-prefix=<prefix char>] < in.map > out.S\n");
   18.95  	exit(1);
   18.96 @@ -102,21 +64,19 @@ usage(void)
   18.97   * This ignores the intensely annoying "mapping symbols" found
   18.98   * in ARM ELF files: $a, $t and $d.
   18.99   */
  18.100 -static inline int
  18.101 -is_arm_mapping_symbol(const char *str)
  18.102 +static inline int is_arm_mapping_symbol(const char *str)
  18.103  {
  18.104  	return str[0] == '$' && strchr("atd", str[1])
  18.105  	       && (str[2] == '\0' || str[2] == '.');
  18.106  }
  18.107  
  18.108 -static int
  18.109 -read_symbol(FILE *in, struct sym_entry *s)
  18.110 +static int read_symbol(FILE *in, struct sym_entry *s)
  18.111  {
  18.112  	char str[500];
  18.113 -	char *sym;
  18.114 +	char *sym, stype;
  18.115  	int rc;
  18.116  
  18.117 -	rc = fscanf(in, "%llx %c %499s\n", &s->addr, &s->type, str);
  18.118 +	rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str);
  18.119  	if (rc != 3) {
  18.120  		if (rc != EOF) {
  18.121  			/* skip line */
  18.122 @@ -135,7 +95,15 @@ read_symbol(FILE *in, struct sym_entry *
  18.123  		_stext = s->addr;
  18.124  	else if (strcmp(sym, "_etext") == 0)
  18.125  		_etext = s->addr;
  18.126 -	else if (toupper(s->type) == 'A')
  18.127 +	else if (strcmp(sym, "_sinittext") == 0)
  18.128 +		_sinittext = s->addr;
  18.129 +	else if (strcmp(sym, "_einittext") == 0)
  18.130 +		_einittext = s->addr;
  18.131 +	else if (strcmp(sym, "_sextratext") == 0)
  18.132 +		_sextratext = s->addr;
  18.133 +	else if (strcmp(sym, "_eextratext") == 0)
  18.134 +		_eextratext = s->addr;
  18.135 +	else if (toupper(stype) == 'A')
  18.136  	{
  18.137  		/* Keep these useful absolute symbols */
  18.138  		if (strcmp(sym, "__kernel_syscall_via_break") &&
  18.139 @@ -145,22 +113,24 @@ read_symbol(FILE *in, struct sym_entry *
  18.140  			return -1;
  18.141  
  18.142  	}
  18.143 -	else if (toupper(s->type) == 'U' ||
  18.144 +	else if (toupper(stype) == 'U' ||
  18.145  		 is_arm_mapping_symbol(sym))
  18.146  		return -1;
  18.147 +	/* exclude also MIPS ELF local symbols ($L123 instead of .L123) */
  18.148 +	else if (str[0] == '$')
  18.149 +		return -1;
  18.150  
  18.151  	/* include the type field in the symbol name, so that it gets
  18.152  	 * compressed together */
  18.153  	s->len = strlen(str) + 1;
  18.154 -	s->sym = (unsigned char *) malloc(s->len + 1);
  18.155 +	s->sym = malloc(s->len + 1);
  18.156  	strcpy((char *)s->sym + 1, str);
  18.157 -	s->sym[0] = s->type;
  18.158 +	s->sym[0] = stype;
  18.159  
  18.160  	return 0;
  18.161  }
  18.162  
  18.163 -static int
  18.164 -symbol_valid(struct sym_entry *s)
  18.165 +static int symbol_valid(struct sym_entry *s)
  18.166  {
  18.167  	/* Symbols which vary between passes.  Passes 1 and 2 must have
  18.168  	 * identical symbol lists.  The symbols_* symbols below are only added
  18.169 @@ -189,7 +159,9 @@ symbol_valid(struct sym_entry *s)
  18.170  	/* if --all-symbols is not specified, then symbols outside the text
  18.171  	 * and inittext sections are discarded */
  18.172  	if (!all_symbols) {
  18.173 -		if (s->addr < _stext || s->addr > _etext)
  18.174 +		if ((s->addr < _stext || s->addr > _etext)
  18.175 +		    && (s->addr < _sinittext || s->addr > _einittext)
  18.176 +		    && (s->addr < _sextratext || s->addr > _eextratext))
  18.177  			return 0;
  18.178  		/* Corner case.  Discard any symbols with the same value as
  18.179  		 * _etext _einittext or _eextratext; they can move between pass
  18.180 @@ -197,7 +169,9 @@ symbol_valid(struct sym_entry *s)
  18.181  		 * move then they may get dropped in pass 2, which breaks the
  18.182  		 * symbols rules.
  18.183  		 */
  18.184 -		if (s->addr == _etext && strcmp((char *)s->sym + offset, "_etext"))
  18.185 +		if ((s->addr == _etext && strcmp((char*)s->sym + offset, "_etext")) ||
  18.186 +		    (s->addr == _einittext && strcmp((char*)s->sym + offset, "_einittext")) ||
  18.187 +		    (s->addr == _eextratext && strcmp((char*)s->sym + offset, "_eextratext")))
  18.188  			return 0;
  18.189  	}
  18.190  
  18.191 @@ -212,20 +186,19 @@ symbol_valid(struct sym_entry *s)
  18.192  	return 1;
  18.193  }
  18.194  
  18.195 -static void
  18.196 -read_map(FILE *in)
  18.197 +static void read_map(FILE *in)
  18.198  {
  18.199  	while (!feof(in)) {
  18.200 -		if (cnt >= size) {
  18.201 -			size += 10000;
  18.202 -			table = realloc(table, sizeof(*table) * size);
  18.203 +		if (table_cnt >= table_size) {
  18.204 +			table_size += 10000;
  18.205 +			table = realloc(table, sizeof(*table) * table_size);
  18.206  			if (!table) {
  18.207  				fprintf(stderr, "out of memory\n");
  18.208  				exit (1);
  18.209  			}
  18.210  		}
  18.211 -		if (read_symbol(in, &table[cnt]) == 0)
  18.212 -			cnt++;
  18.213 +		if (read_symbol(in, &table[table_cnt]) == 0)
  18.214 +			table_cnt++;
  18.215  	}
  18.216  }
  18.217  
  18.218 @@ -269,10 +242,9 @@ static int expand_symbol(unsigned char *
  18.219  	return total;
  18.220  }
  18.221  
  18.222 -static void
  18.223 -write_src(void)
  18.224 +static void write_src(void)
  18.225  {
  18.226 -	int i, k, off, valid;
  18.227 +	unsigned int i, k, off;
  18.228  	unsigned int best_idx[256];
  18.229  	unsigned int *markers;
  18.230  	char buf[KSYM_NAME_LEN+1];
  18.231 @@ -289,33 +261,24 @@ write_src(void)
  18.232  	printf(".data\n");
  18.233  
  18.234  	output_label("symbols_addresses");
  18.235 -	valid = 0;
  18.236 -	for (i = 0; i < cnt; i++) {
  18.237 -		if (table[i].flags & SYM_FLAG_VALID) {
  18.238 -			printf("\tPTR\t%#llx\n", table[i].addr);
  18.239 -			valid++;
  18.240 -		}
  18.241 +	for (i = 0; i < table_cnt; i++) {
  18.242 +		printf("\tPTR\t%#llx\n", table[i].addr);
  18.243  	}
  18.244  	printf("\n");
  18.245  
  18.246  	output_label("symbols_num_syms");
  18.247 -	printf("\tPTR\t%d\n", valid);
  18.248 +	printf("\tPTR\t%d\n", table_cnt);
  18.249  	printf("\n");
  18.250  
  18.251  	/* table of offset markers, that give the offset in the compressed stream
  18.252  	 * every 256 symbols */
  18.253 -	markers = (unsigned int *) malloc(sizeof(unsigned int)*((valid + 255) / 256));
  18.254 +	markers = (unsigned int *) malloc(sizeof(unsigned int) * ((table_cnt + 255) / 256));
  18.255  
  18.256  	output_label("symbols_names");
  18.257 -	valid = 0;
  18.258  	off = 0;
  18.259 -	for (i = 0; i < cnt; i++) {
  18.260 -
  18.261 -		if (!(table[i].flags & SYM_FLAG_VALID))
  18.262 -			continue;
  18.263 -
  18.264 -		if ((valid & 0xFF) == 0)
  18.265 -			markers[valid >> 8] = off;
  18.266 +	for (i = 0; i < table_cnt; i++) {
  18.267 +		if ((i & 0xFF) == 0)
  18.268 +			markers[i >> 8] = off;
  18.269  
  18.270  		printf("\t.byte 0x%02x", table[i].len);
  18.271  		for (k = 0; k < table[i].len; k++)
  18.272 @@ -323,12 +286,11 @@ write_src(void)
  18.273  		printf("\n");
  18.274  
  18.275  		off += table[i].len + 1;
  18.276 -		valid++;
  18.277  	}
  18.278  	printf("\n");
  18.279  
  18.280  	output_label("symbols_markers");
  18.281 -	for (i = 0; i < ((valid + 255) >> 8); i++)
  18.282 +	for (i = 0; i < ((table_cnt + 255) >> 8); i++)
  18.283  		printf("\tPTR\t%d\n", markers[i]);
  18.284  	printf("\n");
  18.285  
  18.286 @@ -338,7 +300,7 @@ write_src(void)
  18.287  	off = 0;
  18.288  	for (i = 0; i < 256; i++) {
  18.289  		best_idx[i] = off;
  18.290 -		expand_symbol(best_table[i],best_table_len[i],buf);
  18.291 +		expand_symbol(best_table[i], best_table_len[i], buf);
  18.292  		printf("\t.asciz\t\"%s\"\n", buf);
  18.293  		off += strlen(buf) + 1;
  18.294  	}
  18.295 @@ -353,153 +315,13 @@ write_src(void)
  18.296  
  18.297  /* table lookup compression functions */
  18.298  
  18.299 -static inline unsigned int rehash_token(unsigned int hash, unsigned char data)
  18.300 -{
  18.301 -	return ((hash * 16777619) ^ data);
  18.302 -}
  18.303 -
  18.304 -static unsigned int hash_token(unsigned char *data, int len)
  18.305 -{
  18.306 -	unsigned int hash=HASH_BASE_OFFSET;
  18.307 -	int i;
  18.308 -
  18.309 -	for (i = 0; i < len; i++)
  18.310 -		hash = rehash_token(hash, data[i]);
  18.311 -
  18.312 -	return HASH_FOLD(hash);
  18.313 -}
  18.314 -
  18.315 -/* find a token given its data and hash value */
  18.316 -static struct token *find_token_hash(unsigned char *data, int len, unsigned int hash)
  18.317 -{
  18.318 -	struct token *ptr;
  18.319 -
  18.320 -	ptr = hash_table[hash];
  18.321 -
  18.322 -	while (ptr) {
  18.323 -		if ((ptr->len == len) && (memcmp(ptr->data, data, len) == 0))
  18.324 -			return ptr;
  18.325 -		ptr=ptr->next;
  18.326 -	}
  18.327 -
  18.328 -	return NULL;
  18.329 -}
  18.330 -
  18.331 -static inline void insert_token_in_group(struct token *head, struct token *ptr)
  18.332 -{
  18.333 -	ptr->right = head->right;
  18.334 -	ptr->right->left = ptr;
  18.335 -	head->right = ptr;
  18.336 -	ptr->left = head;
  18.337 -}
  18.338 -
  18.339 -static inline void remove_token_from_group(struct token *ptr)
  18.340 -{
  18.341 -	ptr->left->right = ptr->right;
  18.342 -	ptr->right->left = ptr->left;
  18.343 -}
  18.344 -
  18.345 -
  18.346 -/* build the counts for all the tokens that start with "data", and have lenghts
  18.347 - * from 2 to "len" */
  18.348 -static void learn_token(unsigned char *data, int len)
  18.349 -{
  18.350 -	struct token *ptr,*last_ptr;
  18.351 -	int i, newprofit;
  18.352 -	unsigned int hash = HASH_BASE_OFFSET;
  18.353 -	unsigned int hashes[MAX_TOK_SIZE + 1];
  18.354 -
  18.355 -	if (len > MAX_TOK_SIZE)
  18.356 -		len = MAX_TOK_SIZE;
  18.357 -
  18.358 -	/* calculate and store the hash values for all the sub-tokens */
  18.359 -	hash = rehash_token(hash, data[0]);
  18.360 -	for (i = 2; i <= len; i++) {
  18.361 -		hash = rehash_token(hash, data[i-1]);
  18.362 -		hashes[i] = HASH_FOLD(hash);
  18.363 -	}
  18.364 -
  18.365 -	last_ptr = NULL;
  18.366 -	ptr = NULL;
  18.367 -
  18.368 -	for (i = len; i >= 2; i--) {
  18.369 -		hash = hashes[i];
  18.370 -
  18.371 -		if (!ptr) ptr = find_token_hash(data, i, hash);
  18.372 -
  18.373 -		if (!ptr) {
  18.374 -			/* create a new token entry */
  18.375 -			ptr = (struct token *) malloc(sizeof(*ptr));
  18.376 -
  18.377 -			memcpy(ptr->data, data, i);
  18.378 -			ptr->len = i;
  18.379 -
  18.380 -			/* when we create an entry, it's profit is 0 because
  18.381 -			 * we also take into account the size of the token on
  18.382 -			 * the compressed table. We then subtract GOOD_BAD_THRESHOLD
  18.383 -			 * so that the test to see if this token belongs to
  18.384 -			 * the good or bad list, is a comparison to zero */
  18.385 -			ptr->profit = -GOOD_BAD_THRESHOLD;
  18.386 -
  18.387 -			ptr->next = hash_table[hash];
  18.388 -			hash_table[hash] = ptr;
  18.389 -
  18.390 -			insert_token_in_group(&bad_head, ptr);
  18.391 -
  18.392 -			ptr->smaller = NULL;
  18.393 -		} else {
  18.394 -			newprofit = ptr->profit + (ptr->len - 1);
  18.395 -			/* check to see if this token needs to be moved to a
  18.396 -			 * different list */
  18.397 -			if((ptr->profit < 0) && (newprofit >= 0)) {
  18.398 -				remove_token_from_group(ptr);
  18.399 -				insert_token_in_group(&good_head,ptr);
  18.400 -			}
  18.401 -			ptr->profit = newprofit;
  18.402 -		}
  18.403 -
  18.404 -		if (last_ptr) last_ptr->smaller = ptr;
  18.405 -		last_ptr = ptr;
  18.406 -
  18.407 -		ptr = ptr->smaller;
  18.408 -	}
  18.409 -}
  18.410 -
  18.411 -/* decrease the counts for all the tokens that start with "data", and have lenghts
  18.412 - * from 2 to "len". This function is much simpler than learn_token because we have
  18.413 - * more guarantees (tho tokens exist, the ->smaller pointer is set, etc.)
  18.414 - * The two separate functions exist only because of compression performance */
  18.415 -static void forget_token(unsigned char *data, int len)
  18.416 -{
  18.417 -	struct token *ptr;
  18.418 -	int i, newprofit;
  18.419 -	unsigned int hash=0;
  18.420 -
  18.421 -	if (len > MAX_TOK_SIZE) len = MAX_TOK_SIZE;
  18.422 -
  18.423 -	hash = hash_token(data, len);
  18.424 -	ptr = find_token_hash(data, len, hash);
  18.425 -
  18.426 -	for (i = len; i >= 2; i--) {
  18.427 -
  18.428 -		newprofit = ptr->profit - (ptr->len - 1);
  18.429 -		if ((ptr->profit >= 0) && (newprofit < 0)) {
  18.430 -			remove_token_from_group(ptr);
  18.431 -			insert_token_in_group(&bad_head, ptr);
  18.432 -		}
  18.433 -		ptr->profit=newprofit;
  18.434 -
  18.435 -		ptr=ptr->smaller;
  18.436 -	}
  18.437 -}
  18.438 -
  18.439  /* count all the possible tokens in a symbol */
  18.440  static void learn_symbol(unsigned char *symbol, int len)
  18.441  {
  18.442  	int i;
  18.443  
  18.444  	for (i = 0; i < len - 1; i++)
  18.445 -		learn_token(symbol + i, len - i);
  18.446 +		token_profit[ symbol[i] + (symbol[i + 1] << 8) ]++;
  18.447  }
  18.448  
  18.449  /* decrease the count for all the possible tokens in a symbol */
  18.450 @@ -508,117 +330,90 @@ static void forget_symbol(unsigned char 
  18.451  	int i;
  18.452  
  18.453  	for (i = 0; i < len - 1; i++)
  18.454 -		forget_token(symbol + i, len - i);
  18.455 +		token_profit[ symbol[i] + (symbol[i + 1] << 8) ]--;
  18.456  }
  18.457  
  18.458 -/* set all the symbol flags and do the initial token count */
  18.459 +/* remove all the invalid symbols from the table and do the initial token count */
  18.460  static void build_initial_tok_table(void)
  18.461  {
  18.462 -	int i, use_it, valid;
  18.463 +	unsigned int i, pos;
  18.464  
  18.465 -	valid = 0;
  18.466 -	for (i = 0; i < cnt; i++) {
  18.467 -		table[i].flags = 0;
  18.468 +	pos = 0;
  18.469 +	for (i = 0; i < table_cnt; i++) {
  18.470  		if ( symbol_valid(&table[i]) ) {
  18.471 -			table[i].flags |= SYM_FLAG_VALID;
  18.472 -			valid++;
  18.473 +			if (pos != i)
  18.474 +				table[pos] = table[i];
  18.475 +			learn_symbol(table[pos].sym, table[pos].len);
  18.476 +			pos++;
  18.477  		}
  18.478  	}
  18.479 -
  18.480 -	use_it = 0;
  18.481 -	for (i = 0; i < cnt; i++) {
  18.482 -
  18.483 -		/* subsample the available symbols. This method is almost like
  18.484 -		 * a Bresenham's algorithm to get uniformly distributed samples
  18.485 -		 * across the symbol table */
  18.486 -		if (table[i].flags & SYM_FLAG_VALID) {
  18.487 -
  18.488 -			use_it += WORKING_SET;
  18.489 -
  18.490 -			if (use_it >= valid) {
  18.491 -				table[i].flags |= SYM_FLAG_SAMPLED;
  18.492 -				use_it -= valid;
  18.493 -			}
  18.494 -		}
  18.495 -		if (table[i].flags & SYM_FLAG_SAMPLED)
  18.496 -			learn_symbol(table[i].sym, table[i].len);
  18.497 -	}
  18.498 +	table_cnt = pos;
  18.499  }
  18.500  
  18.501  /* replace a given token in all the valid symbols. Use the sampled symbols
  18.502   * to update the counts */
  18.503 -static void compress_symbols(unsigned char *str, int tlen, int idx)
  18.504 +static void compress_symbols(unsigned char *str, int idx)
  18.505  {
  18.506 -	int i, len, learn, size;
  18.507 -	unsigned char *p;
  18.508 +	unsigned int i, len, size;
  18.509 +	unsigned char *p1, *p2;
  18.510  
  18.511 -	for (i = 0; i < cnt; i++) {
  18.512 -
  18.513 -		if (!(table[i].flags & SYM_FLAG_VALID)) continue;
  18.514 +	for (i = 0; i < table_cnt; i++) {
  18.515  
  18.516  		len = table[i].len;
  18.517 -		learn = 0;
  18.518 -		p = table[i].sym;
  18.519 +		p1 = table[i].sym;
  18.520 +
  18.521 +		/* find the token on the symbol */
  18.522 +		p2 = memmem(p1, len, str, 2);
  18.523 +		if (!p2) continue;
  18.524 +
  18.525 +		/* decrease the counts for this symbol's tokens */
  18.526 +		forget_symbol(table[i].sym, len);
  18.527 +
  18.528 +		size = len;
  18.529  
  18.530  		do {
  18.531 -			/* find the token on the symbol */
  18.532 -			p = (unsigned char *) strstr((char *) p, (char *) str);
  18.533 -			if (!p) break;
  18.534 +			*p2 = idx;
  18.535 +			p2++;
  18.536 +			size -= (p2 - p1);
  18.537 +			memmove(p2, p2 + 1, size);
  18.538 +			p1 = p2;
  18.539 +			len--;
  18.540  
  18.541 -			if (!learn) {
  18.542 -				/* if this symbol was used to count, decrease it */
  18.543 -				if (table[i].flags & SYM_FLAG_SAMPLED)
  18.544 -					forget_symbol(table[i].sym, len);
  18.545 -				learn = 1;
  18.546 -			}
  18.547 +			if (size < 2) break;
  18.548  
  18.549 -			*p = idx;
  18.550 -			size = (len - (p - table[i].sym)) - tlen + 1;
  18.551 -			memmove(p + 1, p + tlen, size);
  18.552 -			p++;
  18.553 -			len -= tlen - 1;
  18.554 +			/* find the token on the symbol */
  18.555 +			p2 = memmem(p1, size, str, 2);
  18.556 +
  18.557 +		} while (p2);
  18.558  
  18.559 -		} while (size >= tlen);
  18.560 +		table[i].len = len;
  18.561  
  18.562 -		if(learn) {
  18.563 -			table[i].len = len;
  18.564 -			/* if this symbol was used to count, learn it again */
  18.565 -			if(table[i].flags & SYM_FLAG_SAMPLED)
  18.566 -				learn_symbol(table[i].sym, len);
  18.567 -		}
  18.568 +		/* increase the counts for this symbol's new tokens */
  18.569 +		learn_symbol(table[i].sym, len);
  18.570  	}
  18.571  }
  18.572  
  18.573  /* search the token with the maximum profit */
  18.574 -static struct token *find_best_token(void)
  18.575 +static int find_best_token(void)
  18.576  {
  18.577 -	struct token *ptr,*best,*head;
  18.578 -	int bestprofit;
  18.579 +	int i, best, bestprofit;
  18.580  
  18.581  	bestprofit=-10000;
  18.582 -
  18.583 -	/* failsafe: if the "good" list is empty search from the "bad" list */
  18.584 -	if(good_head.right == &good_head) head = &bad_head;
  18.585 -	else head = &good_head;
  18.586 +	best = 0;
  18.587  
  18.588 -	ptr = head->right;
  18.589 -	best = NULL;
  18.590 -	while (ptr != head) {
  18.591 -		if (ptr->profit > bestprofit) {
  18.592 -			bestprofit = ptr->profit;
  18.593 -			best = ptr;
  18.594 +	for (i = 0; i < 0x10000; i++) {
  18.595 +		if (token_profit[i] > bestprofit) {
  18.596 +			best = i;
  18.597 +			bestprofit = token_profit[i];
  18.598  		}
  18.599 -		ptr = ptr->right;
  18.600  	}
  18.601 -
  18.602  	return best;
  18.603  }
  18.604  
  18.605  /* this is the core of the algorithm: calculate the "best" table */
  18.606  static void optimize_result(void)
  18.607  {
  18.608 -	struct token *best;
  18.609 -	int i;
  18.610 +	int i, best;
  18.611  
  18.612  	/* using the '\0' symbol last allows compress_symbols to use standard
  18.613  	 * fast string functions */
  18.614 @@ -632,14 +427,12 @@ static void optimize_result(void)
  18.615  			best = find_best_token();
  18.616  
  18.617  			/* place it in the "best" table */
  18.618 -			best_table_len[i] = best->len;
  18.619 -			memcpy(best_table[i], best->data, best_table_len[i]);
  18.620 -			/* zero terminate the token so that we can use strstr
  18.621 -			   in compress_symbols */
  18.622 -			best_table[i][best_table_len[i]]='\0';
  18.623 +			best_table_len[i] = 2;
  18.624 +			best_table[i][0] = best & 0xFF;
  18.625 +			best_table[i][1] = (best >> 8) & 0xFF;
  18.626  
  18.627  			/* replace this token in all the valid symbols */
  18.628 -			compress_symbols(best_table[i], best_table_len[i], i);
  18.629 +			compress_symbols(best_table[i], i);
  18.630  		}
  18.631  	}
  18.632  }
  18.633 @@ -647,39 +440,28 @@ static void optimize_result(void)
  18.634  /* start by placing the symbols that are actually used on the table */
  18.635  static void insert_real_symbols_in_table(void)
  18.636  {
  18.637 -	int i, j, c;
  18.638 +	unsigned int i, j, c;
  18.639  
  18.640  	memset(best_table, 0, sizeof(best_table));
  18.641  	memset(best_table_len, 0, sizeof(best_table_len));
  18.642  
  18.643 -	for (i = 0; i < cnt; i++) {
  18.644 -		if (table[i].flags & SYM_FLAG_VALID) {
  18.645 -			for (j = 0; j < table[i].len; j++) {
  18.646 -				c = table[i].sym[j];
  18.647 -				best_table[c][0]=c;
  18.648 -				best_table_len[c]=1;
  18.649 -			}
  18.650 +	for (i = 0; i < table_cnt; i++) {
  18.651 +		for (j = 0; j < table[i].len; j++) {
  18.652 +			c = table[i].sym[j];
  18.653 +			best_table[c][0]=c;
  18.654 +			best_table_len[c]=1;
  18.655  		}
  18.656  	}
  18.657  }
  18.658  
  18.659  static void optimize_token_table(void)
  18.660  {
  18.661 -	memset(hash_table, 0, sizeof(hash_table));
  18.662 -
  18.663 -	good_head.left = &good_head;
  18.664 -	good_head.right = &good_head;
  18.665 -
  18.666 -	bad_head.left = &bad_head;
  18.667 -	bad_head.right = &bad_head;
  18.668 -
  18.669  	build_initial_tok_table();
  18.670  
  18.671  	insert_real_symbols_in_table();
  18.672  
  18.673  	/* When valid symbol is not registered, exit to error */
  18.674 -	if (good_head.left == good_head.right &&
  18.675 -	    bad_head.left == bad_head.right) {
  18.676 +	if (!table_cnt) {
  18.677  		fprintf(stderr, "No valid symbol.\n");
  18.678  		exit(1);
  18.679  	}
  18.680 @@ -688,8 +470,7 @@ static void optimize_token_table(void)
  18.681  }
  18.682  
  18.683  
  18.684 -int
  18.685 -main(int argc, char **argv)
  18.686 +int main(int argc, char **argv)
  18.687  {
  18.688  	if (argc >= 2) {
  18.689  		int i;