“a4bccde08c6a9635f483dc805b8c940be8835446”上不存在“...fluid/operators/git@gitcode.net:Crayonxin2000/Paddle.git”
提交 1f738978 编写于 作者: L Linus Torvalds

Merge branch 'for-35' of git://repo.or.cz/linux-kbuild

* 'for-35' of git://repo.or.cz/linux-kbuild: (81 commits)
  kbuild: Revert part of e8d400a9 to resolve a conflict
  kbuild: Fix checking of scm-identifier variable
  gconfig: add support to show hidden options that have prompts
  menuconfig: add support to show hidden options which have prompts
  gconfig: remove show_debug option
  gconfig: remove dbg_print_ptype() and dbg_print_stype()
  kconfig: fix zconfdump()
  kconfig: some small fixes
  add random binaries to .gitignore
  kbuild: Include gen_initramfs_list.sh and the file list in the .d file
  kconfig: recalc symbol value before showing search results
  .gitignore: ignore *.lzo files
  headerdep: perlcritic warning
  scripts/Makefile.lib: Align the output of LZO
  kbuild: Generate modules.builtin in make modules_install
  Revert "kbuild: specify absolute paths for cscope"
  kbuild: Do not unnecessarily regenerate modules.builtin
  headers_install: use local file handles
  headers_check: fix perl warnings
  export_report: fix perl warnings
  ...
