[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |