diff -Nur linux-2.6.34//Makefile linux-dna-2.6.34//Makefile --- linux-2.6.34//Makefile 2010-05-17 05:17:36.000000000 +0800 +++ linux-dna-2.6.34//Makefile 2010-06-24 11:39:36.006494980 +0800 @@ -225,9 +225,9 @@ else if [ -x /bin/bash ]; then echo /bin/bash; \ else echo sh; fi ; fi) -HOSTCC = gcc +HOSTCC = icc HOSTCXX = g++ -HOSTCFLAGS = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer +HOSTCFLAGS = -w -O1 -fomit-frame-pointer HOSTCXXFLAGS = -O2 # Decide whether to build built-in, modular, or both. @@ -312,7 +312,7 @@ AS = $(CROSS_COMPILE)as LD = $(CROSS_COMPILE)ld -CC = $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)icc CPP = $(CC) -E AR = $(CROSS_COMPILE)ar NM = $(CROSS_COMPILE)nm @@ -529,7 +529,7 @@ ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE KBUILD_CFLAGS += -Os else -KBUILD_CFLAGS += -O2 +KBUILD_CFLAGS += -O3 -w endif include $(srctree)/arch/$(SRCARCH)/Makefile @@ -707,7 +707,7 @@ quiet_cmd_vmlinux__ ?= LD $@ cmd_vmlinux__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) -o $@ \ -T $(vmlinux-lds) $(vmlinux-init) \ - --start-group $(vmlinux-main) --end-group \ + --start-group $(vmlinux-main) /usr/lib/libirc_s.a --end-group \ $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o FORCE ,$^) # Generate new vmlinux version diff -Nur linux-2.6.34//arch/x86/Makefile_32.cpu linux-dna-2.6.34//arch/x86/Makefile_32.cpu --- linux-2.6.34//arch/x86/Makefile_32.cpu 2010-05-17 05:17:36.000000000 +0800 +++ linux-dna-2.6.34//arch/x86/Makefile_32.cpu 2010-06-24 11:39:09.937496305 +0800 @@ -52,9 +52,3 @@ # tracer assumptions. For i686, generic, core2 this is set by the # compiler anyway cflags-$(CONFIG_FUNCTION_GRAPH_TRACER) += $(call cc-option,-maccumulate-outgoing-args) - -# Bug fix for binutils: this option is required in order to keep -# binutils from generating NOPL instructions against our will. -ifneq ($(CONFIG_X86_P6_NOP),y) -cflags-y += $(call cc-option,-Wa$(comma)-mtune=generic32,) -endif diff -Nur linux-2.6.34//arch/x86/boot/compressed/Makefile linux-dna-2.6.34//arch/x86/boot/compressed/Makefile --- linux-2.6.34//arch/x86/boot/compressed/Makefile 2010-05-17 05:17:36.000000000 +0800 +++ linux-dna-2.6.34//arch/x86/boot/compressed/Makefile 2010-06-24 11:28:30.278501987 +0800 @@ -1,3 +1,4 @@ +CC=icc # # linux/arch/x86/boot/compressed/Makefile # @@ -6,7 +7,7 @@ targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.lzo head_$(BITS).o misc.o piggy.o -KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 +KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O3 -no-vec KBUILD_CFLAGS += -fno-strict-aliasing -fPIC KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING cflags-$(CONFIG_X86_32) := -march=i386 diff -Nur linux-2.6.34//arch/x86/boot/compressed/misc.c linux-dna-2.6.34//arch/x86/boot/compressed/misc.c --- linux-2.6.34//arch/x86/boot/compressed/misc.c 2010-05-17 05:17:36.000000000 +0800 +++ linux-dna-2.6.34//arch/x86/boot/compressed/misc.c 2010-06-24 11:28:30.280501676 +0800 @@ -112,6 +112,7 @@ * gzip declarations */ #define STATIC static +#define HANDLE_ICC #undef memset #undef memcpy diff -Nur linux-2.6.34//arch/x86/include/asm/current.h linux-dna-2.6.34//arch/x86/include/asm/current.h --- linux-2.6.34//arch/x86/include/asm/current.h 2010-05-17 05:17:36.000000000 +0800 +++ linux-dna-2.6.34//arch/x86/include/asm/current.h 2010-06-24 11:28:30.288494644 +0800 @@ -11,7 +11,7 @@ static __always_inline struct task_struct *get_current(void) { - return percpu_read_stable(current_task); + return percpu_read(current_task); } #define current get_current() diff -Nur linux-2.6.34//arch/x86/include/asm/percpu.h linux-dna-2.6.34//arch/x86/include/asm/percpu.h --- linux-2.6.34//arch/x86/include/asm/percpu.h 2010-05-17 05:17:36.000000000 +0800 +++ linux-dna-2.6.34//arch/x86/include/asm/percpu.h 2010-06-24 11:56:51.662494088 +0800 @@ -48,7 +48,7 @@ #define __percpu_arg(x) "%%"__stringify(__percpu_seg)":%P" #x #define __my_cpu_offset percpu_read(this_cpu_off) #else -#define __percpu_arg(x) "%P" #x +#define __percpu_arg(x) "%" #x #endif /* @@ -161,46 +161,36 @@ } \ } while (0) -#define percpu_from_op(op, var, constraint) \ +#define percpu_from_op(op, var) \ ({ \ typeof(var) pfo_ret__; \ switch (sizeof(var)) { \ case 1: \ asm(op "b "__percpu_arg(1)",%0" \ : "=q" (pfo_ret__) \ - : constraint); \ + : "m" (var)); \ break; \ case 2: \ asm(op "w "__percpu_arg(1)",%0" \ : "=r" (pfo_ret__) \ - : constraint); \ + : "m" (var)); \ break; \ case 4: \ asm(op "l "__percpu_arg(1)",%0" \ : "=r" (pfo_ret__) \ - : constraint); \ + : "m" (var)); \ break; \ case 8: \ asm(op "q "__percpu_arg(1)",%0" \ : "=r" (pfo_ret__) \ - : constraint); \ + : "m" (var)); \ break; \ default: __bad_percpu_size(); \ } \ pfo_ret__; \ }) -/* - * percpu_read() makes gcc load the percpu variable every time it is - * accessed while percpu_read_stable() allows the value to be cached. - * percpu_read_stable() is more efficient and can be used if its value - * is guaranteed to be valid across cpus. The current users include - * get_current() and get_thread_info() both of which are actually - * per-thread variables implemented as per-cpu variables and thus - * stable for the duration of the respective task. - */ -#define percpu_read(var) percpu_from_op("mov", var, "m" (var)) -#define percpu_read_stable(var) percpu_from_op("mov", var, "p" (&(var))) +#define percpu_read(var) percpu_from_op("mov", var) #define percpu_write(var, val) percpu_to_op("mov", var, val) #define percpu_add(var, val) percpu_add_op(var, val) #define percpu_sub(var, val) percpu_add_op(var, -(val)) diff -Nur linux-2.6.34//arch/x86/include/asm/thread_info.h linux-dna-2.6.34//arch/x86/include/asm/thread_info.h --- linux-2.6.34//arch/x86/include/asm/thread_info.h 2010-05-17 05:17:36.000000000 +0800 +++ linux-dna-2.6.34//arch/x86/include/asm/thread_info.h 2010-06-24 11:28:30.297497614 +0800 @@ -215,7 +215,7 @@ static inline struct thread_info *current_thread_info(void) { struct thread_info *ti; - ti = (void *)(percpu_read_stable(kernel_stack) + + ti = (void *)(percpu_read(kernel_stack) + KERNEL_STACK_OFFSET - THREAD_SIZE); return ti; } diff -Nur linux-2.6.34//arch/x86/kernel/apic/nmi.c linux-dna-2.6.34//arch/x86/kernel/apic/nmi.c --- linux-2.6.34//arch/x86/kernel/apic/nmi.c 2010-05-17 05:17:36.000000000 +0800 +++ linux-dna-2.6.34//arch/x86/kernel/apic/nmi.c 2010-06-24 11:35:02.958497837 +0800 @@ -362,7 +362,7 @@ */ static DEFINE_PER_CPU(unsigned, last_irq_sum); -static DEFINE_PER_CPU(long, alert_counter); +static DEFINE_PER_CPU(local_t, alert_counter); static DEFINE_PER_CPU(int, nmi_touch); void touch_nmi_watchdog(void) @@ -439,8 +439,8 @@ * Ayiee, looks like this CPU is stuck ... * wait a few IRQs (5 seconds) before doing the oops ... */ - __this_cpu_inc(alert_counter); - if (__this_cpu_read(alert_counter) == 5 * nmi_hz) + local_inc(&__get_cpu_var(alert_counter)); + if (local_read(&__get_cpu_var(alert_counter)) == 5 * nmi_hz) /* * die_nmi will return ONLY if NOTIFY_STOP happens.. */ @@ -448,7 +448,7 @@ regs, panic_on_timeout); } else { __get_cpu_var(last_irq_sum) = sum; - __this_cpu_write(alert_counter, 0); + local_set(&__get_cpu_var(alert_counter), 0); } /* see if the nmi watchdog went off */ diff -Nur linux-2.6.34//arch/x86/kernel/cpu/common.c linux-dna-2.6.34//arch/x86/kernel/cpu/common.c --- linux-2.6.34//arch/x86/kernel/cpu/common.c 2010-05-17 05:17:36.000000000 +0800 +++ linux-dna-2.6.34//arch/x86/kernel/cpu/common.c 2010-06-24 11:38:42.588496562 +0800 @@ -100,38 +100,38 @@ [GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f3, 0, 0xfffff), [GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xa0fb, 0, 0xfffff), #else - [GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xc09a, 0, 0xfffff), - [GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), - [GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xc0fa, 0, 0xfffff), - [GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f2, 0, 0xfffff), + [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } }, + [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } }, + [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } }, + [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } }, /* * Segments used for calling PnP BIOS have byte granularity. * They code segments and data segments have fixed 64k limits, * the transfer segment sizes are set at run time. */ /* 32-bit code */ - [GDT_ENTRY_PNPBIOS_CS32] = GDT_ENTRY_INIT(0x409a, 0, 0xffff), + [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } }, /* 16-bit code */ - [GDT_ENTRY_PNPBIOS_CS16] = GDT_ENTRY_INIT(0x009a, 0, 0xffff), + [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } }, /* 16-bit data */ - [GDT_ENTRY_PNPBIOS_DS] = GDT_ENTRY_INIT(0x0092, 0, 0xffff), + [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } }, /* 16-bit data */ - [GDT_ENTRY_PNPBIOS_TS1] = GDT_ENTRY_INIT(0x0092, 0, 0), + [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } }, /* 16-bit data */ - [GDT_ENTRY_PNPBIOS_TS2] = GDT_ENTRY_INIT(0x0092, 0, 0), + [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } }, /* * The APM segments have byte granularity and their bases * are set at run time. All have 64k limits. */ /* 32-bit code */ - [GDT_ENTRY_APMBIOS_BASE] = GDT_ENTRY_INIT(0x409a, 0, 0xffff), + [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } }, /* 16-bit code */ - [GDT_ENTRY_APMBIOS_BASE+1] = GDT_ENTRY_INIT(0x009a, 0, 0xffff), + [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } }, /* data */ - [GDT_ENTRY_APMBIOS_BASE+2] = GDT_ENTRY_INIT(0x4092, 0, 0xffff), + [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } }, - [GDT_ENTRY_ESPFIX_SS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), - [GDT_ENTRY_PERCPU] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff), + [GDT_ENTRY_ESPFIX_SS] = { { { 0x0000ffff, 0x00cf9200 } } }, + [GDT_ENTRY_PERCPU] = { { { 0x0000ffff, 0x00cf9200 } } }, GDT_STACK_CANARY_INIT #endif } }; diff -Nur linux-2.6.34//include/linux/module.h linux-dna-2.6.34//include/linux/module.h --- linux-2.6.34//include/linux/module.h 2010-05-17 05:17:36.000000000 +0800 +++ linux-dna-2.6.34//include/linux/module.h 2010-06-24 12:52:30.720808065 +0800 @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include @@ -366,11 +366,11 @@ /* Destruction function. */ void (*exit)(void); - - struct module_ref { - unsigned int incs; - unsigned int decs; - } __percpu *refptr; +#ifdef CONFIG_SMP + char *refptr; +#else + local_t ref; +#endif #endif #ifdef CONFIG_CONSTRUCTORS @@ -458,16 +458,25 @@ #define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x) void symbol_put_addr(void *addr); +static inline local_t *__module_ref_addr(struct module *mod, int cpu) +{ +#ifdef CONFIG_SMP + return (local_t *) (mod->refptr + per_cpu_offset(cpu)); +#else + return &mod->ref; +#endif +} + /* Sometimes we know we already have a refcount, and it's easier not to handle the error case (which only happens with rmmod --wait). */ static inline void __module_get(struct module *module) { if (module) { - preempt_disable(); - __this_cpu_inc(module->refptr->incs); + unsigned int cpu = get_cpu(); + local_inc(__module_ref_addr(module, cpu)); trace_module_get(module, _THIS_IP_, - __this_cpu_read(module->refptr->incs)); - preempt_enable(); + local_read(__module_ref_addr(module, cpu))); + put_cpu(); } } @@ -476,16 +485,16 @@ int ret = 1; if (module) { - preempt_disable(); + unsigned int cpu = get_cpu(); if (likely(module_is_live(module))) { - __this_cpu_inc(module->refptr->incs); + local_inc(__module_ref_addr(module, cpu)); trace_module_get(module, _THIS_IP_, - __this_cpu_read(module->refptr->incs)); + local_read(__module_ref_addr(module, cpu))); } else ret = 0; - preempt_enable(); + put_cpu(); } return ret; } diff -Nur linux-2.6.34//include/linux/tracepoint.h linux-dna-2.6.34//include/linux/tracepoint.h --- linux-2.6.34//include/linux/tracepoint.h 2010-05-17 05:17:36.000000000 +0800 +++ linux-dna-2.6.34//include/linux/tracepoint.h 2010-06-24 11:28:30.312506020 +0800 @@ -83,7 +83,7 @@ #define DEFINE_TRACE_FN(name, reg, unreg) \ static const char __tpstrtab_##name[] \ - __attribute__((section("__tracepoints_strings"))) = #name; \ + __attribute__((section("__tracepoints_strings"), aligned(16))) = #name; \ struct tracepoint __tracepoint_##name \ __attribute__((section("__tracepoints"), aligned(32))) = \ { __tpstrtab_##name, 0, reg, unreg, NULL } diff -Nur linux-2.6.34//kernel/module.c linux-dna-2.6.34//kernel/module.c --- linux-2.6.34//kernel/module.c 2010-05-17 05:17:36.000000000 +0800 +++ linux-dna-2.6.34//kernel/module.c 2010-06-24 12:53:33.369814241 +0800 @@ -522,12 +522,11 @@ INIT_LIST_HEAD(&mod->modules_which_use_me); for_each_possible_cpu(cpu) { - per_cpu_ptr(mod->refptr, cpu)->incs = 0; - per_cpu_ptr(mod->refptr, cpu)->decs = 0; + local_set(__module_ref_addr(mod, cpu), 0); } /* Hold reference count during initialization. */ - __this_cpu_write(mod->refptr->incs, 1); + local_set(__module_ref_addr(mod, raw_smp_processor_id()), 1); /* Backwards compatibility macros put refcount during init. */ mod->waiter = current; } @@ -666,28 +665,12 @@ unsigned int module_refcount(struct module *mod) { - unsigned int incs = 0, decs = 0; + unsigned int total = 0; int cpu; for_each_possible_cpu(cpu) - decs += per_cpu_ptr(mod->refptr, cpu)->decs; - /* - * ensure the incs are added up after the decs. - * module_put ensures incs are visible before decs with smp_wmb. - * - * This 2-count scheme avoids the situation where the refcount - * for CPU0 is read, then CPU0 increments the module refcount, - * then CPU1 drops that refcount, then the refcount for CPU1 is - * read. We would record a decrement but not its corresponding - * increment so we would see a low count (disaster). - * - * Rare situation? But module_refcount can be preempted, and we - * might be tallying up 4096+ CPUs. So it is not impossible. - */ - smp_rmb(); - for_each_possible_cpu(cpu) - incs += per_cpu_ptr(mod->refptr, cpu)->incs; - return incs - decs; + total += local_read(__module_ref_addr(mod, cpu)); + return total; } EXPORT_SYMBOL(module_refcount); @@ -863,16 +846,14 @@ void module_put(struct module *module) { if (module) { - preempt_disable(); - smp_wmb(); /* see comment in module_refcount */ - __this_cpu_inc(module->refptr->decs); - + unsigned int cpu = get_cpu(); + local_dec(__module_ref_addr(module, cpu)); trace_module_put(module, _RET_IP_, - __this_cpu_read(module->refptr->decs)); + local_read(__module_ref_addr(module, cpu))); /* Maybe they're waiting for us to drop reference? */ if (unlikely(!module_is_live(module))) wake_up_process(module->waiter); - preempt_enable(); + put_cpu(); } } EXPORT_SYMBOL(module_put); @@ -1468,9 +1449,9 @@ module_free(mod, mod->module_init); kfree(mod->args); percpu_modfree(mod); -#if defined(CONFIG_MODULE_UNLOAD) +#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) if (mod->refptr) - free_percpu(mod->refptr); + percpu_modfree(mod->refptr); #endif /* Free lock-classes: */ lockdep_free_key_range(mod->module_core, mod->core_size); @@ -2100,6 +2081,8 @@ versindex = find_sec(hdr, sechdrs, secstrings, "__versions"); infoindex = find_sec(hdr, sechdrs, secstrings, ".modinfo"); pcpuindex = find_pcpusec(hdr, sechdrs, secstrings); + if (!sechdrs[pcpuindex].sh_size) + pcpuindex=0; /* Don't keep modinfo and version sections. */ sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC; @@ -2229,8 +2212,8 @@ mod = (void *)sechdrs[modindex].sh_addr; kmemleak_load_module(mod, hdr, sechdrs, secstrings); -#if defined(CONFIG_MODULE_UNLOAD) - mod->refptr = alloc_percpu(struct module_ref); +#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) + mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t),mod->name); if (!mod->refptr) { err = -ENOMEM; goto free_init; @@ -2462,8 +2445,8 @@ kobject_put(&mod->mkobj.kobj); free_unload: module_unload_free(mod); -#if defined(CONFIG_MODULE_UNLOAD) - free_percpu(mod->refptr); +#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) + percpu_modfree(mod->refptr); free_init: #endif module_free(mod, mod->module_init); diff -Nur linux-2.6.34//kernel/trace/trace.h linux-dna-2.6.34//kernel/trace/trace.h --- linux-2.6.34//kernel/trace/trace.h 2010-05-17 05:17:36.000000000 +0800 +++ linux-dna-2.6.34//kernel/trace/trace.h 2010-06-24 11:28:30.340498453 +0800 @@ -444,7 +444,7 @@ extern int ring_buffer_expanded; extern bool tracing_selftest_disabled; -DECLARE_PER_CPU(int, ftrace_cpu_disabled); +DECLARE_PER_CPU(local_t, ftrace_cpu_disabled); #ifdef CONFIG_FTRACE_STARTUP_TEST extern int trace_selftest_startup_function(struct tracer *trace, diff -Nur linux-2.6.34//kernel/trace/trace_events.c linux-dna-2.6.34//kernel/trace/trace_events.c --- linux-2.6.34//kernel/trace/trace_events.c 2010-05-17 05:17:36.000000000 +0800 +++ linux-dna-2.6.34//kernel/trace/trace_events.c 2010-06-24 11:28:30.333498422 +0800 @@ -1057,7 +1057,7 @@ #define for_each_event(event, start, end) \ for (event = start; \ (unsigned long)event < (unsigned long)end; \ - event++) + event=event+0x16) #ifdef CONFIG_MODULES diff -Nur linux-2.6.34//lib/zlib_inflate/inflate.c linux-dna-2.6.34//lib/zlib_inflate/inflate.c --- linux-2.6.34//lib/zlib_inflate/inflate.c 2010-05-17 05:17:36.000000000 +0800 +++ linux-dna-2.6.34//lib/zlib_inflate/inflate.c 2010-06-24 11:28:30.352500462 +0800 @@ -363,6 +363,120 @@ ret = Z_OK; for (;;) switch (state->mode) { +#ifdef HANDLE_ICC + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + case TYPE: + if (flush == Z_BLOCK) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + state->mode = TABLE; + DROPBITS(2); + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); + state->have = 0; + state->mode = LENLENS; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const *)(state->next); + state->lenbits = 7; + ret = zlib_inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + state->have = 0; + state->mode = CODELENS; + while (state->have < state->nlen + state->ndist) { + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.val < 16) { + NEEDBITS(this.bits); + DROPBITS(this.bits); + state->lens[state->have++] = this.val; + } + else { + if (this.val == 16) { + NEEDBITS(this.bits + 2); + DROPBITS(this.bits); + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (this.val == 17) { + NEEDBITS(this.bits + 3); + DROPBITS(this.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(this.bits + 7); + DROPBITS(this.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* build code tables */ + state->next = state->codes; + state->lencode = (code const *)(state->next); + state->lenbits = 9; + ret = zlib_inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + state->distcode = (code const *)(state->next); + state->distbits = 6; + ret = zlib_inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + state->mode = LEN; + RESTORE(); + inflate_fast(strm, out); + LOAD(); + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + INITBITS(); + } + state->mode = DONE; + ret = Z_STREAM_END; + goto inf_leave; + default: + return Z_STREAM_ERROR; + } +#else case HEAD: if (state->wrap == 0) { state->mode = TYPEDO; @@ -721,6 +835,7 @@ default: return Z_STREAM_ERROR; } +#endif /* Return from inflate(), updating the total counts and the check value.