...@@ -28,6 +28,7 @@ modules.builtin ...@@ -28,6 +28,7 @@ modules.builtin
*.gz *.gz
*.bz2 *.bz2
*.lzma *.lzma
*.lzo
*.patch *.patch
*.gcno *.gcno
......
filesystems/dnotify_test
laptops/dslm
timers/hpet_example
vm/hugepage-mmap
vm/hugepage-shm
vm/map_hugetlb
...@@ -65,7 +65,7 @@ CROSS_COMPILE ...@@ -65,7 +65,7 @@ CROSS_COMPILE
Specify an optional fixed part of the binutils filename. Specify an optional fixed part of the binutils filename.
CROSS_COMPILE can be a part of the filename or the full path. CROSS_COMPILE can be a part of the filename or the full path.
CROSS_COMPILE is also used for ccache is some setups. CROSS_COMPILE is also used for ccache in some setups.
CF CF
-------------------------------------------------- --------------------------------------------------
...@@ -162,3 +162,7 @@ For tags/TAGS/cscope targets, you can specify more than one arch ...@@ -162,3 +162,7 @@ For tags/TAGS/cscope targets, you can specify more than one arch
to be included in the databases, separated by blank space. E.g.: to be included in the databases, separated by blank space. E.g.:
$ make ALLSOURCE_ARCHS="x86 mips arm" tags $ make ALLSOURCE_ARCHS="x86 mips arm" tags
To get all available archs you can also specify all. E.g.:
$ make ALLSOURCE_ARCHS=all tags
...@@ -66,14 +66,14 @@ of advantages of mutexes: ...@@ -66,14 +66,14 @@ of advantages of mutexes:
c0377ccb <mutex_lock>: c0377ccb <mutex_lock>:
c0377ccb: f0 ff 08 lock decl (%eax) c0377ccb: f0 ff 08 lock decl (%eax)
c0377cce: 78 0e js c0377cde <.text.lock.mutex> c0377cce: 78 0e js c0377cde <.text..lock.mutex>
c0377cd0: c3 ret c0377cd0: c3 ret
the unlocking fastpath is equally tight: the unlocking fastpath is equally tight:
c0377cd1 <mutex_unlock>: c0377cd1 <mutex_unlock>:
c0377cd1: f0 ff 00 lock incl (%eax) c0377cd1: f0 ff 00 lock incl (%eax)
c0377cd4: 7e 0f jle c0377ce5 <.text.lock.mutex+0x7> c0377cd4: 7e 0f jle c0377ce5 <.text..lock.mutex+0x7>
c0377cd6: c3 ret c0377cd6: c3 ret
- 'struct mutex' semantics are well-defined and are enforced if - 'struct mutex' semantics are well-defined and are enforced if
......
...@@ -3242,7 +3242,7 @@ L: autofs@linux.kernel.org ...@@ -3242,7 +3242,7 @@ L: autofs@linux.kernel.org
S: Maintained S: Maintained
F: fs/autofs4/ F: fs/autofs4/
KERNEL BUILD KERNEL BUILD + files below scripts/ (unless maintained elsewhere)
M: Michal Marek <mmarek@suse.cz> M: Michal Marek <mmarek@suse.cz>
T: git git://repo.or.cz/linux-kbuild.git for-next T: git git://repo.or.cz/linux-kbuild.git for-next
T: git git://repo.or.cz/linux-kbuild.git for-linus T: git git://repo.or.cz/linux-kbuild.git for-linus
...@@ -3251,6 +3251,9 @@ S: Maintained ...@@ -3251,6 +3251,9 @@ S: Maintained
F: Documentation/kbuild/ F: Documentation/kbuild/
F: Makefile F: Makefile
F: scripts/Makefile.* F: scripts/Makefile.*
F: scripts/basic/
F: scripts/mk*
F: scripts/package/
KERNEL JANITORS KERNEL JANITORS
L: kernel-janitors@vger.kernel.org L: kernel-janitors@vger.kernel.org
......
...@@ -183,11 +183,14 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ ...@@ -183,11 +183,14 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
# CROSS_COMPILE can be set on the command line # CROSS_COMPILE can be set on the command line
# make CROSS_COMPILE=ia64-linux- # make CROSS_COMPILE=ia64-linux-
# Alternatively CROSS_COMPILE can be set in the environment. # Alternatively CROSS_COMPILE can be set in the environment.
# A third alternative is to store a setting in .config so that plain
# "make" in the configured kernel build directory always uses that.
# Default value for CROSS_COMPILE is not to prefix executables # Default value for CROSS_COMPILE is not to prefix executables
# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
export KBUILD_BUILDHOST := $(SUBARCH) export KBUILD_BUILDHOST := $(SUBARCH)
ARCH ?= $(SUBARCH) ARCH ?= $(SUBARCH)
CROSS_COMPILE ?= CROSS_COMPILE ?=
CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
# Architecture as present in compile.h # Architecture as present in compile.h
UTS_MACHINE := $(ARCH) UTS_MACHINE := $(ARCH)
...@@ -576,9 +579,6 @@ KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,) ...@@ -576,9 +579,6 @@ KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,)
# disable invalid "can't wrap" optimizations for signed / pointers # disable invalid "can't wrap" optimizations for signed / pointers
KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow) KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow)
# revert to pre-gcc-4.4 behaviour of .eh_frame
KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm)
# conserve stack if available # conserve stack if available
KBUILD_CFLAGS += $(call cc-option,-fconserve-stack) KBUILD_CFLAGS += $(call cc-option,-fconserve-stack)
...@@ -882,9 +882,6 @@ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ; ...@@ -882,9 +882,6 @@ $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
PHONY += $(vmlinux-dirs) PHONY += $(vmlinux-dirs)
$(vmlinux-dirs): prepare scripts $(vmlinux-dirs): prepare scripts
$(Q)$(MAKE) $(build)=$@ $(Q)$(MAKE) $(build)=$@
ifdef CONFIG_MODULES
$(Q)$(MAKE) $(modbuiltin)=$@
endif
# Build the kernel release string # Build the kernel release string
# #
...@@ -907,14 +904,19 @@ endif ...@@ -907,14 +904,19 @@ endif
# $(localver) # $(localver)
# localversion* (files without backups, containing '~') # localversion* (files without backups, containing '~')
# $(CONFIG_LOCALVERSION) (from kernel config setting) # $(CONFIG_LOCALVERSION) (from kernel config setting)
# $(localver-auto) (only if CONFIG_LOCALVERSION_AUTO is set) # $(LOCALVERSION) (from make command line, if provided)
# ./scripts/setlocalversion (SCM tag, if one exists) # $(localver-extra)
# $(LOCALVERSION) (from make command line if provided) # $(scm-identifier) (unique SCM tag, if one exists)
# ./scripts/setlocalversion (only with CONFIG_LOCALVERSION_AUTO)
# .scmversion (only with CONFIG_LOCALVERSION_AUTO)
# + (only without CONFIG_LOCALVERSION_AUTO
# and without LOCALVERSION= and
# repository is at non-tagged commit)
# #
# Note how the final $(localver-auto) string is included *only* if the # For kernels without CONFIG_LOCALVERSION_AUTO compiled from an SCM that has
# kernel config option CONFIG_LOCALVERSION_AUTO is selected. Also, at the # been revised beyond a tagged commit, `+' is appended to the version string
# moment, only git is supported but other SCMs can edit the script # when not overridden by using "make LOCALVERSION=". This indicates that the
# scripts/setlocalversion and add the appropriate checks as needed. # kernel is not a vanilla release version and has been modified.
pattern = ".*/localversion[^~]*" pattern = ".*/localversion[^~]*"
string = $(shell cat /dev/null \ string = $(shell cat /dev/null \
...@@ -923,26 +925,32 @@ string = $(shell cat /dev/null \ ...@@ -923,26 +925,32 @@ string = $(shell cat /dev/null \
localver = $(subst $(space),, $(string) \ localver = $(subst $(space),, $(string) \
$(patsubst "%",%,$(CONFIG_LOCALVERSION))) $(patsubst "%",%,$(CONFIG_LOCALVERSION)))
# If CONFIG_LOCALVERSION_AUTO is set scripts/setlocalversion is called # scripts/setlocalversion is called to create a unique identifier if the source
# and if the SCM is know a tag from the SCM is appended. # is managed by a known SCM and the repository has been revised since the last
# The appended tag is determined by the SCM used. # tagged (release) commit. The format of the identifier is determined by the
# SCM's implementation.
# #
# .scmversion is used when generating rpm packages so we do not loose # .scmversion is used when generating rpm packages so we do not loose
# the version information from the SCM when we do the build of the kernel # the version information from the SCM when we do the build of the kernel
# from the copied source # from the copied source
ifdef CONFIG_LOCALVERSION_AUTO
ifeq ($(wildcard .scmversion),) ifeq ($(wildcard .scmversion),)
_localver-auto = $(shell $(CONFIG_SHELL) \ scm-identifier = $(shell $(CONFIG_SHELL) \
$(srctree)/scripts/setlocalversion $(srctree)) $(srctree)/scripts/setlocalversion $(srctree))
else else
_localver-auto = $(shell cat .scmversion 2> /dev/null) scm-identifier = $(shell cat .scmversion 2> /dev/null)
endif endif
localver-auto = $(LOCALVERSION)$(_localver-auto) ifdef CONFIG_LOCALVERSION_AUTO
localver-extra = $(scm-identifier)
else
ifneq ($(scm-identifier),)
ifeq ($(LOCALVERSION),)
localver-extra = +
endif
endif
endif endif
localver-full = $(localver)$(localver-auto) localver-full = $(localver)$(LOCALVERSION)$(localver-extra)
# Store (new) KERNELRELASE string in include/config/kernel.release # Store (new) KERNELRELASE string in include/config/kernel.release
kernelrelease = $(KERNELVERSION)$(localver-full) kernelrelease = $(KERNELVERSION)$(localver-full)
...@@ -1089,11 +1097,16 @@ all: modules ...@@ -1089,11 +1097,16 @@ all: modules
PHONY += modules PHONY += modules
modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux)
$(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order
$(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.builtin) > $(objtree)/modules.builtin
@$(kecho) ' Building modules, stage 2.'; @$(kecho) ' Building modules, stage 2.';
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modbuild $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modbuild
modules.builtin: $(vmlinux-dirs:%=%/modules.builtin)
$(Q)$(AWK) '!x[$$0]++' $^ > $(objtree)/modules.builtin
%/modules.builtin: include/config/auto.conf
$(Q)$(MAKE) $(modbuiltin)=$*
# Target to prepare building external modules # Target to prepare building external modules
PHONY += modules_prepare PHONY += modules_prepare
...@@ -1104,7 +1117,7 @@ PHONY += modules_install ...@@ -1104,7 +1117,7 @@ PHONY += modules_install
modules_install: _modinst_ _modinst_post modules_install: _modinst_ _modinst_post
PHONY += _modinst_ PHONY += _modinst_
_modinst_: _modinst_: modules.builtin
@if [ -z "`$(DEPMOD) -V 2>/dev/null | grep module-init-tools`" ]; then \ @if [ -z "`$(DEPMOD) -V 2>/dev/null | grep module-init-tools`" ]; then \
echo "Warning: you may need to install module-init-tools"; \ echo "Warning: you may need to install module-init-tools"; \
echo "See http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt";\ echo "See http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt";\
...@@ -1247,7 +1260,9 @@ help: ...@@ -1247,7 +1260,9 @@ help:
@echo ' firmware_install- Install all firmware to INSTALL_FW_PATH' @echo ' firmware_install- Install all firmware to INSTALL_FW_PATH'
@echo ' (default: $$(INSTALL_MOD_PATH)/lib/firmware)' @echo ' (default: $$(INSTALL_MOD_PATH)/lib/firmware)'
@echo ' dir/ - Build all files in dir and below' @echo ' dir/ - Build all files in dir and below'
@echo ' dir/file.[ois] - Build specified target only' @echo ' dir/file.[oisS] - Build specified target only'
@echo ' dir/file.lst - Build specified mixed source/assembly target only'
@echo ' (requires a recent binutils and recent build (System.map))'
@echo ' dir/file.ko - Build module including final link' @echo ' dir/file.ko - Build module including final link'
@echo ' modules_prepare - Set up for building external modules' @echo ' modules_prepare - Set up for building external modules'
@echo ' tags/TAGS - Generate tags file for editors' @echo ' tags/TAGS - Generate tags file for editors'
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
# #
# the break handler has its own stack # the break handler has its own stack
# #
.section .bss.stack .section .bss..stack
.globl __break_user_context .globl __break_user_context
.balign THREAD_SIZE .balign THREAD_SIZE
__break_stack: __break_stack:
...@@ -63,7 +63,7 @@ __break_trace_through_exceptions: ...@@ -63,7 +63,7 @@ __break_trace_through_exceptions:
# entry point for Break Exceptions/Interrupts # entry point for Break Exceptions/Interrupts
# #
############################################################################### ###############################################################################
.section .text.break .section .text..break
.balign 4 .balign 4
.globl __entry_break .globl __entry_break
__entry_break: __entry_break:
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
#define nr_syscalls ((syscall_table_size)/4) #define nr_syscalls ((syscall_table_size)/4)
.section .text.entry .section .text..entry
.balign 4 .balign 4
.macro LEDS val .macro LEDS val
......
...@@ -542,7 +542,7 @@ __head_end: ...@@ -542,7 +542,7 @@ __head_end:
.size _boot, .-_boot .size _boot, .-_boot
# provide a point for GDB to place a break # provide a point for GDB to place a break
.section .text.start,"ax" .section .text..start,"ax"
.globl _start .globl _start
.balign 4 .balign 4
_start: _start:
......
...@@ -57,10 +57,10 @@ SECTIONS ...@@ -57,10 +57,10 @@ SECTIONS
_text = .; _text = .;
_stext = .; _stext = .;
.text : { .text : {
*(.text.start) *(.text..start)
*(.text.entry) *(.text..entry)
*(.text.break) *(.text..break)
*(.text.tlbmiss) *(.text..tlbmiss)
TEXT_TEXT TEXT_TEXT
SCHED_TEXT SCHED_TEXT
LOCK_TEXT LOCK_TEXT
...@@ -114,7 +114,7 @@ SECTIONS ...@@ -114,7 +114,7 @@ SECTIONS
.sbss : { *(.sbss .sbss.*) } .sbss : { *(.sbss .sbss.*) }
.bss : { *(.bss .bss.*) } .bss : { *(.bss .bss.*) }
.bss.stack : { *(.bss) } .bss..stack : { *(.bss) }
__bss_stop = .; __bss_stop = .;
_end = . ; _end = . ;
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/spr-regs.h> #include <asm/spr-regs.h>
.section .text.tlbmiss .section .text..tlbmiss
.balign 4 .balign 4
.globl __entry_insn_mmu_miss .globl __entry_insn_mmu_miss
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#define SRAM_START 0xff4000 #define SRAM_START 0xff4000
.section .text.startup .section .text..startup
.global startup .global startup
startup: startup:
mov.l #SRAM_START+0x8000, sp mov.l #SRAM_START+0x8000, sp
......
...@@ -4,7 +4,7 @@ SECTIONS ...@@ -4,7 +4,7 @@ SECTIONS
{ {
__stext = . ; __stext = . ;
__text = .; __text = .;
*(.text.startup) *(.text..startup)
*(.text) *(.text)
__etext = . ; __etext = . ;
} }
......
...@@ -70,12 +70,12 @@ ...@@ -70,12 +70,12 @@
* path (ivt.S - TLB miss processing) or in places where it might not be * path (ivt.S - TLB miss processing) or in places where it might not be
* safe to use a "tpa" instruction (mca_asm.S - error recovery). * safe to use a "tpa" instruction (mca_asm.S - error recovery).
*/ */
.section ".data.patch.vtop", "a" // declare section & section attributes .section ".data..patch.vtop", "a" // declare section & section attributes
.previous .previous
#define LOAD_PHYSICAL(pr, reg, obj) \ #define LOAD_PHYSICAL(pr, reg, obj) \
[1:](pr)movl reg = obj; \ [1:](pr)movl reg = obj; \
.xdata4 ".data.patch.vtop", 1b-. .xdata4 ".data..patch.vtop", 1b-.
/* /*
* For now, we always put in the McKinley E9 workaround. On CPUs that don't need it, * For now, we always put in the McKinley E9 workaround. On CPUs that don't need it,
...@@ -84,11 +84,11 @@ ...@@ -84,11 +84,11 @@
#define DO_MCKINLEY_E9_WORKAROUND #define DO_MCKINLEY_E9_WORKAROUND
#ifdef DO_MCKINLEY_E9_WORKAROUND #ifdef DO_MCKINLEY_E9_WORKAROUND
.section ".data.patch.mckinley_e9", "a" .section ".data..patch.mckinley_e9", "a"
.previous .previous
/* workaround for Itanium 2 Errata 9: */ /* workaround for Itanium 2 Errata 9: */
# define FSYS_RETURN \ # define FSYS_RETURN \
.xdata4 ".data.patch.mckinley_e9", 1f-.; \ .xdata4 ".data..patch.mckinley_e9", 1f-.; \
1:{ .mib; \ 1:{ .mib; \
nop.m 0; \ nop.m 0; \
mov r16=ar.pfs; \ mov r16=ar.pfs; \
...@@ -107,11 +107,11 @@ ...@@ -107,11 +107,11 @@
* If physical stack register size is different from DEF_NUM_STACK_REG, * If physical stack register size is different from DEF_NUM_STACK_REG,
* dynamically patch the kernel for correct size. * dynamically patch the kernel for correct size.
*/ */
.section ".data.patch.phys_stack_reg", "a" .section ".data..patch.phys_stack_reg", "a"
.previous .previous
#define LOAD_PHYS_STACK_REG_SIZE(reg) \ #define LOAD_PHYS_STACK_REG_SIZE(reg) \
[1:] adds reg=IA64_NUM_PHYS_STACK_REG*8+8,r0; \ [1:] adds reg=IA64_NUM_PHYS_STACK_REG*8+8,r0; \
.xdata4 ".data.patch.phys_stack_reg", 1b-. .xdata4 ".data..patch.phys_stack_reg", 1b-.
/* /*
* Up until early 2004, use of .align within a function caused bad unwind info. * Up until early 2004, use of .align within a function caused bad unwind info.
......
...@@ -24,6 +24,6 @@ ...@@ -24,6 +24,6 @@
# define SMP_CACHE_BYTES (1 << 3) # define SMP_CACHE_BYTES (1 << 3)
#endif #endif
#define __read_mostly __attribute__((__section__(".data.read_mostly"))) #define __read_mostly __attribute__((__section__(".data..read_mostly")))
#endif /* _ASM_IA64_CACHE_H */ #endif /* _ASM_IA64_CACHE_H */
...@@ -31,7 +31,7 @@ extern void *per_cpu_init(void); ...@@ -31,7 +31,7 @@ extern void *per_cpu_init(void);
#endif /* SMP */ #endif /* SMP */
#define PER_CPU_BASE_SECTION ".data.percpu" #define PER_CPU_BASE_SECTION ".data..percpu"
/* /*
* Be extremely careful when taking the address of this variable! Due to virtual * Be extremely careful when taking the address of this variable! Due to virtual
......
...@@ -21,7 +21,7 @@ GATECFLAGS_gate-syms.o = -r ...@@ -21,7 +21,7 @@ GATECFLAGS_gate-syms.o = -r
$(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE $(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE
$(call if_changed,gate) $(call if_changed,gate)
# gate-data.o contains the gate DSO image as data in section .data.gate. # gate-data.o contains the gate DSO image as data in section .data..gate.
# We must build gate.so before we can assemble it. # We must build gate.so before we can assemble it.
# Note: kbuild does not track this dependency due to usage of .incbin # Note: kbuild does not track this dependency due to usage of .incbin
$(obj)/gate-data.o: $(obj)/gate.so $(obj)/gate-data.o: $(obj)/gate.so
.section .data.gate, "aw" .section .data..gate, "aw"
.incbin "arch/ia64/kernel/gate.so" .incbin "arch/ia64/kernel/gate.so"
...@@ -21,18 +21,18 @@ ...@@ -21,18 +21,18 @@
* to targets outside the shared object) and to avoid multi-phase kernel builds, we * to targets outside the shared object) and to avoid multi-phase kernel builds, we
* simply create minimalistic "patch lists" in special ELF sections. * simply create minimalistic "patch lists" in special ELF sections.
*/ */
.section ".data.patch.fsyscall_table", "a" .section ".data..patch.fsyscall_table", "a"
.previous .previous
#define LOAD_FSYSCALL_TABLE(reg) \ #define LOAD_FSYSCALL_TABLE(reg) \
[1:] movl reg=0; \ [1:] movl reg=0; \
.xdata4 ".data.patch.fsyscall_table", 1b-. .xdata4 ".data..patch.fsyscall_table", 1b-.
.section ".data.patch.brl_fsys_bubble_down", "a" .section ".data..patch.brl_fsys_bubble_down", "a"
.previous .previous
#define BRL_COND_FSYS_BUBBLE_DOWN(pr) \ #define BRL_COND_FSYS_BUBBLE_DOWN(pr) \
[1:](pr)brl.cond.sptk 0; \ [1:](pr)brl.cond.sptk 0; \
;; \ ;; \
.xdata4 ".data.patch.brl_fsys_bubble_down", 1b-. .xdata4 ".data..patch.brl_fsys_bubble_down", 1b-.
GLOBAL_ENTRY(__kernel_syscall_via_break) GLOBAL_ENTRY(__kernel_syscall_via_break)
.prologue .prologue
......
...@@ -33,21 +33,21 @@ SECTIONS ...@@ -33,21 +33,21 @@ SECTIONS
*/ */
. = GATE_ADDR + 0x600; . = GATE_ADDR + 0x600;
.data.patch : { .data..patch : {
__paravirt_start_gate_mckinley_e9_patchlist = .; __paravirt_start_gate_mckinley_e9_patchlist = .;
*(.data.patch.mckinley_e9) *(.data..patch.mckinley_e9)
__paravirt_end_gate_mckinley_e9_patchlist = .; __paravirt_end_gate_mckinley_e9_patchlist = .;
__paravirt_start_gate_vtop_patchlist = .; __paravirt_start_gate_vtop_patchlist = .;
*(.data.patch.vtop) *(.data..patch.vtop)
__paravirt_end_gate_vtop_patchlist = .; __paravirt_end_gate_vtop_patchlist = .;
__paravirt_start_gate_fsyscall_patchlist = .; __paravirt_start_gate_fsyscall_patchlist = .;
*(.data.patch.fsyscall_table) *(.data..patch.fsyscall_table)
__paravirt_end_gate_fsyscall_patchlist = .; __paravirt_end_gate_fsyscall_patchlist = .;
__paravirt_start_gate_brl_fsys_bubble_down_patchlist = .; __paravirt_start_gate_brl_fsys_bubble_down_patchlist = .;
*(.data.patch.brl_fsys_bubble_down) *(.data..patch.brl_fsys_bubble_down)
__paravirt_end_gate_brl_fsys_bubble_down_patchlist = .; __paravirt_end_gate_brl_fsys_bubble_down_patchlist = .;
} :readable } :readable
......
...@@ -23,7 +23,7 @@ static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); ...@@ -23,7 +23,7 @@ static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
* Initial task structure. * Initial task structure.
* *
* We need to make sure that this is properly aligned due to the way process stacks are * We need to make sure that this is properly aligned due to the way process stacks are
* handled. This is done by having a special ".data.init_task" section... * handled. This is done by having a special ".data..init_task" section...
*/ */
#define init_thread_info init_task_mem.s.thread_info #define init_thread_info init_task_mem.s.thread_info
......
...@@ -82,7 +82,7 @@ ...@@ -82,7 +82,7 @@
mov r19=n;; /* prepare to save predicates */ \ mov r19=n;; /* prepare to save predicates */ \
br.sptk.many dispatch_to_fault_handler br.sptk.many dispatch_to_fault_handler
.section .text.ivt,"ax" .section .text..ivt,"ax"
.align 32768 // align on 32KB boundary .align 32768 // align on 32KB boundary
.global ia64_ivt .global ia64_ivt
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#define ACCOUNT_SYS_ENTER #define ACCOUNT_SYS_ENTER
#endif #endif
.section ".data.patch.rse", "a" .section ".data..patch.rse", "a"
.previous .previous
/* /*
...@@ -215,7 +215,7 @@ ...@@ -215,7 +215,7 @@
(pUStk) extr.u r17=r18,3,6; \ (pUStk) extr.u r17=r18,3,6; \
(pUStk) sub r16=r18,r22; \ (pUStk) sub r16=r18,r22; \
[1:](pKStk) br.cond.sptk.many 1f; \ [1:](pKStk) br.cond.sptk.many 1f; \
.xdata4 ".data.patch.rse",1b-. \ .xdata4 ".data..patch.rse",1b-. \
;; \ ;; \
cmp.ge p6,p7 = 33,r17; \ cmp.ge p6,p7 = 33,r17; \
;; \ ;; \
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include "entry.h" #include "entry.h"
#define DATA8(sym, init_value) \ #define DATA8(sym, init_value) \
.pushsection .data.read_mostly ; \ .pushsection .data..read_mostly ; \
.align 8 ; \ .align 8 ; \
.global sym ; \ .global sym ; \
sym: ; \ sym: ; \
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#define IVT_TEXT \ #define IVT_TEXT \
VMLINUX_SYMBOL(__start_ivt_text) = .; \ VMLINUX_SYMBOL(__start_ivt_text) = .; \
*(.text.ivt) \ *(.text..ivt) \
VMLINUX_SYMBOL(__end_ivt_text) = .; VMLINUX_SYMBOL(__end_ivt_text) = .;
OUTPUT_FORMAT("elf64-ia64-little") OUTPUT_FORMAT("elf64-ia64-little")
...@@ -54,8 +54,8 @@ SECTIONS ...@@ -54,8 +54,8 @@ SECTIONS
.text2 : AT(ADDR(.text2) - LOAD_OFFSET) .text2 : AT(ADDR(.text2) - LOAD_OFFSET)
{ *(.text2) } { *(.text2) }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
.text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) .text..lock : AT(ADDR(.text..lock) - LOAD_OFFSET)
{ *(.text.lock) } { *(.text..lock) }
#endif #endif
_etext = .; _etext = .;
...@@ -75,10 +75,10 @@ SECTIONS ...@@ -75,10 +75,10 @@ SECTIONS
__stop___mca_table = .; __stop___mca_table = .;
} }
.data.patch.phys_stack_reg : AT(ADDR(.data.patch.phys_stack_reg) - LOAD_OFFSET) .data..patch.phys_stack_reg : AT(ADDR(.data..patch.phys_stack_reg) - LOAD_OFFSET)
{ {
__start___phys_stack_reg_patchlist = .; __start___phys_stack_reg_patchlist = .;
*(.data.patch.phys_stack_reg) *(.data..patch.phys_stack_reg)
__end___phys_stack_reg_patchlist = .; __end___phys_stack_reg_patchlist = .;
} }
...@@ -110,24 +110,24 @@ SECTIONS ...@@ -110,24 +110,24 @@ SECTIONS
INIT_TEXT_SECTION(PAGE_SIZE) INIT_TEXT_SECTION(PAGE_SIZE)
INIT_DATA_SECTION(16) INIT_DATA_SECTION(16)
.data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET) .data..patch.vtop : AT(ADDR(.data..patch.vtop) - LOAD_OFFSET)
{ {
__start___vtop_patchlist = .; __start___vtop_patchlist = .;
*(.data.patch.vtop) *(.data..patch.vtop)
__end___vtop_patchlist = .; __end___vtop_patchlist = .;
} }
.data.patch.rse : AT(ADDR(.data.patch.rse) - LOAD_OFFSET) .data..patch.rse : AT(ADDR(.data..patch.rse) - LOAD_OFFSET)
{ {
__start___rse_patchlist = .; __start___rse_patchlist = .;
*(.data.patch.rse) *(.data..patch.rse)
__end___rse_patchlist = .; __end___rse_patchlist = .;
} }
.data.patch.mckinley_e9 : AT(ADDR(.data.patch.mckinley_e9) - LOAD_OFFSET) .data..patch.mckinley_e9 : AT(ADDR(.data..patch.mckinley_e9) - LOAD_OFFSET)
{ {
__start___mckinley_e9_bundles = .; __start___mckinley_e9_bundles = .;
*(.data.patch.mckinley_e9) *(.data..patch.mckinley_e9)
__end___mckinley_e9_bundles = .; __end___mckinley_e9_bundles = .;
} }
...@@ -175,17 +175,17 @@ SECTIONS ...@@ -175,17 +175,17 @@ SECTIONS
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);
__init_end = .; __init_end = .;
.data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET)
{ {
PAGE_ALIGNED_DATA(PAGE_SIZE) PAGE_ALIGNED_DATA(PAGE_SIZE)
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);
__start_gate_section = .; __start_gate_section = .;
*(.data.gate) *(.data..gate)
__stop_gate_section = .; __stop_gate_section = .;
#ifdef CONFIG_XEN #ifdef CONFIG_XEN
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);
__xen_start_gate_section = .; __xen_start_gate_section = .;
*(.data.gate.xen) *(.data..gate.xen)
__xen_stop_gate_section = .; __xen_stop_gate_section = .;
#endif #endif
} }
......
...@@ -104,7 +104,7 @@ GLOBAL_ENTRY(kvm_vmm_panic) ...@@ -104,7 +104,7 @@ GLOBAL_ENTRY(kvm_vmm_panic)
br.call.sptk.many b6=vmm_panic_handler; br.call.sptk.many b6=vmm_panic_handler;
END(kvm_vmm_panic) END(kvm_vmm_panic)
.section .text.ivt,"ax" .section .text..ivt,"ax"
.align 32768 // align on 32KB boundary .align 32768 // align on 32KB boundary
.global kvm_ia64_ivt .global kvm_ia64_ivt
......
#!/usr/bin/env python #!/usr/bin/python
# #
# Usage: unwcheck.py FILE # Usage: unwcheck.py FILE
# #
......
.section .data.gate.xen, "aw" .section .data..gate.xen, "aw"
.incbin "arch/ia64/xen/gate.so" .incbin "arch/ia64/xen/gate.so"
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <xen/interface/elfnote.h> #include <xen/interface/elfnote.h>
.section .data.read_mostly .section .data..read_mostly
.align 8 .align 8
.global xen_domain_type .global xen_domain_type
xen_domain_type: xen_domain_type:
......
...@@ -57,7 +57,7 @@ SECTIONS { ...@@ -57,7 +57,7 @@ SECTIONS {
.romvec : { .romvec : {
__rom_start = . ; __rom_start = . ;
_romvec = .; _romvec = .;
*(.data.initvect) *(.data..initvect)
} > romvec } > romvec
#endif #endif
...@@ -68,7 +68,7 @@ SECTIONS { ...@@ -68,7 +68,7 @@ SECTIONS {
TEXT_TEXT TEXT_TEXT
SCHED_TEXT SCHED_TEXT
LOCK_TEXT LOCK_TEXT
*(.text.lock) *(.text..lock)
. = ALIGN(16); /* Exception table */ . = ALIGN(16); /* Exception table */
__start___ex_table = .; __start___ex_table = .;
......
...@@ -280,7 +280,7 @@ _dprbase: ...@@ -280,7 +280,7 @@ _dprbase:
* and then overwritten as needed. * and then overwritten as needed.
*/ */
.section ".data.initvect","awx" .section ".data..initvect","awx"
.long RAMEND /* Reset: Initial Stack Pointer - 0. */ .long RAMEND /* Reset: Initial Stack Pointer - 0. */
.long _start /* Reset: Initial Program Counter - 1. */ .long _start /* Reset: Initial Program Counter - 1. */
.long buserr /* Bus Error - 2. */ .long buserr /* Bus Error - 2. */
......
...@@ -291,7 +291,7 @@ _dprbase: ...@@ -291,7 +291,7 @@ _dprbase:
* and then overwritten as needed. * and then overwritten as needed.
*/ */
.section ".data.initvect","awx" .section ".data..initvect","awx"
.long RAMEND /* Reset: Initial Stack Pointer - 0. */ .long RAMEND /* Reset: Initial Stack Pointer - 0. */
.long _start /* Reset: Initial Program Counter - 1. */ .long _start /* Reset: Initial Program Counter - 1. */
.long buserr /* Bus Error - 2. */ .long buserr /* Bus Error - 2. */
......
#include <asm/lasat/head.h> #include <asm/lasat/head.h>
.text .text
.section .text.start, "ax" .section .text..start, "ax"
.set noreorder .set noreorder
.set mips3 .set mips3
......
...@@ -4,7 +4,7 @@ SECTIONS ...@@ -4,7 +4,7 @@ SECTIONS
{ {
.text : .text :
{ {
*(.text.start) *(.text..start)
} }
/* Data in ROM */ /* Data in ROM */
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#define SMP_CACHE_BYTES L1_CACHE_BYTES #define SMP_CACHE_BYTES L1_CACHE_BYTES
#define __read_mostly __attribute__((__section__(".data.read_mostly"))) #define __read_mostly __attribute__((__section__(".data..read_mostly")))
void parisc_cache_init(void); /* initializes cache-flushing */ void parisc_cache_init(void); /* initializes cache-flushing */
void disable_sr_hashing_asm(int); /* low level support for above */ void disable_sr_hashing_asm(int); /* low level support for above */
......
...@@ -174,7 +174,7 @@ static inline void set_eiem(unsigned long val) ...@@ -174,7 +174,7 @@ static inline void set_eiem(unsigned long val)
}) })
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
# define __lock_aligned __attribute__((__section__(".data.lock_aligned"))) # define __lock_aligned __attribute__((__section__(".data..lock_aligned")))
#endif #endif
#define arch_align_stack(x) (x) #define arch_align_stack(x) (x)
......
...@@ -345,7 +345,7 @@ smp_slave_stext: ...@@ -345,7 +345,7 @@ smp_slave_stext:
ENDPROC(stext) ENDPROC(stext)
#ifndef CONFIG_64BIT #ifndef CONFIG_64BIT
.section .data.read_mostly .section .data..read_mostly
.align 4 .align 4
.export $global$,data .export $global$,data
......
...@@ -53,11 +53,11 @@ union thread_union init_thread_union __init_task_data ...@@ -53,11 +53,11 @@ union thread_union init_thread_union __init_task_data
* guarantee that global objects will be laid out in memory in the same order * guarantee that global objects will be laid out in memory in the same order
* as the order of declaration, so put these in different sections and use * as the order of declaration, so put these in different sections and use
* the linker script to order them. */ * the linker script to order them. */
pmd_t pmd0[PTRS_PER_PMD] __attribute__ ((__section__ (".data.vm0.pmd"), aligned(PAGE_SIZE))); pmd_t pmd0[PTRS_PER_PMD] __attribute__ ((__section__ (".data..vm0.pmd"), aligned(PAGE_SIZE)));
#endif #endif
pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((__section__ (".data.vm0.pgd"), aligned(PAGE_SIZE))); pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((__section__ (".data..vm0.pgd"), aligned(PAGE_SIZE)));
pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((__section__ (".data.vm0.pte"), aligned(PAGE_SIZE))); pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((__section__ (".data..vm0.pte"), aligned(PAGE_SIZE)));
/* /*
* Initial task structure. * Initial task structure.
......
...@@ -94,8 +94,8 @@ SECTIONS ...@@ -94,8 +94,8 @@ SECTIONS
/* PA-RISC locks requires 16-byte alignment */ /* PA-RISC locks requires 16-byte alignment */
. = ALIGN(16); . = ALIGN(16);
.data.lock_aligned : { .data..lock_aligned : {
*(.data.lock_aligned) *(.data..lock_aligned)
} }
/* End of data section */ /* End of data section */
...@@ -105,10 +105,10 @@ SECTIONS ...@@ -105,10 +105,10 @@ SECTIONS
__bss_start = .; __bss_start = .;
/* page table entries need to be PAGE_SIZE aligned */ /* page table entries need to be PAGE_SIZE aligned */
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);
.data.vmpages : { .data..vmpages : {
*(.data.vm0.pmd) *(.data..vm0.pmd)
*(.data.vm0.pgd) *(.data..vm0.pgd)
*(.data.vm0.pte) *(.data..vm0.pte)
} }
.bss : { .bss : {
*(.bss) *(.bss)
......
...@@ -112,6 +112,11 @@ KBUILD_CFLAGS += $(call cc-option,-mspe=no) ...@@ -112,6 +112,11 @@ KBUILD_CFLAGS += $(call cc-option,-mspe=no)
# kernel considerably. # kernel considerably.
KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time) KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time)
# FIXME: the module load should be taught about the additional relocs
# generated by this.
# revert to pre-gcc-4.4 behaviour of .eh_frame
KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm)
# Never use string load/store instructions as they are # Never use string load/store instructions as they are
# often slow when they are implemented at all # often slow when they are implemented at all
KBUILD_CFLAGS += -mno-string KBUILD_CFLAGS += -mno-string
......
...@@ -42,7 +42,7 @@ extern struct ppc64_caches ppc64_caches; ...@@ -42,7 +42,7 @@ extern struct ppc64_caches ppc64_caches;
#endif /* __powerpc64__ && ! __ASSEMBLY__ */ #endif /* __powerpc64__ && ! __ASSEMBLY__ */
#if !defined(__ASSEMBLY__) #if !defined(__ASSEMBLY__)
#define __read_mostly __attribute__((__section__(".data.read_mostly"))) #define __read_mostly __attribute__((__section__(".data..read_mostly")))
#endif #endif
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -162,14 +162,6 @@ do { \ ...@@ -162,14 +162,6 @@ do { \
#endif /* !CONFIG_HUGETLB_PAGE */ #endif /* !CONFIG_HUGETLB_PAGE */
#ifdef MODULE
#define __page_aligned __attribute__((__aligned__(PAGE_SIZE)))
#else
#define __page_aligned \
__attribute__((__aligned__(PAGE_SIZE), \
__section__(".data.page_aligned")))
#endif
#define VM_DATA_DEFAULT_FLAGS \ #define VM_DATA_DEFAULT_FLAGS \
(test_thread_flag(TIF_32BIT) ? \ (test_thread_flag(TIF_32BIT) ? \
VM_DATA_DEFAULT_FLAGS32 : VM_DATA_DEFAULT_FLAGS64) VM_DATA_DEFAULT_FLAGS32 : VM_DATA_DEFAULT_FLAGS64)
......
...@@ -223,19 +223,17 @@ SECTIONS ...@@ -223,19 +223,17 @@ SECTIONS
#endif #endif
/* The initial task and kernel stack */ /* The initial task and kernel stack */
.data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { INIT_TASK_DATA_SECTION(THREAD_SIZE)
INIT_TASK_DATA(THREAD_SIZE)
}
.data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET) {
PAGE_ALIGNED_DATA(PAGE_SIZE) PAGE_ALIGNED_DATA(PAGE_SIZE)
} }
.data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { .data..cacheline_aligned : AT(ADDR(.data..cacheline_aligned) - LOAD_OFFSET) {
CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
} }
.data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { .data..read_mostly : AT(ADDR(.data..read_mostly) - LOAD_OFFSET) {
READ_MOSTLY_DATA(L1_CACHE_BYTES) READ_MOSTLY_DATA(L1_CACHE_BYTES)
} }
......
...@@ -14,6 +14,6 @@ ...@@ -14,6 +14,6 @@
#define L1_CACHE_BYTES 256 #define L1_CACHE_BYTES 256
#define L1_CACHE_SHIFT 8 #define L1_CACHE_SHIFT 8
#define __read_mostly __attribute__((__section__(".data.read_mostly"))) #define __read_mostly __attribute__((__section__(".data..read_mostly")))
#endif #endif
...@@ -264,7 +264,7 @@ restore_registers: ...@@ -264,7 +264,7 @@ restore_registers:
lghi %r2,0 lghi %r2,0
br %r14 br %r14
.section .data.nosave,"aw",@progbits .section .data..nosave,"aw",@progbits
.align 8 .align 8
.Ldisabled_wait_31: .Ldisabled_wait_31:
.long 0x000a0000,0x00000000 .long 0x000a0000,0x00000000
......
SECTIONS SECTIONS
{ {
.rodata.compressed : { .rodata..compressed : {
input_len = .; input_len = .;
LONG(input_data_end - input_data) input_data = .; LONG(input_data_end - input_data) input_data = .;
*(.data) *(.data)
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
#define __read_mostly __attribute__((__section__(".data.read_mostly"))) #define __read_mostly __attribute__((__section__(".data..read_mostly")))
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
struct cache_info { struct cache_info {
......
...@@ -325,7 +325,7 @@ int main(int argc,char **argv) ...@@ -325,7 +325,7 @@ int main(int argc,char **argv)
(*rr)->next = NULL; (*rr)->next = NULL;
} }
printf("! Generated by btfixupprep. Do not edit.\n\n"); printf("! Generated by btfixupprep. Do not edit.\n\n");
printf("\t.section\t\".data.init\",#alloc,#write\n\t.align\t4\n\n"); printf("\t.section\t\".data..init\",#alloc,#write\n\t.align\t4\n\n");
printf("\t.global\t___btfixup_start\n___btfixup_start:\n\n"); printf("\t.global\t___btfixup_start\n___btfixup_start:\n\n");
for (i = 0; i < last; i++) { for (i = 0; i < last; i++) {
f = array + i; f = array + i;
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#define SMP_CACHE_BYTES (1 << SMP_CACHE_BYTES_SHIFT) #define SMP_CACHE_BYTES (1 << SMP_CACHE_BYTES_SHIFT)
#define __read_mostly __attribute__((__section__(".data.read_mostly"))) #define __read_mostly __attribute__((__section__(".data..read_mostly")))
#ifdef CONFIG_SPARC32 #ifdef CONFIG_SPARC32
#include <asm/asi.h> #include <asm/asi.h>
......
...@@ -94,7 +94,7 @@ SECTIONS ...@@ -94,7 +94,7 @@ SECTIONS
.data : { .data : {
INIT_TASK_DATA(KERNEL_STACK_SIZE) INIT_TASK_DATA(KERNEL_STACK_SIZE)
. = ALIGN(KERNEL_STACK_SIZE); . = ALIGN(KERNEL_STACK_SIZE);
*(.data.init_irqstack) *(.data..init_irqstack)
DATA_DATA DATA_DATA
*(.data.* .gnu.linkonce.d.*) *(.data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS) SORT(CONSTRUCTORS)
......
...@@ -34,5 +34,5 @@ union thread_union init_thread_union __init_task_data = ...@@ -34,5 +34,5 @@ union thread_union init_thread_union __init_task_data =
{ INIT_THREAD_INFO(init_task) }; { INIT_THREAD_INFO(init_task) };
union thread_union cpu0_irqstack union thread_union cpu0_irqstack
__attribute__((__section__(".data.init_irqstack"))) = __attribute__((__section__(".data..init_irqstack"))) =
{ INIT_THREAD_INFO(init_task) }; { INIT_THREAD_INFO(init_task) };
...@@ -50,7 +50,7 @@ SECTIONS ...@@ -50,7 +50,7 @@ SECTIONS
{ {
INIT_TASK_DATA(KERNEL_STACK_SIZE) INIT_TASK_DATA(KERNEL_STACK_SIZE)
. = ALIGN(KERNEL_STACK_SIZE); . = ALIGN(KERNEL_STACK_SIZE);
*(.data.init_irqstack) *(.data..init_irqstack)
DATA_DATA DATA_DATA
*(.gnu.linkonce.d*) *(.gnu.linkonce.d*)
CONSTRUCTORS CONSTRUCTORS
......
boot/compressed/vmlinux
tools/test_get_len
...@@ -77,7 +77,7 @@ int main(int argc, char *argv[]) ...@@ -77,7 +77,7 @@ int main(int argc, char *argv[])
offs += 32*1024 + 18; /* Add 32K + 18 bytes slack */ offs += 32*1024 + 18; /* Add 32K + 18 bytes slack */
offs = (offs+4095) & ~4095; /* Round to a 4K boundary */ offs = (offs+4095) & ~4095; /* Round to a 4K boundary */
printf(".section \".rodata.compressed\",\"a\",@progbits\n"); printf(".section \".rodata..compressed\",\"a\",@progbits\n");
printf(".globl z_input_len\n"); printf(".globl z_input_len\n");
printf("z_input_len = %lu\n", ilen); printf("z_input_len = %lu\n", ilen);
printf(".globl z_output_len\n"); printf(".globl z_output_len\n");
......
...@@ -26,8 +26,8 @@ SECTIONS ...@@ -26,8 +26,8 @@ SECTIONS
HEAD_TEXT HEAD_TEXT
_ehead = . ; _ehead = . ;
} }
.rodata.compressed : { .rodata..compressed : {
*(.rodata.compressed) *(.rodata..compressed)
} }
.text : { .text : {
_text = .; /* Text */ _text = .; /* Text */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT) #define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
#define __read_mostly __attribute__((__section__(".data.read_mostly"))) #define __read_mostly __attribute__((__section__(".data..read_mostly")))
#define INTERNODE_CACHE_SHIFT CONFIG_X86_INTERNODE_CACHE_SHIFT #define INTERNODE_CACHE_SHIFT CONFIG_X86_INTERNODE_CACHE_SHIFT
#define INTERNODE_CACHE_BYTES (1 << INTERNODE_CACHE_SHIFT) #define INTERNODE_CACHE_BYTES (1 << INTERNODE_CACHE_SHIFT)
......
.section .text.page_aligned .section .text..page_aligned
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/page_types.h> #include <asm/page_types.h>
......
...@@ -34,7 +34,7 @@ EXPORT_SYMBOL(init_task); ...@@ -34,7 +34,7 @@ EXPORT_SYMBOL(init_task);
/* /*
* per-CPU TSS segments. Threads are completely 'soft' on Linux, * per-CPU TSS segments. Threads are completely 'soft' on Linux,
* no more per-task TSS's. The TSS size is kept cacheline-aligned * no more per-task TSS's. The TSS size is kept cacheline-aligned
* so they are allowed to end up in the .data.cacheline_aligned * so they are allowed to end up in the .data..cacheline_aligned
* section. Since TSS's are completely CPU-local, we want them * section. Since TSS's are completely CPU-local, we want them
* on exact cacheline boundaries, to eliminate cacheline ping-pong. * on exact cacheline boundaries, to eliminate cacheline ping-pong.
*/ */
......
...@@ -247,7 +247,7 @@ void __init setup_per_cpu_areas(void) ...@@ -247,7 +247,7 @@ void __init setup_per_cpu_areas(void)
#endif #endif
#endif #endif
/* /*
* Up to this point, the boot CPU has been using .data.init * Up to this point, the boot CPU has been using .init.data
* area. Reload any changed state for the boot CPU. * area. Reload any changed state for the boot CPU.
*/ */
if (cpu == boot_cpu_id) if (cpu == boot_cpu_id)
......
...@@ -97,7 +97,7 @@ SECTIONS ...@@ -97,7 +97,7 @@ SECTIONS
HEAD_TEXT HEAD_TEXT
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);
*(.text.page_aligned) *(.text..page_aligned)
#endif #endif
. = ALIGN(8); . = ALIGN(8);
_stext = .; _stext = .;
...@@ -305,7 +305,7 @@ SECTIONS ...@@ -305,7 +305,7 @@ SECTIONS
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);
.bss : AT(ADDR(.bss) - LOAD_OFFSET) { .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
__bss_start = .; __bss_start = .;
*(.bss.page_aligned) *(.bss..page_aligned)
*(.bss) *(.bss)
. = ALIGN(4); . = ALIGN(4);
__bss_stop = .; __bss_stop = .;
......
...@@ -80,7 +80,7 @@ extern void setup_per_cpu_areas(void); ...@@ -80,7 +80,7 @@ extern void setup_per_cpu_areas(void);
#ifndef PER_CPU_BASE_SECTION #ifndef PER_CPU_BASE_SECTION
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
#define PER_CPU_BASE_SECTION ".data.percpu" #define PER_CPU_BASE_SECTION ".data..percpu"
#else #else
#define PER_CPU_BASE_SECTION ".data" #define PER_CPU_BASE_SECTION ".data"
#endif #endif
...@@ -92,15 +92,15 @@ extern void setup_per_cpu_areas(void); ...@@ -92,15 +92,15 @@ extern void setup_per_cpu_areas(void);
#define PER_CPU_SHARED_ALIGNED_SECTION "" #define PER_CPU_SHARED_ALIGNED_SECTION ""
#define PER_CPU_ALIGNED_SECTION "" #define PER_CPU_ALIGNED_SECTION ""
#else #else
#define PER_CPU_SHARED_ALIGNED_SECTION ".shared_aligned" #define PER_CPU_SHARED_ALIGNED_SECTION "..shared_aligned"
#define PER_CPU_ALIGNED_SECTION ".shared_aligned" #define PER_CPU_ALIGNED_SECTION "..shared_aligned"
#endif #endif
#define PER_CPU_FIRST_SECTION ".first" #define PER_CPU_FIRST_SECTION "..first"
#else #else
#define PER_CPU_SHARED_ALIGNED_SECTION "" #define PER_CPU_SHARED_ALIGNED_SECTION ""
#define PER_CPU_ALIGNED_SECTION ".shared_aligned" #define PER_CPU_ALIGNED_SECTION "..shared_aligned"
#define PER_CPU_FIRST_SECTION "" #define PER_CPU_FIRST_SECTION ""
#endif #endif
......
...@@ -175,25 +175,25 @@ ...@@ -175,25 +175,25 @@
#define NOSAVE_DATA \ #define NOSAVE_DATA \
. = ALIGN(PAGE_SIZE); \ . = ALIGN(PAGE_SIZE); \
VMLINUX_SYMBOL(__nosave_begin) = .; \ VMLINUX_SYMBOL(__nosave_begin) = .; \
*(.data.nosave) \ *(.data..nosave) \
. = ALIGN(PAGE_SIZE); \ . = ALIGN(PAGE_SIZE); \
VMLINUX_SYMBOL(__nosave_end) = .; VMLINUX_SYMBOL(__nosave_end) = .;
#define PAGE_ALIGNED_DATA(page_align) \ #define PAGE_ALIGNED_DATA(page_align) \
. = ALIGN(page_align); \ . = ALIGN(page_align); \
*(.data.page_aligned) *(.data..page_aligned)
#define READ_MOSTLY_DATA(align) \ #define READ_MOSTLY_DATA(align) \
. = ALIGN(align); \ . = ALIGN(align); \
*(.data.read_mostly) *(.data..read_mostly)
#define CACHELINE_ALIGNED_DATA(align) \ #define CACHELINE_ALIGNED_DATA(align) \
. = ALIGN(align); \ . = ALIGN(align); \
*(.data.cacheline_aligned) *(.data..cacheline_aligned)
#define INIT_TASK_DATA(align) \ #define INIT_TASK_DATA(align) \
. = ALIGN(align); \ . = ALIGN(align); \
*(.data.init_task) *(.data..init_task)
/* /*
* Read only Data * Read only Data
...@@ -435,7 +435,7 @@ ...@@ -435,7 +435,7 @@
*/ */
#define INIT_TASK_DATA_SECTION(align) \ #define INIT_TASK_DATA_SECTION(align) \
. = ALIGN(align); \ . = ALIGN(align); \
.data.init_task : { \ .data..init_task : { \
INIT_TASK_DATA(align) \ INIT_TASK_DATA(align) \
} }
...@@ -499,7 +499,7 @@ ...@@ -499,7 +499,7 @@
#define BSS(bss_align) \ #define BSS(bss_align) \
. = ALIGN(bss_align); \ . = ALIGN(bss_align); \
.bss : AT(ADDR(.bss) - LOAD_OFFSET) { \ .bss : AT(ADDR(.bss) - LOAD_OFFSET) { \
*(.bss.page_aligned) \ *(.bss..page_aligned) \
*(.dynbss) \ *(.dynbss) \
*(.bss) \ *(.bss) \
*(COMMON) \ *(COMMON) \
...@@ -666,16 +666,16 @@ ...@@ -666,16 +666,16 @@
*/ */
#define PERCPU_VADDR(vaddr, phdr) \ #define PERCPU_VADDR(vaddr, phdr) \
VMLINUX_SYMBOL(__per_cpu_load) = .; \ VMLINUX_SYMBOL(__per_cpu_load) = .; \
.data.percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load) \ .data..percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load) \
- LOAD_OFFSET) { \ - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__per_cpu_start) = .; \ VMLINUX_SYMBOL(__per_cpu_start) = .; \
*(.data.percpu.first) \ *(.data..percpu..first) \
*(.data.percpu.page_aligned) \ *(.data..percpu..page_aligned) \
*(.data.percpu) \ *(.data..percpu) \
*(.data.percpu.shared_aligned) \ *(.data..percpu..shared_aligned) \
VMLINUX_SYMBOL(__per_cpu_end) = .; \ VMLINUX_SYMBOL(__per_cpu_end) = .; \
} phdr \ } phdr \
. = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data.percpu); . = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data..percpu);
/** /**
* PERCPU - define output section for percpu area, simple version * PERCPU - define output section for percpu area, simple version
...@@ -687,18 +687,18 @@ ...@@ -687,18 +687,18 @@
* *
* This macro is equivalent to ALIGN(align); PERCPU_VADDR( , ) except * This macro is equivalent to ALIGN(align); PERCPU_VADDR( , ) except
* that __per_cpu_load is defined as a relative symbol against * that __per_cpu_load is defined as a relative symbol against
* .data.percpu which is required for relocatable x86_32 * .data..percpu which is required for relocatable x86_32
* configuration. * configuration.
*/ */
#define PERCPU(align) \ #define PERCPU(align) \
. = ALIGN(align); \ . = ALIGN(align); \
.data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { \ .data..percpu : AT(ADDR(.data..percpu) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__per_cpu_load) = .; \ VMLINUX_SYMBOL(__per_cpu_load) = .; \
VMLINUX_SYMBOL(__per_cpu_start) = .; \ VMLINUX_SYMBOL(__per_cpu_start) = .; \
*(.data.percpu.first) \ *(.data..percpu..first) \
*(.data.percpu.page_aligned) \ *(.data..percpu..page_aligned) \
*(.data.percpu) \ *(.data..percpu) \
*(.data.percpu.shared_aligned) \ *(.data..percpu..shared_aligned) \
VMLINUX_SYMBOL(__per_cpu_end) = .; \ VMLINUX_SYMBOL(__per_cpu_end) = .; \
} }
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#ifndef __cacheline_aligned #ifndef __cacheline_aligned
#define __cacheline_aligned \ #define __cacheline_aligned \
__attribute__((__aligned__(SMP_CACHE_BYTES), \ __attribute__((__aligned__(SMP_CACHE_BYTES), \
__section__(".data.cacheline_aligned"))) __section__(".data..cacheline_aligned")))
#endif /* __cacheline_aligned */ #endif /* __cacheline_aligned */
#ifndef __cacheline_aligned_in_smp #ifndef __cacheline_aligned_in_smp
......
...@@ -301,7 +301,7 @@ void __init parse_early_options(char *cmdline); ...@@ -301,7 +301,7 @@ void __init parse_early_options(char *cmdline);
#endif #endif
/* Data marked not to be saved by software suspend */ /* Data marked not to be saved by software suspend */
#define __nosavedata __section(.data.nosave) #define __nosavedata __section(.data..nosave)
/* This means "can be init if no module support, otherwise module load /* This means "can be init if no module support, otherwise module load
may call it." */ may call it." */
......
...@@ -183,7 +183,7 @@ extern struct cred init_cred; ...@@ -183,7 +183,7 @@ extern struct cred init_cred;
} }
/* Attach to the init_task data structure for proper alignment */ /* Attach to the init_task data structure for proper alignment */
#define __init_task_data __attribute__((__section__(".data.init_task"))) #define __init_task_data __attribute__((__section__(".data..init_task")))
#endif #endif
...@@ -18,8 +18,8 @@ ...@@ -18,8 +18,8 @@
# define asmregparm # define asmregparm
#endif #endif
#define __page_aligned_data __section(.data.page_aligned) __aligned(PAGE_SIZE) #define __page_aligned_data __section(.data..page_aligned) __aligned(PAGE_SIZE)
#define __page_aligned_bss __section(.bss.page_aligned) __aligned(PAGE_SIZE) #define __page_aligned_bss __section(.bss..page_aligned) __aligned(PAGE_SIZE)
/* /*
* For assembly routines. * For assembly routines.
...@@ -27,8 +27,8 @@ ...@@ -27,8 +27,8 @@
* Note when using these that you must specify the appropriate * Note when using these that you must specify the appropriate
* alignment directives yourself * alignment directives yourself
*/ */
#define __PAGE_ALIGNED_DATA .section ".data.page_aligned", "aw" #define __PAGE_ALIGNED_DATA .section ".data..page_aligned", "aw"
#define __PAGE_ALIGNED_BSS .section ".bss.page_aligned", "aw" #define __PAGE_ALIGNED_BSS .section ".bss..page_aligned", "aw"
/* /*
* This is used by architectures to keep arguments on the stack * This is used by architectures to keep arguments on the stack
......
...@@ -131,11 +131,11 @@ ...@@ -131,11 +131,11 @@
* Declaration/definition used for per-CPU variables that must be page aligned. * Declaration/definition used for per-CPU variables that must be page aligned.
*/ */
#define DECLARE_PER_CPU_PAGE_ALIGNED(type, name) \ #define DECLARE_PER_CPU_PAGE_ALIGNED(type, name) \
DECLARE_PER_CPU_SECTION(type, name, ".page_aligned") \ DECLARE_PER_CPU_SECTION(type, name, "..page_aligned") \
__aligned(PAGE_SIZE) __aligned(PAGE_SIZE)
#define DEFINE_PER_CPU_PAGE_ALIGNED(type, name) \ #define DEFINE_PER_CPU_PAGE_ALIGNED(type, name) \
DEFINE_PER_CPU_SECTION(type, name, ".page_aligned") \ DEFINE_PER_CPU_SECTION(type, name, "..page_aligned") \
__aligned(PAGE_SIZE) __aligned(PAGE_SIZE)
/* /*
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
/* /*
* Must define these before including other files, inline functions need them * Must define these before including other files, inline functions need them
*/ */
#define LOCK_SECTION_NAME ".text.lock."KBUILD_BASENAME #define LOCK_SECTION_NAME ".text..lock."KBUILD_BASENAME
#define LOCK_SECTION_START(extra) \ #define LOCK_SECTION_START(extra) \
".subsection 1\n\t" \ ".subsection 1\n\t" \
......
...@@ -76,6 +76,14 @@ config INIT_ENV_ARG_LIMIT ...@@ -76,6 +76,14 @@ config INIT_ENV_ARG_LIMIT
variables passed to init from the kernel command line. variables passed to init from the kernel command line.
config CROSS_COMPILE
string "Cross-compiler tool prefix"
help
Same as running 'make CROSS_COMPILE=prefix-' but stored for
default make runs in this kernel build directory. You don't
need to set this unless you want the configured kernel build
directory to select the cross-compiler automatically.
config LOCALVERSION config LOCALVERSION
string "Local version - append to kernel release" string "Local version - append to kernel release"
help help
......
...@@ -403,7 +403,7 @@ static unsigned int find_pcpusec(Elf_Ehdr *hdr, ...@@ -403,7 +403,7 @@ static unsigned int find_pcpusec(Elf_Ehdr *hdr,
Elf_Shdr *sechdrs, Elf_Shdr *sechdrs,
const char *secstrings) const char *secstrings)
{ {
return find_sec(hdr, sechdrs, secstrings, ".data.percpu"); return find_sec(hdr, sechdrs, secstrings, ".data..percpu");
} }
static void percpu_modcopy(struct module *mod, static void percpu_modcopy(struct module *mod,
......
...@@ -82,7 +82,7 @@ ifneq ($(strip $(lib-y) $(lib-m) $(lib-n) $(lib-)),) ...@@ -82,7 +82,7 @@ ifneq ($(strip $(lib-y) $(lib-m) $(lib-n) $(lib-)),)
lib-target := $(obj)/lib.a lib-target := $(obj)/lib.a
endif endif
ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(lib-target)),) ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(subdir-m) $(lib-target)),)
builtin-target := $(obj)/built-in.o builtin-target := $(obj)/built-in.o
endif endif
......
...@@ -241,7 +241,7 @@ cmd_lzma = (cat $(filter-out FORCE,$^) | \ ...@@ -241,7 +241,7 @@ cmd_lzma = (cat $(filter-out FORCE,$^) | \
lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
(rm -f $@ ; false) (rm -f $@ ; false)
quiet_cmd_lzo = LZO $@ quiet_cmd_lzo = LZO $@
cmd_lzo = (cat $(filter-out FORCE,$^) | \ cmd_lzo = (cat $(filter-out FORCE,$^) | \
lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
(rm -f $@ ; false) (rm -f $@ ; false)
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
# you do have real dups and do not have them under #ifdef's. You # you do have real dups and do not have them under #ifdef's. You
# could also just review the results. # could also just review the results.
use strict;
sub usage { sub usage {
print "Usage: checkincludes.pl [-r]\n"; print "Usage: checkincludes.pl [-r]\n";
print "By default we just warn of duplicates\n"; print "By default we just warn of duplicates\n";
...@@ -35,23 +37,24 @@ if ($#ARGV >= 1) { ...@@ -35,23 +37,24 @@ if ($#ARGV >= 1) {
} }
} }
foreach $file (@ARGV) { foreach my $file (@ARGV) {
open(FILE, $file) or die "Cannot open $file: $!.\n"; open(my $f, '<', $file)
or die "Cannot open $file: $!.\n";
my %includedfiles = (); my %includedfiles = ();
my @file_lines = (); my @file_lines = ();
while (<FILE>) { while (<$f>) {
if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) { if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) {
++$includedfiles{$1}; ++$includedfiles{$1};
} }
push(@file_lines, $_); push(@file_lines, $_);
} }
close(FILE); close($f);
if (!$remove) { if (!$remove) {
foreach $filename (keys %includedfiles) { foreach my $filename (keys %includedfiles) {
if ($includedfiles{$filename} > 1) { if ($includedfiles{$filename} > 1) {
print "$file: $filename is included more than once.\n"; print "$file: $filename is included more than once.\n";
} }
...@@ -59,27 +62,28 @@ foreach $file (@ARGV) { ...@@ -59,27 +62,28 @@ foreach $file (@ARGV) {
next; next;
} }
open(FILE,">$file") || die("Cannot write to $file: $!"); open($f, '>', $file)
or die("Cannot write to $file: $!");
my $dups = 0; my $dups = 0;
foreach (@file_lines) { foreach (@file_lines) {
if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) { if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) {
foreach $filename (keys %includedfiles) { foreach my $filename (keys %includedfiles) {
if ($1 eq $filename) { if ($1 eq $filename) {
if ($includedfiles{$filename} > 1) { if ($includedfiles{$filename} > 1) {
$includedfiles{$filename}--; $includedfiles{$filename}--;
$dups++; $dups++;
} else { } else {
print FILE $_; print {$f} $_;
} }
} }
} }
} else { } else {
print FILE $_; print {$f} $_;
} }
} }
if ($dups > 0) { if ($dups > 0) {
print "$file: removed $dups duplicate includes\n"; print "$file: removed $dups duplicate includes\n";
} }
close(FILE); close($f);
} }
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
# #
# TODO : Port to all architectures (one regex per arch) # TODO : Port to all architectures (one regex per arch)
use strict;
# check for arch # check for arch
# #
# $re is used for two matches: # $re is used for two matches:
...@@ -104,19 +106,11 @@ my (@stack, $re, $dre, $x, $xs); ...@@ -104,19 +106,11 @@ my (@stack, $re, $dre, $x, $xs);
} }
} }
sub bysize($) {
my ($asize, $bsize);
($asize = $a) =~ s/.*: *(.*)$/$1/;
($bsize = $b) =~ s/.*: *(.*)$/$1/;
$bsize <=> $asize
}
# #
# main() # main()
# #
my $funcre = qr/^$x* <(.*)>:$/; my $funcre = qr/^$x* <(.*)>:$/;
my $func; my ($func, $file, $lastslash);
my $file, $lastslash;
while (my $line = <STDIN>) { while (my $line = <STDIN>) {
if ($line =~ m/$funcre/) { if ($line =~ m/$funcre/) {
...@@ -173,4 +167,6 @@ while (my $line = <STDIN>) { ...@@ -173,4 +167,6 @@ while (my $line = <STDIN>) {
} }
} }
print sort bysize @stack; # Sort output by size (last field)
print sort { ($b =~ /:\t*(\d+)$/)[0] <=> ($a =~ /:\t*(\d+)$/)[0] } @stack;
...@@ -5,23 +5,22 @@ ...@@ -5,23 +5,22 @@
# including <linux/version.h> that don't need it. # including <linux/version.h> that don't need it.
# Copyright (C) 2003, Randy Dunlap <rdunlap@xenotime.net> # Copyright (C) 2003, Randy Dunlap <rdunlap@xenotime.net>
use strict;
$| = 1; $| = 1;
my $debugging = 0; my $debugging;
foreach $file (@ARGV) foreach my $file (@ARGV) {
{
# Open this file. # Open this file.
open(FILE, $file) || die "Can't open $file: $!\n"; open( my $f, '<', $file )
or die "Can't open $file: $!\n";
# Initialize variables. # Initialize variables.
my $fInComment = 0; my ($fInComment, $fInString, $fUseVersion);
my $fInString = 0;
my $fUseVersion = 0;
my $iLinuxVersion = 0; my $iLinuxVersion = 0;
LINE: while ( <FILE> ) while (<$f>) {
{
# Strip comments. # Strip comments.
$fInComment && (s+^.*?\*/+ +o ? ($fInComment = 0) : next); $fInComment && (s+^.*?\*/+ +o ? ($fInComment = 0) : next);
m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1))); m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1)));
...@@ -43,8 +42,8 @@ foreach $file (@ARGV) ...@@ -43,8 +42,8 @@ foreach $file (@ARGV)
# Look for uses: LINUX_VERSION_CODE, KERNEL_VERSION, UTS_RELEASE # Look for uses: LINUX_VERSION_CODE, KERNEL_VERSION, UTS_RELEASE
if (($_ =~ /LINUX_VERSION_CODE/) || ($_ =~ /\WKERNEL_VERSION/)) { if (($_ =~ /LINUX_VERSION_CODE/) || ($_ =~ /\WKERNEL_VERSION/)) {
$fUseVersion = 1; $fUseVersion = 1;
last LINE if $iLinuxVersion; last if $iLinuxVersion;
} }
} }
# Report used version IDs without include? # Report used version IDs without include?
...@@ -67,5 +66,5 @@ foreach $file (@ARGV) ...@@ -67,5 +66,5 @@ foreach $file (@ARGV)
} }
} }
close(FILE); close($f);
} }
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# AFLAGS=--32 decodecode < 386.oops # AFLAGS=--32 decodecode < 386.oops
cleanup() { cleanup() {
rm -f $T $T.s $T.o $T.oo $T.aa $T.aaa rm -f $T $T.s $T.o $T.oo $T.aa $T.dis
exit 1 exit 1
} }
...@@ -39,6 +39,29 @@ fi ...@@ -39,6 +39,29 @@ fi
echo $code echo $code
code=`echo $code | sed -e 's/.*Code: //'` code=`echo $code | sed -e 's/.*Code: //'`
width=`expr index "$code" ' '`
width=$[($width-1)/2]
case $width in
1) type=byte ;;
2) type=2byte ;;
4) type=4byte ;;
esac
disas() {
${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s &> /dev/null
if [ "$ARCH" == "arm" ]; then
if [ $width == 2 ]; then
OBJDUMPFLAGS="-M force-thumb"
fi
${CROSS_COMPILE}strip $1.o
fi
${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \
grep -v "/tmp\|Disassembly\|\.text\|^$" &> $1.dis
}
marker=`expr index "$code" "\<"` marker=`expr index "$code" "\<"`
if [ $marker -eq 0 ]; then if [ $marker -eq 0 ]; then
marker=`expr index "$code" "\("` marker=`expr index "$code" "\("`
...@@ -49,26 +72,25 @@ if [ $marker -ne 0 ]; then ...@@ -49,26 +72,25 @@ if [ $marker -ne 0 ]; then
echo All code >> $T.oo echo All code >> $T.oo
echo ======== >> $T.oo echo ======== >> $T.oo
beforemark=`echo "$code"` beforemark=`echo "$code"`
echo -n " .byte 0x" > $T.s echo -n " .$type 0x" > $T.s
echo $beforemark | sed -e 's/ /,0x/g' | sed -e 's/<//g' | sed -e 's/>//g' >> $T.s echo $beforemark | sed -e 's/ /,0x/g; s/[<>()]//g' >> $T.s
as $AFLAGS -o $T.o $T.s &> /dev/null disas $T
objdump -S $T.o | grep -v "/tmp" | grep -v "Disassembly" | grep -v "\.text" | grep -v "^$" &> $T.ooo cat $T.dis >> $T.oo
cat $T.ooo >> $T.oo rm -f $T.o $T.s $T.dis
rm -f $T.o $T.s $T.ooo
# and fix code at-and-after marker # and fix code at-and-after marker
code=`echo "$code" | cut -c$((${marker} + 1))-` code=`echo "$code" | cut -c$((${marker} + 1))-`
fi fi
echo Code starting with the faulting instruction > $T.aa echo Code starting with the faulting instruction > $T.aa
echo =========================================== >> $T.aa echo =========================================== >> $T.aa
code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g'` code=`echo $code | sed -e 's/ [<(]/ /;s/[>)] / /;s/ /,0x/g; s/[>)]$//'`
echo -n " .byte 0x" > $T.s echo -n " .$type 0x" > $T.s
echo $code >> $T.s echo $code >> $T.s
as $AFLAGS -o $T.o $T.s &> /dev/null disas $T
objdump -S $T.o | grep -v "Disassembly" | grep -v "/tmp" | grep -v "\.text" | grep -v "^$" &> $T.aaa cat $T.dis >> $T.aa
cat $T.aaa >> $T.aa
faultline=`cat $T.aaa | head -1 | cut -d":" -f2` faultline=`cat $T.dis | head -1 | cut -d":" -f2`
faultline=`echo "$faultline" | sed -e 's/\[/\\\[/g; s/\]/\\\]/g'`
cat $T.oo | sed -e "s/\($faultline\)/\*\1 <-- trapping instruction/g" cat $T.oo | sed -e "s/\($faultline\)/\*\1 <-- trapping instruction/g"
echo echo
......
...@@ -49,10 +49,10 @@ sub usage { ...@@ -49,10 +49,10 @@ sub usage {
} }
sub collectcfiles { sub collectcfiles {
my @file = `cat .tmp_versions/*.mod | grep '.*\.ko\$'`; my @file
@file = grep {s/\.ko/.mod.c/} @file; = `cat .tmp_versions/*.mod | grep '.*\.ko\$' | sed s/\.ko$/.mod.c/`;
chomp @file; chomp @file;
return @file; return @file;
} }
my (%SYMBOL, %MODULE, %opt, @allcfiles); my (%SYMBOL, %MODULE, %opt, @allcfiles);
...@@ -71,37 +71,40 @@ if (not defined $opt{'k'}) { ...@@ -71,37 +71,40 @@ if (not defined $opt{'k'}) {
$opt{'k'} = "Module.symvers"; $opt{'k'} = "Module.symvers";
} }
unless (open(MODULE_SYMVERS, $opt{'k'})) { open (my $module_symvers, '<', $opt{'k'})
die "Sorry, cannot open $opt{'k'}: $!\n"; or die "Sorry, cannot open $opt{'k'}: $!\n";
}
if (defined $opt{'o'}) { if (defined $opt{'o'}) {
unless (open(OUTPUT_HANDLE, ">$opt{'o'}")) { open (my $out, '>', $opt{'o'})
die "Sorry, cannot open $opt{'o'} $!\n"; or die "Sorry, cannot open $opt{'o'} $!\n";
}
select OUTPUT_HANDLE; select $out;
} }
# #
# collect all the symbols and their attributes from the # collect all the symbols and their attributes from the
# Module.symvers file # Module.symvers file
# #
while ( <MODULE_SYMVERS> ) { while ( <$module_symvers> ) {
chomp; chomp;
my (undef, $symbol, $module, $gpl) = split; my (undef, $symbol, $module, $gpl) = split;
$SYMBOL { $symbol } = [ $module , "0" , $symbol, $gpl]; $SYMBOL { $symbol } = [ $module , "0" , $symbol, $gpl];
} }
close(MODULE_SYMVERS); close($module_symvers);
# #
# collect the usage count of each symbol. # collect the usage count of each symbol.
# #
foreach my $thismod (@allcfiles) { foreach my $thismod (@allcfiles) {
unless (open(MODULE_MODULE, $thismod)) { my $module;
print "Sorry, cannot open $thismod: $!\n";
unless (open ($module, '<', $thismod)) {
warn "Sorry, cannot open $thismod: $!\n";
next; next;
} }
my $state=0; my $state=0;
while ( <MODULE_MODULE> ) { while ( <$module> ) {
chomp; chomp;
if ($state == 0) { if ($state == 0) {
$state = 1 if ($_ =~ /static const struct modversion_info/); $state = 1 if ($_ =~ /static const struct modversion_info/);
...@@ -124,7 +127,7 @@ foreach my $thismod (@allcfiles) { ...@@ -124,7 +127,7 @@ foreach my $thismod (@allcfiles) {
if ($state != 2) { if ($state != 2) {
print "WARNING:$thismod is not built with CONFIG_MODVERSION enabled\n"; print "WARNING:$thismod is not built with CONFIG_MODVERSION enabled\n";
} }
close(MODULE_MODULE); close($module);
} }
print "\tThis file reports the exported symbols usage patterns by in-tree\n", print "\tThis file reports the exported symbols usage patterns by in-tree\n",
......
...@@ -202,6 +202,7 @@ input_file() { ...@@ -202,6 +202,7 @@ input_file() {
print_mtime "$1" >> ${output} print_mtime "$1" >> ${output}
cat "$1" >> ${output} cat "$1" >> ${output}
else else
echo "$1 \\"
cat "$1" | while read type dir file perm ; do cat "$1" | while read type dir file perm ; do
if [ "$type" == "file" ]; then if [ "$type" == "file" ]; then
echo "$file \\"; echo "$file \\";
...@@ -231,7 +232,7 @@ arg="$1" ...@@ -231,7 +232,7 @@ arg="$1"
case "$arg" in case "$arg" in
"-l") # files included in initramfs - used by kbuild "-l") # files included in initramfs - used by kbuild
dep_list="list_" dep_list="list_"
echo "deps_initramfs := \\" echo "deps_initramfs := $0 \\"
shift shift
;; ;;
"-o") # generate compressed cpio image named $1 "-o") # generate compressed cpio image named $1
......
...@@ -758,8 +758,10 @@ int main(int argc, char **argv) ...@@ -758,8 +758,10 @@ int main(int argc, char **argv)
/* setlinebuf(debugfile); */ /* setlinebuf(debugfile); */
} }
if (flag_reference) if (flag_reference) {
read_reference(ref_file); read_reference(ref_file);
fclose(ref_file);
}
yyparse(); yyparse();
......
...@@ -80,8 +80,7 @@ sub search { ...@@ -80,8 +80,7 @@ sub search {
my $path = "$i/$filename"; my $path = "$i/$filename";
return $path if -f $path; return $path if -f $path;
} }
return;
return undef;
} }
sub parse_all { sub parse_all {
......
...@@ -28,11 +28,12 @@ my $lineno = 0; ...@@ -28,11 +28,12 @@ my $lineno = 0;
my $filename; my $filename;
foreach my $file (@files) { foreach my $file (@files) {
local *FH;
$filename = $file; $filename = $file;
open(FH, "<$filename") or die "$filename: $!\n";
open(my $fh, '<', $filename)
or die "$filename: $!\n";
$lineno = 0; $lineno = 0;
while ($line = <FH>) { while ($line = <$fh>) {
$lineno++; $lineno++;
&check_include(); &check_include();
&check_asm_types(); &check_asm_types();
...@@ -40,7 +41,7 @@ foreach my $file (@files) { ...@@ -40,7 +41,7 @@ foreach my $file (@files) {
&check_declarations(); &check_declarations();
# Dropped for now. Too much noise &check_config(); # Dropped for now. Too much noise &check_config();
} }
close FH; close $fh;
} }
exit $ret; exit $ret;
...@@ -78,7 +79,7 @@ sub check_config ...@@ -78,7 +79,7 @@ sub check_config
} }
my $linux_asm_types; my $linux_asm_types;
sub check_asm_types() sub check_asm_types
{ {
if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) { if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) {
return; return;
......
...@@ -23,13 +23,13 @@ my ($readdir, $installdir, $arch, @files) = @ARGV; ...@@ -23,13 +23,13 @@ my ($readdir, $installdir, $arch, @files) = @ARGV;
my $unifdef = "scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__"; my $unifdef = "scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__";
foreach my $file (@files) { foreach my $file (@files) {
local *INFILE;
local *OUTFILE;
my $tmpfile = "$installdir/$file.tmp"; my $tmpfile = "$installdir/$file.tmp";
open(INFILE, "<$readdir/$file")
or die "$readdir/$file: $!\n"; open(my $in, '<', "$readdir/$file")
open(OUTFILE, ">$tmpfile") or die "$tmpfile: $!\n"; or die "$readdir/$file: $!\n";
while (my $line = <INFILE>) { open(my $out, '>', $tmpfile)
or die "$tmpfile: $!\n";
while (my $line = <$in>) {
$line =~ s/([\s(])__user\s/$1/g; $line =~ s/([\s(])__user\s/$1/g;
$line =~ s/([\s(])__force\s/$1/g; $line =~ s/([\s(])__force\s/$1/g;
$line =~ s/([\s(])__iomem\s/$1/g; $line =~ s/([\s(])__iomem\s/$1/g;
...@@ -39,10 +39,11 @@ foreach my $file (@files) { ...@@ -39,10 +39,11 @@ foreach my $file (@files) {
$line =~ s/(^|\s)(inline)\b/$1__$2__/g; $line =~ s/(^|\s)(inline)\b/$1__$2__/g;
$line =~ s/(^|\s)(asm)\b(\s|[(]|$)/$1__$2__$3/g; $line =~ s/(^|\s)(asm)\b(\s|[(]|$)/$1__$2__$3/g;
$line =~ s/(^|\s|[(])(volatile)\b(\s|[(]|$)/$1__$2__$3/g; $line =~ s/(^|\s|[(])(volatile)\b(\s|[(]|$)/$1__$2__$3/g;
printf OUTFILE "%s", $line; printf {$out} "%s", $line;
} }
close OUTFILE; close $out;
close INFILE; close $in;
system $unifdef . " $tmpfile > $installdir/$file"; system $unifdef . " $tmpfile > $installdir/$file";
unlink $tmpfile; unlink $tmpfile;
} }
......
...@@ -108,8 +108,10 @@ static int read_symbol(FILE *in, struct sym_entry *s) ...@@ -108,8 +108,10 @@ static int read_symbol(FILE *in, struct sym_entry *s)
rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str); rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str);
if (rc != 3) { if (rc != 3) {
if (rc != EOF) { if (rc != EOF) {
/* skip line */ /* skip line. sym is used as dummy to
fgets(str, 500, in); * shut of "warn_unused_result" warning.
*/
sym = fgets(str, 500, in);
} }
return -1; return -1;
} }
......
...@@ -23,6 +23,9 @@ menuconfig: $(obj)/mconf ...@@ -23,6 +23,9 @@ menuconfig: $(obj)/mconf
config: $(obj)/conf config: $(obj)/conf
$< $(Kconfig) $< $(Kconfig)
nconfig: $(obj)/nconf
$< $(Kconfig)
oldconfig: $(obj)/conf oldconfig: $(obj)/conf
$< -o $(Kconfig) $< -o $(Kconfig)
...@@ -120,6 +123,7 @@ endif ...@@ -120,6 +123,7 @@ endif
# Help text used by make help # Help text used by make help
help: help:
@echo ' config - Update current config utilising a line-oriented program' @echo ' config - Update current config utilising a line-oriented program'
@echo ' nconfig - Update current config utilising a ncurses menu based program'
@echo ' menuconfig - Update current config utilising a menu based program' @echo ' menuconfig - Update current config utilising a menu based program'
@echo ' xconfig - Update current config utilising a QT based front-end' @echo ' xconfig - Update current config utilising a QT based front-end'
@echo ' gconfig - Update current config utilising a GTK based front-end' @echo ' gconfig - Update current config utilising a GTK based front-end'
...@@ -147,6 +151,8 @@ HOST_EXTRACFLAGS += -DLOCALE ...@@ -147,6 +151,8 @@ HOST_EXTRACFLAGS += -DLOCALE
# =========================================================================== # ===========================================================================
# Shared Makefile for the various kconfig executables: # Shared Makefile for the various kconfig executables:
# conf: Used for defconfig, oldconfig and related targets # conf: Used for defconfig, oldconfig and related targets
# nconf: Used for the nconfig target.
# Utilizes ncurses
# mconf: Used for the menuconfig target # mconf: Used for the menuconfig target
# Utilizes the lxdialog package # Utilizes the lxdialog package
# qconf: Used for the xconfig target # qconf: Used for the xconfig target
...@@ -159,11 +165,16 @@ lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o ...@@ -159,11 +165,16 @@ lxdialog := lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o
lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o lxdialog += lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o
conf-objs := conf.o zconf.tab.o conf-objs := conf.o zconf.tab.o
mconf-objs := mconf.o zconf.tab.o $(lxdialog) mconf-objs := mconf.o zconf.tab.o $(lxdialog)
nconf-objs := nconf.o zconf.tab.o nconf.gui.o
kxgettext-objs := kxgettext.o zconf.tab.o kxgettext-objs := kxgettext.o zconf.tab.o
hostprogs-y := conf qconf gconf kxgettext hostprogs-y := conf qconf gconf kxgettext
ifeq ($(MAKECMDGOALS),nconfig)
hostprogs-y += nconf
endif
ifeq ($(MAKECMDGOALS),menuconfig) ifeq ($(MAKECMDGOALS),menuconfig)
hostprogs-y += mconf hostprogs-y += mconf
endif endif
...@@ -187,7 +198,7 @@ endif ...@@ -187,7 +198,7 @@ endif
clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \ clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \
.tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h
clean-files += mconf qconf gconf clean-files += mconf qconf gconf nconf
clean-files += config.pot linux.pot clean-files += config.pot linux.pot
# Check that we have the required ncurses stuff installed for lxdialog (menuconfig) # Check that we have the required ncurses stuff installed for lxdialog (menuconfig)
...@@ -212,6 +223,7 @@ HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` ...@@ -212,6 +223,7 @@ HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0`
HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \
-D LKC_DIRECT_LINK -D LKC_DIRECT_LINK
HOSTLOADLIBES_nconf = -lmenu -lpanel -lncurses
$(obj)/qconf.o: $(obj)/.tmp_qtcheck $(obj)/qconf.o: $(obj)/.tmp_qtcheck
ifeq ($(qconf-target),1) ifeq ($(qconf-target),1)
......
...@@ -1097,9 +1097,32 @@ void expr_fprint(struct expr *e, FILE *out) ...@@ -1097,9 +1097,32 @@ void expr_fprint(struct expr *e, FILE *out)
static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str) static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
{ {
str_append((struct gstr*)data, str); struct gstr *gs = (struct gstr*)data;
const char *sym_str = NULL;
if (sym)
sym_str = sym_get_string_value(sym);
if (gs->max_width) {
unsigned extra_length = strlen(str);
const char *last_cr = strrchr(gs->s, '\n');
unsigned last_line_length;
if (sym_str)
extra_length += 4 + strlen(sym_str);
if (!last_cr)
last_cr = gs->s;
last_line_length = strlen(gs->s) - (last_cr - gs->s);
if ((last_line_length + extra_length) > gs->max_width)
str_append(gs, "\\\n");
}
str_append(gs, str);
if (sym) if (sym)
str_printf((struct gstr*)data, " [=%s]", sym_get_string_value(sym)); str_printf(gs, " [=%s]", sym_str);
} }
void expr_gstr_print(struct expr *e, struct gstr *gs) void expr_gstr_print(struct expr *e, struct gstr *gs)
......
...@@ -86,7 +86,7 @@ struct symbol { ...@@ -86,7 +86,7 @@ struct symbol {
struct expr_value rev_dep; struct expr_value rev_dep;
}; };
#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) #define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
#define SYMBOL_CONST 0x0001 /* symbol is const */ #define SYMBOL_CONST 0x0001 /* symbol is const */
#define SYMBOL_CHECK 0x0008 /* used during dependency checking */ #define SYMBOL_CHECK 0x0008 /* used during dependency checking */
...@@ -108,8 +108,7 @@ struct symbol { ...@@ -108,8 +108,7 @@ struct symbol {
#define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */ #define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */
#define SYMBOL_MAXLENGTH 256 #define SYMBOL_MAXLENGTH 256
#define SYMBOL_HASHSIZE 257 #define SYMBOL_HASHSIZE 9973
#define SYMBOL_HASHMASK 0xff
/* A property represent the config options that can be associated /* A property represent the config options that can be associated
* with a config "symbol". * with a config "symbol".
......
...@@ -30,13 +30,16 @@ enum { ...@@ -30,13 +30,16 @@ enum {
SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW
}; };
enum {
OPT_NORMAL, OPT_ALL, OPT_PROMPT
};
static gint view_mode = FULL_VIEW; static gint view_mode = FULL_VIEW;
static gboolean show_name = TRUE; static gboolean show_name = TRUE;
static gboolean show_range = TRUE; static gboolean show_range = TRUE;
static gboolean show_value = TRUE; static gboolean show_value = TRUE;
static gboolean show_all = FALSE;
static gboolean show_debug = FALSE;
static gboolean resizeable = FALSE; static gboolean resizeable = FALSE;
static int opt_mode = OPT_NORMAL;
GtkWidget *main_wnd = NULL; GtkWidget *main_wnd = NULL;
GtkWidget *tree1_w = NULL; // left frame GtkWidget *tree1_w = NULL; // left frame
...@@ -76,36 +79,7 @@ static void conf_changed(void); ...@@ -76,36 +79,7 @@ static void conf_changed(void);
/* Helping/Debugging Functions */ /* Helping/Debugging Functions */
const char *dbg_sym_flags(int val)
const char *dbg_print_stype(int val)
{
static char buf[256];
bzero(buf, 256);
if (val == S_UNKNOWN)
strcpy(buf, "unknown");
if (val == S_BOOLEAN)
strcpy(buf, "boolean");
if (val == S_TRISTATE)
strcpy(buf, "tristate");
if (val == S_INT)
strcpy(buf, "int");
if (val == S_HEX)
strcpy(buf, "hex");
if (val == S_STRING)
strcpy(buf, "string");
if (val == S_OTHER)
strcpy(buf, "other");
#ifdef DEBUG
printf("%s", buf);
#endif
return buf;
}
const char *dbg_print_flags(int val)
{ {
static char buf[256]; static char buf[256];
...@@ -131,40 +105,10 @@ const char *dbg_print_flags(int val) ...@@ -131,40 +105,10 @@ const char *dbg_print_flags(int val)
strcat(buf, "auto/"); strcat(buf, "auto/");
buf[strlen(buf) - 1] = '\0'; buf[strlen(buf) - 1] = '\0';
#ifdef DEBUG
printf("%s", buf);
#endif
return buf;
}
const char *dbg_print_ptype(int val)
{
static char buf[256];
bzero(buf, 256);
if (val == P_UNKNOWN)
strcpy(buf, "unknown");
if (val == P_PROMPT)
strcpy(buf, "prompt");
if (val == P_COMMENT)
strcpy(buf, "comment");
if (val == P_MENU)
strcpy(buf, "menu");
if (val == P_DEFAULT)
strcpy(buf, "default");
if (val == P_CHOICE)
strcpy(buf, "choice");
#ifdef DEBUG
printf("%s", buf);
#endif
return buf; return buf;
} }
void replace_button_icon(GladeXML * xml, GdkDrawable * window, void replace_button_icon(GladeXML * xml, GdkDrawable * window,
GtkStyle * style, gchar * btn_name, gchar ** xpm) GtkStyle * style, gchar * btn_name, gchar ** xpm)
{ {
...@@ -697,20 +641,29 @@ void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data) ...@@ -697,20 +641,29 @@ void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data)
void void
on_show_all_options1_activate(GtkMenuItem * menuitem, gpointer user_data) on_set_option_mode1_activate(GtkMenuItem *menuitem, gpointer user_data)
{ {
show_all = GTK_CHECK_MENU_ITEM(menuitem)->active; opt_mode = OPT_NORMAL;
gtk_tree_store_clear(tree2);
display_tree(&rootmenu); /* instead of update_tree to speed-up */
}
void
on_set_option_mode2_activate(GtkMenuItem *menuitem, gpointer user_data)
{
opt_mode = OPT_ALL;
gtk_tree_store_clear(tree2); gtk_tree_store_clear(tree2);
display_tree(&rootmenu); // instead of update_tree to speed-up display_tree(&rootmenu); /* instead of update_tree to speed-up */
} }
void void
on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data) on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data)
{ {
show_debug = GTK_CHECK_MENU_ITEM(menuitem)->active; opt_mode = OPT_PROMPT;
update_tree(&rootmenu, NULL); gtk_tree_store_clear(tree2);
display_tree(&rootmenu); /* instead of update_tree to speed-up */
} }
...@@ -1163,7 +1116,10 @@ static gchar **fill_row(struct menu *menu) ...@@ -1163,7 +1116,10 @@ static gchar **fill_row(struct menu *menu)
g_strdup_printf("%s %s", _(menu_get_prompt(menu)), g_strdup_printf("%s %s", _(menu_get_prompt(menu)),
sym && sym_has_value(sym) ? "(NEW)" : ""); sym && sym_has_value(sym) ? "(NEW)" : "");
if (show_all && !menu_is_visible(menu)) if (opt_mode == OPT_ALL && !menu_is_visible(menu))
row[COL_COLOR] = g_strdup("DarkGray");
else if (opt_mode == OPT_PROMPT &&
menu_has_prompt(menu) && !menu_is_visible(menu))
row[COL_COLOR] = g_strdup("DarkGray"); row[COL_COLOR] = g_strdup("DarkGray");
else else
row[COL_COLOR] = g_strdup("Black"); row[COL_COLOR] = g_strdup("Black");
...@@ -1386,16 +1342,19 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) ...@@ -1386,16 +1342,19 @@ static void update_tree(struct menu *src, GtkTreeIter * dst)
menu2 ? menu_get_prompt(menu2) : "nil"); menu2 ? menu_get_prompt(menu2) : "nil");
#endif #endif
if (!menu_is_visible(child1) && !show_all) { // remove node if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) ||
(opt_mode == OPT_PROMPT && !menu_has_prompt(child1))) {
/* remove node */
if (gtktree_iter_find_node(dst, menu1) != NULL) { if (gtktree_iter_find_node(dst, menu1) != NULL) {
memcpy(&tmp, child2, sizeof(GtkTreeIter)); memcpy(&tmp, child2, sizeof(GtkTreeIter));
valid = gtk_tree_model_iter_next(model2, valid = gtk_tree_model_iter_next(model2,
child2); child2);
gtk_tree_store_remove(tree2, &tmp); gtk_tree_store_remove(tree2, &tmp);
if (!valid) if (!valid)
return; // next parent return; /* next parent */
else else
goto reparse; // next child goto reparse; /* next child */
} else } else
continue; continue;
} }
...@@ -1464,17 +1423,19 @@ static void display_tree(struct menu *menu) ...@@ -1464,17 +1423,19 @@ static void display_tree(struct menu *menu)
&& (tree == tree2)) && (tree == tree2))
continue; continue;
if (menu_is_visible(child) || show_all) if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) ||
(opt_mode == OPT_PROMPT && menu_has_prompt(child)) ||
(opt_mode == OPT_ALL))
place_node(child, fill_row(child)); place_node(child, fill_row(child));
#ifdef DEBUG #ifdef DEBUG
printf("%*c%s: ", indent, ' ', menu_get_prompt(child)); printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : ""); printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : "");
dbg_print_ptype(ptype); printf("%s", prop_get_type_name(ptype));
printf(" | "); printf(" | ");
if (sym) { if (sym) {
dbg_print_stype(sym->type); printf("%s", sym_type_name(sym->type));
printf(" | "); printf(" | ");
dbg_print_flags(sym->flags); printf("%s", dbg_sym_flags(sym->flags));
printf("\n"); printf("\n");
} else } else
printf("\n"); printf("\n");
......
...@@ -190,26 +190,40 @@ ...@@ -190,26 +190,40 @@
</child> </child>
<child> <child>
<widget class="GtkCheckMenuItem" id="show_all_options1"> <widget class="GtkRadioMenuItem" id="set_option_mode1">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Show normal options</property>
<property name="label" translatable="yes">Show normal options</property>
<property name="use_underline">True</property>
<property name="active">True</property>
<signal name="activate" handler="on_set_option_mode1_activate"/>
</widget>
</child>
<child>
<widget class="GtkRadioMenuItem" id="set_option_mode2">
<property name="visible">True</property> <property name="visible">True</property>
<property name="tooltip" translatable="yes">Show all options</property> <property name="tooltip" translatable="yes">Show all options</property>
<property name="label" translatable="yes">Show all _options</property> <property name="label" translatable="yes">Show all _options</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="active">False</property> <property name="active">False</property>
<signal name="activate" handler="on_show_all_options1_activate"/> <property name="group">set_option_mode1</property>
<signal name="activate" handler="on_set_option_mode2_activate"/>
</widget> </widget>
</child> </child>
<child> <child>
<widget class="GtkCheckMenuItem" id="show_debug_info1"> <widget class="GtkRadioMenuItem" id="set_option_mode3">
<property name="visible">True</property> <property name="visible">True</property>
<property name="tooltip" translatable="yes">Show masked options</property> <property name="tooltip" translatable="yes">Show all options with prompts</property>
<property name="label" translatable="yes">Show _debug info</property> <property name="label" translatable="yes">Show all prompt options</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="active">False</property> <property name="active">False</property>
<signal name="activate" handler="on_show_debug_info1_activate"/> <property name="group">set_option_mode1</property>
<signal name="activate" handler="on_set_option_mode3_activate"/>
</widget> </widget>
</child> </child>
</widget> </widget>
</child> </child>
</widget> </widget>
......
...@@ -84,7 +84,7 @@ void conf_set_all_new_symbols(enum conf_def_mode mode); ...@@ -84,7 +84,7 @@ void conf_set_all_new_symbols(enum conf_def_mode mode);
void kconfig_load(void); void kconfig_load(void);
/* menu.c */ /* menu.c */
void menu_init(void); void _menu_init(void);
void menu_warn(struct menu *menu, const char *fmt, ...); void menu_warn(struct menu *menu, const char *fmt, ...);
struct menu *menu_add_menu(void); struct menu *menu_add_menu(void);
void menu_end_menu(void); void menu_end_menu(void);
...@@ -106,6 +106,11 @@ int file_write_dep(const char *name); ...@@ -106,6 +106,11 @@ int file_write_dep(const char *name);
struct gstr { struct gstr {
size_t len; size_t len;
char *s; char *s;
/*
* when max_width is not zero long lines in string s (if any) get
* wrapped not to exceed the max_width value
*/
int max_width;
}; };
struct gstr str_new(void); struct gstr str_new(void);
struct gstr str_assign(const char *s); struct gstr str_assign(const char *s);
......
...@@ -11,13 +11,15 @@ P(conf_set_changed_callback, void,(void (*fn)(void))); ...@@ -11,13 +11,15 @@ P(conf_set_changed_callback, void,(void (*fn)(void)));
/* menu.c */ /* menu.c */
P(rootmenu,struct menu,); P(rootmenu,struct menu,);
P(menu_is_visible,bool,(struct menu *menu)); P(menu_is_visible, bool, (struct menu *menu));
P(menu_has_prompt, bool, (struct menu *menu));
P(menu_get_prompt,const char *,(struct menu *menu)); P(menu_get_prompt,const char *,(struct menu *menu));
P(menu_get_root_menu,struct menu *,(struct menu *menu)); P(menu_get_root_menu,struct menu *,(struct menu *menu));
P(menu_get_parent_menu,struct menu *,(struct menu *menu)); P(menu_get_parent_menu,struct menu *,(struct menu *menu));
P(menu_has_help,bool,(struct menu *menu)); P(menu_has_help,bool,(struct menu *menu));
P(menu_get_help,const char *,(struct menu *menu)); P(menu_get_help,const char *,(struct menu *menu));
P(get_symbol_str,void,(struct gstr *r, struct symbol *sym)); P(get_symbol_str, void, (struct gstr *r, struct symbol *sym));
P(get_relations_str, struct gstr, (struct symbol **sym_arr));
P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help)); P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help));
/* symbol.c */ /* symbol.c */
......
...@@ -180,7 +180,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width ...@@ -180,7 +180,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
case KEY_LEFT: case KEY_LEFT:
switch (button) { switch (button) {
case -1: case -1:
button = 1; /* Indicates "Cancel" button is selected */ button = 1; /* Indicates "Help" button is selected */
print_buttons(dialog, height, width, 1); print_buttons(dialog, height, width, 1);
break; break;
case 0: case 0:
...@@ -204,7 +204,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width ...@@ -204,7 +204,7 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
print_buttons(dialog, height, width, 0); print_buttons(dialog, height, width, 0);
break; break;
case 0: case 0:
button = 1; /* Indicates "Cancel" button is selected */ button = 1; /* Indicates "Help" button is selected */
print_buttons(dialog, height, width, 1); print_buttons(dialog, height, width, 1);
break; break;
case 1: case 1:
......
...@@ -383,6 +383,10 @@ int dialog_menu(const char *title, const char *prompt, ...@@ -383,6 +383,10 @@ int dialog_menu(const char *title, const char *prompt,
case 'n': case 'n':
case 'm': case 'm':
case '/': case '/':
case 'h':
case '?':
case 'z':
case '\n':
/* save scroll info */ /* save scroll info */
*s_scroll = scroll; *s_scroll = scroll;
delwin(menu); delwin(menu);
...@@ -390,8 +394,10 @@ int dialog_menu(const char *title, const char *prompt, ...@@ -390,8 +394,10 @@ int dialog_menu(const char *title, const char *prompt,
item_set(scroll + choice); item_set(scroll + choice);
item_set_selected(1); item_set_selected(1);
switch (key) { switch (key) {
case 'h':
case '?':
return 2;
case 's': case 's':
return 3;
case 'y': case 'y':
return 3; return 3;
case 'n': case 'n':
...@@ -402,18 +408,12 @@ int dialog_menu(const char *title, const char *prompt, ...@@ -402,18 +408,12 @@ int dialog_menu(const char *title, const char *prompt,
return 6; return 6;
case '/': case '/':
return 7; return 7;
case 'z':
return 8;
case '\n':
return button;
} }
return 0; return 0;
case 'h':
case '?':
button = 2;
case '\n':
*s_scroll = scroll;
delwin(menu);
delwin(dialog);
item_set(scroll + choice);
item_set_selected(1);
return button;
case 'e': case 'e':
case 'x': case 'x':
key = KEY_ESC; key = KEY_ESC;
......
...@@ -67,13 +67,15 @@ static const char mconf_readme[] = N_( ...@@ -67,13 +67,15 @@ static const char mconf_readme[] = N_(
" there is a delayed response which you may find annoying.\n" " there is a delayed response which you may find annoying.\n"
"\n" "\n"
" Also, the <TAB> and cursor keys will cycle between <Select>,\n" " Also, the <TAB> and cursor keys will cycle between <Select>,\n"
" <Exit> and <Help>\n" " <Exit> and <Help>.\n"
"\n" "\n"
"o To get help with an item, use the cursor keys to highlight <Help>\n" "o To get help with an item, use the cursor keys to highlight <Help>\n"
" and Press <ENTER>.\n" " and press <ENTER>.\n"
"\n" "\n"
" Shortcut: Press <H> or <?>.\n" " Shortcut: Press <H> or <?>.\n"
"\n" "\n"
"o To show hidden options, press <Z>.\n"
"\n"
"\n" "\n"
"Radiolists (Choice lists)\n" "Radiolists (Choice lists)\n"
"-----------\n" "-----------\n"
...@@ -272,6 +274,7 @@ static int indent; ...@@ -272,6 +274,7 @@ static int indent;
static struct menu *current_menu; static struct menu *current_menu;
static int child_count; static int child_count;
static int single_menu_mode; static int single_menu_mode;
static int show_all_options;
static void conf(struct menu *menu); static void conf(struct menu *menu);
static void conf_choice(struct menu *menu); static void conf_choice(struct menu *menu);
...@@ -282,19 +285,6 @@ static void show_textbox(const char *title, const char *text, int r, int c); ...@@ -282,19 +285,6 @@ static void show_textbox(const char *title, const char *text, int r, int c);
static void show_helptext(const char *title, const char *text); static void show_helptext(const char *title, const char *text);
static void show_help(struct menu *menu); static void show_help(struct menu *menu);
static struct gstr get_relations_str(struct symbol **sym_arr)
{
struct symbol *sym;
struct gstr res = str_new();
int i;
for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
get_symbol_str(&res, sym);
if (!i)
str_append(&res, _("No matches found.\n"));
return res;
}
static char filename[PATH_MAX+1]; static char filename[PATH_MAX+1];
static void set_config_filename(const char *config_filename) static void set_config_filename(const char *config_filename)
{ {
...@@ -359,8 +349,16 @@ static void build_conf(struct menu *menu) ...@@ -359,8 +349,16 @@ static void build_conf(struct menu *menu)
int type, tmp, doint = 2; int type, tmp, doint = 2;
tristate val; tristate val;
char ch; char ch;
bool visible;
if (!menu_is_visible(menu))
/*
* note: menu_is_visible() has side effect that it will
* recalc the value of the symbol.
*/
visible = menu_is_visible(menu);
if (show_all_options && !menu_has_prompt(menu))
return;
else if (!show_all_options && !visible)
return; return;
sym = menu->sym; sym = menu->sym;
...@@ -619,6 +617,9 @@ static void conf(struct menu *menu) ...@@ -619,6 +617,9 @@ static void conf(struct menu *menu)
case 7: case 7:
search_conf(); search_conf();
break; break;
case 8:
show_all_options = !show_all_options;
break;
} }
} }
} }
...@@ -638,6 +639,7 @@ static void show_help(struct menu *menu) ...@@ -638,6 +639,7 @@ static void show_help(struct menu *menu)
{ {
struct gstr help = str_new(); struct gstr help = str_new();
help.max_width = getmaxx(stdscr) - 10;
menu_get_ext_help(menu, &help); menu_get_ext_help(menu, &help);
show_helptext(_(menu_get_prompt(menu)), str_get(&help)); show_helptext(_(menu_get_prompt(menu)), str_get(&help));
......
...@@ -38,7 +38,7 @@ static void prop_warn(struct property *prop, const char *fmt, ...) ...@@ -38,7 +38,7 @@ static void prop_warn(struct property *prop, const char *fmt, ...)
va_end(ap); va_end(ap);
} }
void menu_init(void) void _menu_init(void)
{ {
current_entry = current_menu = &rootmenu; current_entry = current_menu = &rootmenu;
last_entry_ptr = &rootmenu.list; last_entry_ptr = &rootmenu.list;
...@@ -197,7 +197,7 @@ static void sym_check_prop(struct symbol *sym) ...@@ -197,7 +197,7 @@ static void sym_check_prop(struct symbol *sym)
if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) && if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
prop->expr->type != E_SYMBOL) prop->expr->type != E_SYMBOL)
prop_warn(prop, prop_warn(prop,
"default for config symbol '%'" "default for config symbol '%s'"
" must be a single symbol", sym->name); " must be a single symbol", sym->name);
break; break;
case P_SELECT: case P_SELECT:
...@@ -390,6 +390,13 @@ void menu_finalize(struct menu *parent) ...@@ -390,6 +390,13 @@ void menu_finalize(struct menu *parent)
} }
} }
bool menu_has_prompt(struct menu *menu)
{
if (!menu->prompt)
return false;
return true;
}
bool menu_is_visible(struct menu *menu) bool menu_is_visible(struct menu *menu)
{ {
struct menu *child; struct menu *child;
...@@ -398,6 +405,7 @@ bool menu_is_visible(struct menu *menu) ...@@ -398,6 +405,7 @@ bool menu_is_visible(struct menu *menu)
if (!menu->prompt) if (!menu->prompt)
return false; return false;
sym = menu->sym; sym = menu->sym;
if (sym) { if (sym) {
sym_calc_value(sym); sym_calc_value(sym);
...@@ -407,12 +415,14 @@ bool menu_is_visible(struct menu *menu) ...@@ -407,12 +415,14 @@ bool menu_is_visible(struct menu *menu)
if (visible != no) if (visible != no)
return true; return true;
if (!sym || sym_get_tristate_value(menu->sym) == no) if (!sym || sym_get_tristate_value(menu->sym) == no)
return false; return false;
for (child = menu->list; child; child = child->next) for (child = menu->list; child; child = child->next)
if (menu_is_visible(child)) if (menu_is_visible(child))
return true; return true;
return false; return false;
} }
...@@ -515,6 +525,20 @@ void get_symbol_str(struct gstr *r, struct symbol *sym) ...@@ -515,6 +525,20 @@ void get_symbol_str(struct gstr *r, struct symbol *sym)
str_append(r, "\n\n"); str_append(r, "\n\n");
} }
struct gstr get_relations_str(struct symbol **sym_arr)
{
struct symbol *sym;
struct gstr res = str_new();
int i;
for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
get_symbol_str(&res, sym);
if (!i)
str_append(&res, _("No matches found.\n"));
return res;
}
void menu_get_ext_help(struct menu *menu, struct gstr *help) void menu_get_ext_help(struct menu *menu, struct gstr *help)
{ {
struct symbol *sym = menu->sym; struct symbol *sym = menu->sym;
......
/*
* Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
* Released under the terms of the GNU GPL v2.0.
*
* Derived from menuconfig.
*
*/
#define LKC_DIRECT_LINK
#include "lkc.h"
#include "nconf.h"
static const char nconf_readme[] = N_(
"Overview\n"
"--------\n"
"Some kernel features may be built directly into the kernel.\n"
"Some may be made into loadable runtime modules. Some features\n"
"may be completely removed altogether. There are also certain\n"
"kernel parameters which are not really features, but must be\n"
"entered in as decimal or hexadecimal numbers or possibly text.\n"
"\n"
"Menu items beginning with following braces represent features that\n"
" [ ] can be built in or removed\n"
" < > can be built in, modularized or removed\n"
" { } can be built in or modularized (selected by other feature)\n"
" - - are selected by other feature,\n"
" XXX cannot be selected. use Symbol Info to find out why,\n"
"while *, M or whitespace inside braces means to build in, build as\n"
"a module or to exclude the feature respectively.\n"
"\n"
"To change any of these features, highlight it with the cursor\n"
"keys and press <Y> to build it in, <M> to make it a module or\n"
"<N> to removed it. You may also press the <Space Bar> to cycle\n"
"through the available options (ie. Y->N->M->Y).\n"
"\n"
"Some additional keyboard hints:\n"
"\n"
"Menus\n"
"----------\n"
"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
" you wish to change use <Enter> or <Space>. Goto submenu by \n"
" pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n"
" Submenus are designated by \"--->\".\n"
"\n"
" Shortcut: Press the option's highlighted letter (hotkey).\n"
" Pressing a hotkey more than once will sequence\n"
" through all visible items which use that hotkey.\n"
"\n"
" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
" unseen options into view.\n"
"\n"
"o To exit a menu use the just press <ESC> <F5> <F8> or <left-arrow>.\n"
"\n"
"o To get help with an item, press <F1>\n"
" Shortcut: Press <h> or <?>.\n"
"\n"
"\n"
"Radiolists (Choice lists)\n"
"-----------\n"
"o Use the cursor keys to select the option you wish to set and press\n"
" <S> or the <SPACE BAR>.\n"
"\n"
" Shortcut: Press the first letter of the option you wish to set then\n"
" press <S> or <SPACE BAR>.\n"
"\n"
"o To see available help for the item, press <F1>\n"
" Shortcut: Press <H> or <?>.\n"
"\n"
"\n"
"Data Entry\n"
"-----------\n"
"o Enter the requested information and press <ENTER>\n"
" If you are entering hexadecimal values, it is not necessary to\n"
" add the '0x' prefix to the entry.\n"
"\n"
"o For help, press <F1>.\n"
"\n"
"\n"
"Text Box (Help Window)\n"
"--------\n"
"o Use the cursor keys to scroll up/down/left/right. The VI editor\n"
" keys h,j,k,l function here as do <SPACE BAR> for those\n"
" who are familiar with less and lynx.\n"
"\n"
"o Press <Enter>, <F1>, <F5>, <F7> or <Esc> to exit.\n"
"\n"
"\n"
"Alternate Configuration Files\n"
"-----------------------------\n"
"nconfig supports the use of alternate configuration files for\n"
"those who, for various reasons, find it necessary to switch\n"
"between different kernel configurations.\n"
"\n"
"At the end of the main menu you will find two options. One is\n"
"for saving the current configuration to a file of your choosing.\n"
"The other option is for loading a previously saved alternate\n"
"configuration.\n"
"\n"
"Even if you don't use alternate configuration files, but you\n"
"find during a nconfig session that you have completely messed\n"
"up your settings, you may use the \"Load Alternate...\" option to\n"
"restore your previously saved settings from \".config\" without\n"
"restarting nconfig.\n"
"\n"
"Other information\n"
"-----------------\n"
"If you use nconfig in an XTERM window make sure you have your\n"
"$TERM variable set to point to a xterm definition which supports color.\n"
"Otherwise, nconfig will look rather bad. nconfig will not\n"
"display correctly in a RXVT window because rxvt displays only one\n"
"intensity of color, bright.\n"
"\n"
"nconfig will display larger menus on screens or xterms which are\n"
"set to display more than the standard 25 row by 80 column geometry.\n"
"In order for this to work, the \"stty size\" command must be able to\n"
"display the screen's current row and column geometry. I STRONGLY\n"
"RECOMMEND that you make sure you do NOT have the shell variables\n"
"LINES and COLUMNS exported into your environment. Some distributions\n"
"export those variables via /etc/profile. Some ncurses programs can\n"
"become confused when those variables (LINES & COLUMNS) don't reflect\n"
"the true screen size.\n"
"\n"
"Optional personality available\n"
"------------------------------\n"
"If you prefer to have all of the kernel options listed in a single\n"
"menu, rather than the default multimenu hierarchy, run the nconfig\n"
"with NCONFIG_MODE environment variable set to single_menu. Example:\n"
"\n"
"make NCONFIG_MODE=single_menu nconfig\n"
"\n"
"<Enter> will then unroll the appropriate category, or enfold it if it\n"
"is already unrolled.\n"
"\n"
"Note that this mode can eventually be a little more CPU expensive\n"
"(especially with a larger number of unrolled categories) than the\n"
"default mode.\n"
"\n"),
menu_no_f_instructions[] = N_(
" You do not have function keys support. Please follow the\n"
" following instructions:\n"
" Arrow keys navigate the menu.\n"
" <Enter> or <right-arrow> selects submenus --->.\n"
" Capital Letters are hotkeys.\n"
" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
" Pressing SpaceBar toggles between the above options\n"
" Press <Esc> or <left-arrow> to go back one menu, \n"
" <?> or <h> for Help, </> for Search.\n"
" <1> is interchangable with <F1>, <2> with <F2>, etc.\n"
" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
" <Esc> always leaves the current window\n"),
menu_instructions[] = N_(
" Arrow keys navigate the menu.\n"
" <Enter> or <right-arrow> selects submenus --->.\n"
" Capital Letters are hotkeys.\n"
" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
" Pressing SpaceBar toggles between the above options\n"
" Press <Esc>, <F3> or <left-arrow> to go back one menu, \n"
" <?>, <F1> or <h> for Help, </> for Search.\n"
" <1> is interchangable with <F1>, <2> with <F2>, etc.\n"
" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
" <Esc> always leaves the current window\n"),
radiolist_instructions[] = N_(
" Use the arrow keys to navigate this window or\n"
" press the hotkey of the item you wish to select\n"
" followed by the <SPACE BAR>.\n"
" Press <?>, <F1> or <h> for additional information about this option.\n"),
inputbox_instructions_int[] = N_(
"Please enter a decimal value.\n"
"Fractions will not be accepted.\n"
"Press <RETURN> to accept, <ESC> to cancel."),
inputbox_instructions_hex[] = N_(
"Please enter a hexadecimal value.\n"
"Press <RETURN> to accept, <ESC> to cancel."),
inputbox_instructions_string[] = N_(
"Please enter a string value.\n"
"Press <RETURN> to accept, <ESC> to cancel."),
setmod_text[] = N_(
"This feature depends on another which\n"
"has been configured as a module.\n"
"As a result, this feature will be built as a module."),
nohelp_text[] = N_(
"There is no help available for this kernel option.\n"),
load_config_text[] = N_(
"Enter the name of the configuration file you wish to load.\n"
"Accept the name shown to restore the configuration you\n"
"last retrieved. Leave blank to abort."),
load_config_help[] = N_(
"\n"
"For various reasons, one may wish to keep several different kernel\n"
"configurations available on a single machine.\n"
"\n"
"If you have saved a previous configuration in a file other than the\n"
"kernel's default, entering the name of the file here will allow you\n"
"to modify that configuration.\n"
"\n"
"If you are uncertain, then you have probably never used alternate\n"
"configuration files. You should therefor leave this blank to abort.\n"),
save_config_text[] = N_(
"Enter a filename to which this configuration should be saved\n"
"as an alternate. Leave blank to abort."),
save_config_help[] = N_(
"\n"
"For various reasons, one may wish to keep different kernel\n"
"configurations available on a single machine.\n"
"\n"
"Entering a file name here will allow you to later retrieve, modify\n"
"and use the current configuration as an alternate to whatever\n"
"configuration options you have selected at that time.\n"
"\n"
"If you are uncertain what all this means then you should probably\n"
"leave this blank.\n"),
search_help[] = N_(
"\n"
"Search for CONFIG_ symbols and display their relations.\n"
"Regular expressions are allowed.\n"
"Example: search for \"^FOO\"\n"
"Result:\n"
"-----------------------------------------------------------------\n"
"Symbol: FOO [ = m]\n"
"Prompt: Foo bus is used to drive the bar HW\n"
"Defined at drivers/pci/Kconfig:47\n"
"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
"Location:\n"
" -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n"
" -> PCI support (PCI [ = y])\n"
" -> PCI access mode (<choice> [ = y])\n"
"Selects: LIBCRC32\n"
"Selected by: BAR\n"
"-----------------------------------------------------------------\n"
"o The line 'Prompt:' shows the text used in the menu structure for\n"
" this CONFIG_ symbol\n"
"o The 'Defined at' line tell at what file / line number the symbol\n"
" is defined\n"
"o The 'Depends on:' line tell what symbols needs to be defined for\n"
" this symbol to be visible in the menu (selectable)\n"
"o The 'Location:' lines tell where in the menu structure this symbol\n"
" is located\n"
" A location followed by a [ = y] indicate that this is a selectable\n"
" menu item - and current value is displayed inside brackets.\n"
"o The 'Selects:' line tell what symbol will be automatically\n"
" selected if this symbol is selected (y or m)\n"
"o The 'Selected by' line tell what symbol has selected this symbol\n"
"\n"
"Only relevant lines are shown.\n"
"\n\n"
"Search examples:\n"
"Examples: USB = > find all CONFIG_ symbols containing USB\n"
" ^USB => find all CONFIG_ symbols starting with USB\n"
" USB$ => find all CONFIG_ symbols ending with USB\n"
"\n");
struct mitem {
char str[256];
char tag;
void *usrptr;
int is_hot;
int is_visible;
};
#define MAX_MENU_ITEMS 4096
static int show_all_items;
static int indent;
static struct menu *current_menu;
static int child_count;
static int single_menu_mode;
/* the window in which all information appears */
static WINDOW *main_window;
/* the largest size of the menu window */
static int mwin_max_lines;
static int mwin_max_cols;
/* the window in which we show option buttons */
static MENU *curses_menu;
static ITEM *curses_menu_items[MAX_MENU_ITEMS];
static struct mitem k_menu_items[MAX_MENU_ITEMS];
static int items_num;
static int global_exit;
/* the currently selected button */
const char *current_instructions = menu_instructions;
/* this array is used to implement hot keys. it is updated in item_make and
* resetted in clean_items. It would be better to use a hash, but lets keep it
* simple... */
#define MAX_SAME_KEY MAX_MENU_ITEMS
struct {
int count;
int ptrs[MAX_MENU_ITEMS];
} hotkeys[1<<(sizeof(char)*8)];
static void conf(struct menu *menu);
static void conf_choice(struct menu *menu);
static void conf_string(struct menu *menu);
static void conf_load(void);
static void conf_save(void);
static void show_help(struct menu *menu);
static int do_exit(void);
static void setup_windows(void);
typedef void (*function_key_handler_t)(int *key, struct menu *menu);
static void handle_f1(int *key, struct menu *current_item);
static void handle_f2(int *key, struct menu *current_item);
static void handle_f3(int *key, struct menu *current_item);
static void handle_f4(int *key, struct menu *current_item);
static void handle_f5(int *key, struct menu *current_item);
static void handle_f6(int *key, struct menu *current_item);
static void handle_f7(int *key, struct menu *current_item);
static void handle_f8(int *key, struct menu *current_item);
struct function_keys {
const char *key_str;
const char *func;
function_key key;
function_key_handler_t handler;
};
static const int function_keys_num = 8;
struct function_keys function_keys[] = {
{
.key_str = "F1",
.func = "Help",
.key = F_HELP,
.handler = handle_f1,
},
{
.key_str = "F2",
.func = "Symbol Info",
.key = F_SYMBOL,
.handler = handle_f2,
},
{
.key_str = "F3",
.func = "Instructions",
.key = F_INSTS,
.handler = handle_f3,
},
{
.key_str = "F4",
.func = "Config",
.key = F_CONF,
.handler = handle_f4,
},
{
.key_str = "F5",
.func = "Back",
.key = F_BACK,
.handler = handle_f5,
},
{
.key_str = "F6",
.func = "Save",
.key = F_SAVE,
.handler = handle_f6,
},
{
.key_str = "F7",
.func = "Load",
.key = F_LOAD,
.handler = handle_f7,
},
{
.key_str = "F8",
.func = "Exit",
.key = F_EXIT,
.handler = handle_f8,
},
};
static void print_function_line(void)
{
int i;
int offset = 1;
const int skip = 1;
for (i = 0; i < function_keys_num; i++) {
wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
mvwprintw(main_window, LINES-3, offset,
"%s",
function_keys[i].key_str);
wattrset(main_window, attributes[FUNCTION_TEXT]);
offset += strlen(function_keys[i].key_str);
mvwprintw(main_window, LINES-3,
offset, "%s",
function_keys[i].func);
offset += strlen(function_keys[i].func) + skip;
}
wattrset(main_window, attributes[NORMAL]);
}
/* help */
static void handle_f1(int *key, struct menu *current_item)
{
show_scroll_win(main_window,
_("README"), _(nconf_readme));
return;
}
/* symbole help */
static void handle_f2(int *key, struct menu *current_item)
{
show_help(current_item);
return;
}
/* instructions */
static void handle_f3(int *key, struct menu *current_item)
{
show_scroll_win(main_window,
_("Instructions"),
_(current_instructions));
return;
}
/* config */
static void handle_f4(int *key, struct menu *current_item)
{
int res = btn_dialog(main_window,
_("Show all symbols?"),
2,
" <Show All> ",
"<Don't show all>");
if (res == 0)
show_all_items = 1;
else if (res == 1)
show_all_items = 0;
return;
}
/* back */
static void handle_f5(int *key, struct menu *current_item)
{
*key = KEY_LEFT;
return;
}
/* save */
static void handle_f6(int *key, struct menu *current_item)
{
conf_save();
return;
}
/* load */
static void handle_f7(int *key, struct menu *current_item)
{
conf_load();
return;
}
/* exit */
static void handle_f8(int *key, struct menu *current_item)
{
do_exit();
return;
}
/* return != 0 to indicate the key was handles */
static int process_special_keys(int *key, struct menu *menu)
{
int i;
if (*key == KEY_RESIZE) {
setup_windows();
return 1;
}
for (i = 0; i < function_keys_num; i++) {
if (*key == KEY_F(function_keys[i].key) ||
*key == '0' + function_keys[i].key){
function_keys[i].handler(key, menu);
return 1;
}
}
return 0;
}
static void clean_items(void)
{
int i;
for (i = 0; curses_menu_items[i]; i++)
free_item(curses_menu_items[i]);
bzero(curses_menu_items, sizeof(curses_menu_items));
bzero(k_menu_items, sizeof(k_menu_items));
bzero(hotkeys, sizeof(hotkeys));
items_num = 0;
}
/* return the index of the next hot item, or -1 if no such item exists */
static int get_next_hot(int c)
{
static int hot_index;
static int hot_char;
if (c < 0 || c > 255 || hotkeys[c].count <= 0)
return -1;
if (hot_char == c) {
hot_index = (hot_index+1)%hotkeys[c].count;
return hotkeys[c].ptrs[hot_index];
} else {
hot_char = c;
hot_index = 0;
return hotkeys[c].ptrs[0];
}
}
/* can the char c be a hot key? no, if c is a common shortcut used elsewhere */
static int canbhot(char c)
{
c = tolower(c);
return isalnum(c) && c != 'y' && c != 'm' && c != 'h' &&
c != 'n' && c != '?';
}
/* check if str already contains a hot key. */
static int is_hot(int index)
{
return k_menu_items[index].is_hot;
}
/* find the first possible hot key, and mark it.
* index is the index of the item in the menu
* return 0 on success*/
static int make_hot(char *dest, int len, const char *org, int index)
{
int position = -1;
int i;
int tmp;
int c;
int org_len = strlen(org);
if (org == NULL || is_hot(index))
return 1;
/* make sure not to make hot keys out of markers.
* find where to start looking for a hot key
*/
i = 0;
/* skip white space */
while (i < org_len && org[i] == ' ')
i++;
if (i == org_len)
return -1;
/* if encountering '(' or '<' or '[', find the match and look from there
**/
if (org[i] == '[' || org[i] == '<' || org[i] == '(') {
i++;
for (; i < org_len; i++)
if (org[i] == ']' || org[i] == '>' || org[i] == ')')
break;
}
if (i == org_len)
return -1;
for (; i < org_len; i++) {
if (canbhot(org[i]) && org[i-1] != '<' && org[i-1] != '(') {
position = i;
break;
}
}
if (position == -1)
return 1;
/* ok, char at org[position] should be a hot key to this item */
c = tolower(org[position]);
tmp = hotkeys[c].count;
hotkeys[c].ptrs[tmp] = index;
hotkeys[c].count++;
/*
snprintf(dest, len, "%.*s(%c)%s", position, org, org[position],
&org[position+1]);
*/
/* make org[position] uppercase, and all leading letter small case */
strncpy(dest, org, len);
for (i = 0; i < position; i++)
dest[i] = tolower(dest[i]);
dest[position] = toupper(dest[position]);
k_menu_items[index].is_hot = 1;
return 0;
}
/* Make a new item. Add a hotkey mark in the first possible letter.
* As ncurses does not allow any attributes inside menue item, we mark the
* hot key as the first capitalized letter in the string */
static void item_make(struct menu *menu, char tag, const char *fmt, ...)
{
va_list ap;
char tmp_str[256];
if (items_num > MAX_MENU_ITEMS-1)
return;
bzero(&k_menu_items[items_num], sizeof(k_menu_items[0]));
k_menu_items[items_num].tag = tag;
k_menu_items[items_num].usrptr = menu;
if (menu != NULL)
k_menu_items[items_num].is_visible =
menu_is_visible(menu);
else
k_menu_items[items_num].is_visible = 1;
va_start(ap, fmt);
vsnprintf(tmp_str, sizeof(tmp_str), fmt, ap);
if (!k_menu_items[items_num].is_visible)
memcpy(tmp_str, "XXX", 3);
va_end(ap);
if (make_hot(
k_menu_items[items_num].str,
sizeof(k_menu_items[items_num].str), tmp_str, items_num) != 0)
strncpy(k_menu_items[items_num].str,
tmp_str,
sizeof(k_menu_items[items_num].str));
curses_menu_items[items_num] = new_item(
k_menu_items[items_num].str,
k_menu_items[items_num].str);
set_item_userptr(curses_menu_items[items_num],
&k_menu_items[items_num]);
/*
if (!k_menu_items[items_num].is_visible)
item_opts_off(curses_menu_items[items_num], O_SELECTABLE);
*/
items_num++;
curses_menu_items[items_num] = NULL;
}
/* very hackish. adds a string to the last item added */
static void item_add_str(const char *fmt, ...)
{
va_list ap;
int index = items_num-1;
char new_str[256];
char tmp_str[256];
if (index < 0)
return;
va_start(ap, fmt);
vsnprintf(new_str, sizeof(new_str), fmt, ap);
va_end(ap);
snprintf(tmp_str, sizeof(tmp_str), "%s%s",
k_menu_items[index].str, new_str);
if (make_hot(k_menu_items[index].str,
sizeof(k_menu_items[index].str), tmp_str, index) != 0)
strncpy(k_menu_items[index].str,
tmp_str,
sizeof(k_menu_items[index].str));
free_item(curses_menu_items[index]);
curses_menu_items[index] = new_item(
k_menu_items[index].str,
k_menu_items[index].str);
set_item_userptr(curses_menu_items[index],
&k_menu_items[index]);
}
/* get the tag of the currently selected item */
static char item_tag(void)
{
ITEM *cur;
struct mitem *mcur;
cur = current_item(curses_menu);
if (cur == NULL)
return 0;
mcur = (struct mitem *) item_userptr(cur);
return mcur->tag;
}
static int curses_item_index(void)
{
return item_index(current_item(curses_menu));
}
static void *item_data(void)
{
ITEM *cur;
struct mitem *mcur;
cur = current_item(curses_menu);
mcur = (struct mitem *) item_userptr(cur);
return mcur->usrptr;
}
static int item_is_tag(char tag)
{
return item_tag() == tag;
}
static char filename[PATH_MAX+1];
static char menu_backtitle[PATH_MAX+128];
static const char *set_config_filename(const char *config_filename)
{
int size;
struct symbol *sym;
sym = sym_lookup("KERNELVERSION", 0);
sym_calc_value(sym);
size = snprintf(menu_backtitle, sizeof(menu_backtitle),
_("%s - Linux Kernel v%s Configuration"),
config_filename, sym_get_string_value(sym));
if (size >= sizeof(menu_backtitle))
menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
size = snprintf(filename, sizeof(filename), "%s", config_filename);
if (size >= sizeof(filename))
filename[sizeof(filename)-1] = '\0';
return menu_backtitle;
}
/* command = 0 is supress, 1 is restore */
static void supress_stdout(int command)
{
static FILE *org_stdout;
static FILE *org_stderr;
if (command == 0) {
org_stdout = stdout;
org_stderr = stderr;
stdout = fopen("/dev/null", "a");
stderr = fopen("/dev/null", "a");
} else {
fclose(stdout);
fclose(stderr);
stdout = org_stdout;
stderr = org_stderr;
}
}
/* return = 0 means we are successful.
* -1 means go on doing what you were doing
*/
static int do_exit(void)
{
int res;
if (!conf_get_changed()) {
global_exit = 1;
return 0;
}
res = btn_dialog(main_window,
_("Do you wish to save your "
"new kernel configuration?\n"
"<ESC> to cancel and resume nconfig."),
2,
" <save> ",
"<don't save>");
if (res == KEY_EXIT) {
global_exit = 0;
return -1;
}
/* if we got here, the user really wants to exit */
switch (res) {
case 0:
supress_stdout(0);
res = conf_write(filename);
supress_stdout(1);
if (res)
btn_dialog(
main_window,
_("Error during writing of the kernel "
"configuration.\n"
"Your kernel configuration "
"changes were NOT saved."),
1,
"<OK>");
else {
char buf[1024];
snprintf(buf, 1024,
_("Configuration written to %s\n"
"End of Linux kernel configuration.\n"
"Execute 'make' to build the kernel or try"
" 'make help'."), filename);
btn_dialog(
main_window,
buf,
1,
"<OK>");
}
break;
default:
btn_dialog(
main_window,
_("Your kernel configuration changes were NOT saved."),
1,
"<OK>");
break;
}
global_exit = 1;
return 0;
}
static void search_conf(void)
{
struct symbol **sym_arr;
struct gstr res;
char dialog_input_result[100];
char *dialog_input;
int dres;
again:
dres = dialog_inputbox(main_window,
_("Search Configuration Parameter"),
_("Enter CONFIG_ (sub)string to search for "
"(with or without \"CONFIG\")"),
"", dialog_input_result, 99);
switch (dres) {
case 0:
break;
case 1:
show_scroll_win(main_window,
_("Search Configuration"), search_help);
goto again;
default:
return;
}
/* strip CONFIG_ if necessary */
dialog_input = dialog_input_result;
if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0)
dialog_input += 7;
sym_arr = sym_re_search(dialog_input);
res = get_relations_str(sym_arr);
free(sym_arr);
show_scroll_win(main_window,
_("Search Results"), str_get(&res));
str_free(&res);
}
static void build_conf(struct menu *menu)
{
struct symbol *sym;
struct property *prop;
struct menu *child;
int type, tmp, doint = 2;
tristate val;
char ch;
if (!menu || (!show_all_items && !menu_is_visible(menu)))
return;
sym = menu->sym;
prop = menu->prompt;
if (!sym) {
if (prop && menu != current_menu) {
const char *prompt = menu_get_prompt(menu);
enum prop_type ptype;
ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
switch (ptype) {
case P_MENU:
child_count++;
prompt = _(prompt);
if (single_menu_mode) {
item_make(menu, 'm',
"%s%*c%s",
menu->data ? "-->" : "++>",
indent + 1, ' ', prompt);
} else
item_make(menu, 'm',
" %*c%s --->",
indent + 1,
' ', prompt);
if (single_menu_mode && menu->data)
goto conf_childs;
return;
case P_COMMENT:
if (prompt) {
child_count++;
item_make(menu, ':',
" %*c*** %s ***",
indent + 1, ' ',
_(prompt));
}
break;
default:
if (prompt) {
child_count++;
item_make(menu, ':', "---%*c%s",
indent + 1, ' ',
_(prompt));
}
}
} else
doint = 0;
goto conf_childs;
}
type = sym_get_type(sym);
if (sym_is_choice(sym)) {
struct symbol *def_sym = sym_get_choice_value(sym);
struct menu *def_menu = NULL;
child_count++;
for (child = menu->list; child; child = child->next) {
if (menu_is_visible(child) && child->sym == def_sym)
def_menu = child;
}
val = sym_get_tristate_value(sym);
if (sym_is_changable(sym)) {
switch (type) {
case S_BOOLEAN:
item_make(menu, 't', "[%c]",
val == no ? ' ' : '*');
break;
case S_TRISTATE:
switch (val) {
case yes:
ch = '*';
break;
case mod:
ch = 'M';
break;
default:
ch = ' ';
break;
}
item_make(menu, 't', "<%c>", ch);
break;
}
} else {
item_make(menu, def_menu ? 't' : ':', " ");
}
item_add_str("%*c%s", indent + 1,
' ', _(menu_get_prompt(menu)));
if (val == yes) {
if (def_menu) {
item_add_str(" (%s)",
_(menu_get_prompt(def_menu)));
item_add_str(" --->");
if (def_menu->list) {
indent += 2;
build_conf(def_menu);
indent -= 2;
}
}
return;
}
} else {
if (menu == current_menu) {
item_make(menu, ':',
"---%*c%s", indent + 1,
' ', _(menu_get_prompt(menu)));
goto conf_childs;
}
child_count++;
val = sym_get_tristate_value(sym);
if (sym_is_choice_value(sym) && val == yes) {
item_make(menu, ':', " ");
} else {
switch (type) {
case S_BOOLEAN:
if (sym_is_changable(sym))
item_make(menu, 't', "[%c]",
val == no ? ' ' : '*');
else
item_make(menu, 't', "-%c-",
val == no ? ' ' : '*');
break;
case S_TRISTATE:
switch (val) {
case yes:
ch = '*';
break;
case mod:
ch = 'M';
break;
default:
ch = ' ';
break;
}
if (sym_is_changable(sym)) {
if (sym->rev_dep.tri == mod)
item_make(menu,
't', "{%c}", ch);
else
item_make(menu,
't', "<%c>", ch);
} else
item_make(menu, 't', "-%c-", ch);
break;
default:
tmp = 2 + strlen(sym_get_string_value(sym));
item_make(menu, 's', " (%s)",
sym_get_string_value(sym));
tmp = indent - tmp + 4;
if (tmp < 0)
tmp = 0;
item_add_str("%*c%s%s", tmp, ' ',
_(menu_get_prompt(menu)),
(sym_has_value(sym) ||
!sym_is_changable(sym)) ? "" :
_(" (NEW)"));
goto conf_childs;
}
}
item_add_str("%*c%s%s", indent + 1, ' ',
_(menu_get_prompt(menu)),
(sym_has_value(sym) || !sym_is_changable(sym)) ?
"" : _(" (NEW)"));
if (menu->prompt && menu->prompt->type == P_MENU) {
item_add_str(" --->");
return;
}
}
conf_childs:
indent += doint;
for (child = menu->list; child; child = child->next)
build_conf(child);
indent -= doint;
}
static void reset_menu(void)
{
unpost_menu(curses_menu);
clean_items();
}
/* adjust the menu to show this item.
* prefer not to scroll the menu if possible*/
static void center_item(int selected_index, int *last_top_row)
{
int toprow;
int maxy, maxx;
scale_menu(curses_menu, &maxy, &maxx);
set_top_row(curses_menu, *last_top_row);
toprow = top_row(curses_menu);
if (selected_index >= toprow && selected_index < toprow+maxy) {
/* we can only move the selected item. no need to scroll */
set_current_item(curses_menu,
curses_menu_items[selected_index]);
} else {
toprow = max(selected_index-maxy/2, 0);
if (toprow >= item_count(curses_menu)-maxy)
toprow = item_count(curses_menu)-mwin_max_lines;
set_top_row(curses_menu, toprow);
set_current_item(curses_menu,
curses_menu_items[selected_index]);
}
*last_top_row = toprow;
post_menu(curses_menu);
refresh_all_windows(main_window);
}
/* this function assumes reset_menu has been called before */
static void show_menu(const char *prompt, const char *instructions,
int selected_index, int *last_top_row)
{
int maxx, maxy;
WINDOW *menu_window;
current_instructions = instructions;
clear();
wattrset(main_window, attributes[NORMAL]);
print_in_middle(stdscr, 1, 0, COLS,
menu_backtitle,
attributes[MAIN_HEADING]);
wattrset(main_window, attributes[MAIN_MENU_BOX]);
box(main_window, 0, 0);
wattrset(main_window, attributes[MAIN_MENU_HEADING]);
mvwprintw(main_window, 0, 3, " %s ", prompt);
wattrset(main_window, attributes[NORMAL]);
set_menu_items(curses_menu, curses_menu_items);
/* position the menu at the middle of the screen */
scale_menu(curses_menu, &maxy, &maxx);
maxx = min(maxx, mwin_max_cols-2);
maxy = mwin_max_lines-2;
menu_window = derwin(main_window,
maxy,
maxx,
2,
(mwin_max_cols-maxx)/2);
keypad(menu_window, TRUE);
set_menu_win(curses_menu, menu_window);
set_menu_sub(curses_menu, menu_window);
/* must reassert this after changing items, otherwise returns to a
* default of 16
*/
set_menu_format(curses_menu, maxy, 1);
center_item(selected_index, last_top_row);
set_menu_format(curses_menu, maxy, 1);
print_function_line();
/* Post the menu */
post_menu(curses_menu);
refresh_all_windows(main_window);
}
static void conf(struct menu *menu)
{
char pattern[256];
struct menu *submenu = 0;
const char *prompt = menu_get_prompt(menu);
struct symbol *sym;
struct menu *active_menu = NULL;
int res;
int current_index = 0;
int last_top_row = 0;
bzero(pattern, sizeof(pattern));
while (!global_exit) {
reset_menu();
current_menu = menu;
build_conf(menu);
if (!child_count)
break;
show_menu(prompt ? _(prompt) : _("Main Menu"),
_(menu_instructions),
current_index, &last_top_row);
keypad((menu_win(curses_menu)), TRUE);
while (!global_exit && (res = wgetch(menu_win(curses_menu)))) {
if (process_special_keys(&res,
(struct menu *) item_data()))
break;
switch (res) {
case KEY_DOWN:
menu_driver(curses_menu, REQ_DOWN_ITEM);
break;
case KEY_UP:
menu_driver(curses_menu, REQ_UP_ITEM);
break;
case KEY_NPAGE:
menu_driver(curses_menu, REQ_SCR_DPAGE);
break;
case KEY_PPAGE:
menu_driver(curses_menu, REQ_SCR_UPAGE);
break;
case KEY_HOME:
menu_driver(curses_menu, REQ_FIRST_ITEM);
break;
case KEY_END:
menu_driver(curses_menu, REQ_LAST_ITEM);
break;
case 'h':
case '?':
show_help((struct menu *) item_data());
break;
}
if (res == 10 || res == 27 ||
res == 32 || res == 'n' || res == 'y' ||
res == KEY_LEFT || res == KEY_RIGHT ||
res == 'm' || res == '/')
break;
else if (canbhot(res)) {
/* check for hot keys: */
int tmp = get_next_hot(res);
if (tmp != -1)
center_item(tmp, &last_top_row);
}
refresh_all_windows(main_window);
}
refresh_all_windows(main_window);
/* if ESC or left*/
if (res == 27 || (menu != &rootmenu && res == KEY_LEFT))
break;
/* remember location in the menu */
last_top_row = top_row(curses_menu);
current_index = curses_item_index();
if (!item_tag())
continue;
submenu = (struct menu *) item_data();
active_menu = (struct menu *)item_data();
if (!submenu || !menu_is_visible(submenu))
continue;
if (submenu)
sym = submenu->sym;
else
sym = NULL;
switch (res) {
case ' ':
if (item_is_tag('t'))
sym_toggle_tristate_value(sym);
else if (item_is_tag('m'))
conf(submenu);
break;
case KEY_RIGHT:
case 10: /* ENTER WAS PRESSED */
switch (item_tag()) {
case 'm':
if (single_menu_mode)
submenu->data =
(void *) (long) !submenu->data;
else
conf(submenu);
break;
case 't':
if (sym_is_choice(sym) &&
sym_get_tristate_value(sym) == yes)
conf_choice(submenu);
else if (submenu->prompt &&
submenu->prompt->type == P_MENU)
conf(submenu);
else if (res == 10)
sym_toggle_tristate_value(sym);
break;
case 's':
conf_string(submenu);
break;
}
break;
case 'y':
if (item_is_tag('t')) {
if (sym_set_tristate_value(sym, yes))
break;
if (sym_set_tristate_value(sym, mod))
btn_dialog(main_window, setmod_text, 0);
}
break;
case 'n':
if (item_is_tag('t'))
sym_set_tristate_value(sym, no);
break;
case 'm':
if (item_is_tag('t'))
sym_set_tristate_value(sym, mod);
break;
case '/':
search_conf();
break;
}
}
}
static void show_help(struct menu *menu)
{
struct gstr help = str_new();
if (menu && menu->sym && menu_has_help(menu)) {
if (menu->sym->name) {
str_printf(&help, "CONFIG_%s:\n\n", menu->sym->name);
str_append(&help, _(menu_get_help(menu)));
str_append(&help, "\n");
get_symbol_str(&help, menu->sym);
}
} else {
str_append(&help, nohelp_text);
}
show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help));
str_free(&help);
}
static void conf_choice(struct menu *menu)
{
const char *prompt = _(menu_get_prompt(menu));
struct menu *child = 0;
struct symbol *active;
int selected_index = 0;
int last_top_row = 0;
int res, i = 0;
active = sym_get_choice_value(menu->sym);
/* this is mostly duplicated from the conf() function. */
while (!global_exit) {
reset_menu();
for (i = 0, child = menu->list; child; child = child->next) {
if (!show_all_items && !menu_is_visible(child))
continue;
if (child->sym == sym_get_choice_value(menu->sym))
item_make(child, ':', "<X> %s",
_(menu_get_prompt(child)));
else
item_make(child, ':', " %s",
_(menu_get_prompt(child)));
if (child->sym == active){
last_top_row = top_row(curses_menu);
selected_index = i;
}
i++;
}
show_menu(prompt ? _(prompt) : _("Choice Menu"),
_(radiolist_instructions),
selected_index,
&last_top_row);
while (!global_exit && (res = wgetch(menu_win(curses_menu)))) {
if (process_special_keys(
&res,
(struct menu *) item_data()))
break;
switch (res) {
case KEY_DOWN:
menu_driver(curses_menu, REQ_DOWN_ITEM);
break;
case KEY_UP:
menu_driver(curses_menu, REQ_UP_ITEM);
break;
case KEY_NPAGE:
menu_driver(curses_menu, REQ_SCR_DPAGE);
break;
case KEY_PPAGE:
menu_driver(curses_menu, REQ_SCR_UPAGE);
break;
case KEY_HOME:
menu_driver(curses_menu, REQ_FIRST_ITEM);
break;
case KEY_END:
menu_driver(curses_menu, REQ_LAST_ITEM);
break;
case 'h':
case '?':
show_help((struct menu *) item_data());
break;
}
if (res == 10 || res == 27 || res == ' ' ||
res == KEY_LEFT)
break;
else if (canbhot(res)) {
/* check for hot keys: */
int tmp = get_next_hot(res);
if (tmp != -1)
center_item(tmp, &last_top_row);
}
refresh_all_windows(main_window);
}
/* if ESC or left */
if (res == 27 || res == KEY_LEFT)
break;
child = item_data();
if (!child || !menu_is_visible(child))
continue;
switch (res) {
case ' ':
case 10:
case KEY_RIGHT:
sym_set_tristate_value(child->sym, yes);
return;
case 'h':
case '?':
show_help(child);
active = child->sym;
break;
case KEY_EXIT:
return;
}
}
}
static void conf_string(struct menu *menu)
{
const char *prompt = menu_get_prompt(menu);
char dialog_input_result[256];
while (1) {
int res;
const char *heading;
switch (sym_get_type(menu->sym)) {
case S_INT:
heading = _(inputbox_instructions_int);
break;
case S_HEX:
heading = _(inputbox_instructions_hex);
break;
case S_STRING:
heading = _(inputbox_instructions_string);
break;
default:
heading = _("Internal nconf error!");
}
res = dialog_inputbox(main_window,
prompt ? _(prompt) : _("Main Menu"),
heading,
sym_get_string_value(menu->sym),
dialog_input_result,
sizeof(dialog_input_result));
switch (res) {
case 0:
if (sym_set_string_value(menu->sym,
dialog_input_result))
return;
btn_dialog(main_window,
_("You have made an invalid entry."), 0);
break;
case 1:
show_help(menu);
break;
case KEY_EXIT:
return;
}
}
}
static void conf_load(void)
{
char dialog_input_result[256];
while (1) {
int res;
res = dialog_inputbox(main_window,
NULL, load_config_text,
filename,
dialog_input_result,
sizeof(dialog_input_result));
switch (res) {
case 0:
if (!dialog_input_result[0])
return;
if (!conf_read(dialog_input_result)) {
set_config_filename(dialog_input_result);
sym_set_change_count(1);
return;
}
btn_dialog(main_window, _("File does not exist!"), 0);
break;
case 1:
show_scroll_win(main_window,
_("Load Alternate Configuration"),
load_config_help);
break;
case KEY_EXIT:
return;
}
}
}
static void conf_save(void)
{
char dialog_input_result[256];
while (1) {
int res;
res = dialog_inputbox(main_window,
NULL, save_config_text,
filename,
dialog_input_result,
sizeof(dialog_input_result));
switch (res) {
case 0:
if (!dialog_input_result[0])
return;
supress_stdout(0);
res = conf_write(dialog_input_result);
supress_stdout(1);
if (!res) {
char buf[1024];
sprintf(buf, "%s %s",
_("configuration file saved to: "),
dialog_input_result);
btn_dialog(main_window,
buf, 1, "<OK>");
set_config_filename(dialog_input_result);
return;
}
btn_dialog(main_window, _("Can't create file! "
"Probably a nonexistent directory."),
1, "<OK>");
break;
case 1:
show_scroll_win(main_window,
_("Save Alternate Configuration"),
save_config_help);
break;
case KEY_EXIT:
return;
}
}
}
void setup_windows(void)
{
if (main_window != NULL)
delwin(main_window);
/* set up the menu and menu window */
main_window = newwin(LINES-2, COLS-2, 2, 1);
keypad(main_window, TRUE);
mwin_max_lines = LINES-6;
mwin_max_cols = COLS-6;
/* panels order is from bottom to top */
new_panel(main_window);
}
int main(int ac, char **av)
{
char *mode;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
conf_parse(av[1]);
conf_read(NULL);
mode = getenv("NCONFIG_MODE");
if (mode) {
if (!strcasecmp(mode, "single_menu"))
single_menu_mode = 1;
}
/* Initialize curses */
initscr();
/* set color theme */
set_colors();
cbreak();
noecho();
keypad(stdscr, TRUE);
curs_set(0);
if (COLS < 75 || LINES < 20) {
endwin();
printf("Your terminal should have at "
"least 20 lines and 75 columns\n");
return 1;
}
notimeout(stdscr, FALSE);
ESCDELAY = 1;
/* set btns menu */
curses_menu = new_menu(curses_menu_items);
menu_opts_off(curses_menu, O_SHOWDESC);
menu_opts_off(curses_menu, O_SHOWMATCH);
menu_opts_on(curses_menu, O_ONEVALUE);
menu_opts_on(curses_menu, O_NONCYCLIC);
set_menu_mark(curses_menu, " ");
set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]);
set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]);
set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]);
set_config_filename(conf_get_configname());
setup_windows();
/* check for KEY_FUNC(1) */
if (has_key(KEY_F(1)) == FALSE) {
show_scroll_win(main_window,
_("Instructions"),
_(menu_no_f_instructions));
}
/* do the work */
while (!global_exit) {
conf(&rootmenu);
if (!global_exit && do_exit() == 0)
break;
}
/* ok, we are done */
unpost_menu(curses_menu);
free_menu(curses_menu);
delwin(main_window);
clear();
refresh();
endwin();
return 0;
}
/*
* Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
* Released under the terms of the GNU GPL v2.0.
*
* Derived from menuconfig.
*
*/
#include "nconf.h"
/* a list of all the different widgets we use */
attributes_t attributes[ATTR_MAX+1] = {0};
/* available colors:
COLOR_BLACK 0
COLOR_RED 1
COLOR_GREEN 2
COLOR_YELLOW 3
COLOR_BLUE 4
COLOR_MAGENTA 5
COLOR_CYAN 6
COLOR_WHITE 7
*/
static void set_normal_colors(void)
{
init_pair(NORMAL, -1, -1);
init_pair(MAIN_HEADING, COLOR_MAGENTA, -1);
/* FORE is for the selected item */
init_pair(MAIN_MENU_FORE, -1, -1);
/* BACK for all the rest */
init_pair(MAIN_MENU_BACK, -1, -1);
init_pair(MAIN_MENU_GREY, -1, -1);
init_pair(MAIN_MENU_HEADING, COLOR_GREEN, -1);
init_pair(MAIN_MENU_BOX, COLOR_YELLOW, -1);
init_pair(SCROLLWIN_TEXT, -1, -1);
init_pair(SCROLLWIN_HEADING, COLOR_GREEN, -1);
init_pair(SCROLLWIN_BOX, COLOR_YELLOW, -1);
init_pair(DIALOG_TEXT, -1, -1);
init_pair(DIALOG_BOX, COLOR_YELLOW, -1);
init_pair(DIALOG_MENU_BACK, COLOR_YELLOW, -1);
init_pair(DIALOG_MENU_FORE, COLOR_RED, -1);
init_pair(INPUT_BOX, COLOR_YELLOW, -1);
init_pair(INPUT_HEADING, COLOR_GREEN, -1);
init_pair(INPUT_TEXT, -1, -1);
init_pair(INPUT_FIELD, -1, -1);
init_pair(FUNCTION_HIGHLIGHT, -1, -1);
init_pair(FUNCTION_TEXT, COLOR_BLUE, -1);
}
/* available attributes:
A_NORMAL Normal display (no highlight)
A_STANDOUT Best highlighting mode of the terminal.
A_UNDERLINE Underlining
A_REVERSE Reverse video
A_BLINK Blinking
A_DIM Half bright
A_BOLD Extra bright or bold
A_PROTECT Protected mode
A_INVIS Invisible or blank mode
A_ALTCHARSET Alternate character set
A_CHARTEXT Bit-mask to extract a character
COLOR_PAIR(n) Color-pair number n
*/
static void normal_color_theme(void)
{
/* automatically add color... */
#define mkattr(name, attr) do { \
attributes[name] = attr | COLOR_PAIR(name); } while (0)
mkattr(NORMAL, NORMAL);
mkattr(MAIN_HEADING, A_BOLD | A_UNDERLINE);
mkattr(MAIN_MENU_FORE, A_REVERSE);
mkattr(MAIN_MENU_BACK, A_NORMAL);
mkattr(MAIN_MENU_GREY, A_NORMAL);
mkattr(MAIN_MENU_HEADING, A_BOLD);
mkattr(MAIN_MENU_BOX, A_NORMAL);
mkattr(SCROLLWIN_TEXT, A_NORMAL);
mkattr(SCROLLWIN_HEADING, A_BOLD);
mkattr(SCROLLWIN_BOX, A_BOLD);
mkattr(DIALOG_TEXT, A_BOLD);
mkattr(DIALOG_BOX, A_BOLD);
mkattr(DIALOG_MENU_FORE, A_STANDOUT);
mkattr(DIALOG_MENU_BACK, A_NORMAL);
mkattr(INPUT_BOX, A_NORMAL);
mkattr(INPUT_HEADING, A_BOLD);
mkattr(INPUT_TEXT, A_NORMAL);
mkattr(INPUT_FIELD, A_UNDERLINE);
mkattr(FUNCTION_HIGHLIGHT, A_BOLD);
mkattr(FUNCTION_TEXT, A_REVERSE);
}
static void no_colors_theme(void)
{
/* automatically add highlight, no color */
#define mkattrn(name, attr) { attributes[name] = attr; }
mkattrn(NORMAL, NORMAL);
mkattrn(MAIN_HEADING, A_BOLD | A_UNDERLINE);
mkattrn(MAIN_MENU_FORE, A_STANDOUT);
mkattrn(MAIN_MENU_BACK, A_NORMAL);
mkattrn(MAIN_MENU_GREY, A_NORMAL);
mkattrn(MAIN_MENU_HEADING, A_BOLD);
mkattrn(MAIN_MENU_BOX, A_NORMAL);
mkattrn(SCROLLWIN_TEXT, A_NORMAL);
mkattrn(SCROLLWIN_HEADING, A_BOLD);
mkattrn(SCROLLWIN_BOX, A_BOLD);
mkattrn(DIALOG_TEXT, A_NORMAL);
mkattrn(DIALOG_BOX, A_BOLD);
mkattrn(DIALOG_MENU_FORE, A_STANDOUT);
mkattrn(DIALOG_MENU_BACK, A_NORMAL);
mkattrn(INPUT_BOX, A_BOLD);
mkattrn(INPUT_HEADING, A_BOLD);
mkattrn(INPUT_TEXT, A_NORMAL);
mkattrn(INPUT_FIELD, A_UNDERLINE);
mkattrn(FUNCTION_HIGHLIGHT, A_BOLD);
mkattrn(FUNCTION_TEXT, A_REVERSE);
}
void set_colors()
{
start_color();
use_default_colors();
set_normal_colors();
if (has_colors()) {
normal_color_theme();
} else {
/* give deafults */
no_colors_theme();
}
}
/* this changes the windows attributes !!! */
void print_in_middle(WINDOW *win,
int starty,
int startx,
int width,
const char *string,
chtype color)
{ int length, x, y;
float temp;
if (win == NULL)
win = stdscr;
getyx(win, y, x);
if (startx != 0)
x = startx;
if (starty != 0)
y = starty;
if (width == 0)
width = 80;
length = strlen(string);
temp = (width - length) / 2;
x = startx + (int)temp;
wattrset(win, color);
mvwprintw(win, y, x, "%s", string);
refresh();
}
int get_line_no(const char *text)
{
int i;
int total = 1;
if (!text)
return 0;
for (i = 0; text[i] != '\0'; i++)
if (text[i] == '\n')
total++;
return total;
}
const char *get_line(const char *text, int line_no)
{
int i;
int lines = 0;
if (!text)
return 0;
for (i = 0; text[i] != '\0' && lines < line_no; i++)
if (text[i] == '\n')
lines++;
return text+i;
}
int get_line_length(const char *line)
{
int res = 0;
while (*line != '\0' && *line != '\n') {
line++;
res++;
}
return res;
}
/* print all lines to the window. */
void fill_window(WINDOW *win, const char *text)
{
int x, y;
int total_lines = get_line_no(text);
int i;
getmaxyx(win, y, x);
/* do not go over end of line */
total_lines = min(total_lines, y);
for (i = 0; i < total_lines; i++) {
char tmp[x+10];
const char *line = get_line(text, i);
int len = get_line_length(line);
strncpy(tmp, line, min(len, x));
tmp[len] = '\0';
mvwprintw(win, i, 0, tmp);
}
}
/* get the message, and buttons.
* each button must be a char*
* return the selected button
*
* this dialog is used for 2 different things:
* 1) show a text box, no buttons.
* 2) show a dialog, with horizontal buttons
*/
int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
{
va_list ap;
char *btn;
int btns_width = 0;
int msg_lines = 0;
int msg_width = 0;
int total_width;
int win_rows = 0;
WINDOW *win;
WINDOW *msg_win;
WINDOW *menu_win;
MENU *menu;
ITEM *btns[btn_num+1];
int i, x, y;
int res = -1;
va_start(ap, btn_num);
for (i = 0; i < btn_num; i++) {
btn = va_arg(ap, char *);
btns[i] = new_item(btn, "");
btns_width += strlen(btn)+1;
}
va_end(ap);
btns[btn_num] = NULL;
/* find the widest line of msg: */
msg_lines = get_line_no(msg);
for (i = 0; i < msg_lines; i++) {
const char *line = get_line(msg, i);
int len = get_line_length(line);
if (msg_width < len)
msg_width = len;
}
total_width = max(msg_width, btns_width);
/* place dialog in middle of screen */
y = (LINES-(msg_lines+4))/2;
x = (COLS-(total_width+4))/2;
/* create the windows */
if (btn_num > 0)
win_rows = msg_lines+4;
else
win_rows = msg_lines+2;
win = newwin(win_rows, total_width+4, y, x);
keypad(win, TRUE);
menu_win = derwin(win, 1, btns_width, win_rows-2,
1+(total_width+2-btns_width)/2);
menu = new_menu(btns);
msg_win = derwin(win, win_rows-2, msg_width, 1,
1+(total_width+2-msg_width)/2);
set_menu_fore(menu, attributes[DIALOG_MENU_FORE]);
set_menu_back(menu, attributes[DIALOG_MENU_BACK]);
wattrset(win, attributes[DIALOG_BOX]);
box(win, 0, 0);
/* print message */
wattrset(msg_win, attributes[DIALOG_TEXT]);
fill_window(msg_win, msg);
set_menu_win(menu, win);
set_menu_sub(menu, menu_win);
set_menu_format(menu, 1, btn_num);
menu_opts_off(menu, O_SHOWDESC);
menu_opts_off(menu, O_SHOWMATCH);
menu_opts_on(menu, O_ONEVALUE);
menu_opts_on(menu, O_NONCYCLIC);
set_menu_mark(menu, "");
post_menu(menu);
touchwin(win);
refresh_all_windows(main_window);
while ((res = wgetch(win))) {
switch (res) {
case KEY_LEFT:
menu_driver(menu, REQ_LEFT_ITEM);
break;
case KEY_RIGHT:
menu_driver(menu, REQ_RIGHT_ITEM);
break;
case 10: /* ENTER */
case 27: /* ESCAPE */
case ' ':
case KEY_F(F_BACK):
case KEY_F(F_EXIT):
break;
}
touchwin(win);
refresh_all_windows(main_window);
if (res == 10 || res == ' ') {
res = item_index(current_item(menu));
break;
} else if (res == 27 || res == KEY_F(F_BACK) ||
res == KEY_F(F_EXIT)) {
res = KEY_EXIT;
break;
}
}
unpost_menu(menu);
free_menu(menu);
for (i = 0; i < btn_num; i++)
free_item(btns[i]);
delwin(win);
return res;
}
int dialog_inputbox(WINDOW *main_window,
const char *title, const char *prompt,
const char *init, char *result, int result_len)
{
int prompt_lines = 0;
int prompt_width = 0;
WINDOW *win;
WINDOW *prompt_win;
WINDOW *form_win;
PANEL *panel;
int i, x, y;
int res = -1;
int cursor_position = strlen(init);
/* find the widest line of msg: */
prompt_lines = get_line_no(prompt);
for (i = 0; i < prompt_lines; i++) {
const char *line = get_line(prompt, i);
int len = get_line_length(line);
prompt_width = max(prompt_width, len);
}
if (title)
prompt_width = max(prompt_width, strlen(title));
/* place dialog in middle of screen */
y = (LINES-(prompt_lines+4))/2;
x = (COLS-(prompt_width+4))/2;
strncpy(result, init, result_len);
/* create the windows */
win = newwin(prompt_lines+6, prompt_width+7, y, x);
prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2);
form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2);
keypad(form_win, TRUE);
wattrset(form_win, attributes[INPUT_FIELD]);
wattrset(win, attributes[INPUT_BOX]);
box(win, 0, 0);
wattrset(win, attributes[INPUT_HEADING]);
if (title)
mvwprintw(win, 0, 3, "%s", title);
/* print message */
wattrset(prompt_win, attributes[INPUT_TEXT]);
fill_window(prompt_win, prompt);
mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
mvwprintw(form_win, 0, 0, "%s", result);
/* create panels */
panel = new_panel(win);
/* show the cursor */
curs_set(1);
touchwin(win);
refresh_all_windows(main_window);
while ((res = wgetch(form_win))) {
int len = strlen(result);
switch (res) {
case 10: /* ENTER */
case 27: /* ESCAPE */
case KEY_F(F_HELP):
case KEY_F(F_EXIT):
case KEY_F(F_BACK):
break;
case 127:
case KEY_BACKSPACE:
if (cursor_position > 0) {
memmove(&result[cursor_position-1],
&result[cursor_position],
len-cursor_position+1);
cursor_position--;
}
break;
case KEY_DC:
if (cursor_position >= 0 && cursor_position < len) {
memmove(&result[cursor_position],
&result[cursor_position+1],
len-cursor_position+1);
}
break;
case KEY_UP:
case KEY_RIGHT:
if (cursor_position < len &&
cursor_position < min(result_len, prompt_width))
cursor_position++;
break;
case KEY_DOWN:
case KEY_LEFT:
if (cursor_position > 0)
cursor_position--;
break;
default:
if ((isgraph(res) || isspace(res)) &&
len-2 < result_len) {
/* insert the char at the proper position */
memmove(&result[cursor_position+1],
&result[cursor_position],
len+1);
result[cursor_position] = res;
cursor_position++;
} else {
mvprintw(0, 0, "unknow key: %d\n", res);
}
break;
}
wmove(form_win, 0, 0);
wclrtoeol(form_win);
mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
mvwprintw(form_win, 0, 0, "%s", result);
wmove(form_win, 0, cursor_position);
touchwin(win);
refresh_all_windows(main_window);
if (res == 10) {
res = 0;
break;
} else if (res == 27 || res == KEY_F(F_BACK) ||
res == KEY_F(F_EXIT)) {
res = KEY_EXIT;
break;
} else if (res == KEY_F(F_HELP)) {
res = 1;
break;
}
}
/* hide the cursor */
curs_set(0);
del_panel(panel);
delwin(prompt_win);
delwin(form_win);
delwin(win);
return res;
}
/* refresh all windows in the correct order */
void refresh_all_windows(WINDOW *main_window)
{
update_panels();
touchwin(main_window);
refresh();
}
/* layman's scrollable window... */
void show_scroll_win(WINDOW *main_window,
const char *title,
const char *text)
{
int res;
int total_lines = get_line_no(text);
int x, y;
int start_x = 0, start_y = 0;
int text_lines = 0, text_cols = 0;
int total_cols = 0;
int win_cols = 0;
int win_lines = 0;
int i = 0;
WINDOW *win;
WINDOW *pad;
PANEL *panel;
/* find the widest line of msg: */
total_lines = get_line_no(text);
for (i = 0; i < total_lines; i++) {
const char *line = get_line(text, i);
int len = get_line_length(line);
total_cols = max(total_cols, len+2);
}
/* create the pad */
pad = newpad(total_lines+10, total_cols+10);
wattrset(pad, attributes[SCROLLWIN_TEXT]);
fill_window(pad, text);
win_lines = min(total_lines+4, LINES-2);
win_cols = min(total_cols+2, COLS-2);
text_lines = max(win_lines-4, 0);
text_cols = max(win_cols-2, 0);
/* place window in middle of screen */
y = (LINES-win_lines)/2;
x = (COLS-win_cols)/2;
win = newwin(win_lines, win_cols, y, x);
keypad(win, TRUE);
/* show the help in the help window, and show the help panel */
wattrset(win, attributes[SCROLLWIN_BOX]);
box(win, 0, 0);
wattrset(win, attributes[SCROLLWIN_HEADING]);
mvwprintw(win, 0, 3, " %s ", title);
panel = new_panel(win);
/* handle scrolling */
do {
copywin(pad, win, start_y, start_x, 2, 2, text_lines,
text_cols, 0);
print_in_middle(win,
text_lines+2,
0,
text_cols,
"<OK>",
attributes[DIALOG_MENU_FORE]);
wrefresh(win);
res = wgetch(win);
switch (res) {
case KEY_NPAGE:
case ' ':
start_y += text_lines-2;
break;
case KEY_PPAGE:
start_y -= text_lines+2;
break;
case KEY_HOME:
start_y = 0;
break;
case KEY_END:
start_y = total_lines-text_lines;
break;
case KEY_DOWN:
case 'j':
start_y++;
break;
case KEY_UP:
case 'k':
start_y--;
break;
case KEY_LEFT:
case 'h':
start_x--;
break;
case KEY_RIGHT:
case 'l':
start_x++;
break;
}
if (res == 10 || res == 27 || res == 'q'
|| res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) {
break;
}
if (start_y < 0)
start_y = 0;
if (start_y >= total_lines-text_lines)
start_y = total_lines-text_lines;
if (start_x < 0)
start_x = 0;
if (start_x >= total_cols-text_cols)
start_x = total_cols-text_cols;
} while (res);
del_panel(panel);
delwin(win);
refresh_all_windows(main_window);
}
/*
* Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com?
* Released under the terms of the GNU GPL v2.0.
*
* Derived from menuconfig.
*
*/
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <locale.h>
#include <curses.h>
#include <menu.h>
#include <panel.h>
#include <form.h>
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include "ncurses.h"
#define max(a, b) ({\
typeof(a) _a = a;\
typeof(b) _b = b;\
_a > _b ? _a : _b; })
#define min(a, b) ({\
typeof(a) _a = a;\
typeof(b) _b = b;\
_a < _b ? _a : _b; })
typedef enum {
NORMAL = 1,
MAIN_HEADING,
MAIN_MENU_BOX,
MAIN_MENU_FORE,
MAIN_MENU_BACK,
MAIN_MENU_GREY,
MAIN_MENU_HEADING,
SCROLLWIN_TEXT,
SCROLLWIN_HEADING,
SCROLLWIN_BOX,
DIALOG_TEXT,
DIALOG_MENU_FORE,
DIALOG_MENU_BACK,
DIALOG_BOX,
INPUT_BOX,
INPUT_HEADING,
INPUT_TEXT,
INPUT_FIELD,
FUNCTION_TEXT,
FUNCTION_HIGHLIGHT,
ATTR_MAX
} attributes_t;
extern attributes_t attributes[];
typedef enum {
F_HELP = 1,
F_SYMBOL = 2,
F_INSTS = 3,
F_CONF = 4,
F_BACK = 5,
F_SAVE = 6,
F_LOAD = 7,
F_EXIT = 8
} function_key;
void set_colors(void);
/* this changes the windows attributes !!! */
void print_in_middle(WINDOW *win,
int starty,
int startx,
int width,
const char *string,
chtype color);
int get_line_length(const char *line);
int get_line_no(const char *text);
const char *get_line(const char *text, int line_no);
void fill_window(WINDOW *win, const char *text);
int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...);
int dialog_inputbox(WINDOW *main_window,
const char *title, const char *prompt,
const char *init, char *result, int result_len);
void refresh_all_windows(WINDOW *main_window);
void show_scroll_win(WINDOW *main_window,
const char *title,
const char *text);
...@@ -651,12 +651,20 @@ bool sym_is_changable(struct symbol *sym) ...@@ -651,12 +651,20 @@ bool sym_is_changable(struct symbol *sym)
return sym->visible > sym->rev_dep.tri; return sym->visible > sym->rev_dep.tri;
} }
static unsigned strhash(const char *s)
{
/* fnv32 hash */
unsigned hash = 2166136261U;
for (; *s; s++)
hash = (hash ^ *s) * 0x01000193;
return hash;
}
struct symbol *sym_lookup(const char *name, int flags) struct symbol *sym_lookup(const char *name, int flags)
{ {
struct symbol *symbol; struct symbol *symbol;
const char *ptr;
char *new_name; char *new_name;
int hash = 0; int hash;
if (name) { if (name) {
if (name[0] && !name[1]) { if (name[0] && !name[1]) {
...@@ -666,12 +674,11 @@ struct symbol *sym_lookup(const char *name, int flags) ...@@ -666,12 +674,11 @@ struct symbol *sym_lookup(const char *name, int flags)
case 'n': return &symbol_no; case 'n': return &symbol_no;
} }
} }
for (ptr = name; *ptr; ptr++) hash = strhash(name) % SYMBOL_HASHSIZE;
hash += *ptr;
hash &= 0xff;
for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
if (!strcmp(symbol->name, name) && if (symbol->name &&
!strcmp(symbol->name, name) &&
(flags ? symbol->flags & flags (flags ? symbol->flags & flags
: !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE)))) : !(symbol->flags & (SYMBOL_CONST|SYMBOL_CHOICE))))
return symbol; return symbol;
...@@ -679,7 +686,7 @@ struct symbol *sym_lookup(const char *name, int flags) ...@@ -679,7 +686,7 @@ struct symbol *sym_lookup(const char *name, int flags)
new_name = strdup(name); new_name = strdup(name);
} else { } else {
new_name = NULL; new_name = NULL;
hash = 256; hash = 0;
} }
symbol = malloc(sizeof(*symbol)); symbol = malloc(sizeof(*symbol));
...@@ -697,7 +704,6 @@ struct symbol *sym_lookup(const char *name, int flags) ...@@ -697,7 +704,6 @@ struct symbol *sym_lookup(const char *name, int flags)
struct symbol *sym_find(const char *name) struct symbol *sym_find(const char *name)
{ {
struct symbol *symbol = NULL; struct symbol *symbol = NULL;
const char *ptr;
int hash = 0; int hash = 0;
if (!name) if (!name)
...@@ -710,12 +716,11 @@ struct symbol *sym_find(const char *name) ...@@ -710,12 +716,11 @@ struct symbol *sym_find(const char *name)
case 'n': return &symbol_no; case 'n': return &symbol_no;
} }
} }
for (ptr = name; *ptr; ptr++) hash = strhash(name) % SYMBOL_HASHSIZE;
hash += *ptr;
hash &= 0xff;
for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
if (!strcmp(symbol->name, name) && if (symbol->name &&
!strcmp(symbol->name, name) &&
!(symbol->flags & SYMBOL_CONST)) !(symbol->flags & SYMBOL_CONST))
break; break;
} }
...@@ -750,6 +755,7 @@ struct symbol **sym_re_search(const char *pattern) ...@@ -750,6 +755,7 @@ struct symbol **sym_re_search(const char *pattern)
return NULL; return NULL;
} }
} }
sym_calc_value(sym);
sym_arr[cnt++] = sym; sym_arr[cnt++] = sym;
} }
if (sym_arr) if (sym_arr)
......
...@@ -78,6 +78,7 @@ struct gstr str_new(void) ...@@ -78,6 +78,7 @@ struct gstr str_new(void)
struct gstr gs; struct gstr gs;
gs.s = malloc(sizeof(char) * 64); gs.s = malloc(sizeof(char) * 64);
gs.len = 64; gs.len = 64;
gs.max_width = 0;
strcpy(gs.s, "\0"); strcpy(gs.s, "\0");
return gs; return gs;
} }
...@@ -88,6 +89,7 @@ struct gstr str_assign(const char *s) ...@@ -88,6 +89,7 @@ struct gstr str_assign(const char *s)
struct gstr gs; struct gstr gs;
gs.s = strdup(s); gs.s = strdup(s);
gs.len = strlen(s) + 1; gs.len = strlen(s) + 1;
gs.max_width = 0;
return gs; return gs;
} }
......
...@@ -104,7 +104,7 @@ static void zconf_error(const char *err, ...); ...@@ -104,7 +104,7 @@ static void zconf_error(const char *err, ...);
static void zconferror(const char *err); static void zconferror(const char *err);
static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken); static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
struct symbol *symbol_hash[257]; struct symbol *symbol_hash[SYMBOL_HASHSIZE];
static struct menu *current_menu, *current_entry; static struct menu *current_menu, *current_entry;
...@@ -2220,7 +2220,7 @@ void conf_parse(const char *name) ...@@ -2220,7 +2220,7 @@ void conf_parse(const char *name)
zconf_initscan(name); zconf_initscan(name);
sym_init(); sym_init();
menu_init(); _menu_init();
modules_sym = sym_lookup(NULL, 0); modules_sym = sym_lookup(NULL, 0);
modules_sym->type = S_BOOLEAN; modules_sym->type = S_BOOLEAN;
modules_sym->flags |= SYMBOL_AUTO; modules_sym->flags |= SYMBOL_AUTO;
...@@ -2336,9 +2336,9 @@ static void print_symbol(FILE *out, struct menu *menu) ...@@ -2336,9 +2336,9 @@ static void print_symbol(FILE *out, struct menu *menu)
struct property *prop; struct property *prop;
if (sym_is_choice(sym)) if (sym_is_choice(sym))
fprintf(out, "choice\n"); fprintf(out, "\nchoice\n");
else else
fprintf(out, "config %s\n", sym->name); fprintf(out, "\nconfig %s\n", sym->name);
switch (sym->type) { switch (sym->type) {
case S_BOOLEAN: case S_BOOLEAN:
fputs(" boolean\n", out); fputs(" boolean\n", out);
...@@ -2384,6 +2384,21 @@ static void print_symbol(FILE *out, struct menu *menu) ...@@ -2384,6 +2384,21 @@ static void print_symbol(FILE *out, struct menu *menu)
case P_CHOICE: case P_CHOICE:
fputs(" #choice value\n", out); fputs(" #choice value\n", out);
break; break;
case P_SELECT:
fputs( " select ", out);
expr_fprint(prop->expr, out);
fputc('\n', out);
break;
case P_RANGE:
fputs( " range ", out);
expr_fprint(prop->expr, out);
fputc('\n', out);
break;
case P_MENU:
fputs( " menu ", out);
print_quoted_string(out, prop->text);
fputc('\n', out);
break;
default: default:
fprintf(out, " unknown prop %d!\n", prop->type); fprintf(out, " unknown prop %d!\n", prop->type);
break; break;
...@@ -2395,7 +2410,6 @@ static void print_symbol(FILE *out, struct menu *menu) ...@@ -2395,7 +2410,6 @@ static void print_symbol(FILE *out, struct menu *menu)
menu->help[len] = 0; menu->help[len] = 0;
fprintf(out, " help\n%s\n", menu->help); fprintf(out, " help\n%s\n", menu->help);
} }
fputc('\n', out);
} }
void zconfdump(FILE *out) void zconfdump(FILE *out)
...@@ -2428,7 +2442,6 @@ void zconfdump(FILE *out) ...@@ -2428,7 +2442,6 @@ void zconfdump(FILE *out)
expr_fprint(prop->visible.expr, out); expr_fprint(prop->visible.expr, out);
fputc('\n', out); fputc('\n', out);
} }
fputs("\n", out);
} }
if (menu->list) if (menu->list)
......
...@@ -27,7 +27,7 @@ static void zconf_error(const char *err, ...); ...@@ -27,7 +27,7 @@ static void zconf_error(const char *err, ...);
static void zconferror(const char *err); static void zconferror(const char *err);
static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken); static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
struct symbol *symbol_hash[257]; struct symbol *symbol_hash[SYMBOL_HASHSIZE];
static struct menu *current_menu, *current_entry; static struct menu *current_menu, *current_entry;
...@@ -475,7 +475,7 @@ void conf_parse(const char *name) ...@@ -475,7 +475,7 @@ void conf_parse(const char *name)
zconf_initscan(name); zconf_initscan(name);
sym_init(); sym_init();
menu_init(); _menu_init();
modules_sym = sym_lookup(NULL, 0); modules_sym = sym_lookup(NULL, 0);
modules_sym->type = S_BOOLEAN; modules_sym->type = S_BOOLEAN;
modules_sym->flags |= SYMBOL_AUTO; modules_sym->flags |= SYMBOL_AUTO;
...@@ -591,9 +591,9 @@ static void print_symbol(FILE *out, struct menu *menu) ...@@ -591,9 +591,9 @@ static void print_symbol(FILE *out, struct menu *menu)
struct property *prop; struct property *prop;
if (sym_is_choice(sym)) if (sym_is_choice(sym))
fprintf(out, "choice\n"); fprintf(out, "\nchoice\n");
else else
fprintf(out, "config %s\n", sym->name); fprintf(out, "\nconfig %s\n", sym->name);
switch (sym->type) { switch (sym->type) {
case S_BOOLEAN: case S_BOOLEAN:
fputs(" boolean\n", out); fputs(" boolean\n", out);
...@@ -639,6 +639,21 @@ static void print_symbol(FILE *out, struct menu *menu) ...@@ -639,6 +639,21 @@ static void print_symbol(FILE *out, struct menu *menu)
case P_CHOICE: case P_CHOICE:
fputs(" #choice value\n", out); fputs(" #choice value\n", out);
break; break;
case P_SELECT:
fputs( " select ", out);
expr_fprint(prop->expr, out);
fputc('\n', out);
break;
case P_RANGE:
fputs( " range ", out);
expr_fprint(prop->expr, out);
fputc('\n', out);
break;
case P_MENU:
fputs( " menu ", out);
print_quoted_string(out, prop->text);
fputc('\n', out);
break;
default: default:
fprintf(out, " unknown prop %d!\n", prop->type); fprintf(out, " unknown prop %d!\n", prop->type);
break; break;
...@@ -650,7 +665,6 @@ static void print_symbol(FILE *out, struct menu *menu) ...@@ -650,7 +665,6 @@ static void print_symbol(FILE *out, struct menu *menu)
menu->help[len] = 0; menu->help[len] = 0;
fprintf(out, " help\n%s\n", menu->help); fprintf(out, " help\n%s\n", menu->help);
} }
fputc('\n', out);
} }
void zconfdump(FILE *out) void zconfdump(FILE *out)
...@@ -683,7 +697,6 @@ void zconfdump(FILE *out) ...@@ -683,7 +697,6 @@ void zconfdump(FILE *out)
expr_fprint(prop->visible.expr, out); expr_fprint(prop->visible.expr, out);
fputc('\n', out); fputc('\n', out);
} }
fputs("\n", out);
} }
if (menu->list) if (menu->list)
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
use File::Basename; use File::Basename;
use Math::BigInt; use Math::BigInt;
use Getopt::Long;
# Copyright 2008, Intel Corporation # Copyright 2008, Intel Corporation
# #
...@@ -15,6 +16,16 @@ use Math::BigInt; ...@@ -15,6 +16,16 @@ use Math::BigInt;
# Arjan van de Ven <arjan@linux.intel.com> # Arjan van de Ven <arjan@linux.intel.com>
my $cross_compile = "";
my $vmlinux_name = "";
my $modulefile = "";
# Get options
Getopt::Long::GetOptions(
'cross-compile|c=s' => \$cross_compile,
'module|m=s' => \$modulefile,
'help|h' => \&usage,
) || usage ();
my $vmlinux_name = $ARGV[0]; my $vmlinux_name = $ARGV[0];
if (!defined($vmlinux_name)) { if (!defined($vmlinux_name)) {
my $kerver = `uname -r`; my $kerver = `uname -r`;
...@@ -23,9 +34,8 @@ if (!defined($vmlinux_name)) { ...@@ -23,9 +34,8 @@ if (!defined($vmlinux_name)) {
print "No vmlinux specified, assuming $vmlinux_name\n"; print "No vmlinux specified, assuming $vmlinux_name\n";
} }
my $filename = $vmlinux_name; my $filename = $vmlinux_name;
#
# Step 1: Parse the oops to find the EIP value # Parse the oops to find the EIP value
#
my $target = "0"; my $target = "0";
my $function; my $function;
...@@ -177,26 +187,26 @@ my $decodestart = Math::BigInt->from_hex("0x$target") - Math::BigInt->from_hex(" ...@@ -177,26 +187,26 @@ my $decodestart = Math::BigInt->from_hex("0x$target") - Math::BigInt->from_hex("
my $decodestop = Math::BigInt->from_hex("0x$target") + 8192; my $decodestop = Math::BigInt->from_hex("0x$target") + 8192;
if ($target eq "0") { if ($target eq "0") {
print "No oops found!\n"; print "No oops found!\n";
print "Usage: \n"; usage();
print " dmesg | perl scripts/markup_oops.pl vmlinux\n";
exit;
} }
# if it's a module, we need to find the .ko file and calculate a load offset # if it's a module, we need to find the .ko file and calculate a load offset
if ($module ne "") { if ($module ne "") {
my $modulefile = `modinfo $module | grep '^filename:' | awk '{ print \$2 }'`; if ($modulefile eq "") {
chomp($modulefile); $modulefile = `modinfo -F filename $module`;
chomp($modulefile);
}
$filename = $modulefile; $filename = $modulefile;
if ($filename eq "") { if ($filename eq "") {
print "Module .ko file for $module not found. Aborting\n"; print "Module .ko file for $module not found. Aborting\n";
exit; exit;
} }
# ok so we found the module, now we need to calculate the vma offset # ok so we found the module, now we need to calculate the vma offset
open(FILE, "objdump -dS $filename |") || die "Cannot start objdump"; open(FILE, $cross_compile."objdump -dS $filename |") || die "Cannot start objdump";
while (<FILE>) { while (<FILE>) {
if ($_ =~ /^([0-9a-f]+) \<$function\>\:/) { if ($_ =~ /^([0-9a-f]+) \<$function\>\:/) {
my $fu = $1; my $fu = $1;
$vmaoffset = hex($target) - hex($fu) - hex($func_offset); $vmaoffset = Math::BigInt->from_hex("0x$target") - Math::BigInt->from_hex("0x$fu") - Math::BigInt->from_hex("0x$func_offset");
} }
} }
close(FILE); close(FILE);
...@@ -204,7 +214,7 @@ if ($module ne "") { ...@@ -204,7 +214,7 @@ if ($module ne "") {
my $counter = 0; my $counter = 0;
my $state = 0; my $state = 0;
my $center = 0; my $center = -1;
my @lines; my @lines;
my @reglines; my @reglines;
...@@ -212,7 +222,7 @@ sub InRange { ...@@ -212,7 +222,7 @@ sub InRange {
my ($address, $target) = @_; my ($address, $target) = @_;
my $ad = "0x".$address; my $ad = "0x".$address;
my $ta = "0x".$target; my $ta = "0x".$target;
my $delta = hex($ad) - hex($ta); my $delta = Math::BigInt->from_hex($ad) - Math::BigInt->from_hex($ta);
if (($delta > -4096) && ($delta < 4096)) { if (($delta > -4096) && ($delta < 4096)) {
return 1; return 1;
...@@ -225,7 +235,7 @@ sub InRange { ...@@ -225,7 +235,7 @@ sub InRange {
# first, parse the input into the lines array, but to keep size down, # first, parse the input into the lines array, but to keep size down,
# we only do this for 4Kb around the sweet spot # we only do this for 4Kb around the sweet spot
open(FILE, "objdump -dS --adjust-vma=$vmaoffset --start-address=$decodestart --stop-address=$decodestop $filename |") || die "Cannot start objdump"; open(FILE, $cross_compile."objdump -dS --adjust-vma=$vmaoffset --start-address=$decodestart --stop-address=$decodestop $filename |") || die "Cannot start objdump";
while (<FILE>) { while (<FILE>) {
my $line = $_; my $line = $_;
...@@ -236,7 +246,8 @@ while (<FILE>) { ...@@ -236,7 +246,8 @@ while (<FILE>) {
$state = 1; $state = 1;
} }
} }
} else { }
if ($state == 1) {
if ($line =~ /^([a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]+)\:/) { if ($line =~ /^([a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]+)\:/) {
my $val = $1; my $val = $1;
if (!InRange($val, $target)) { if (!InRange($val, $target)) {
...@@ -259,7 +270,7 @@ if ($counter == 0) { ...@@ -259,7 +270,7 @@ if ($counter == 0) {
exit; exit;
} }
if ($center == 0) { if ($center == -1) {
print "No matching code found \n"; print "No matching code found \n";
exit; exit;
} }
...@@ -344,3 +355,16 @@ while ($i < $finish) { ...@@ -344,3 +355,16 @@ while ($i < $finish) {
$i = $i +1; $i = $i +1;
} }
sub usage {
print <<EOT;
Usage:
dmesg | perl $0 [OPTION] [VMLINUX]
OPTION:
-c, --cross-compile CROSS_COMPILE Specify the prefix used for toolchain.
-m, --module MODULE_DIRNAME Specify the module filename.
-h, --help Help.
EOT
exit;
}
...@@ -67,9 +67,8 @@ UTS_TRUNCATE="cut -b -$UTS_LEN" ...@@ -67,9 +67,8 @@ UTS_TRUNCATE="cut -b -$UTS_LEN"
echo \#define LINUX_COMPILE_BY \"`whoami`\" echo \#define LINUX_COMPILE_BY \"`whoami`\"
echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\" echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\"
if [ -x /bin/dnsdomainname ]; then domain=`dnsdomainname 2> /dev/null`
domain=`dnsdomainname 2> /dev/null` if [ -z "$domain" ]; then
elif [ -x /bin/domainname ]; then
domain=`domainname 2> /dev/null` domain=`domainname 2> /dev/null`
fi fi
......
...@@ -781,10 +781,13 @@ static void check_section(const char *modname, struct elf_info *elf, ...@@ -781,10 +781,13 @@ static void check_section(const char *modname, struct elf_info *elf,
#define ALL_EXIT_TEXT_SECTIONS \ #define ALL_EXIT_TEXT_SECTIONS \
".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$" ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$"
#define ALL_INIT_SECTIONS INIT_SECTIONS, DEV_INIT_SECTIONS, \ #define ALL_XXXINIT_SECTIONS DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, \
CPU_INIT_SECTIONS, MEM_INIT_SECTIONS MEM_INIT_SECTIONS
#define ALL_EXIT_SECTIONS EXIT_SECTIONS, DEV_EXIT_SECTIONS, \ #define ALL_XXXEXIT_SECTIONS DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, \
CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS MEM_EXIT_SECTIONS
#define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS
#define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS
#define DATA_SECTIONS ".data$", ".data.rel$" #define DATA_SECTIONS ".data$", ".data.rel$"
#define TEXT_SECTIONS ".text$" #define TEXT_SECTIONS ".text$"
...@@ -814,33 +817,29 @@ static const char *data_sections[] = { DATA_SECTIONS, NULL }; ...@@ -814,33 +817,29 @@ static const char *data_sections[] = { DATA_SECTIONS, NULL };
/* symbols in .data that may refer to init/exit sections */ /* symbols in .data that may refer to init/exit sections */
static const char *symbol_white_list[] = #define DEFAULT_SYMBOL_WHITE_LIST \
{ "*driver", \
"*driver", "*_template", /* scsi uses *_template a lot */ \
"*_template", /* scsi uses *_template a lot */ "*_timer", /* arm uses ops structures named _timer a lot */ \
"*_timer", /* arm uses ops structures named _timer a lot */ "*_sht", /* scsi also used *_sht to some extent */ \
"*_sht", /* scsi also used *_sht to some extent */ "*_ops", \
"*_ops", "*_probe", \
"*_probe", "*_probe_one", \
"*_probe_one", "*_console"
"*_console",
NULL
};
static const char *head_sections[] = { ".head.text*", NULL }; static const char *head_sections[] = { ".head.text*", NULL };
static const char *linker_symbols[] = static const char *linker_symbols[] =
{ "__init_begin", "_sinittext", "_einittext", NULL }; { "__init_begin", "_sinittext", "_einittext", NULL };
enum mismatch { enum mismatch {
NO_MISMATCH, TEXT_TO_ANY_INIT,
TEXT_TO_INIT, DATA_TO_ANY_INIT,
DATA_TO_INIT, TEXT_TO_ANY_EXIT,
TEXT_TO_EXIT, DATA_TO_ANY_EXIT,
DATA_TO_EXIT, XXXINIT_TO_SOME_INIT,
XXXINIT_TO_INIT, XXXEXIT_TO_SOME_EXIT,
XXXEXIT_TO_EXIT, ANY_INIT_TO_ANY_EXIT,
INIT_TO_EXIT, ANY_EXIT_TO_ANY_INIT,
EXIT_TO_INIT,
EXPORT_TO_INIT_EXIT, EXPORT_TO_INIT_EXIT,
}; };
...@@ -848,6 +847,7 @@ struct sectioncheck { ...@@ -848,6 +847,7 @@ struct sectioncheck {
const char *fromsec[20]; const char *fromsec[20];
const char *tosec[20]; const char *tosec[20];
enum mismatch mismatch; enum mismatch mismatch;
const char *symbol_white_list[20];
}; };
const struct sectioncheck sectioncheck[] = { const struct sectioncheck sectioncheck[] = {
...@@ -857,80 +857,103 @@ const struct sectioncheck sectioncheck[] = { ...@@ -857,80 +857,103 @@ const struct sectioncheck sectioncheck[] = {
{ {
.fromsec = { TEXT_SECTIONS, NULL }, .fromsec = { TEXT_SECTIONS, NULL },
.tosec = { ALL_INIT_SECTIONS, NULL }, .tosec = { ALL_INIT_SECTIONS, NULL },
.mismatch = TEXT_TO_INIT, .mismatch = TEXT_TO_ANY_INIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
}, },
{ {
.fromsec = { DATA_SECTIONS, NULL }, .fromsec = { DATA_SECTIONS, NULL },
.tosec = { ALL_INIT_SECTIONS, NULL }, .tosec = { ALL_XXXINIT_SECTIONS, NULL },
.mismatch = DATA_TO_INIT, .mismatch = DATA_TO_ANY_INIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
},
{
.fromsec = { DATA_SECTIONS, NULL },
.tosec = { INIT_SECTIONS, NULL },
.mismatch = DATA_TO_ANY_INIT,
.symbol_white_list = {
"*_template", "*_timer", "*_sht", "*_ops",
"*_probe", "*_probe_one", "*_console", NULL
},
}, },
{ {
.fromsec = { TEXT_SECTIONS, NULL }, .fromsec = { TEXT_SECTIONS, NULL },
.tosec = { ALL_EXIT_SECTIONS, NULL }, .tosec = { ALL_EXIT_SECTIONS, NULL },
.mismatch = TEXT_TO_EXIT, .mismatch = TEXT_TO_ANY_EXIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
}, },
{ {
.fromsec = { DATA_SECTIONS, NULL }, .fromsec = { DATA_SECTIONS, NULL },
.tosec = { ALL_EXIT_SECTIONS, NULL }, .tosec = { ALL_EXIT_SECTIONS, NULL },
.mismatch = DATA_TO_EXIT, .mismatch = DATA_TO_ANY_EXIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
}, },
/* Do not reference init code/data from devinit/cpuinit/meminit code/data */ /* Do not reference init code/data from devinit/cpuinit/meminit code/data */
{ {
.fromsec = { DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, MEM_INIT_SECTIONS, NULL }, .fromsec = { ALL_XXXINIT_SECTIONS, NULL },
.tosec = { INIT_SECTIONS, NULL }, .tosec = { INIT_SECTIONS, NULL },
.mismatch = XXXINIT_TO_INIT, .mismatch = XXXINIT_TO_SOME_INIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
}, },
/* Do not reference cpuinit code/data from meminit code/data */ /* Do not reference cpuinit code/data from meminit code/data */
{ {
.fromsec = { MEM_INIT_SECTIONS, NULL }, .fromsec = { MEM_INIT_SECTIONS, NULL },
.tosec = { CPU_INIT_SECTIONS, NULL }, .tosec = { CPU_INIT_SECTIONS, NULL },
.mismatch = XXXINIT_TO_INIT, .mismatch = XXXINIT_TO_SOME_INIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
}, },
/* Do not reference meminit code/data from cpuinit code/data */ /* Do not reference meminit code/data from cpuinit code/data */
{ {
.fromsec = { CPU_INIT_SECTIONS, NULL }, .fromsec = { CPU_INIT_SECTIONS, NULL },
.tosec = { MEM_INIT_SECTIONS, NULL }, .tosec = { MEM_INIT_SECTIONS, NULL },
.mismatch = XXXINIT_TO_INIT, .mismatch = XXXINIT_TO_SOME_INIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
}, },
/* Do not reference exit code/data from devexit/cpuexit/memexit code/data */ /* Do not reference exit code/data from devexit/cpuexit/memexit code/data */
{ {
.fromsec = { DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS, NULL }, .fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
.tosec = { EXIT_SECTIONS, NULL }, .tosec = { EXIT_SECTIONS, NULL },
.mismatch = XXXEXIT_TO_EXIT, .mismatch = XXXEXIT_TO_SOME_EXIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
}, },
/* Do not reference cpuexit code/data from memexit code/data */ /* Do not reference cpuexit code/data from memexit code/data */
{ {
.fromsec = { MEM_EXIT_SECTIONS, NULL }, .fromsec = { MEM_EXIT_SECTIONS, NULL },
.tosec = { CPU_EXIT_SECTIONS, NULL }, .tosec = { CPU_EXIT_SECTIONS, NULL },
.mismatch = XXXEXIT_TO_EXIT, .mismatch = XXXEXIT_TO_SOME_EXIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
}, },
/* Do not reference memexit code/data from cpuexit code/data */ /* Do not reference memexit code/data from cpuexit code/data */
{ {
.fromsec = { CPU_EXIT_SECTIONS, NULL }, .fromsec = { CPU_EXIT_SECTIONS, NULL },
.tosec = { MEM_EXIT_SECTIONS, NULL }, .tosec = { MEM_EXIT_SECTIONS, NULL },
.mismatch = XXXEXIT_TO_EXIT, .mismatch = XXXEXIT_TO_SOME_EXIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
}, },
/* Do not use exit code/data from init code */ /* Do not use exit code/data from init code */
{ {
.fromsec = { ALL_INIT_SECTIONS, NULL }, .fromsec = { ALL_INIT_SECTIONS, NULL },
.tosec = { ALL_EXIT_SECTIONS, NULL }, .tosec = { ALL_EXIT_SECTIONS, NULL },
.mismatch = INIT_TO_EXIT, .mismatch = ANY_INIT_TO_ANY_EXIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
}, },
/* Do not use init code/data from exit code */ /* Do not use init code/data from exit code */
{ {
.fromsec = { ALL_EXIT_SECTIONS, NULL }, .fromsec = { ALL_EXIT_SECTIONS, NULL },
.tosec = { ALL_INIT_SECTIONS, NULL }, .tosec = { ALL_INIT_SECTIONS, NULL },
.mismatch = EXIT_TO_INIT, .mismatch = ANY_EXIT_TO_ANY_INIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
}, },
/* Do not export init/exit functions or data */ /* Do not export init/exit functions or data */
{ {
.fromsec = { "__ksymtab*", NULL }, .fromsec = { "__ksymtab*", NULL },
.tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL }, .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
.mismatch = EXPORT_TO_INIT_EXIT .mismatch = EXPORT_TO_INIT_EXIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
} }
}; };
static int section_mismatch(const char *fromsec, const char *tosec) static const struct sectioncheck *section_mismatch(
const char *fromsec, const char *tosec)
{ {
int i; int i;
int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck); int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck);
...@@ -939,10 +962,10 @@ static int section_mismatch(const char *fromsec, const char *tosec) ...@@ -939,10 +962,10 @@ static int section_mismatch(const char *fromsec, const char *tosec)
for (i = 0; i < elems; i++) { for (i = 0; i < elems; i++) {
if (match(fromsec, check->fromsec) && if (match(fromsec, check->fromsec) &&
match(tosec, check->tosec)) match(tosec, check->tosec))
return check->mismatch; return check;
check++; check++;
} }
return NO_MISMATCH; return NULL;
} }
/** /**
...@@ -961,7 +984,7 @@ static int section_mismatch(const char *fromsec, const char *tosec) ...@@ -961,7 +984,7 @@ static int section_mismatch(const char *fromsec, const char *tosec)
* Pattern 2: * Pattern 2:
* Many drivers utilise a *driver container with references to * Many drivers utilise a *driver container with references to
* add, remove, probe functions etc. * add, remove, probe functions etc.
* These functions may often be marked __init and we do not want to * These functions may often be marked __devinit and we do not want to
* warn here. * warn here.
* the pattern is identified by: * the pattern is identified by:
* tosec = init or exit section * tosec = init or exit section
...@@ -982,7 +1005,8 @@ static int section_mismatch(const char *fromsec, const char *tosec) ...@@ -982,7 +1005,8 @@ static int section_mismatch(const char *fromsec, const char *tosec)
* refsymname = __init_begin, _sinittext, _einittext * refsymname = __init_begin, _sinittext, _einittext
* *
**/ **/
static int secref_whitelist(const char *fromsec, const char *fromsym, static int secref_whitelist(const struct sectioncheck *mismatch,
const char *fromsec, const char *fromsym,
const char *tosec, const char *tosym) const char *tosec, const char *tosym)
{ {
/* Check for pattern 1 */ /* Check for pattern 1 */
...@@ -994,7 +1018,7 @@ static int secref_whitelist(const char *fromsec, const char *fromsym, ...@@ -994,7 +1018,7 @@ static int secref_whitelist(const char *fromsec, const char *fromsym,
/* Check for pattern 2 */ /* Check for pattern 2 */
if (match(tosec, init_exit_sections) && if (match(tosec, init_exit_sections) &&
match(fromsec, data_sections) && match(fromsec, data_sections) &&
match(fromsym, symbol_white_list)) match(fromsym, mismatch->symbol_white_list))
return 0; return 0;
/* Check for pattern 3 */ /* Check for pattern 3 */
...@@ -1155,7 +1179,8 @@ static int is_function(Elf_Sym *sym) ...@@ -1155,7 +1179,8 @@ static int is_function(Elf_Sym *sym)
* Try to find symbols near it so user can find it. * Try to find symbols near it so user can find it.
* Check whitelist before warning - it may be a false positive. * Check whitelist before warning - it may be a false positive.
*/ */
static void report_sec_mismatch(const char *modname, enum mismatch mismatch, static void report_sec_mismatch(const char *modname,
const struct sectioncheck *mismatch,
const char *fromsec, const char *fromsec,
unsigned long long fromaddr, unsigned long long fromaddr,
const char *fromsym, const char *fromsym,
...@@ -1186,8 +1211,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, ...@@ -1186,8 +1211,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec, modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec,
tosym, to_p); tosym, to_p);
switch (mismatch) { switch (mismatch->mismatch) {
case TEXT_TO_INIT: case TEXT_TO_ANY_INIT:
fprintf(stderr, fprintf(stderr,
"The function %s%s() references\n" "The function %s%s() references\n"
"the %s %s%s%s.\n" "the %s %s%s%s.\n"
...@@ -1197,8 +1222,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, ...@@ -1197,8 +1222,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
to, sec2annotation(tosec), tosym, to_p, to, sec2annotation(tosec), tosym, to_p,
fromsym, sec2annotation(tosec), tosym); fromsym, sec2annotation(tosec), tosym);
break; break;
case DATA_TO_INIT: { case DATA_TO_ANY_INIT: {
const char **s = symbol_white_list; const char *const *s = mismatch->symbol_white_list;
fprintf(stderr, fprintf(stderr,
"The variable %s references\n" "The variable %s references\n"
"the %s %s%s%s\n" "the %s %s%s%s\n"
...@@ -1211,15 +1236,15 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, ...@@ -1211,15 +1236,15 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
fprintf(stderr, "\n"); fprintf(stderr, "\n");
break; break;
} }
case TEXT_TO_EXIT: case TEXT_TO_ANY_EXIT:
fprintf(stderr, fprintf(stderr,
"The function %s() references a %s in an exit section.\n" "The function %s() references a %s in an exit section.\n"
"Often the %s %s%s has valid usage outside the exit section\n" "Often the %s %s%s has valid usage outside the exit section\n"
"and the fix is to remove the %sannotation of %s.\n", "and the fix is to remove the %sannotation of %s.\n",
fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym); fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym);
break; break;
case DATA_TO_EXIT: { case DATA_TO_ANY_EXIT: {
const char **s = symbol_white_list; const char *const *s = mismatch->symbol_white_list;
fprintf(stderr, fprintf(stderr,
"The variable %s references\n" "The variable %s references\n"
"the %s %s%s%s\n" "the %s %s%s%s\n"
...@@ -1232,8 +1257,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, ...@@ -1232,8 +1257,8 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
fprintf(stderr, "\n"); fprintf(stderr, "\n");
break; break;
} }
case XXXINIT_TO_INIT: case XXXINIT_TO_SOME_INIT:
case XXXEXIT_TO_EXIT: case XXXEXIT_TO_SOME_EXIT:
fprintf(stderr, fprintf(stderr,
"The %s %s%s%s references\n" "The %s %s%s%s references\n"
"a %s %s%s%s.\n" "a %s %s%s%s.\n"
...@@ -1243,7 +1268,7 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, ...@@ -1243,7 +1268,7 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
to, sec2annotation(tosec), tosym, to_p, to, sec2annotation(tosec), tosym, to_p,
tosym, fromsym, tosym); tosym, fromsym, tosym);
break; break;
case INIT_TO_EXIT: case ANY_INIT_TO_ANY_EXIT:
fprintf(stderr, fprintf(stderr,
"The %s %s%s%s references\n" "The %s %s%s%s references\n"
"a %s %s%s%s.\n" "a %s %s%s%s.\n"
...@@ -1256,7 +1281,7 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, ...@@ -1256,7 +1281,7 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
to, sec2annotation(tosec), tosym, to_p, to, sec2annotation(tosec), tosym, to_p,
sec2annotation(tosec), tosym, to_p); sec2annotation(tosec), tosym, to_p);
break; break;
case EXIT_TO_INIT: case ANY_EXIT_TO_ANY_INIT:
fprintf(stderr, fprintf(stderr,
"The %s %s%s%s references\n" "The %s %s%s%s references\n"
"a %s %s%s%s.\n" "a %s %s%s%s.\n"
...@@ -1275,8 +1300,6 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch, ...@@ -1275,8 +1300,6 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
"Fix this by removing the %sannotation of %s " "Fix this by removing the %sannotation of %s "
"or drop the export.\n", "or drop the export.\n",
tosym, sec2annotation(tosec), sec2annotation(tosec), tosym); tosym, sec2annotation(tosec), sec2annotation(tosec), tosym);
case NO_MISMATCH:
/* To get warnings on missing members */
break; break;
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
...@@ -1286,11 +1309,11 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf, ...@@ -1286,11 +1309,11 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf,
Elf_Rela *r, Elf_Sym *sym, const char *fromsec) Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
{ {
const char *tosec; const char *tosec;
enum mismatch mismatch; const struct sectioncheck *mismatch;
tosec = sec_name(elf, sym->st_shndx); tosec = sec_name(elf, sym->st_shndx);
mismatch = section_mismatch(fromsec, tosec); mismatch = section_mismatch(fromsec, tosec);
if (mismatch != NO_MISMATCH) { if (mismatch) {
Elf_Sym *to; Elf_Sym *to;
Elf_Sym *from; Elf_Sym *from;
const char *tosym; const char *tosym;
...@@ -1302,7 +1325,8 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf, ...@@ -1302,7 +1325,8 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf,
tosym = sym_name(elf, to); tosym = sym_name(elf, to);
/* check whitelist - we may ignore it */ /* check whitelist - we may ignore it */
if (secref_whitelist(fromsec, fromsym, tosec, tosym)) { if (secref_whitelist(mismatch,
fromsec, fromsym, tosec, tosym)) {
report_sec_mismatch(modname, mismatch, report_sec_mismatch(modname, mismatch,
fromsec, r->r_offset, fromsym, fromsec, r->r_offset, fromsym,
is_function(from), tosec, tosym, is_function(from), tosec, tosym,
......
...@@ -175,12 +175,11 @@ sub do_nm ...@@ -175,12 +175,11 @@ sub do_nm
} }
if (! -e "$source.c" && ! -e "$source.S") { if (! -e "$source.c" && ! -e "$source.S") {
# No obvious source, exclude the object if it is conglomerate # No obvious source, exclude the object if it is conglomerate
if (! open(OBJDUMPDATA, "$objdump $basename|")) { open(my $objdumpdata, "$objdump $basename|")
printf STDERR "$objdump $fullname failed $!\n"; or die "$objdump $fullname failed $!\n";
return;
}
my $comment; my $comment;
while (<OBJDUMPDATA>) { while (<$objdumpdata>) {
chomp(); chomp();
if (/^In archive/) { if (/^In archive/) {
# Archives are always conglomerate # Archives are always conglomerate
...@@ -190,18 +189,18 @@ sub do_nm ...@@ -190,18 +189,18 @@ sub do_nm
next if (! /^[ 0-9a-f]{5,} /); next if (! /^[ 0-9a-f]{5,} /);
$comment .= substr($_, 43); $comment .= substr($_, 43);
} }
close(OBJDUMPDATA); close($objdumpdata);
if (!defined($comment) || $comment !~ /GCC\:.*GCC\:/m) { if (!defined($comment) || $comment !~ /GCC\:.*GCC\:/m) {
printf STDERR "No source file found for $fullname\n"; printf STDERR "No source file found for $fullname\n";
} }
return; return;
} }
if (! open(NMDATA, "$nm $basename|")) { open (my $nmdata, "$nm $basename|")
printf STDERR "$nm $fullname failed $!\n"; or die "$nm $fullname failed $!\n";
return;
}
my @nmdata; my @nmdata;
while (<NMDATA>) { while (<$nmdata>) {
chop; chop;
($type, $name) = (split(/ +/, $_, 3))[1..2]; ($type, $name) = (split(/ +/, $_, 3))[1..2];
# Expected types # Expected types
...@@ -268,7 +267,8 @@ sub do_nm ...@@ -268,7 +267,8 @@ sub do_nm
} }
} }
} }
close(NMDATA); close($nmdata);
if ($#nmdata < 0) { if ($#nmdata < 0) {
if ( if (
$fullname ne "lib/brlock.o" $fullname ne "lib/brlock.o"
...@@ -316,8 +316,7 @@ sub drop_def ...@@ -316,8 +316,7 @@ sub drop_def
sub list_multiply_defined sub list_multiply_defined
{ {
my ($name, $module); foreach my $name (keys(%def)) {
foreach $name (keys(%def)) {
if ($#{$def{$name}} > 0) { if ($#{$def{$name}} > 0) {
# Special case for cond_syscall # Special case for cond_syscall
if ($#{$def{$name}} == 1 && $name =~ /^sys_/ && if ($#{$def{$name}} == 1 && $name =~ /^sys_/ &&
...@@ -333,8 +332,9 @@ sub list_multiply_defined ...@@ -333,8 +332,9 @@ sub list_multiply_defined
&drop_def("arch/x86/kernel/vsyscall-sysenter_32.o", $name); &drop_def("arch/x86/kernel/vsyscall-sysenter_32.o", $name);
next; next;
} }
printf "$name is multiply defined in :-\n"; printf "$name is multiply defined in :-\n";
foreach $module (@{$def{$name}}) { foreach my $module (@{$def{$name}}) {
printf "\t$module\n"; printf "\t$module\n";
} }
} }
...@@ -343,12 +343,13 @@ sub list_multiply_defined ...@@ -343,12 +343,13 @@ sub list_multiply_defined
sub resolve_external_references sub resolve_external_references
{ {
my ($object, $type, $name, $i, $j, $kstrtab, $ksymtab, $export); my ($kstrtab, $ksymtab, $export);
printf "\n"; printf "\n";
foreach $object (keys(%nmdata)) { foreach my $object (keys(%nmdata)) {
my $nmdata = $nmdata{$object}; my $nmdata = $nmdata{$object};
for ($i = 0; $i <= $#{$nmdata}; ++$i) { for (my $i = 0; $i <= $#{$nmdata}; ++$i) {
($type, $name) = split(' ', $nmdata->[$i], 2); my ($type, $name) = split(' ', $nmdata->[$i], 2);
if ($type eq "U" || $type eq "w") { if ($type eq "U" || $type eq "w") {
if (exists($def{$name}) || exists($ksymtab{$name})) { if (exists($def{$name}) || exists($ksymtab{$name})) {
# add the owning object to the nmdata # add the owning object to the nmdata
...@@ -357,7 +358,7 @@ sub resolve_external_references ...@@ -357,7 +358,7 @@ sub resolve_external_references
$kstrtab = "R __kstrtab_$name"; $kstrtab = "R __kstrtab_$name";
$ksymtab = "R __ksymtab_$name"; $ksymtab = "R __ksymtab_$name";
$export = 0; $export = 0;
for ($j = 0; $j <= $#{$nmdata}; ++$j) { for (my $j = 0; $j <= $#{$nmdata}; ++$j) {
if ($nmdata->[$j] eq $kstrtab || if ($nmdata->[$j] eq $kstrtab ||
$nmdata->[$j] eq $ksymtab) { $nmdata->[$j] eq $ksymtab) {
$export = 1; $export = 1;
...@@ -424,11 +425,11 @@ sub resolve_external_references ...@@ -424,11 +425,11 @@ sub resolve_external_references
sub list_extra_externals sub list_extra_externals
{ {
my %noref = (); my %noref = ();
my ($name, @module, $module, $export);
foreach $name (keys(%def)) { foreach my $name (keys(%def)) {
if (! exists($ref{$name})) { if (! exists($ref{$name})) {
@module = @{$def{$name}}; my @module = @{$def{$name}};
foreach $module (@module) { foreach my $module (@module) {
if (! exists($noref{$module})) { if (! exists($noref{$module})) {
$noref{$module} = []; $noref{$module} = [];
} }
...@@ -438,16 +439,16 @@ sub list_extra_externals ...@@ -438,16 +439,16 @@ sub list_extra_externals
} }
if (%noref) { if (%noref) {
printf "\nExternally defined symbols with no external references\n"; printf "\nExternally defined symbols with no external references\n";
foreach $module (sort(keys(%noref))) { foreach my $module (sort(keys(%noref))) {
printf " $module\n"; printf " $module\n";
foreach (sort(@{$noref{$module}})) { foreach (sort(@{$noref{$module}})) {
if (exists($export{$_})) { my $export;
$export = " (export only)"; if (exists($export{$_})) {
} $export = " (export only)";
else { } else {
$export = ""; $export = "";
} }
printf " $_$export\n"; printf " $_$export\n";
} }
} }
} }
......
...@@ -18,6 +18,8 @@ create_package() { ...@@ -18,6 +18,8 @@ create_package() {
cp debian/copyright "$pdir/usr/share/doc/$pname/" cp debian/copyright "$pdir/usr/share/doc/$pname/"
cp debian/changelog "$pdir/usr/share/doc/$pname/changelog.Debian" cp debian/changelog "$pdir/usr/share/doc/$pname/changelog.Debian"
gzip -9 "$pdir/usr/share/doc/$pname/changelog.Debian" gzip -9 "$pdir/usr/share/doc/$pname/changelog.Debian"
sh -c "cd '$pdir'; find . -type f ! -path './DEBIAN/*' -printf '%P\0' \
| xargs -r0 md5sum > DEBIAN/md5sums"
# Fix ownership and permissions # Fix ownership and permissions
chown -R root:root "$pdir" chown -R root:root "$pdir"
......
...@@ -39,7 +39,7 @@ if ! $PREBUILT; then ...@@ -39,7 +39,7 @@ if ! $PREBUILT; then
echo "Source: kernel-$__KERNELRELEASE.tar.gz" echo "Source: kernel-$__KERNELRELEASE.tar.gz"
fi fi
echo "BuildRoot: /var/tmp/%{name}-%{PACKAGE_VERSION}-root" echo "BuildRoot: %{_tmppath}/%{name}-%{PACKAGE_VERSION}-root"
echo "Provides: $PROVIDES" echo "Provides: $PROVIDES"
echo "%define __spec_install_post /usr/lib/rpm/brp-compress || :" echo "%define __spec_install_post /usr/lib/rpm/brp-compress || :"
echo "%define debug_package %{nil}" echo "%define debug_package %{nil}"
......
...@@ -7,15 +7,13 @@ ...@@ -7,15 +7,13 @@
# usage: # usage:
# readprofile | sort -rn | perl profile2linkerlist.pl > functionlist # readprofile | sort -rn | perl profile2linkerlist.pl > functionlist
# #
use strict;
while (<>) { while (<>) {
my $line = $_; my $line = $_;
$_ =~ /\W*[0-9]+\W*([a-zA-Z\_0-9]+)\W*[0-9]+/; $_ =~ /\W*[0-9]+\W*([a-zA-Z\_0-9]+)\W*[0-9]+/;
if ( ($line =~ /unknown/) || ($line =~ /total/)) { print "*(.text.$1)\n"
unless ($line =~ /unknown/) || ($line =~ /total/);
} else {
print "*(.text.$1)\n";
}
} }
#!/usr/bin/env python #!/usr/bin/python
# #
# rt-mutex tester # rt-mutex tester
# #
......
#!/usr/bin/env python #!/usr/bin/python
# #
# show_deltas: Read list of printk messages instrumented with # show_deltas: Read list of printk messages instrumented with
# time data, and format with time deltas. # time data, and format with time deltas.
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
# mode may be any of: tags, TAGS, cscope # mode may be any of: tags, TAGS, cscope
# #
# Uses the following environment variables: # Uses the following environment variables:
# ARCH, SUBARCH, srctree, src, obj # ARCH, SUBARCH, SRCARCH, srctree, src, obj
if [ "$KBUILD_VERBOSE" = "1" ]; then if [ "$KBUILD_VERBOSE" = "1" ]; then
set -x set -x
...@@ -17,28 +17,48 @@ ignore="( -name SCCS -o -name BitKeeper -o -name .svn -o \ ...@@ -17,28 +17,48 @@ ignore="( -name SCCS -o -name BitKeeper -o -name .svn -o \
-name .git ) \ -name .git ) \
-prune -o" -prune -o"
# Do not use full path is we do not use O=.. builds # Do not use full path if we do not use O=.. builds
# Use make O=. {tags|cscope}
# to force full paths for a non-O= build
if [ "${KBUILD_SRC}" = "" ]; then if [ "${KBUILD_SRC}" = "" ]; then
tree= tree=
else else
tree=${srctree}/ tree=${srctree}/
fi fi
# Find all available archs
find_all_archs()
{
ALLSOURCE_ARCHS=""
for arch in `ls ${tree}arch`; do
ALLSOURCE_ARCHS="${ALLSOURCE_ARCHS} "${arch##\/}
done
}
# Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH # Detect if ALLSOURCE_ARCHS is set. If not, we assume SRCARCH
if [ "${ALLSOURCE_ARCHS}" = "" ]; then if [ "${ALLSOURCE_ARCHS}" = "" ]; then
ALLSOURCE_ARCHS=${SRCARCH} ALLSOURCE_ARCHS=${SRCARCH}
elif [ "${ALLSOURCE_ARCHS}" = "all" ]; then
find_all_archs
fi fi
# find sources in arch/$ARCH # find sources in arch/$ARCH
find_arch_sources() find_arch_sources()
{ {
find ${tree}arch/$1 $ignore -name "$2" -print; for i in $archincludedir; do
prune="$prune -wholename $i -prune -o"
done
find ${tree}arch/$1 $ignore $prune -name "$2" -print;
} }
# find sources in arch/$1/include # find sources in arch/$1/include
find_arch_include_sources() find_arch_include_sources()
{ {
find ${tree}arch/$1/include $ignore -name "$2" -print; include=$(find ${tree}arch/$1/ -name include -type d);
if [ -n "$include" ]; then
archincludedir="$archincludedir $include"
find $include $ignore -name "$2" -print;
fi
} }
# find sources in include/ # find sources in include/
...@@ -63,14 +83,15 @@ find_sources() ...@@ -63,14 +83,15 @@ find_sources()
all_sources() all_sources()
{ {
for arch in $ALLSOURCE_ARCHS find_arch_include_sources ${SRCARCH} '*.[chS]'
do
find_sources $arch '*.[chS]'
done
if [ ! -z "$archinclude" ]; then if [ ! -z "$archinclude" ]; then
find_arch_include_sources $archinclude '*.[chS]' find_arch_include_sources $archinclude '*.[chS]'
fi fi
find_include_sources '*.[chS]' find_include_sources '*.[chS]'
for arch in $ALLSOURCE_ARCHS
do
find_sources $arch '*.[chS]'
done
find_other_sources '*.[chS]' find_other_sources '*.[chS]'
} }
...@@ -89,13 +110,7 @@ all_defconfigs() ...@@ -89,13 +110,7 @@ all_defconfigs()
docscope() docscope()
{ {
# always use absolute paths for cscope, as recommended by cscope (echo \-k; echo \-q; all_sources) > cscope.files
# upstream
case "$tree" in
/*) ;;
*) tree=$PWD/$tree ;;
esac
(cd /; echo \-k; echo \-q; all_sources) > cscope.files
cscope -b -f cscope.out cscope -b -f cscope.out
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册