From: "Jan Beulich" <JBeulich@novell.com>
To: <linux-kernel@vger.kernel.org>
Subject: [PATCH 1/39] NLKD - an alternative kallsyms approach
Date: Wed, 09 Nov 2005 14:56:46 +0100 [thread overview]
Message-ID: <43720E2E.76F0.0078.0@novell.com> (raw)
In-Reply-To: 43720DAE.76F0.0078.0@novell.com
[-- Attachment #1: Type: text/plain, Size: 1091 bytes --]
This patch provides an alternative to the pre-exisiting kallsyms code.
That code, from a kernel debugger perspective at least, suffers from
incomplete information, making it impossible to
(a) disambiguate multiple static functions of the same name (in
different source files),
(b) determine a complete set of attributes for a symbol (namely, the
symbol's size, but also its type, which gets converted to an nm-like
one-character representation), and
(c) retain full section information
This new approach basically makes handling core kernel and module
symbols the same, by retrieving the kernel's section, symbol, and
string tables rather than parsing the system map.
At once it adds the functionality to strip unneeded symbols from
modules, which results in non-neglectable space savings for typical
distributions (which large amounts of modules). Note that with certain
recent, but broken binutils versions (2.16.90*, 2.16.91* up to
and including 2.16.91.0.3) this can only be built without
CONFIG_MODVERSIONS.
Signed-Off-By: Jan Beulich <jbeulich@novell.com>
(actual patch attached)
[-- Attachment #2: linux-2.6.14-kallsyms.patch --]
[-- Type: application/octet-stream, Size: 68058 bytes --]
This patch provides an alternative to the pre-exisiting kallsyms code.
That code, from a kernel debugger perspective at least, suffers from
incomplete information, making it impossible to
(a) disambiguate multiple static functions of the same name (in
different source files),
(b) determine a complete set of attributes for a symbol (namely, the
symbol's size, but also its type, which gets converted to an nm-like
one-character representation), and
(c) retain full section information
This new approach basically makes handling core kernel and module
symbols the same, by retrieving the kernel's section, symbol, and
string tables rather than parsing the system map.
At once it adds the functionality to strip unneeded symbols from
modules, which results in non-neglectable space savings for typical
distributions (which large amounts of modules). Note that with certain
recent, but broken binutils versions (2.16.90*, 2.16.91* up to
and including 2.16.91.0.3) this can only be built without
CONFIG_MODVERSIONS.
Signed-Off-By: Jan Beulich <jbeulich@novell.com>
--- 2.6.14/Makefile 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/Makefile 2005-11-04 16:20:57.000000000 +0100
@@ -160,15 +160,19 @@ LOCALVERSION = $(subst $(space),, \
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)$(LOCALVERSION)
+HOSTARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
+ -e s/arm.*/arm/ -e s/sa110/arm/ \
+ -e s/s390x/s390/ -e s/parisc64/parisc/ )
+
# SUBARCH tells the usermode build what the underlying arch is. That is set
# first, and if a usermode build is happening, the "ARCH=um" on the command
# line overrides the setting of ARCH below. If a native build is happening,
# then ARCH is assigned, getting whatever value it gets normally, and
# SUBARCH is subsequently ignored.
-SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
- -e s/arm.*/arm/ -e s/sa110/arm/ \
- -e s/s390x/s390/ -e s/parisc64/parisc/ )
+ifeq ($(SUBARCH),)
+SUBARCH := $(if $(filter-out um,$(ARCH)),$(ARCH),$(HOSTARCH))
+endif
# Cross compiling and selecting different set of gcc/bin-utils
# ---------------------------------------------------------------------------
@@ -327,6 +331,7 @@ NM = $(CROSS_COMPILE)nm
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
+READELF = $(CROSS_COMPILE)readelf
AWK = awk
GENKSYMS = scripts/genksyms/genksyms
DEPMOD = /sbin/depmod
@@ -729,24 +734,108 @@ endef
# Generate .S file with all kernel symbols
quiet_cmd_kallsyms = KSYM $@
- cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) \
- $(if $(CONFIG_KALLSYMS_ALL),--all-symbols) > $@
-.tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE
+ifdef CONFIG_KALLSYMS_TRADITIONAL
+
+cmd_kallsyms = { test $* -eq 0 || $(NM) -n $<; } | $(KALLSYMS) $(if $(CONFIG_KALLSYMS_ALL),--all-symbols) >$@
+
+kallsyms-strip-ext :=
+
+else
+
+cmd_kallsyms = { test $* -eq 0 || $(NM) -n $<; } | $(KALLSYMS) -$$(expr $* + 1) >$@
+
+kallsyms-strip-src := $(if $(CONFIG_KALLSYMS_STRIP_GENERATED),$(srctree)/$(KALLSYMS))
+kallsyms-strip-src += $(if $(CONFIG_KALLSYMS_STRIP_GENERATED),$(wildcard $(srctree)/arch/$(ARCH)/kallsyms))
+kallsyms-strip-src += $(if $(CONFIG_KALLSYMS_ALL),,.tmp_data)
+kallsyms-strip-src := $(strip $(kallsyms-strip-src))
+kallsyms-strip-ext := $(if $(kallsyms-strip-src),.stripped)
+
+quiet_cmd_ktab = KTAB $@
+define cmd_ktab
+ if [ $* -eq 0 ]; then \
+ echo "placeholder" >$@; \
+ else \
+ rm -f $@; \
+ $(READELF) -SW $< | while read idx name type addr offs size more; do \
+ if [ "$(suffix $@)" = "$$name" ]; then \
+ tail -c+$$((0x$$offs+1)) <$< | head -c $$((0x$$size)) >$@; \
+ break; \
+ fi; \
+ done; \
+ test -s $@; \
+ fi
+endef
+
+quiet_cmd_kshdr = KSHDR $@
+define cmd_kshdr
+ if [ $* -eq 0 ]; then \
+ echo "placeholder" >$@; \
+ else \
+ nsect= ;: grab this from the first decimal number; \
+ osect= ;: grab this from the first hexadecimal number; \
+ for i in $$($(READELF) -S $< | egrep '^[^]\[()]*$$'); \
+ do \
+ test -z "$$nsect" && nsect=$$(echo $${i%:*} | egrep '^[[:digit:]]+$$'); \
+ test -z "$$osect" && osect=$$(echo $${i%:*} | egrep '^0[xX][[:xdigit:]]+$$'); \
+ done; \
+ zsect= ;: grab this from the last number that is followed by a unit specification; \
+ for i in $$($(READELF) -h $< | egrep ':[[:space:]]+[[:digit:]]+[[:space:]]+\(.*\)'); \
+ do \
+ val=$$(echo $$i | egrep '^([[:digit:]]+|0[xX][[:xdigit:]]+)$$'); \
+ test -n "$$val" && zsect=$$val; \
+ done; \
+ tail -c+$$((osect+1)) <$< | head -c $$((nsect*zsect)) >$@; \
+ fi
+endef
+
+quiet_cmd_kstrip = STRIP $<
+cmd_kstrip = $(OBJCOPY) $(addprefix --strip-symbols ,$(filter %.strip,$^)) -w $< $@
+
+.tmp_kallsyms%.symtab: .tmp_vmlinux%$(kallsyms-strip-ext)
+ $(call cmd,ktab)
+
+.tmp_kallsyms%.strtab: .tmp_vmlinux%$(kallsyms-strip-ext)
+ $(call cmd,ktab)
+
+.tmp_kallsyms%.sections: .tmp_vmlinux%$(kallsyms-strip-ext)
+ $(call cmd,kshdr)
+
+.tmp_kallsyms%.shstrtab: .tmp_vmlinux%$(kallsyms-strip-ext)
+ $(call cmd,ktab)
+
+.tmp_vmlinux%.stripped: .tmp_vmlinux% $(addsuffix .strip,$(kallsyms-strip-src)) $(objtree)/include/linux/autoconf.h
+ $(call cmd,kstrip)
+
+.tmp_data.strip: .tmp_vmlinux1 $(objtree)/include/linux/autoconf.h
+ $(Q)$(NM) $< | sed -n 's,[[:xdigit:]]\+[[:space:]]\+[^tT][[:space:]]\+\(.*\),\1,p' \
+ | while read i; do case $$i in \
+ $(addsuffix $(close);;, \
+ $(shell cat $(addsuffix .strip,$(filter $(srctree)/%,$(kallsyms-strip-src))) /dev/null \
+ | sed 's,\([;|&<>()$$\\]\),\\\1,g')) \
+ *) echo $$i;; \
+ esac; done >$@
+
+endif # CONFIG_KALLSYMS_TRADITIONAL
+
+$(foreach n,0 1 2 3,.tmp_kallsyms$(n).o): AFLAGS+=-Wa,--strip-local-absolute
+$(foreach n,0 1 2 3,.tmp_kallsyms$(n).o): %.o: %.S $(if $(CONFIG_KALLSYMS_TRADITIONAL),,%.symtab %.strtab %.sections %.shstrtab) scripts FORCE
$(call if_changed_dep,as_o_S)
-.tmp_kallsyms%.S: .tmp_vmlinux% $(KALLSYMS)
+.tmp_kallsyms%.S: .tmp_vmlinux%$(kallsyms-strip-ext) $(KALLSYMS) $(objtree)/include/linux/autoconf.h
$(call cmd,kallsyms)
-# .tmp_vmlinux1 must be complete except kallsyms, so update vmlinux version
-.tmp_vmlinux1: $(vmlinux-lds) $(vmlinux-all) FORCE
- $(call if_changed_rule,ksym_ld)
+.tmp_vmlinux0$(kallsyms-strip-ext):
+ $(Q)echo "placeholder" >$@
-.tmp_vmlinux2: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms1.o FORCE
- $(call if_changed,vmlinux__)
+.tmp_vmlinux1: .tmp_kallsyms0.o
+.tmp_vmlinux2: .tmp_kallsyms1.o
+.tmp_vmlinux3: .tmp_kallsyms2.o
-.tmp_vmlinux3: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms2.o FORCE
- $(call if_changed,vmlinux__)
+.tmp_vmlinux%: LDFLAGS_vmlinux += -S
+# .tmp_vmlinux1 must be complete except kallsyms, so update vmlinux version
+.tmp_vmlinux%: $(vmlinux-lds) $(vmlinux-all) FORCE
+ $(if $(filter 1,$*),$(call if_changed_rule,ksym_ld),$(call if_changed,vmlinux__))
# Needs to visit scripts/ before $(KALLSYMS) can be used.
$(KALLSYMS): scripts ;
@@ -980,7 +1069,7 @@ endif # CONFIG_MODULES
# Directories & files removed with 'make clean'
CLEAN_DIRS += $(MODVERDIR)
CLEAN_FILES += vmlinux System.map \
- .tmp_kallsyms* .tmp_version .tmp_vmlinux* .tmp_System.map
+ .tmp_data* .tmp_kallsyms* .tmp_version .tmp_vmlinux* .tmp_System.map
# Directories & files removed with 'make mrproper'
MRPROPER_DIRS += include/config include2
--- 2.6.14/arch/alpha/defconfig 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/alpha/defconfig 2005-09-07 12:36:02.000000000 +0200
@@ -32,6 +32,7 @@ CONFIG_LOG_BUF_SHIFT=14
# CONFIG_IKCONFIG is not set
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_FUTEX=y
--- 2.6.14/arch/frv/defconfig 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/frv/defconfig 2005-09-07 12:34:09.000000000 +0200
@@ -33,6 +33,7 @@ CONFIG_SYSCTL=y
# CONFIG_IKCONFIG is not set
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_PRINTK=y
--- 2.6.14/arch/i386/defconfig 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/i386/defconfig 2005-09-07 12:32:14.000000000 +0200
@@ -28,6 +28,8 @@ CONFIG_HOTPLUG=y
# CONFIG_IKCONFIG is not set
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_IOSCHED_NOOP=y
--- 2.6.14/arch/i386/kernel/entry.S 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/i386/kernel/entry.S 2005-11-04 16:45:13.000000000 +0100
@@ -129,6 +129,7 @@ ENTRY(ret_from_fork)
GET_THREAD_INFO(%ebp)
popl %eax
jmp syscall_exit
+END(ret_from_fork)
/*
* Return to user mode is not as complex as all this looks,
@@ -156,6 +157,7 @@ ENTRY(resume_userspace)
# int/exception return?
jne work_pending
jmp restore_all
+END(ret_from_exception)
#ifdef CONFIG_PREEMPT
ENTRY(resume_kernel)
@@ -170,6 +172,7 @@ need_resched:
jz restore_all
call preempt_schedule_irq
jmp need_resched
+END(resume_kernel)
#endif
/* SYSENTER_RETURN points to after the "sysenter" instruction in
@@ -219,6 +222,7 @@ sysenter_past_esp:
xorl %ebp,%ebp
sti
sysexit
+ENDPROC(sysenter_entry)
# system call handler stub
@@ -293,6 +297,7 @@ ldt_ss:
.align 4
.long 1b,iret_exc
.previous
+ENDPROC(system_call)
# perform work that needs to be done immediately before resumption
ALIGN
@@ -330,6 +335,7 @@ work_notifysig_v86:
xorl %edx, %edx
call do_notify_resume
jmp resume_userspace
+END(work_pending)
# perform syscall exit tracing
ALIGN
@@ -345,6 +351,7 @@ syscall_trace_entry:
cmpl $(nr_syscalls), %eax
jnae syscall_call
jmp syscall_exit
+END(syscall_trace_entry)
# perform syscall exit tracing
ALIGN
@@ -357,6 +364,7 @@ syscall_exit_work:
movl $1, %edx
call do_syscall_trace
jmp resume_userspace
+END(syscall_exit_work)
ALIGN
syscall_fault:
@@ -365,11 +373,13 @@ syscall_fault:
GET_THREAD_INFO(%ebp)
movl $-EFAULT,EAX(%esp)
jmp resume_userspace
+END(syscall_fault)
ALIGN
syscall_badsys:
movl $-ENOSYS,EAX(%esp)
jmp resume_userspace
+END(syscall_badsys)
#define FIXUP_ESPFIX_STACK \
movl %esp, %eax; \
@@ -398,19 +408,24 @@ syscall_badsys:
*/
.data
ENTRY(interrupt)
-.text
+.previous
-vector=0
ENTRY(irq_entries_start)
+vector=0
.rept NR_IRQS
ALIGN
1: pushl $vector-256
jmp common_interrupt
-.data
+ .data
.long 1b
-.text
-vector=vector+1
+ .previous
+ vector=vector+1
.endr
+END(irq_entries_start)
+
+.data
+END(interrupt)
+.previous
ALIGN
common_interrupt:
@@ -418,6 +433,7 @@ common_interrupt:
movl %esp,%eax
call do_IRQ
jmp ret_from_intr
+ENDPROC(common_interrupt)
#define BUILD_INTERRUPT(name, nr) \
ENTRY(name) \
@@ -425,7 +441,8 @@ ENTRY(name) \
SAVE_ALL \
movl %esp,%eax; \
call smp_/**/name; \
- jmp ret_from_intr;
+ jmp ret_from_intr; \
+ENDPROC(name)
/* The include is where all of the SMP etc. interrupts come from */
#include "entry_arch.h"
@@ -433,6 +450,7 @@ ENTRY(name) \
ENTRY(divide_error)
pushl $0 # no error code
pushl $do_divide_error
+END(divide_error)
ALIGN
error_code:
pushl %ds
@@ -459,16 +477,19 @@ error_code:
movl %esp,%eax # pt_regs pointer
call *%edi
jmp ret_from_exception
+ENDPROC(error_code)
ENTRY(coprocessor_error)
pushl $0
pushl $do_coprocessor_error
jmp error_code
+END(coprocessor_error)
ENTRY(simd_coprocessor_error)
pushl $0
pushl $do_simd_coprocessor_error
jmp error_code
+END(simd_coprocessor_error)
ENTRY(device_not_available)
pushl $-1 # mark this as an int
@@ -484,6 +505,7 @@ device_not_available_emulate:
call math_emulate
addl $4, %esp
jmp ret_from_exception
+END(device_not_available)
/*
* Debug traps and NMI can happen at the one SYSENTER instruction
@@ -518,6 +540,7 @@ debug_stack_correct:
movl %esp,%eax # pt_regs pointer
call do_debug
jmp ret_from_exception
+END(debug)
.previous .text
/*
* NMI is doubly nasty. It can happen _while_ we're handling
@@ -590,6 +613,7 @@ nmi_16bit_stack:
.align 4
.long 1b,iret_exc
.previous
+ENDPROC(nmi)
KPROBE_ENTRY(int3)
pushl $-1 # mark this as an int
@@ -598,52 +622,63 @@ KPROBE_ENTRY(int3)
movl %esp,%eax # pt_regs pointer
call do_int3
jmp ret_from_exception
+END(int3)
.previous .text
ENTRY(overflow)
pushl $0
pushl $do_overflow
jmp error_code
+END(overflow)
ENTRY(bounds)
pushl $0
pushl $do_bounds
jmp error_code
+END(bounds)
ENTRY(invalid_op)
pushl $0
pushl $do_invalid_op
jmp error_code
+END(invalid_op)
ENTRY(coprocessor_segment_overrun)
pushl $0
pushl $do_coprocessor_segment_overrun
jmp error_code
+END(coprocessor_segment_overrun)
ENTRY(invalid_TSS)
pushl $do_invalid_TSS
jmp error_code
+END(invalid_TSS)
ENTRY(segment_not_present)
pushl $do_segment_not_present
jmp error_code
+END(segment_not_present)
ENTRY(stack_segment)
pushl $do_stack_segment
jmp error_code
+END(stack_segment)
KPROBE_ENTRY(general_protection)
pushl $do_general_protection
jmp error_code
+END(general_protection)
.previous .text
ENTRY(alignment_check)
pushl $do_alignment_check
jmp error_code
+END(alignment_check)
KPROBE_ENTRY(page_fault)
pushl $do_page_fault
jmp error_code
+END(page_fault)
.previous .text
#ifdef CONFIG_X86_MCE
@@ -651,12 +686,14 @@ ENTRY(machine_check)
pushl $0
pushl machine_check_vector
jmp error_code
+END(machine_check)
#endif
ENTRY(spurious_interrupt_bug)
pushl $0
pushl $do_spurious_interrupt_bug
jmp error_code
+END(spurious_interrupt_bug)
#include "syscall_table.S"
--- 2.6.14/arch/ia64/Makefile 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/ia64/Makefile 2005-09-07 11:52:28.000000000 +0200
@@ -9,7 +9,6 @@
#
NM := $(CROSS_COMPILE)nm -B
-READELF := $(CROSS_COMPILE)readelf
export AWK
--- 2.6.14/arch/ia64/defconfig 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/ia64/defconfig 2005-09-07 12:34:27.000000000 +0200
@@ -29,6 +29,7 @@ CONFIG_IKCONFIG_PROC=y
# CONFIG_CPUSETS is not set
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_PRINTK=y
--- 2.6.14/arch/m68k/defconfig 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/m68k/defconfig 2005-09-07 12:34:56.000000000 +0200
@@ -32,6 +32,7 @@ CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
--- 2.6.14/arch/mips/defconfig 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/mips/defconfig 2005-09-07 12:35:22.000000000 +0200
@@ -32,6 +32,7 @@ CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_FUTEX=y
CONFIG_EPOLL=y
--- 2.6.14/arch/ppc64/defconfig 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/ppc64/defconfig 2005-09-07 12:36:57.000000000 +0200
@@ -41,6 +41,7 @@ CONFIG_CPUSETS=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_PRINTK=y
--- 2.6.14/arch/s390/defconfig 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/s390/defconfig 2005-09-07 12:35:46.000000000 +0200
@@ -37,6 +37,7 @@ CONFIG_IKCONFIG_PROC=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_PRINTK=y
--- 2.6.14/arch/sparc/defconfig 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/sparc/defconfig 2005-09-07 12:37:27.000000000 +0200
@@ -28,7 +28,9 @@ CONFIG_LOG_BUF_SHIFT=14
# CONFIG_IKCONFIG is not set
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_IOSCHED_NOOP=y
--- 2.6.14/arch/sparc64/defconfig 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/sparc64/defconfig 2005-09-07 12:37:48.000000000 +0200
@@ -30,6 +30,7 @@ CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_FUTEX=y
--- 2.6.14/arch/um/defconfig 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/um/defconfig 2005-09-07 12:33:51.000000000 +0200
@@ -70,6 +70,7 @@ CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
# CONFIG_KALLSYMS_ALL is not set
CONFIG_KALLSYMS_EXTRA_PASS=y
CONFIG_PRINTK=y
--- 2.6.14/arch/x86_64/defconfig 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/x86_64/defconfig 2005-09-07 12:38:00.000000000 +0200
@@ -43,6 +43,7 @@ CONFIG_IKCONFIG_PROC=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_PRINTK=y
--- 2.6.14/arch/x86_64/kernel/entry.S 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/x86_64/kernel/entry.S 2005-11-07 14:56:02.000000000 +0100
@@ -153,6 +153,7 @@ rff_trace:
GET_THREAD_INFO(%rcx)
jmp rff_action
CFI_ENDPROC
+END(ret_from_fork)
/*
* System call entry. Upto 6 arguments in registers are supported.
@@ -281,6 +282,7 @@ tracesys:
RESTORE_REST
jmp ret_from_sys_call
CFI_ENDPROC
+END(system_call)
/*
* Syscall return path ending with IRET.
@@ -359,6 +361,7 @@ int_restore_rest:
cli
jmp int_with_check
CFI_ENDPROC
+END(int_ret_from_sys_call)
/*
* Certain special system calls that need to save a complete full stack frame.
@@ -370,6 +373,7 @@ int_restore_rest:
leaq \func(%rip),%rax
leaq -ARGOFFSET+8(%rsp),\arg /* 8 for return address */
jmp ptregscall_common
+END(\label)
.endm
CFI_STARTPROC
@@ -399,6 +403,7 @@ ENTRY(ptregscall_common)
CFI_REL_OFFSET rip, 0
ret
CFI_ENDPROC
+END(ptregscall_common)
ENTRY(stub_execve)
CFI_STARTPROC
@@ -429,6 +434,7 @@ exec_32bit:
RESTORE_REST
jmp int_ret_from_sys_call
CFI_ENDPROC
+END(stub_execve)
/*
* sigreturn is special because it needs to restore all registers on return.
@@ -446,6 +452,7 @@ ENTRY(stub_rt_sigreturn)
RESTORE_REST
jmp int_ret_from_sys_call
CFI_ENDPROC
+END(stub_rt_sigreturn)
/*
* initial frame state for interrupts and exceptions
@@ -596,6 +603,7 @@ retint_kernel:
jmp exit_intr
#endif
CFI_ENDPROC
+END(common_interrupt)
/*
* APIC interrupts.
@@ -611,14 +619,17 @@ retint_kernel:
ENTRY(thermal_interrupt)
apicinterrupt THERMAL_APIC_VECTOR,smp_thermal_interrupt
+END(thermal_interrupt)
#ifdef CONFIG_SMP
ENTRY(reschedule_interrupt)
apicinterrupt RESCHEDULE_VECTOR,smp_reschedule_interrupt
+END(reschedule_interrupt)
.macro INVALIDATE_ENTRY num
ENTRY(invalidate_interrupt\num)
apicinterrupt INVALIDATE_TLB_VECTOR_START+\num,smp_invalidate_interrupt
+END(invalidate_interrupt\num)
.endm
INVALIDATE_ENTRY 0
@@ -632,17 +643,21 @@ ENTRY(invalidate_interrupt\num)
ENTRY(call_function_interrupt)
apicinterrupt CALL_FUNCTION_VECTOR,smp_call_function_interrupt
+END(call_function_interrupt)
#endif
#ifdef CONFIG_X86_LOCAL_APIC
ENTRY(apic_timer_interrupt)
apicinterrupt LOCAL_TIMER_VECTOR,smp_apic_timer_interrupt
+END(apic_timer_interrupt)
ENTRY(error_interrupt)
apicinterrupt ERROR_APIC_VECTOR,smp_error_interrupt
+END(error_interrupt)
ENTRY(spurious_interrupt)
apicinterrupt SPURIOUS_APIC_VECTOR,smp_spurious_interrupt
+END(spurious_interrupt)
#endif
/*
@@ -770,6 +785,7 @@ error_kernelspace:
cmpq $gs_change,RIP(%rsp)
je error_swapgs
jmp error_sti
+END(error_entry)
/* Reload gs selector with exception handling */
/* edi: new selector */
@@ -787,6 +803,7 @@ gs_change:
CFI_ADJUST_CFA_OFFSET -8
ret
CFI_ENDPROC
+ENDPROC(load_gs_index)
.section __ex_table,"a"
.align 8
@@ -840,7 +857,7 @@ ENTRY(kernel_thread)
UNFAKE_STACK_FRAME
ret
CFI_ENDPROC
-
+ENDPROC(kernel_thread)
child_rip:
/*
@@ -853,6 +870,7 @@ child_rip:
# exit
xorl %edi, %edi
call do_exit
+ENDPROC(child_rip)
/*
* execve(). This function needs to use IRET, not SYSRET, to set up all state properly.
@@ -882,19 +900,24 @@ ENTRY(execve)
UNFAKE_STACK_FRAME
ret
CFI_ENDPROC
+ENDPROC(execve)
KPROBE_ENTRY(page_fault)
errorentry do_page_fault
+END(page_fault)
.previous .text
ENTRY(coprocessor_error)
zeroentry do_coprocessor_error
+END(coprocessor_error)
ENTRY(simd_coprocessor_error)
zeroentry do_simd_coprocessor_error
+END(simd_coprocessor_error)
ENTRY(device_not_available)
zeroentry math_state_restore
+END(device_not_available)
/* runs on exception stack */
KPROBE_ENTRY(debug)
@@ -904,6 +927,7 @@ KPROBE_ENTRY(debug)
paranoidentry do_debug
jmp paranoid_exit
CFI_ENDPROC
+END(debug)
.previous .text
/* runs on exception stack */
@@ -954,25 +978,32 @@ paranoid_schedule:
cli
jmp paranoid_userspace
CFI_ENDPROC
+END(nmi)
KPROBE_ENTRY(int3)
zeroentry do_int3
+END(int3)
.previous .text
ENTRY(overflow)
zeroentry do_overflow
+END(overflow)
ENTRY(bounds)
zeroentry do_bounds
+END(bounds)
ENTRY(invalid_op)
zeroentry do_invalid_op
+END(invalid_op)
ENTRY(coprocessor_segment_overrun)
zeroentry do_coprocessor_segment_overrun
+END(coprocessor_segment_overrun)
ENTRY(reserved)
zeroentry do_reserved
+END(reserved)
/* runs on exception stack */
ENTRY(double_fault)
@@ -980,12 +1011,15 @@ ENTRY(double_fault)
paranoidentry do_double_fault
jmp paranoid_exit
CFI_ENDPROC
+END(double_fault)
ENTRY(invalid_TSS)
errorentry do_invalid_TSS
+END(invalid_TSS)
ENTRY(segment_not_present)
errorentry do_segment_not_present
+END(segment_not_present)
/* runs on exception stack */
ENTRY(stack_segment)
@@ -993,19 +1027,24 @@ ENTRY(stack_segment)
paranoidentry do_stack_segment
jmp paranoid_exit
CFI_ENDPROC
+END(stack_segment)
KPROBE_ENTRY(general_protection)
errorentry do_general_protection
+END(general_protection)
.previous .text
ENTRY(alignment_check)
errorentry do_alignment_check
+END(alignment_check)
ENTRY(divide_error)
zeroentry do_divide_error
+END(divide_error)
ENTRY(spurious_interrupt_bug)
zeroentry do_spurious_interrupt_bug
+END(spurious_interrupt_bug)
#ifdef CONFIG_X86_MCE
/* runs on exception stack */
@@ -1016,10 +1055,12 @@ ENTRY(machine_check)
paranoidentry do_machine_check
jmp paranoid_exit
CFI_ENDPROC
+END(machine_check)
#endif
ENTRY(call_debug)
zeroentry do_call_debug
+END(call_debug)
ENTRY(call_softirq)
CFI_STARTPROC
@@ -1038,3 +1079,4 @@ ENTRY(call_softirq)
CFI_ADJUST_CFA_OFFSET -8
ret
CFI_ENDPROC
+ENDPROC(call_softirq)
--- 2.6.14/include/linux/kallsyms.h 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/include/linux/kallsyms.h 2005-11-04 16:19:34.000000000 +0100
@@ -19,6 +19,25 @@ const char *kallsyms_lookup(unsigned lon
unsigned long *offset,
char **modname, char *namebuf);
+#ifdef CONFIG_MODULES
+
+#if defined(Elf_Shdr) && defined(Elf_Sym)
+char kallsyms_elf_type(const Elf_Sym *sym,
+ const Elf_Shdr *sechdrs,
+ const char *secstrings);
+#endif
+
+struct module;
+void module_init_done(struct module *);
+
+unsigned long kallsyms_find_symname(struct module *, const char *);
+
+const char *kallsyms_get_ksymbol(struct module *,
+ unsigned long addr,
+ unsigned long *size,
+ unsigned long *offset);
+#endif
+
/* Replace "%s" in format with address, if found */
extern void __print_symbol(const char *fmt, unsigned long address);
@@ -64,4 +83,12 @@ do { \
__print_symbol(fmt, addr); \
} while(0)
+#if defined(CONFIG_KALLSYMS) && !defined(CONFIG_KALLSYMS_TRADITIONAL)
+void kallsyms_early_init(void);
+void kallsyms_init_done(void);
+#else
+#define kallsyms_early_init() ((void)0)
+#define kallsyms_init_done() ((void)0)
+#endif
+
#endif /*_LINUX_KALLSYMS_H*/
--- 2.6.14/include/linux/linkage.h 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/include/linux/linkage.h 2005-11-07 10:44:38.000000000 +0100
@@ -39,6 +39,16 @@
ALIGN; \
name:
+#ifdef CONFIG_KALLSYMS
+#define ENDPROC(name) \
+ .type name, @function; \
+ END(name)
+#define END(name) \
+ .size name, .-name
+#else
+#define ENDPROC(name)
+#define END(name)
+#endif
#endif
--- 2.6.14/include/linux/module.h 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/include/linux/module.h 2005-11-04 16:19:34.000000000 +0100
@@ -301,7 +301,14 @@ struct module
/* We keep the symbol and string tables for kallsyms. */
Elf_Sym *symtab;
unsigned long num_symtab;
- char *strtab;
+ const char *strtab;
+
+# ifndef CONFIG_KALLSYMS_TRADITIONAL
+ /* And also the sections and their string table. */
+ Elf_Shdr *sections;
+ unsigned long num_sections;
+ const char *shstrtab;
+# endif
/* Section attributes */
struct module_sect_attrs *sect_attrs;
--- 2.6.14/init/Kconfig 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/init/Kconfig 2005-11-07 10:51:19.000000000 +0100
@@ -272,9 +272,19 @@ config KALLSYMS
symbolic stack backtraces. This increases the size of the kernel
somewhat, as all symbols have to be loaded into the kernel image.
+config KALLSYMS_TRADITIONAL
+ bool "Traditional kallsyms symbol table format"
+ depends on KALLSYMS
+ default !MODULES
+ help
+ Say N here if you want the kernel symbol table to be consistent with
+ that loadable modules use (i.e. the ELF symbol table extracted from
+ the kernel binary).
+
config KALLSYMS_ALL
bool "Include all symbols in kallsyms"
depends on DEBUG_KERNEL && KALLSYMS
+ default DEBUG_KERNEL
help
Normally kallsyms only contains the symbols of functions, for nicer
OOPS messages. Some debuggers can use kallsyms for other
@@ -283,6 +293,13 @@ config KALLSYMS_ALL
Say N.
+config KALLSYMS_STRIP_GENERATED
+ bool "Strip machine generated symbols from kallsyms" if KALLSYMS_ALL
+ depends on KALLSYMS && !KALLSYMS_TRADITIONAL
+ default y
+ help
+ Say N if you want kallsyms to retain even machine generated symbols.
+
config KALLSYMS_EXTRA_PASS
bool "Do an extra kallsyms pass"
depends on KALLSYMS
--- 2.6.14/init/main.c 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/init/main.c 2005-11-07 10:53:53.000000000 +0100
@@ -481,6 +481,7 @@ asmlinkage void __init start_kernel(void
&unknown_bootoption);
sort_main_extable();
trap_init();
+ kallsyms_early_init();
rcu_init();
init_IRQ();
pidhash_init();
@@ -708,6 +709,7 @@ static int init(void * unused)
* we're essentially up and running. Get rid of the
* initmem segments and start the user-mode stuff..
*/
+ kallsyms_init_done();
free_initmem();
unlock_kernel();
system_state = SYSTEM_RUNNING;
--- 2.6.14/kernel/kallsyms.c 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/kernel/kallsyms.c 2005-11-08 12:22:46.000000000 +0100
@@ -11,8 +11,8 @@
* Changed the compression method from stem compression to "table lookup"
* compression (see scripts/kallsyms.c for a more complete description)
*/
-#include <linux/kallsyms.h>
#include <linux/module.h>
+#include <linux/kallsyms.h>
#include <linux/init.h>
#include <linux/seq_file.h>
#include <linux/fs.h>
@@ -28,15 +28,42 @@
#define all_var 0
#endif
-/* These will be re-linked against their real values during the second link stage */
-extern unsigned long kallsyms_addresses[] __attribute__((weak));
-extern unsigned long kallsyms_num_syms __attribute__((weak,section("data")));
-extern u8 kallsyms_names[] __attribute__((weak));
+#ifdef CONFIG_KALLSYMS_TRADITIONAL
+extern const unsigned long kallsyms_addresses[];
+extern const unsigned long kallsyms_num_syms __attribute__((section("data")));
+extern const u8 kallsyms_names[];
+
+extern const u8 kallsyms_token_table[];
+extern const u16 kallsyms_token_index[];
-extern u8 kallsyms_token_table[] __attribute__((weak));
-extern u16 kallsyms_token_index[] __attribute__((weak));
+extern const unsigned long kallsyms_markers[];
+#else
+extern Elf_Shdr kallsyms_sections[];
+extern Elf_Sym kallsyms_symtab[];
+extern const char kallsyms_shstrtab[], kallsyms_strtab[];
+# ifdef CONFIG_MODULES
+struct module kallsyms_kernel_module = {
+ .module_core = _text,
+ .module_init = __init_begin,
+ .symtab = kallsyms_symtab,
+ .strtab = kallsyms_strtab,
+ .sections = kallsyms_sections,
+ .shstrtab = kallsyms_shstrtab
+};
+# else
+const void*const kallsyms_module_core = _text;
+const void*const kallsyms_module_init = __init_begin;
+size_t kallsyms_core_size = 0, kallsyms_init_size = 0;
+static size_t kallsyms_core_text_size, kallsyms_init_text_size;
+size_t kallsyms_num_sections = 0, kallsyms_num_symtab = 0;
+# define KALLSYMS_VAR(mod, var) kallsyms_##var
+# endif
+# define kallsyms_num_syms KALLSYMS_VAR(&kallsyms_kernel_module, num_symtab)
+#endif
-extern unsigned long kallsyms_markers[] __attribute__((weak));
+#ifdef CONFIG_MODULES
+# define KALLSYMS_VAR(mod, var) (mod)->var
+#endif
static inline int is_kernel_inittext(unsigned long addr)
{
@@ -68,12 +95,36 @@ static inline int is_kernel(unsigned lon
return in_gate_area_no_task(addr);
}
+static inline int within(unsigned long addr, const void *start, unsigned long size)
+{
+ return ((void *)addr >= start && (void *)addr < start + size);
+}
+
+#if defined(CONFIG_MODULES) || !defined(CONFIG_KALLSYMS_TRADITIONAL)
+# ifndef CONFIG_MODULES
+static inline
+# define kallsyms_find_symname(m, n) kallsyms_find_symname(n)
+# endif
+unsigned long kallsyms_find_symname(
+ struct module *mod,
+ const char *name)
+{
+ unsigned long i;
+
+ for (i = 0; i < KALLSYMS_VAR(mod, num_symtab); i++)
+ if (strcmp(name, KALLSYMS_VAR(mod, strtab) + KALLSYMS_VAR(mod, symtab)[i].st_name) == 0)
+ return KALLSYMS_VAR(mod, symtab)[i].st_value;
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_KALLSYMS_TRADITIONAL
/* expand a compressed symbol data into the resulting uncompressed string,
given the offset to where the symbol is in the compressed stream */
static unsigned int kallsyms_expand_symbol(unsigned int off, char *result)
{
int len, skipped_first = 0;
- u8 *tptr, *data;
+ const u8 *tptr, *data;
/* get the compressed symbol length from the first symbol byte */
data = &kallsyms_names[off];
@@ -121,7 +172,7 @@ static char kallsyms_get_symbol_type(uns
* kallsyms array */
static unsigned int get_symbol_offset(unsigned long pos)
{
- u8 *name;
+ const u8 *name;
int i;
/* use the closest marker we have. We have markers every 256 positions,
@@ -137,10 +188,12 @@ static unsigned int get_symbol_offset(un
return name - kallsyms_names;
}
+#endif
/* Lookup the address for this symbol. Returns 0 if not found. */
unsigned long kallsyms_lookup_name(const char *name)
{
+#ifdef CONFIG_KALLSYMS_TRADITIONAL
char namebuf[KSYM_NAME_LEN+1];
unsigned long i;
unsigned int off;
@@ -151,10 +204,78 @@ unsigned long kallsyms_lookup_name(const
if (strcmp(namebuf, name) == 0)
return kallsyms_addresses[i];
}
+#else
+ unsigned long kaddr = kallsyms_find_symname(&kallsyms_kernel_module, name);
+
+ if (kaddr)
+ return kaddr;
+#endif
return module_kallsyms_lookup_name(name);
}
EXPORT_SYMBOL_GPL(kallsyms_lookup_name);
+#if defined(CONFIG_MODULES) || !defined(CONFIG_KALLSYMS_TRADITIONAL)
+/*
+ * This ignores the intensely annoying "mapping symbols" found
+ * in ARM ELF files: $a, $t and $d.
+ */
+static inline int is_arm_mapping_symbol(const char *str)
+{
+#ifdef CONFIG_ARM
+ return str[0] == '$' && strchr("atd", str[1])
+ && (str[2] == '\0' || str[2] == '.');
+#else
+ return 0;
+#endif
+}
+
+# ifndef CONFIG_MODULES
+static inline
+# define kallsyms_get_ksymbol(m, a, s, o) kallsyms_get_ksymbol(a, s, o)
+# endif
+const char *kallsyms_get_ksymbol(struct module *mod,
+ unsigned long addr,
+ unsigned long *size,
+ unsigned long *offset)
+{
+ unsigned long i, best = 0;
+ unsigned long nextval;
+
+ /* At worse, next value is at end of module */
+ if (within(addr, KALLSYMS_VAR(mod, module_init), KALLSYMS_VAR(mod, init_size)))
+ nextval = (unsigned long)KALLSYMS_VAR(mod, module_init) + KALLSYMS_VAR(mod, init_text_size);
+ else
+ nextval = (unsigned long)KALLSYMS_VAR(mod, module_core) + KALLSYMS_VAR(mod, core_text_size);
+
+ /* Scan for closest preceeding symbol, and next symbol. (ELF
+ starts real symbols at 1). */
+ for (i = 1; i < KALLSYMS_VAR(mod, num_symtab); i++) {
+ if (KALLSYMS_VAR(mod, symtab)[i].st_shndx == SHN_UNDEF)
+ continue;
+
+ /* We ignore unnamed symbols: they're uninformative
+ * and inserted at a whim. */
+ if (KALLSYMS_VAR(mod, symtab)[i].st_value <= addr
+ && KALLSYMS_VAR(mod, symtab)[i].st_value > KALLSYMS_VAR(mod, symtab)[best].st_value
+ && *(KALLSYMS_VAR(mod, strtab) + KALLSYMS_VAR(mod, symtab)[i].st_name) != '\0'
+ && !is_arm_mapping_symbol(KALLSYMS_VAR(mod, strtab) + KALLSYMS_VAR(mod, symtab)[i].st_name))
+ best = i;
+ if (KALLSYMS_VAR(mod, symtab)[i].st_value > addr
+ && KALLSYMS_VAR(mod, symtab)[i].st_value < nextval
+ && *(KALLSYMS_VAR(mod, strtab) + KALLSYMS_VAR(mod, symtab)[i].st_name) != '\0'
+ && !is_arm_mapping_symbol(KALLSYMS_VAR(mod, strtab) + KALLSYMS_VAR(mod, symtab)[i].st_name))
+ nextval = KALLSYMS_VAR(mod, symtab)[i].st_value;
+ }
+
+ if (!best)
+ return NULL;
+
+ *size = nextval - KALLSYMS_VAR(mod, symtab)[best].st_value;
+ *offset = addr - KALLSYMS_VAR(mod, symtab)[best].st_value;
+ return KALLSYMS_VAR(mod, strtab) + KALLSYMS_VAR(mod, symtab)[best].st_name;
+}
+#endif
+
/*
* Lookup an address
* - modname is set to NULL if it's in the kernel
@@ -167,18 +288,18 @@ const char *kallsyms_lookup(unsigned lon
unsigned long *offset,
char **modname, char *namebuf)
{
- unsigned long i, low, high, mid;
const char *msym;
- /* This kernel should never had been booted. */
- BUG_ON(!kallsyms_addresses);
-
namebuf[KSYM_NAME_LEN] = 0;
namebuf[0] = 0;
- if ((all_var && is_kernel(addr)) ||
- (!all_var && (is_kernel_text(addr) || is_kernel_inittext(addr) ||
- is_kernel_extratext(addr)))) {
+ if (all_var
+ ? is_kernel(addr)
+ : is_kernel_text(addr)
+ || is_kernel_inittext(addr)
+ || is_kernel_extratext(addr)) {
+#ifdef CONFIG_KALLSYMS_TRADITIONAL
+ unsigned long i, low, high, mid;
unsigned long symbol_end = 0;
/* do a binary search on the sorted kallsyms_addresses array */
@@ -219,6 +340,10 @@ const char *kallsyms_lookup(unsigned lon
*modname = NULL;
*offset = addr - kallsyms_addresses[low];
return namebuf;
+#else
+ *modname = NULL;
+ return kallsyms_get_ksymbol(&kallsyms_kernel_module, addr, symbolsize, offset);
+#endif
}
/* see if it's in a module */
@@ -236,30 +361,46 @@ void __print_symbol(const char *fmt, uns
const char *name;
unsigned long offset, size;
char namebuf[KSYM_NAME_LEN+1];
- char buffer[sizeof("%s+%#lx/%#lx [%s]") + KSYM_NAME_LEN +
- 2*(BITS_PER_LONG*3/10) + MODULE_NAME_LEN + 1];
name = kallsyms_lookup(address, &size, &offset, &modname, namebuf);
- if (!name)
- sprintf(buffer, "0x%lx", address);
- else {
- if (modname)
- sprintf(buffer, "%s+%#lx/%#lx [%s]", name, offset,
- size, modname);
- else
- sprintf(buffer, "%s+%#lx/%#lx", name, offset, size);
+ if (!name) {
+ char addrstr[sizeof("0x%lx") + (BITS_PER_LONG*3/10)];
+
+ sprintf(addrstr, "0x%lx", address);
+ printk(fmt, addrstr);
+ return;
+ }
+
+ if (modname) {
+ /* This is pretty small. */
+ char buffer[sizeof("%s+%#lx/%#lx [%s]")
+ + strlen(name) + 2*(BITS_PER_LONG*3/10)
+ + strlen(modname)];
+
+ sprintf(buffer, "%s+%#lx/%#lx [%s]",
+ name, offset, size, modname);
+ printk(fmt, buffer);
+ } else {
+ char buffer[sizeof("%s+%#lx/%#lx")
+ + strlen(name) + 2*(BITS_PER_LONG*3/10)];
+
+ sprintf(buffer, "%s+%#lx/%#lx", name, offset, size);
+ printk(fmt, buffer);
}
- printk(fmt, buffer);
}
/* To avoid using get_symbol_offset for every symbol, we carry prefix along. */
struct kallsym_iter
{
+#ifdef CONFIG_KALLSYMS_TRADITIONAL
loff_t pos;
+#endif
struct module *owner;
unsigned long value;
+#ifdef CONFIG_KALLSYMS_TRADITIONAL
unsigned int nameoff; /* If iterating in core kernel symbols */
+#endif
char type;
char name[KSYM_NAME_LEN+1];
};
@@ -271,9 +412,9 @@ static void upcase_if_global(struct kall
iter->type += 'A' - 'a';
}
-static int get_ksymbol_mod(struct kallsym_iter *iter)
+static int get_ksymbol_mod(struct kallsym_iter *iter, loff_t pos)
{
- iter->owner = module_get_kallsym(iter->pos - kallsyms_num_syms,
+ iter->owner = module_get_kallsym(pos,
&iter->value,
&iter->type, iter->name);
if (iter->owner == NULL)
@@ -283,6 +424,7 @@ static int get_ksymbol_mod(struct kallsy
return 1;
}
+#ifdef CONFIG_KALLSYMS_TRADITIONAL
/* Returns space to next name. */
static unsigned long get_ksymbol_core(struct kallsym_iter *iter)
{
@@ -304,26 +446,87 @@ static void reset_iter(struct kallsym_it
iter->nameoff = get_symbol_offset(new_pos);
iter->pos = new_pos;
}
+#else
+# define reset_iter(iter, new_pos) ((void)((iter)->name[0] = '\0'))
+#endif
/* Returns false if pos at or past end of file. */
static int update_iter(struct kallsym_iter *iter, loff_t pos)
{
/* Module symbols can be accessed randomly. */
- if (pos >= kallsyms_num_syms) {
- iter->pos = pos;
- return get_ksymbol_mod(iter);
- }
+ if (pos >= kallsyms_num_syms)
+ return get_ksymbol_mod(iter, pos - kallsyms_num_syms);
+#ifdef CONFIG_KALLSYMS_TRADITIONAL
/* If we're not on the desired position, reset to new position. */
if (pos != iter->pos)
reset_iter(iter, pos);
iter->nameoff += get_ksymbol_core(iter);
iter->pos++;
+#else
+ iter->owner = NULL;
+ iter->value = KALLSYMS_VAR(&kallsyms_kernel_module, symtab)[pos].st_value;
+ iter->type = KALLSYMS_VAR(&kallsyms_kernel_module, symtab)[pos].st_other;
+ strncpy(iter->name,
+ KALLSYMS_VAR(&kallsyms_kernel_module, strtab) + KALLSYMS_VAR(&kallsyms_kernel_module, symtab)[pos].st_name,
+ 127);
+ upcase_if_global(iter);
+#endif
return 1;
}
+#if defined(CONFIG_MODULES) || !defined(CONFIG_KALLSYMS_TRADITIONAL)
+# ifndef ARCH_SHF_SMALL
+# define ARCH_SHF_SMALL 0
+# endif
+/* As per nm */
+# ifndef CONFIG_MODULES
+static inline __init
+# endif
+char kallsyms_elf_type(const Elf_Sym *sym,
+ const Elf_Shdr *sechdrs,
+ const char *secstrings)
+{
+ if (ELF_ST_BIND(sym->st_info) == STB_WEAK) {
+ if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT)
+ return 'v';
+ else
+ return 'w';
+ }
+ if (sym->st_shndx == SHN_UNDEF)
+ return 'U';
+ if (sym->st_shndx == SHN_ABS)
+ return 'a';
+ if (sym->st_shndx >= SHN_LORESERVE)
+ return '?';
+ if (sechdrs) {
+ if (sechdrs[sym->st_shndx].sh_flags & SHF_EXECINSTR)
+ return 't';
+ if (sechdrs[sym->st_shndx].sh_flags & SHF_ALLOC
+ && sechdrs[sym->st_shndx].sh_type != SHT_NOBITS) {
+ if (!(sechdrs[sym->st_shndx].sh_flags & SHF_WRITE))
+ return 'r';
+ else if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
+ return 'g';
+ else
+ return 'd';
+ }
+ if (sechdrs[sym->st_shndx].sh_type == SHT_NOBITS) {
+ if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
+ return 's';
+ else
+ return 'b';
+ }
+ if (strncmp(secstrings + sechdrs[sym->st_shndx].sh_name,
+ ".debug", strlen(".debug")) == 0)
+ return 'n';
+ }
+ return '?';
+}
+#endif
+
static void *s_next(struct seq_file *m, void *p, loff_t *pos)
{
(*pos)++;
@@ -417,4 +620,73 @@ static int __init kallsyms_init(void)
}
__initcall(kallsyms_init);
+
+#ifndef CONFIG_KALLSYMS_TRADITIONAL
+
+extern const size_t kallsyms_size_sections, kallsyms_size_symtab;
+extern const size_t kallsyms_size_shstrtab, kallsyms_size_strtab;
+
+void __init kallsyms_early_init() {
+ Elf_Shdr*section;
+ Elf_Sym*symbol;
+
+ KALLSYMS_VAR(&kallsyms_kernel_module, core_size) = _end - _text;
+ KALLSYMS_VAR(&kallsyms_kernel_module, core_text_size) = _etext - _stext;
+ KALLSYMS_VAR(&kallsyms_kernel_module, init_size) = __init_end - __init_begin;
+ KALLSYMS_VAR(&kallsyms_kernel_module, init_text_size) = _einittext - _sinittext;
+
+ BUG_ON(kallsyms_size_sections <= sizeof(*kallsyms_sections));
+ BUG_ON(kallsyms_size_sections % sizeof(*kallsyms_sections));
+ BUG_ON(kallsyms_size_shstrtab <= 0);
+ BUG_ON(*kallsyms_shstrtab);
+ BUG_ON(kallsyms_shstrtab[kallsyms_size_shstrtab - 1]);
+ for(section = kallsyms_sections + 1; (unsigned long)section < (unsigned long)kallsyms_sections + kallsyms_size_sections; ++section)
+ if(section->sh_name >= kallsyms_size_shstrtab)
+ section->sh_name = 0;
+ KALLSYMS_VAR(&kallsyms_kernel_module, num_sections) = kallsyms_size_sections / sizeof(*kallsyms_sections);
+
+ BUG_ON(kallsyms_size_symtab <= sizeof(*kallsyms_symtab));
+ BUG_ON(kallsyms_size_symtab % sizeof(*kallsyms_symtab));
+ BUG_ON(kallsyms_size_strtab <= 0);
+ BUG_ON(*kallsyms_strtab);
+ BUG_ON(kallsyms_strtab[kallsyms_size_strtab - 1]);
+ for(symbol = kallsyms_symtab + 1; (unsigned long)symbol < (unsigned long)kallsyms_symtab + kallsyms_size_symtab; ++symbol) {
+ if(symbol->st_name >= kallsyms_size_strtab)
+ symbol->st_name = 0;
+ symbol->st_other = kallsyms_elf_type(symbol, kallsyms_sections, kallsyms_shstrtab);
+ }
+ KALLSYMS_VAR(&kallsyms_kernel_module, num_symtab) = kallsyms_size_symtab / sizeof(*kallsyms_symtab);
+}
+
+
+void __init kallsyms_init_done() {
+# ifdef CONFIG_MODULES
+ module_init_done(&kallsyms_kernel_module);
+# else
+ Elf_Shdr*section;
+ const Elf_Sym*src;
+ Elf_Sym*dst;
+
+ for(section = kallsyms_sections + 1; (unsigned long)section < (unsigned long)kallsyms_sections + kallsyms_size_sections; ++section)
+ if(section->sh_addr >= (unsigned long)__init_begin
+ && (section->sh_size
+ ? section->sh_addr + section->sh_size - 1
+ : section->sh_addr) < (unsigned long)__init_end)
+ section->sh_addr = 0;
+ for(src = dst = kallsyms_symtab + 1; (unsigned long)src < (unsigned long)kallsyms_symtab + kallsyms_size_symtab; ++src) {
+ if(!src->st_shndx || !src->st_name)
+ continue;
+ if(src->st_shndx < kallsyms_num_sections
+ && !kallsyms_sections[src->st_shndx].sh_addr)
+ continue;
+ if(src != dst)
+ *dst = *src;
+ ++dst;
+ }
+ kallsyms_num_symtab = dst - kallsyms_symtab;
+# endif
+}
+
+#endif /* CONFIG_KALLSYMS_TRADITIONAL */
+
EXPORT_SYMBOL(__print_symbol);
--- 2.6.14/kernel/module.c 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/kernel/module.c 2005-11-04 16:19:34.000000000 +0100
@@ -37,6 +37,7 @@
#include <linux/stop_machine.h>
#include <linux/device.h>
#include <linux/string.h>
+#include <linux/kallsyms.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#include <asm/cacheflush.h>
@@ -1163,6 +1164,8 @@ static int __unlink_module(void *_mod)
return 0;
}
+static void cleanup_kallsyms(struct module *);
+
/* Free a module, remove from lists, etc (must hold module mutex). */
static void free_module(struct module *mod)
{
@@ -1177,6 +1180,8 @@ static void free_module(struct module *m
/* Module unload stuff */
module_unload_free(mod);
+ cleanup_kallsyms(mod);
+
/* This may be NULL, but that's OK */
module_free(mod, mod->module_init);
kfree(mod->args);
@@ -1425,49 +1430,9 @@ int is_exported(const char *name, const
return 0;
}
-/* As per nm */
-static char elf_type(const Elf_Sym *sym,
- Elf_Shdr *sechdrs,
- const char *secstrings,
- struct module *mod)
-{
- if (ELF_ST_BIND(sym->st_info) == STB_WEAK) {
- if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT)
- return 'v';
- else
- return 'w';
- }
- if (sym->st_shndx == SHN_UNDEF)
- return 'U';
- if (sym->st_shndx == SHN_ABS)
- return 'a';
- if (sym->st_shndx >= SHN_LORESERVE)
- return '?';
- if (sechdrs[sym->st_shndx].sh_flags & SHF_EXECINSTR)
- return 't';
- if (sechdrs[sym->st_shndx].sh_flags & SHF_ALLOC
- && sechdrs[sym->st_shndx].sh_type != SHT_NOBITS) {
- if (!(sechdrs[sym->st_shndx].sh_flags & SHF_WRITE))
- return 'r';
- else if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
- return 'g';
- else
- return 'd';
- }
- if (sechdrs[sym->st_shndx].sh_type == SHT_NOBITS) {
- if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
- return 's';
- else
- return 'b';
- }
- if (strncmp(secstrings + sechdrs[sym->st_shndx].sh_name,
- ".debug", strlen(".debug")) == 0)
- return 'n';
- return '?';
-}
-
static void add_kallsyms(struct module *mod,
- Elf_Shdr *sechdrs,
+ const Elf_Ehdr *hdr,
+ const Elf_Shdr *sechdrs,
unsigned int symindex,
unsigned int strindex,
const char *secstrings)
@@ -1476,23 +1441,125 @@ static void add_kallsyms(struct module *
mod->symtab = (void *)sechdrs[symindex].sh_addr;
mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
- mod->strtab = (void *)sechdrs[strindex].sh_addr;
+ mod->strtab = (const void *)sechdrs[strindex].sh_addr;
+
+ if (mod->num_symtab > 1
+ && sechdrs[strindex].sh_size > 0
+ && !*mod->strtab
+ && !mod->strtab[sechdrs[strindex].sh_size - 1]) {
+ /* Set types up while we still have access to sections. */
+ for (i = 1; i < mod->num_symtab; i++) {
+ if (mod->symtab[i].st_name >= sechdrs[strindex].sh_size)
+ mod->symtab[i].st_name = 0;
+ mod->symtab[i].st_other
+ = kallsyms_elf_type(&mod->symtab[i], sechdrs, secstrings);
+ }
+ }
+ else {
+ mod->symtab = NULL;
+ mod->num_symtab = 0;
+ mod->strtab = NULL;
+ }
- /* Set types up while we still have access to sections. */
- for (i = 0; i < mod->num_symtab; i++)
- mod->symtab[i].st_info
- = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
+# ifndef CONFIG_KALLSYMS_TRADITIONAL
+ if (hdr->e_shnum > 1
+ && sechdrs[hdr->e_shstrndx].sh_size > 0
+ && !*secstrings
+ && !secstrings[sechdrs[hdr->e_shstrndx].sh_size - 1]) {
+ if (hdr->e_shnum < PAGE_SIZE / sizeof(*sechdrs))
+ mod->sections = kmalloc(hdr->e_shnum * sizeof(*sechdrs), GFP_KERNEL);
+ else
+ mod->sections = vmalloc(hdr->e_shnum * sizeof(*sechdrs));
+ }
+ else
+ mod->sections = NULL;
+ if (mod->sections) {
+ mod->num_sections = hdr->e_shnum;
+ memset(mod->sections, 0, sizeof(*mod->sections));
+ mod->shstrtab = (const void *)sechdrs[hdr->e_shstrndx].sh_addr;
+ for (i = 1; i < mod->num_sections; ++i) {
+ mod->sections[i] = sechdrs[i];
+ if (mod->sections[i].sh_name >= sechdrs[hdr->e_shstrndx].sh_size)
+ mod->sections[i].sh_name = 0;
+ if (!(mod->sections[i].sh_flags & SHF_ALLOC))
+ mod->sections[i].sh_addr = 0;
+ }
+ }
+ else {
+ mod->num_sections = 0;
+ mod->shstrtab = NULL;
+ }
+#endif
+}
+
+static void cleanup_kallsyms(struct module *mod)
+{
+# ifndef CONFIG_KALLSYMS_TRADITIONAL
+ if (mod->num_sections) {
+ if (mod->num_sections < PAGE_SIZE / sizeof(*mod->sections))
+ kfree(mod->sections);
+ else
+ vfree(mod->sections);
+ mod->num_sections = 0;
+ }
+# endif
+ mod->num_symtab = 0;
}
#else
static inline void add_kallsyms(struct module *mod,
- Elf_Shdr *sechdrs,
+ const Elf_Ehdr *hdr,
+ const Elf_Shdr *sechdrs,
unsigned int symindex,
unsigned int strindex,
const char *secstrings)
{
}
+
+static inline void cleanup_kallsyms(struct module *mod)
+{
+}
#endif /* CONFIG_KALLSYMS */
+#ifndef CONFIG_KALLSYMS
+static inline
+#endif
+void module_init_done(struct module *mod)
+{
+#ifdef CONFIG_KALLSYMS
+ if (mod->init_size) {
+ const Elf_Sym*src;
+ Elf_Sym*dst;
+# ifndef CONFIG_KALLSYMS_TRADITIONAL
+ Elf_Shdr*section;
+
+ for(section = mod->sections + 1; section < mod->sections + mod->num_sections; ++section)
+ if(section->sh_entsize & INIT_OFFSET_MASK)
+ section->sh_addr = 0;
+# endif
+ for(src = dst = mod->symtab + 1; src < mod->symtab + mod->num_symtab; ++src) {
+ if(!src->st_shndx || !src->st_name)
+ continue;
+# ifndef CONFIG_KALLSYMS_TRADITIONAL
+ if(src->st_shndx < mod->num_sections
+ && !mod->sections[src->st_shndx].sh_addr)
+ continue;
+# else
+ if(src->st_value >= (unsigned long)mod->module_init
+ && src->st_value < (unsigned long)mod->module_init + mod->init_size)
+ continue;
+# endif
+ if(src != dst)
+ *dst = *src;
+ ++dst;
+ }
+ mod->num_symtab = dst - mod->symtab;
+ }
+#endif
+ mod->module_init = NULL;
+ mod->init_size = 0;
+ mod->init_text_size = 0;
+}
+
/* Allocate and load the module: note that size of section 0 is always
zero, and we rely on this for optional sections. */
static struct module *load_module(void __user *umod,
@@ -1531,7 +1598,8 @@ static struct module *load_module(void _
if (memcmp(hdr->e_ident, ELFMAG, 4) != 0
|| hdr->e_type != ET_REL
|| !elf_check_arch(hdr)
- || hdr->e_shentsize != sizeof(*sechdrs)) {
+ || hdr->e_shentsize != sizeof(*sechdrs)
+ || !hdr->e_shstrndx) {
err = -ENOEXEC;
goto free_hdr;
}
@@ -1555,6 +1623,10 @@ static struct module *load_module(void _
/* Internal symbols and strings. */
if (sechdrs[i].sh_type == SHT_SYMTAB) {
+ if (symindex) {
+ err = -ENOEXEC;
+ goto free_hdr;
+ }
symindex = i;
strindex = sechdrs[i].sh_link;
strtab = (char *)hdr + sechdrs[strindex].sh_offset;
@@ -1566,6 +1638,11 @@ static struct module *load_module(void _
#endif
}
+ if (!symindex || !strindex) {
+ err = -ENOEXEC;
+ goto free_hdr;
+ }
+
modindex = find_sec(hdr, sechdrs, secstrings,
".gnu.linkonce.this_module");
if (!modindex) {
@@ -1597,9 +1674,14 @@ static struct module *load_module(void _
/* Don't keep modinfo section */
sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
#ifdef CONFIG_KALLSYMS
+ mod->num_symtab = 0;
/* Keep symbol and string tables for decoding later. */
sechdrs[symindex].sh_flags |= SHF_ALLOC;
sechdrs[strindex].sh_flags |= SHF_ALLOC;
+# ifndef CONFIG_KALLSYMS_TRADITIONAL
+ mod->num_sections = 0;
+ sechdrs[hdr->e_shstrndx].sh_flags |= SHF_ALLOC;
+# endif
#endif
/* Check module struct version now, before we try to use module. */
@@ -1775,7 +1857,7 @@ static struct module *load_module(void _
percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr,
sechdrs[pcpuindex].sh_size);
- add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
+ add_kallsyms(mod, hdr, sechdrs, symindex, strindex, secstrings);
err = module_finalize(hdr, sechdrs, mod);
if (err < 0)
@@ -1843,6 +1925,7 @@ static struct module *load_module(void _
module_arch_cleanup(mod);
cleanup:
module_unload_free(mod);
+ cleanup_kallsyms(mod);
module_free(mod, mod->module_init);
free_core:
module_free(mod, mod->module_core);
@@ -1934,9 +2017,7 @@ sys_init_module(void __user *umod,
/* Drop initial reference. */
module_put(mod);
module_free(mod, mod->module_init);
- mod->module_init = NULL;
- mod->init_size = 0;
- mod->init_text_size = 0;
+ module_init_done(mod);
up(&module_mutex);
return 0;
@@ -1948,58 +2029,6 @@ static inline int within(unsigned long a
}
#ifdef CONFIG_KALLSYMS
-/*
- * This ignores the intensely annoying "mapping symbols" found
- * in ARM ELF files: $a, $t and $d.
- */
-static inline int is_arm_mapping_symbol(const char *str)
-{
- return str[0] == '$' && strchr("atd", str[1])
- && (str[2] == '\0' || str[2] == '.');
-}
-
-static const char *get_ksymbol(struct module *mod,
- unsigned long addr,
- unsigned long *size,
- unsigned long *offset)
-{
- unsigned int i, best = 0;
- unsigned long nextval;
-
- /* At worse, next value is at end of module */
- if (within(addr, mod->module_init, mod->init_size))
- nextval = (unsigned long)mod->module_init+mod->init_text_size;
- else
- nextval = (unsigned long)mod->module_core+mod->core_text_size;
-
- /* Scan for closest preceeding symbol, and next symbol. (ELF
- starts real symbols at 1). */
- for (i = 1; i < mod->num_symtab; i++) {
- if (mod->symtab[i].st_shndx == SHN_UNDEF)
- continue;
-
- /* We ignore unnamed symbols: they're uninformative
- * and inserted at a whim. */
- if (mod->symtab[i].st_value <= addr
- && mod->symtab[i].st_value > mod->symtab[best].st_value
- && *(mod->strtab + mod->symtab[i].st_name) != '\0'
- && !is_arm_mapping_symbol(mod->strtab + mod->symtab[i].st_name))
- best = i;
- if (mod->symtab[i].st_value > addr
- && mod->symtab[i].st_value < nextval
- && *(mod->strtab + mod->symtab[i].st_name) != '\0'
- && !is_arm_mapping_symbol(mod->strtab + mod->symtab[i].st_name))
- nextval = mod->symtab[i].st_value;
- }
-
- if (!best)
- return NULL;
-
- *size = nextval - mod->symtab[best].st_value;
- *offset = addr - mod->symtab[best].st_value;
- return mod->strtab + mod->symtab[best].st_name;
-}
-
/* For kallsyms to ask for address resolution. NULL means not found.
We don't lock, as this is used for oops resolution and races are a
lesser concern. */
@@ -2014,7 +2043,7 @@ const char *module_address_lookup(unsign
if (within(addr, mod->module_init, mod->init_size)
|| within(addr, mod->module_core, mod->core_size)) {
*modname = mod->name;
- return get_ksymbol(mod, addr, size, offset);
+ return kallsyms_get_ksymbol(mod, addr, size, offset);
}
}
return NULL;
@@ -2031,7 +2060,7 @@ struct module *module_get_kallsym(unsign
list_for_each_entry(mod, &modules, list) {
if (symnum < mod->num_symtab) {
*value = mod->symtab[symnum].st_value;
- *type = mod->symtab[symnum].st_info;
+ *type = mod->symtab[symnum].st_other;
strncpy(namebuf,
mod->strtab + mod->symtab[symnum].st_name,
127);
@@ -2044,16 +2073,6 @@ struct module *module_get_kallsym(unsign
return NULL;
}
-static unsigned long mod_find_symname(struct module *mod, const char *name)
-{
- unsigned int i;
-
- for (i = 0; i < mod->num_symtab; i++)
- if (strcmp(name, mod->strtab+mod->symtab[i].st_name) == 0)
- return mod->symtab[i].st_value;
- return 0;
-}
-
/* Look for this name: can be of form module:name. */
unsigned long module_kallsyms_lookup_name(const char *name)
{
@@ -2065,11 +2084,11 @@ unsigned long module_kallsyms_lookup_nam
if ((colon = strchr(name, ':')) != NULL) {
*colon = '\0';
if ((mod = find_module(name)) != NULL)
- ret = mod_find_symname(mod, colon+1);
+ ret = kallsyms_find_symname(mod, colon+1);
*colon = ':';
} else {
list_for_each_entry(mod, &modules, list)
- if ((ret = mod_find_symname(mod, name)) != 0)
+ if ((ret = kallsyms_find_symname(mod, name)) != 0)
break;
}
return ret;
--- 2.6.14/scripts/Kbuild.include 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/scripts/Kbuild.include 2005-11-07 11:12:52.000000000 +0100
@@ -5,6 +5,8 @@
comma := ,
empty :=
space := $(empty) $(empty)
+open := (
+close := )
###
# The temporary file to save gcc -MD generated dependencies must not
--- 2.6.14/scripts/Makefile 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/scripts/Makefile 2005-11-04 16:19:35.000000000 +0100
@@ -8,6 +8,7 @@
# conmakehash: Create arrays for initializing the kernel console tables
hostprogs-$(CONFIG_KALLSYMS) += kallsyms
+HOSTCFLAGS_kallsyms.o := -D ARCH_$(SUBARCH)
hostprogs-$(CONFIG_LOGO) += pnmtologo
hostprogs-$(CONFIG_VT) += conmakehash
hostprogs-$(CONFIG_PROM_CONSOLE) += conmakehash
--- 2.6.14/scripts/Makefile.build 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/scripts/Makefile.build 2005-11-08 12:29:46.000000000 +0100
@@ -156,23 +156,26 @@ else
# are done.
# o otherwise, we calculate symbol versions using the good old
# genksyms on the preprocessed source and postprocess them in a way
-# that they are usable as a linker script
-# o generate <file>.o from .tmp_<file>.o using the linker to
-# replace the unresolved symbols __crc_exported_symbol with
-# the actual value of the checksum generated by genksyms
+# that they are usable as assembly source
+# o recompile <file>.o from <file>.c forcing inclusion of assembler
+# directives defining the actual values of __crc_*, followed by
+# objcopy-ing them to force these symbols to be local to permit
+# stripping them during the final module linking stage.
cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
cmd_modversions = \
if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \
- $(CPP) -D__GENKSYMS__ $(c_flags) $< \
- | $(GENKSYMS) \
- > $(@D)/.tmp_$(@F:.o=.ver); \
- \
- $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
- -T $(@D)/.tmp_$(@F:.o=.ver); \
- rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \
+ if $(CPP) -D__GENKSYMS__ $(c_flags) $< \
+ | $(GENKSYMS) -a > $(@D)/.tmp_$(@F:.o=.ver) \
+ && $(CC) $(c_flags) -c -w -include $(@D)/.tmp_$(@F:.o=.ver) -o $@ $< \
+ && $(OBJCOPY) -L '__crc_*' -w $@; then \
+ rm -f $(@D)/.tmp_$(@F); \
+ else \
+ rm -f $@; exit 1; \
+ fi; \
else \
mv -f $(@D)/.tmp_$(@F) $@; \
+ rm -f $(@D)/.tmp_$(@F:.o=.ver); \
fi;
endif
@@ -183,6 +186,12 @@ define rule_cc_o_c
$(cmd_cc_o_c); \
$(cmd_modversions) \
scripts/basic/fixdep $(depfile) $@ '$(subst ','\'',$(cmd_cc_o_c))' > $(@D)/.$(@F).tmp; \
+ if [ -r $(@D)/.tmp_$(@F:.o=.ver) ]; then \
+ echo >> $(@D)/.$(@F).tmp; \
+ echo '$@: $(GENKSYMS)' >> $(@D)/.$(@F).tmp; \
+ echo '$(GENKSYMS):: ;' >> $(@D)/.$(@F).tmp; \
+ rm $(@D)/.tmp_$(@F:.o=.ver); \
+ fi; \
rm -f $(depfile); \
mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd
endef
--- 2.6.14/scripts/Makefile.modinst 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/scripts/Makefile.modinst 2005-11-04 16:19:35.000000000 +0100
@@ -17,7 +17,8 @@ __modinst: $(modules)
@:
quiet_cmd_modules_install = INSTALL $@
- cmd_modules_install = mkdir -p $(2); cp $@ $(2)
+ cmd_modules_install = mkdir -p $(2); \
+ cp $(firstword $(wildcard $@s) $@) $(2)/$(basename $(@F)).ko
# Modules built outside the kernel source tree go into extra by default
INSTALL_MOD_DIR ?= extra
--- 2.6.14/scripts/Makefile.modpost 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/scripts/Makefile.modpost 2005-11-04 16:19:35.000000000 +0100
@@ -41,9 +41,33 @@ include scripts/Makefile.lib
symverfile := $(objtree)/Module.symvers
+ifdef CONFIG_KALLSYMS
+
+ifdef CONFIG_KALLSYMS_TRADITIONAL
+
+kallsyms-strip-src :=
+
+else
+
+kallsyms-strip-src := $(if $(CONFIG_KALLSYMS_STRIP_GENERATED),$(srctree)/scripts/kallsyms.strip)
+kallsyms-strip-src += $(if $(CONFIG_KALLSYMS_STRIP_GENERATED),$(wildcard $(srctree)/arch/$(ARCH)/kallsyms.strip))
+# binutils up to at least 2.15 do not permit stripping symbols by name while
+# retaining those that are needed by relocations...
+# kallsyms-strip-src += $(if $(CONFIG_KALLSYMS_ALL),,data)
+
+endif
+
+ko := $(if $(strip $(kallsyms-strip-src)),.kos,.ko)
+
+else
+
+ko := .kos
+
+endif
+
# Step 1), find all modules listed in $(MODVERDIR)/
__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
-modules := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o)))
+modules := $(patsubst %.o,%$(ko), $(wildcard $(__modules:.ko=.o)))
_modpost: $(modules)
@@ -58,12 +82,12 @@ quiet_cmd_modpost = MODPOST
$(filter-out FORCE,$^)
.PHONY: __modpost
-__modpost: $(wildcard vmlinux) $(modules:.ko=.o) FORCE
+__modpost: $(wildcard vmlinux) $(modules:$(ko)=.o) FORCE
$(call cmd,modpost)
# Declare generated files as targets for modpost
$(symverfile): __modpost ;
-$(modules:.ko=.mod.c): __modpost ;
+$(modules:$(ko)=.mod.c): __modpost ;
# Step 5), compile all *.mod.c files
@@ -75,19 +99,51 @@ quiet_cmd_cc_o_c = CC $@
cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE) \
-c -o $@ $<
-$(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE
+$(modules:$(ko)=.mod.o): %.mod.o: %.mod.c FORCE
$(call if_changed_dep,cc_o_c)
-targets += $(modules:.ko=.mod.o)
+targets += $(modules:$(ko)=.mod.o)
# Step 6), final link of the modules
quiet_cmd_ld_ko_o = LD [M] $@
cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \
$(filter-out FORCE,$^)
-$(modules): %.ko :%.o %.mod.o FORCE
+ifeq ($(ko),.ko)
+
+$(modules): %.ko: %.o %.mod.o FORCE
+ $(Q)rm -f $@s
+ $(call if_changed,ld_ko_o)
+
+else
+
+$(patsubst %$(ko),%.ko,$(modules)): %.ko: %.o %.mod.o FORCE
$(call if_changed,ld_ko_o)
+# Step 7), strip as many symbols from the modules as feasible
+quiet_cmd_strip_kos_ko = STRIP $<
+ifdef CONFIG_KALLSYMS
+cmd_strip_kos_ko = $(OBJCOPY) --strip-debug $(addprefix --strip-symbols ,$(filter %.strip,$^)) -w $< $@
+else
+cmd_strip_kos_ko = $(OBJCOPY) --strip-debug --strip-unneeded $< $@
+endif
+
+%$(ko): %.ko $(filter %.strip,$(kallsyms-strip-src)) $(if $(filter data,$(kallsyms-strip-src)),.data_%.strip) FORCE
+ $(call if_changed,strip_kos_ko)
+
+.PRECIOUS: .data_%.strip
+.data_%.strip: %.ko .config
+ $(Q)$(NM) $< | sed -n 's,[[:xdigit:]]\+[[:space:]]\+[^tT][[:space:]]\+\(.*\),\1,p' \
+ | while read i; do case $$i in \
+ $(addsuffix $(close);;,$(shell cat $(filter $(srctree)/%,$(kallsyms-strip-src)) \
+ | sed 's,\([;|&<>()$$\\]\),\\\1,g')) \
+ *) echo $$i;; \
+ esac; done >$@
+
+targets += $(patsubst %$(ko),%.ko,$(modules))
+
+endif
+
targets += $(modules)
--- 2.6.14/scripts/genksyms/genksyms.c 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/scripts/genksyms/genksyms.c 2005-11-04 16:19:35.000000000 +0100
@@ -43,7 +43,7 @@ FILE *debugfile;
int cur_line = 1;
char *cur_filename, *output_directory;
-int flag_debug, flag_dump_defs, flag_warnings;
+int flag_debug, flag_dump_defs, flag_warnings, flag_inline_asm;
static int errors;
static int nsyms;
@@ -457,8 +457,16 @@ export_symbol(const char *name)
if (flag_dump_defs)
fputs(">\n", debugfile);
- /* Used as a linker script. */
- printf("__crc_%s = 0x%08lx ;\n", name, crc);
+ if (!flag_inline_asm)
+ {
+ /* Used as a linker script. */
+ printf("__crc_%s = 0x%08lx ;\n", name, crc);
+ }
+ else
+ {
+ /* Used as inline assembly. */
+ printf("__asm__(\".equiv __crc_%s, 0x%08lx\");\n", name, crc);
+ }
}
}
@@ -529,6 +537,7 @@ main(int argc, char **argv)
#ifdef __GNU_LIBRARY__
struct option long_opts[] = {
+ {"asm", 0, 0, 'a'},
{"debug", 0, 0, 'd'},
{"warnings", 0, 0, 'w'},
{"quiet", 0, 0, 'q'},
@@ -538,13 +547,16 @@ main(int argc, char **argv)
{0, 0, 0, 0}
};
- while ((o = getopt_long(argc, argv, "dwqVDk:p:",
+ while ((o = getopt_long(argc, argv, "adwqVDk:p:",
&long_opts[0], NULL)) != EOF)
#else /* __GNU_LIBRARY__ */
- while ((o = getopt(argc, argv, "dwqVDk:p:")) != EOF)
+ while ((o = getopt(argc, argv, "adwqVDk:p:")) != EOF)
#endif /* __GNU_LIBRARY__ */
switch (o)
{
+ case 'a':
+ flag_inline_asm = 1;
+ break;
case 'd':
flag_debug++;
break;
--- 2.6.14/scripts/kallsyms.c 2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/scripts/kallsyms.c 2005-11-07 11:55:11.000000000 +0100
@@ -30,6 +30,7 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+#include <limits.h>
#define KSYM_NAME_LEN 127
@@ -43,6 +44,7 @@ struct sym_entry {
static struct sym_entry *table;
static unsigned int table_size, table_cnt;
+static long stage;
static unsigned long long _stext, _etext, _sinittext, _einittext, _sextratext, _eextratext;
static int all_symbols = 0;
static char symbol_prefix_char = '\0';
@@ -56,7 +58,7 @@ unsigned char best_table_len[256];
static void usage(void)
{
- fprintf(stderr, "Usage: kallsyms [--all-symbols] [--symbol-prefix=<prefix char>] < in.map > out.S\n");
+ fprintf(stderr, "Usage: kallsyms [stage] [--all-symbols] [--symbol-prefix=<prefix char>] < in.map > out.S\n");
exit(1);
}
@@ -66,8 +68,12 @@ static void usage(void)
*/
static inline int is_arm_mapping_symbol(const char *str)
{
+#if defined(ARCH_arm) || defined(ARCH_arm26)
return str[0] == '$' && strchr("atd", str[1])
&& (str[2] == '\0' || str[2] == '.');
+#else
+ return 0;
+#endif
}
static int read_symbol(FILE *in, struct sym_entry *s)
@@ -138,13 +144,6 @@ static int symbol_valid(struct sym_entry
* specified so exclude them to get a stable symbol list.
*/
static char *special_symbols[] = {
- "kallsyms_addresses",
- "kallsyms_num_syms",
- "kallsyms_names",
- "kallsyms_markers",
- "kallsyms_token_table",
- "kallsyms_token_index",
-
/* Exclude linker generated symbols which vary between passes */
"_SDA_BASE_", /* ppc */
"_SDA2_BASE_", /* ppc */
@@ -176,7 +175,8 @@ static int symbol_valid(struct sym_entry
}
/* Exclude symbols which vary between passes. */
- if (strstr((char *)s->sym + offset, "_compiled."))
+ if (strstr((char *)s->sym + offset, "_compiled.")
+ || strncmp((char *)s->sym + offset, "__compound_literal.", 19) == 0)
return 0;
for (i = 0; special_symbols[i]; i++)
@@ -258,7 +258,42 @@ static void write_src(void)
printf("#define ALGN .align 4\n");
printf("#endif\n");
- printf(".data\n");
+ printf(".section .rodata, \"a\"\n");
+
+ if (stage) {
+ static struct {
+ const char*name;
+ unsigned writeable:1;
+ unsigned aligned:1;
+ } const what[] = {
+ {"sections", 1, 1},
+ {"symtab", 1, 1},
+ {"strtab", 0, 0},
+ {"shstrtab", 0, 0}
+ };
+
+ for (i = 0; i < sizeof(what)/sizeof(*what); ++i) {
+ if (what[i].writeable)
+ printf(".data\n");
+ printf(".globl kallsyms_%s, kallsyms_size_%s\n", what[i].name, what[i].name);
+ if (what[i].aligned)
+ printf("\tALGN\n");
+ printf("kallsyms_%s:\n", what[i].name);
+ printf(".incbin \".tmp_kallsyms%ld.%s\"\n", labs(stage) - 1, what[i].name);
+ printf(".equ __kallsyms_size_%s, . - kallsyms_%s\n", what[i].name, what[i].name);
+ if (what[i].writeable)
+ printf(".previous\n");
+ printf("\n");
+ }
+ printf("\tALGN\n");
+ for (i = 0; i < sizeof(what)/sizeof(*what); ++i) {
+ printf("kallsyms_size_%s:\n", what[i].name);
+ printf("\tPTR\t__kallsyms_size_%s\n", what[i].name);
+ }
+ printf("\n");
+ }
+ if (stage < 0)
+ return;
output_label("kallsyms_addresses");
for (i = 0; i < table_cnt; i++) {
@@ -472,25 +507,28 @@ static void optimize_token_table(void)
int main(int argc, char **argv)
{
- if (argc >= 2) {
- int i;
- for (i = 1; i < argc; i++) {
- if(strcmp(argv[i], "--all-symbols") == 0)
- all_symbols = 1;
- else if (strncmp(argv[i], "--symbol-prefix=", 16) == 0) {
- char *p = &argv[i][16];
- /* skip quote */
- if ((*p == '"' && *(p+2) == '"') || (*p == '\'' && *(p+2) == '\''))
- p++;
- symbol_prefix_char = *p;
- } else
- usage();
- }
- } else if (argc != 1)
- usage();
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ if(strcmp(argv[i], "--all-symbols") == 0)
+ all_symbols = 1;
+ else if (strncmp(argv[i], "--symbol-prefix=", 16) == 0) {
+ char *p = &argv[i][16];
+
+ /* skip quote */
+ if ((*p == '"' || *p == '\'') && p[2] == *p)
+ p++;
+ symbol_prefix_char = *p;
+ } else if ((stage = strtol(argv[i], argv + i, 0)) == 0
+ || stage >= LONG_MAX
+ || stage <= LONG_MIN
+ || *argv[i])
+ usage();
+ }
read_map(stdin);
- optimize_token_table();
+ if (stage >= 0 && table_cnt)
+ optimize_token_table();
write_src();
return 0;
--- 2.6.14/scripts/kallsyms.strip 1970-01-01 01:00:00.000000000 +0100
+++ 2.6.14-kallsyms/scripts/kallsyms.strip 2005-03-21 16:34:09.000000000 +0100
@@ -0,0 +1,18 @@
+<*>
+__compound_literal[$.][0-9]*
+__crc_[a-zA-Z_]*
+__exitcall_[a-zA-Z_]*
+__func__[$.][0-9]*
+__FUNCTION__[$.][0-9]*
+gcc[0-9]_compiled[$.]
+__initcall_[a-zA-Z_]*
+__kcrctab_[a-zA-Z_]*
+__kstrtab_[a-zA-Z_]*
+__ksymtab_[a-zA-Z_]*
+__mod_[a-zA-Z_]*[0-9]
+__module_depends
+__param_[a-zA-Z_]*
+__pci_fixup_[A-Z]*
+__PRETTY_FUNCTION__[$.][0-9]*
+__setup_[a-zA-Z_0-9]*
+____versions
next prev parent reply other threads:[~2005-11-09 13:55 UTC|newest]
Thread overview: 105+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-11-09 13:54 [PATCH 0/39] NLKD - Novell Linux Kernel Debugger Jan Beulich
2005-11-09 13:56 ` Jan Beulich [this message]
2005-11-09 13:57 ` [PATCH 2/39] NLKD - an alternative early ioremap approach Jan Beulich
2005-11-09 13:58 ` [PATCH 3/39] NLKD - early/late CPU up/down notification Jan Beulich
2005-11-09 13:59 ` [PATCH 4/39] NLKD/i386 " Jan Beulich
2005-11-09 14:01 ` [PATCH 5/39] NLKD/x86-64 " Jan Beulich
2005-11-10 13:10 ` Andi Kleen
2005-11-14 8:04 ` [discuss] " Jan Beulich
2005-11-14 12:37 ` Andi Kleen
2005-11-09 14:01 ` [PATCH 6/39] NLKD - early panic notification Jan Beulich
2005-11-09 14:02 ` [PATCH 7/39] NLKD - task create/destroy notification Jan Beulich
2005-11-09 14:03 ` [PATCH 8/39] NLKD - rmmod notification Jan Beulich
2005-11-09 14:04 ` [PATCH 9/39] NLKD - hotkey notification Jan Beulich
2005-11-09 14:05 ` [PATCH 10/39] NLKD - console layout change notification Jan Beulich
2005-11-09 14:06 ` [PATCH 11/39] NLKD - time adjustment Jan Beulich
2005-11-09 14:06 ` [PATCH 12/39] NLKD/i386 " Jan Beulich
2005-11-09 19:10 ` George Anzinger
2005-11-10 8:12 ` Jan Beulich
2005-11-11 0:17 ` George Anzinger
2005-11-09 14:08 ` [PATCH 13/39] NLKD/x86-64 " Jan Beulich
2005-11-09 14:13 ` [PATCH 18/39] NLKD/x86-64 - INT1/INT3 handling changes Jan Beulich
2005-11-09 14:14 ` [PATCH 19/39] NLKD/x86-64 - stack-pointer-invalid markers Jan Beulich
2005-11-09 14:15 ` [PATCH 20/39] NLKD/x86-64 - switch_to() floating point adjustment Jan Beulich
2005-11-09 14:16 ` [PATCH 21/39] NLKD/x86-64 - core adjustments Jan Beulich
2005-11-10 13:24 ` [PATCH 20/39] NLKD/x86-64 - switch_to() floating point adjustment Andi Kleen
2005-11-10 14:07 ` Jan Beulich
2005-11-10 13:23 ` [PATCH 19/39] NLKD/x86-64 - stack-pointer-invalid markers Andi Kleen
2005-11-10 14:25 ` Jan Beulich
2005-11-10 13:21 ` [PATCH 18/39] NLKD/x86-64 - INT1/INT3 handling changes Andi Kleen
2005-11-10 14:07 ` Jan Beulich
2005-11-10 14:25 ` Andi Kleen
2005-11-10 15:00 ` Jan Beulich
2005-11-11 3:39 ` [discuss] " Andi Kleen
2005-11-10 13:19 ` [PATCH 13/39] NLKD/x86-64 - time adjustment Andi Kleen
2005-11-10 14:23 ` Jan Beulich
2005-11-11 2:12 ` Andi Kleen
2005-11-12 9:22 ` Vojtech Pavlik
2005-11-12 17:21 ` Andi Kleen
2005-11-12 20:44 ` Vojtech Pavlik
2005-11-15 0:38 ` George Anzinger
2005-11-15 1:05 ` [discuss] " Andi Kleen
2005-11-15 7:50 ` Vojtech Pavlik
2005-11-15 8:24 ` Jan Beulich
2005-11-10 14:43 ` Vojtech Pavlik
2005-11-09 14:09 ` [PATCH 14/39] NLKD - kernel trace buffer access Jan Beulich
2005-11-09 14:09 ` [PATCH 15/39] NLKD - early pseudo-fs Jan Beulich
2005-11-09 14:11 ` [PATCH 16/39] NLKD - core adjustments Jan Beulich
2005-11-09 14:11 ` [PATCH 17/39] NLKD/i386 " Jan Beulich
2005-11-09 19:00 ` Adrian Bunk
2005-11-10 8:04 ` Jan Beulich
2005-11-10 10:29 ` Adrian Bunk
2005-11-10 11:52 ` Jan Beulich
2005-11-10 12:36 ` Lars Marowsky-Bree
2005-11-09 14:18 ` [PATCH 22/39] NLKD - core Jan Beulich
2005-11-09 14:19 ` [PATCH 23/39] NLKD/x86 " Jan Beulich
2005-11-09 14:20 ` [PATCH 24/39] NLKD/i386 " Jan Beulich
2005-11-09 14:21 ` [PATCH 25/39] NLKD/x86-64 " Jan Beulich
2005-11-10 13:30 ` Andi Kleen
2005-11-09 14:22 ` [PATCH 26/39] NLKD - run time library Jan Beulich
2005-11-09 14:23 ` [PATCH 27/39] NLKD/i386 " Jan Beulich
2005-11-09 14:23 ` [PATCH 28/39] NLKD/x86-64 " Jan Beulich
2005-11-10 13:32 ` Andi Kleen
[not found] ` <437214B7.76F0.0078.0@novell.com>
[not found] ` <4372156A.76F0.0078.0@novell.com>
2005-11-09 14:28 ` [PATCH 34/39] NLKD/x86 - Console Debug Agent Jan Beulich
[not found] ` <43721600.76F0.0078.0@novell.com>
2005-11-09 14:30 ` [PATCH 38/39] NLKD/i386 - Remote " Jan Beulich
2005-11-09 14:31 ` [PATCH 39/39] NLKD/x86-64 " Jan Beulich
2005-11-09 14:29 ` [PATCH 15/39] NLKD - early pseudo-fs Al Viro
2005-11-09 14:37 ` Jan Beulich
2005-11-09 15:00 ` Al Viro
2005-11-09 16:00 ` Jan Beulich
2005-11-10 5:44 ` [PATCH 14/39] NLKD - kernel trace buffer access Keith Owens
2005-11-10 8:02 ` Jan Beulich
2005-11-09 18:51 ` [PATCH 11/39] NLKD - time adjustment George Anzinger
2005-11-09 16:50 ` [PATCH 6/39] NLKD - early panic notification Greg KH
2005-11-09 16:45 ` [PATCH 3/39] NLKD - early/late CPU up/down notification Greg KH
2005-11-09 17:09 ` Jan Beulich
2005-11-09 17:19 ` Greg KH
2005-11-10 7:41 ` Jan Beulich
2005-11-10 20:59 ` Sam Ravnborg
2005-11-11 7:52 ` Jan Beulich
2005-11-12 20:52 ` Randy.Dunlap
2005-11-10 23:01 ` Greg KH
2005-11-11 10:06 ` [PATCH 2/39] NLKD - an alternative early ioremap approach Pavel Machek
2005-11-11 10:19 ` Jan Beulich
2005-11-09 16:50 ` [PATCH 1/39] NLKD - an alternative kallsyms approach Randy.Dunlap
2005-11-09 16:57 ` Greg KH
2005-11-09 17:20 ` Jan Beulich
2005-11-09 16:59 ` [PATCH 0/39] NLKD - Novell Linux Kernel Debugger Jeff Garzik
2005-11-09 17:06 ` Randy.Dunlap
2005-11-09 17:14 ` Jan Beulich
2005-11-09 17:56 ` Alan Cox
2005-11-09 18:05 ` Greg KH
2005-11-09 18:54 ` Paul Jackson
2005-11-10 12:41 ` Christoph Hellwig
2005-11-13 1:09 ` Andi Kleen
2005-11-13 2:53 ` jmerkey
2005-11-13 3:44 ` Andi Kleen
2005-11-13 3:26 ` Jeff V. Merkey
2005-11-13 3:32 ` Jeff V. Merkey
2005-11-09 17:53 ` Alan Cox
2005-11-09 16:25 ` Jeffrey V. Merkey
2005-11-10 14:48 ` Mark Lord
2005-11-10 15:28 ` Tom Rini
2005-11-10 16:37 ` Alan Cox
2005-11-13 1:11 ` Andi Kleen
[not found] ` <437214E4.76F0.0078.0@novell.com>
[not found] ` <4372153C.76F0.0078.0@novell.com>
2005-11-10 13:33 ` [PATCH 32/39] NLKD/x86-64 - Core Debug Engine Andi Kleen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=43720E2E.76F0.0078.0@novell.com \
--to=jbeulich@novell.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox