2008-06-10 19:02:37

by Sam Ravnborg

[permalink] [raw]
Subject: kbuild breaks um - fails to find util when linking

Hi Jeff.

In an attempt to make the final link of vmlinux
readable/hackable I have broken um build.

um used a special rule so it could use gcc as linker.
With my changes we need to use ld to link vmlinux and
ld now fails to locate util.

I hope you have a clue why. I tried various things but
did not find out why ld cannot locate util.

I have appended a combinded diff of the relvant two patches
including my um/Makefile changes.

I would really like to fix um and fold the fix into my
tree.

You can use "make V=3" to see the exact command used in the
link phase.

Thanks,
Sam

diff --git a/Makefile b/Makefile
index 2b95120..6a14c95 100644
--- a/Makefile
+++ b/Makefile
@@ -626,206 +626,32 @@ libs-y1 := $(patsubst %/, %/lib.a, $(libs-y))
libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y))
libs-y := $(libs-y1) $(libs-y2)

-# Build vmlinux
-# ---------------------------------------------------------------------------
-# vmlinux is built from the objects selected by $(vmlinux-init) and
-# $(vmlinux-main). Most are built-in.o files from top-level directories
-# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
-# Ordering when linking is important, and $(vmlinux-init) must be first.
#
-# vmlinux
-# ^
-# |
-# +-< $(vmlinux-init)
-# | +--< init/version.o + more
-# |
-# +--< $(vmlinux-main)
-# | +--< driver/built-in.o mm/built-in.o + more
-# |
-# +-< kallsyms.o (see description in CONFIG_KALLSYMS section)
-#
-# vmlinux version (uname -v) cannot be updated during normal
-# descending-into-subdirs phase since we do not yet know if we need to
-# update vmlinux.
-# Therefore this step is delayed until just before final link of vmlinux -
-# except in the kallsyms case where it is done just before adding the
-# symbols to the kernel.
+# Build vmlinux
#
-# System.map is generated to document addresses of all kernel symbols
-
-vmlinux-init := $(head-y) $(init-y)
-vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
-vmlinux-all := $(vmlinux-init) $(vmlinux-main)
-vmlinux-lds := arch/$(SRCARCH)/kernel/vmlinux.lds
-export KBUILD_VMLINUX_OBJS := $(vmlinux-all)
-
-# Rule to link vmlinux - also used during CONFIG_KALLSYMS
-# May be overridden by arch/$(ARCH)/Makefile
-quiet_cmd_vmlinux__ ?= LD $@
- cmd_vmlinux__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) -o $@ \
- -T $(vmlinux-lds) $(vmlinux-init) \
- --start-group $(vmlinux-main) --end-group \
- $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o FORCE ,$^)
-
-# Generate new vmlinux version
-quiet_cmd_vmlinux_version = GEN .version
- cmd_vmlinux_version = set -e; \
- if [ ! -r .version ]; then \
- rm -f .version; \
- echo 1 >.version; \
- else \
- mv .version .old_version; \
- expr 0$$(cat .old_version) + 1 >.version; \
- fi; \
- $(MAKE) $(build)=init
-
-# Generate System.map
-quiet_cmd_sysmap = SYSMAP
- cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap
-
-# Link of vmlinux
-# If CONFIG_KALLSYMS is set .version is already updated
-# Generate System.map and verify that the content is consistent
-# Use + in front of the vmlinux_version rule to silent warning with make -j2
-# First command is ':' to allow us to use + in front of the rule
-define rule_vmlinux__
- :
- $(if $(CONFIG_KALLSYMS),,+$(call cmd,vmlinux_version))
-
- $(call cmd,vmlinux__)
- $(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
-
- $(Q)$(if $($(quiet)cmd_sysmap), \
- echo ' $($(quiet)cmd_sysmap) System.map' &&) \
- $(cmd_sysmap) $@ System.map; \
- if [ $$? -ne 0 ]; then \
- rm -f $@; \
- /bin/false; \
- fi;
- $(verify_kallsyms)
-endef
-
-
-ifdef CONFIG_KALLSYMS
-# Generate section listing all symbols and add it into vmlinux $(kallsyms.o)
-# It's a three stage process:
-# o .tmp_vmlinux1 has all symbols and sections, but __kallsyms is
-# empty
-# Running kallsyms on that gives us .tmp_kallsyms1.o with
-# the right size - vmlinux version (uname -v) is updated during this step
-# o .tmp_vmlinux2 now has a __kallsyms section of the right size,
-# but due to the added section, some addresses have shifted.
-# From here, we generate a correct .tmp_kallsyms2.o
-# o The correct .tmp_kallsyms2.o is linked into the final vmlinux.
-# o Verify that the System.map from vmlinux matches the map from
-# .tmp_vmlinux2, just in case we did not generate kallsyms correctly.
-# o If CONFIG_KALLSYMS_EXTRA_PASS is set, do an extra pass using
-# .tmp_vmlinux3 and .tmp_kallsyms3.o. This is only meant as a
-# temporary bypass to allow the kernel to be built while the
-# maintainers work out what went wrong with kallsyms.
-
-ifdef CONFIG_KALLSYMS_EXTRA_PASS
-last_kallsyms := 3
-else
-last_kallsyms := 2
-endif
-
-kallsyms.o := .tmp_kallsyms$(last_kallsyms).o
-
-define verify_kallsyms
- $(Q)$(if $($(quiet)cmd_sysmap), \
- echo ' $($(quiet)cmd_sysmap) .tmp_System.map' &&) \
- $(cmd_sysmap) .tmp_vmlinux$(last_kallsyms) .tmp_System.map
- $(Q)cmp -s System.map .tmp_System.map || \
- (echo Inconsistent kallsyms data; \
- echo Try setting CONFIG_KALLSYMS_EXTRA_PASS; \
- rm .tmp_kallsyms* ; /bin/false )
-endef
-
-# Update vmlinux version before link
-# Use + in front of this rule to silent warning about make -j1
-# First command is ':' to allow us to use + in front of this rule
-cmd_ksym_ld = $(cmd_vmlinux__)
-define rule_ksym_ld
- :
- +$(call cmd,vmlinux_version)
- $(call cmd,vmlinux__)
- $(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
-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
- $(call if_changed_dep,as_o_S)
-
-.tmp_kallsyms%.S: .tmp_vmlinux% $(KALLSYMS)
- $(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_vmlinux2: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms1.o FORCE
- $(call if_changed,vmlinux__)
-
-.tmp_vmlinux3: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms2.o FORCE
- $(call if_changed,vmlinux__)
-
-# Needs to visit scripts/ before $(KALLSYMS) can be used.
-$(KALLSYMS): scripts ;
-
-# Generate some data for debugging strange kallsyms problems
-debug_kallsyms: .tmp_map$(last_kallsyms)
-
-.tmp_map%: .tmp_vmlinux% FORCE
- ($(OBJDUMP) -h $< | $(AWK) '/^ +[0-9]/{print $$4 " 0 " $$2}'; $(NM) $<) | sort > $@
-
-.tmp_map3: .tmp_map2
-
-.tmp_map2: .tmp_map1
-
-endif # ifdef CONFIG_KALLSYMS
+# ---------------------------------------------------------------------------
+export KBUILD_VMLINUX_INIT := $(head-y) $(init-y)
+export KBUILD_VMLINUX_MAIN := $(core-y) $(libs-y) $(drivers-y) $(net-y)
+export KBUILD_VMLINUX_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds
+export KBUILD_VMLINUX_EXTRA
+export LDFLAGS_vmlinux

-# Do modpost on a prelinked vmlinux. The finally linked vmlinux has
-# relevant sections renamed as per the linker script.
-quiet_cmd_vmlinux-modpost = LD $@
- cmd_vmlinux-modpost = $(LD) $(LDFLAGS) -r -o $@ \
- $(vmlinux-init) --start-group $(vmlinux-main) --end-group \
- $(filter-out $(vmlinux-init) $(vmlinux-main) FORCE ,$^)
-define rule_vmlinux-modpost
- :
- +$(call cmd,vmlinux-modpost)
- $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@
- $(Q)echo 'cmd_$@ := $(cmd_vmlinux-modpost)' > $(dot-target).cmd
-endef
+vmlinux-deps := $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN)
+vmlinux-deps += $(KBUILD_VMLINUX_LDS)

# vmlinux image - including updated kernel symbols
-vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE
+vmlinux: $(vmlinux-deps)
ifdef CONFIG_HEADERS_CHECK
$(Q)$(MAKE) -f $(srctree)/Makefile headers_check
endif
ifdef CONFIG_SAMPLES
$(Q)$(MAKE) $(build)=samples
endif
- $(call vmlinux-modpost)
- $(call if_changed_rule,vmlinux__)
- $(Q)rm -f .old_version
-
-# build vmlinux.o first to catch section mismatch errors early
-ifdef CONFIG_KALLSYMS
-.tmp_vmlinux1: vmlinux.o
-endif
-
-modpost-init := $(filter-out init/built-in.o, $(vmlinux-init))
-vmlinux.o: $(modpost-init) $(vmlinux-main) FORCE
- $(call if_changed_rule,vmlinux-modpost)
+ $(Q)$(CONFIG_SHELL) $(srctree)/scripts/link-vmlinux.sh

-# The actual objects are generated when descending,
+# The actual objects are generated when descending,
# make sure no implicit rule kicks in
-$(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
+$(sort $(vmlinux-deps)): $(vmlinux-dirs) ;

# Handle descending into subdirectories listed in $(vmlinux-dirs)
# Preset locale variables to speed up the build process. Limit locale
diff --git a/arch/um/Makefile b/arch/um/Makefile
index dbeab15..06cbc09 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -104,7 +104,7 @@ archprepare: $(ARCH_SYMLINKS) $(ARCH_DIR)/include/user_constants.h
prepare: $(ARCH_DIR)/include/kern_constants.h

LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static
-LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib
+LINK-$(CONFIG_LD_SCRIPT_DYN) += -rpath /lib -rpath /usr/lib

CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) \
$(call cc-option, -fno-stack-protector,) \
@@ -117,19 +117,8 @@ CPPFLAGS_vmlinux.lds = -U$(SUBARCH) -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
-DELF_FORMAT="$(ELF_FORMAT)" -DKERNEL_STACK_SIZE=$(STACK_SIZE)

# The wrappers will select whether using "malloc" or the kernel allocator.
-LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
-
-LD_FLAGS_CMDLINE = $(foreach opt,$(LDFLAGS),-Wl,$(opt))
-
-CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) $(LD_FLAGS_CMDLINE)
-define cmd_vmlinux__
- $(CC) $(CFLAGS_vmlinux) -o $@ \
- -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \
- -Wl,--start-group $(vmlinux-main) -Wl,--end-group \
- -lutil \
- $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o \
- FORCE ,$^) ; rm -f linux
-endef
+LDFLAGS_vmlinux := $(LINK-y) --wrap malloc --wrap free --wrap calloc
+KBUILD_VMLINUX_EXTRA := -lutil

# When cleaning we don't include .config, so we don't include
# TT or skas makefiles and don't clean skas_ptregs.h.
diff --git a/init/Kconfig b/init/Kconfig
index 6199d11..5fc1067 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -588,18 +588,6 @@ config KALLSYMS_ALL

Say N.

-config KALLSYMS_EXTRA_PASS
- bool "Do an extra kallsyms pass"
- depends on KALLSYMS
- help
- If kallsyms is not working correctly, the build will fail with
- inconsistent kallsyms data. If that occurs, log a bug report and
- turn on KALLSYMS_EXTRA_PASS which should result in a stable build.
- Always say N here unless you find a bug in kallsyms, which must be
- reported. KALLSYMS_EXTRA_PASS is only a temporary workaround while
- you wait for kallsyms to be fixed.
-
-
config HOTPLUG
bool "Support for hot-pluggable devices" if EMBEDDED
default y
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
new file mode 100644
index 0000000..b9ecff5
--- /dev/null
+++ b/scripts/link-vmlinux.sh
@@ -0,0 +1,145 @@
+# Build vmlinux
+# ---------------------------------------------------------------------------
+# vmlinux is built from the objects selected by $(KBUILD_VMLINUX_INIT) and
+# $(KBUILD_VMLINUX_MAIN). Most are built-in.o files from top-level directories
+# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
+# Ordering when linking is important, and $(KBUILD_VMLINUX_INIT) must be first.
+#
+# vmlinux
+# ^
+# |
+# +-< $(KBUILD_VMLINUX_INIT)
+# | +--< init/version.o + more
+# |
+# +--< $(KBUILD_VMLINUX_MAIN)
+# | +--< driver/built-in.o mm/built-in.o + more
+# |
+# +-< $(KBUILD_VMLINUX_EXTRA)
+#
+# vmlinux version (uname -v) cannot be updated during normal
+# descending-into-subdirs phase since we do not yet know if we need to
+# update vmlinux.
+#
+# System.map is generated to document addresses of all kernel symbols
+
+
+# We need access to CONFIG_ symbols
+source .config
+# Error out on error
+set -e
+# USe "make V=3" to debug this script
+if [ "${KBUILD_VERBOSE}" = "3" ]; then
+ set -x
+fi
+
+MAKE=make
+# Override MAKEFLAGS to avoid parrallel builds
+MAKEFLAGS='--no-print-directory -Rr --include-dir=$(srctree)'
+# Delete output files in case of error
+trap cleanup SIGHUP SIGINT SIGQUIT SIGTERM ERR
+cleanup()
+{
+ rm -f vmlinux.o
+ rm -f .old_version
+ rm -f .tmp_vmlinux*
+ rm -f .tmp_kallsyms*
+ rm -f vmlinux
+ rm -f .tmp_System.map
+ rm -f System.map
+}
+# non-verbose output
+tell()
+{
+ printf " %-7s %s\n" $1 $2
+}
+
+#####
+# Generate System.map
+
+# $NM produces the following output:
+# f0081e80 T alloc_vfsmnt
+
+# The second row specify the type of the symbol:
+# A = Absolute
+# B = Uninitialised data (.bss)
+# C = Comon symbol
+# D = Initialised data
+# G = Initialised data for small objects
+# I = Indirect reference to another symbol
+# N = Debugging symbol
+# R = Read only
+# S = Uninitialised data for small objects
+# T = Text code symbol
+# U = Undefined symbol
+# V = Weak symbol
+# W = Weak symbol
+# Corresponding small letters are local symbols
+
+# For System.map filter away:
+# a - local absolute symbols
+# N = Debugging symbol
+# U - undefined global symbols
+# w - local weak symbols
+
+# readprofile starts reading symbols when _stext is found, and
+# continue until it finds a symbol which is not either of 'T', 't',
+# 'W' or 'w'. __crc_ are 'A' and placed in the middle
+# so we just ignore them to let readprofile continue to work.
+# (At least sparc64 has __crc_ in the middle).
+mksysmap()
+{
+ $NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)'
+}
+
+# link vmlinux.o
+tell LD vmlinux.o
+${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -r -o vmlinux.o \
+ ${KBUILD_VMLINUX_INIT} \
+ --start-group ${KBUILD_VMLINUX_MAIN} --end-group \
+ ${KBUILD_VMLINUX_EXTRA}
+
+# modpost vmlinux.o
+${MAKE} -f ${srctree}/scripts/Makefile.modpost vmlinux.o
+
+# Update version
+tell GEN .version
+if [ ! -r .version ]; then
+ rm -f .version;
+ echo 1 >.version;
+else
+ mv .version .old_version;
+ expr 0$(cat .old_version) + 1 >.version;
+fi;
+
+# final build of init/
+${MAKE} -f ${srctree}/scripts/Makefile.build obj=init
+
+VMLINUX=vmlinux
+if [ "${CONFIG_KALLSYMS}" = "y" ]; then
+ VMLINUX=.tmp_vmlinux
+fi
+
+# First stage of fully linked vmlinux
+tell LD ${VMLINUX}
+${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${VMLINUX} \
+ -T ${KBUILD_VMLINUX_LDS} vmlinux.o
+
+if [ "${CONFIG_KALLSYMS}" = "y" ]; then
+
+ # Do an extra pass to link in kallsyms data
+ ${NM} -n .tmp_vmlinux | scripts/kallsyms > .tmp_kallsyms.S
+ ${CC} ${KBUILD_AFLAGS} ${KBUILD_CPPFLAGS} -c -o .tmp_kallsyms.o \
+ .tmp_kallsyms.S
+ # link in kalll symbols
+ tell LD vmlinux
+ ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o vmlinux \
+ -T ${KBUILD_VMLINUX_LDS} vmlinux.o .tmp_kallsyms.o
+fi
+
+tell SYSMAP System.map
+mksysmap vmlinux > System.map
+
+# We made a new kernel - delete old version file
+rm -f .old_version
+
+
diff --git a/scripts/mksysmap b/scripts/mksysmap
deleted file mode 100644
index 6e133a0..0000000
--- a/scripts/mksysmap
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh -x
-# Based on the vmlinux file create the System.map file
-# System.map is used by module-init tools and some debugging
-# tools to retrieve the actual addresses of symbols in the kernel.
-#
-# Usage
-# mksysmap vmlinux System.map
-
-
-#####
-# Generate System.map (actual filename passed as second argument)
-
-# $NM produces the following output:
-# f0081e80 T alloc_vfsmnt
-
-# The second row specify the type of the symbol:
-# A = Absolute
-# B = Uninitialised data (.bss)
-# C = Comon symbol
-# D = Initialised data
-# G = Initialised data for small objects
-# I = Indirect reference to another symbol
-# N = Debugging symbol
-# R = Read only
-# S = Uninitialised data for small objects
-# T = Text code symbol
-# U = Undefined symbol
-# V = Weak symbol
-# W = Weak symbol
-# Corresponding small letters are local symbols
-
-# For System.map filter away:
-# a - local absolute symbols
-# U - undefined global symbols
-# N - debugging symbols
-# w - local weak symbols
-
-# readprofile starts reading symbols when _stext is found, and
-# continue until it finds a symbol which is not either of 'T', 't',
-# 'W' or 'w'. __crc_ are 'A' and placed in the middle
-# so we just ignore them to let readprofile continue to work.
-# (At least sparc64 has __crc_ in the middle).
-
-$NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)' > $2
-


2008-06-11 15:11:29

by Jeff Dike

[permalink] [raw]
Subject: Re: kbuild breaks um - fails to find util when linking

On Tue, Jun 10, 2008 at 09:03:07PM +0200, Sam Ravnborg wrote:
> In an attempt to make the final link of vmlinux
> readable/hackable I have broken um build.
>
> um used a special rule so it could use gcc as linker.
> With my changes we need to use ld to link vmlinux and
> ld now fails to locate util.
>
> I hope you have a clue why. I tried various things but
> did not find out why ld cannot locate util.

Looks to me like replacing the "-rpath foo" with -Lfoo does the trick.

I'll work up an incremental patch for this.

Jeff

--
Work email - jdike at linux dot intel dot com

2008-06-11 15:23:34

by Jeff Dike

[permalink] [raw]
Subject: Re: kbuild breaks um - fails to find util when linking

On Tue, Jun 10, 2008 at 09:03:07PM +0200, Sam Ravnborg wrote:
> Hi Jeff.
>
> In an attempt to make the final link of vmlinux
> readable/hackable I have broken um build.
>
> um used a special rule so it could use gcc as linker.
> With my changes we need to use ld to link vmlinux and
> ld now fails to locate util.
>
> I hope you have a clue why. I tried various things but
> did not find out why ld cannot locate util.

This little patch fixes the -lutil problem linking vmlinux.o, but on
the final link, I get what appears to be every libc symbol
undefined...

Index: linux-2.6-git/arch/um/Makefile
===================================================================
--- linux-2.6-git.orig/arch/um/Makefile 2008-06-11 10:46:03.000000000 -0400
+++ linux-2.6-git/arch/um/Makefile 2008-06-11 11:19:05.000000000 -0400
@@ -104,7 +104,7 @@ archprepare: $(ARCH_SYMLINKS) $(ARCH_DIR
prepare: $(ARCH_DIR)/include/kern_constants.h

LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static
-LINK-$(CONFIG_LD_SCRIPT_DYN) += -rpath /lib -rpath /usr/lib
+LINK-$(CONFIG_LD_SCRIPT_DYN) += -L/lib -L/usr/lib

CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) \
$(call cc-option, -fno-stack-protector,) \

Jeff

--
Work email - jdike at linux dot intel dot com

2008-06-11 15:48:35

by Jeff Dike

[permalink] [raw]
Subject: Re: kbuild breaks um - fails to find util when linking

This patch obviously isn't usable for anyone else, but UML needs a
hook or something to add libgcc and libc to the ld commands:

Index: linux-2.6-git/scripts/link-vmlinux.sh
===================================================================
--- linux-2.6-git.orig/scripts/link-vmlinux.sh 2008-06-11 11:26:07.000000000 -0400
+++ linux-2.6-git/scripts/link-vmlinux.sh 2008-06-11 11:41:04.000000000 -0400
@@ -122,7 +122,7 @@ fi
# First stage of fully linked vmlinux
tell LD ${VMLINUX}
${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${VMLINUX} \
- -T ${KBUILD_VMLINUX_LDS} vmlinux.o
+ -T ${KBUILD_VMLINUX_LDS} vmlinux.o `gcc -print-libgcc-file-name` -lc

if [ "${CONFIG_KALLSYMS}" = "y" ]; then

@@ -133,7 +133,8 @@ if [ "${CONFIG_KALLSYMS}" = "y" ]; then
# link in kalll symbols
tell LD vmlinux
${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o vmlinux \
- -T ${KBUILD_VMLINUX_LDS} vmlinux.o .tmp_kallsyms.o
+ -T ${KBUILD_VMLINUX_LDS} vmlinux.o .tmp_kallsyms.o \
+ `gcc -print-libgcc-file-name` -lc
fi

tell SYSMAP System.map

This fixes the flood of undefined symbols, but I still get this on the
link:
ld: warning: Cannot create .note.gnu.build-id section, --build-id ignored.
ld: warning: cannot find entry symbol _start; defaulting to 08056320

And when I run the result, I get this, which I don't understand at
all:

-bash: ./uml/linux: /usr/lib/libc.so.1: bad ELF interpreter: No
such file or directory

Jeff

--
Work email - jdike at linux dot intel dot com

2008-06-11 19:48:41

by Sam Ravnborg

[permalink] [raw]
Subject: Re: kbuild breaks um - fails to find util when linking

On Wed, Jun 11, 2008 at 11:48:16AM -0400, Jeff Dike wrote:
> This patch obviously isn't usable for anyone else, but UML needs a
> hook or something to add libgcc and libc to the ld commands:
>
> Index: linux-2.6-git/scripts/link-vmlinux.sh
> ===================================================================
> --- linux-2.6-git.orig/scripts/link-vmlinux.sh 2008-06-11 11:26:07.000000000 -0400
> +++ linux-2.6-git/scripts/link-vmlinux.sh 2008-06-11 11:41:04.000000000 -0400
> @@ -122,7 +122,7 @@ fi
> # First stage of fully linked vmlinux
> tell LD ${VMLINUX}
> ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${VMLINUX} \
> - -T ${KBUILD_VMLINUX_LDS} vmlinux.o
> + -T ${KBUILD_VMLINUX_LDS} vmlinux.o `gcc -print-libgcc-file-name` -lc
>
> if [ "${CONFIG_KALLSYMS}" = "y" ]; then
>
> @@ -133,7 +133,8 @@ if [ "${CONFIG_KALLSYMS}" = "y" ]; then
> # link in kalll symbols
> tell LD vmlinux
> ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o vmlinux \
> - -T ${KBUILD_VMLINUX_LDS} vmlinux.o .tmp_kallsyms.o
> + -T ${KBUILD_VMLINUX_LDS} vmlinux.o .tmp_kallsyms.o \
> + `gcc -print-libgcc-file-name` -lc
> fi
>
> tell SYSMAP System.map
>
> This fixes the flood of undefined symbols, but I still get this on the
> link:
> ld: warning: Cannot create .note.gnu.build-id section, --build-id ignored.
> ld: warning: cannot find entry symbol _start; defaulting to 08056320
>
> And when I run the result, I get this, which I don't understand at
> all:
>
> -bash: ./uml/linux: /usr/lib/libc.so.1: bad ELF interpreter: No
> such file or directory

Thanks Jeff.

I will take an additional look tomorrow.

Sam

2008-06-12 18:08:27

by Sam Ravnborg

[permalink] [raw]
Subject: Re: kbuild breaks um - fails to find util when linking

On Wed, Jun 11, 2008 at 11:48:16AM -0400, Jeff Dike wrote:
> This patch obviously isn't usable for anyone else, but UML needs a
> hook or something to add libgcc and libc to the ld commands:
>
> Index: linux-2.6-git/scripts/link-vmlinux.sh
> ===================================================================
> --- linux-2.6-git.orig/scripts/link-vmlinux.sh 2008-06-11 11:26:07.000000000 -0400
> +++ linux-2.6-git/scripts/link-vmlinux.sh 2008-06-11 11:41:04.000000000 -0400
> @@ -122,7 +122,7 @@ fi
> # First stage of fully linked vmlinux
> tell LD ${VMLINUX}
> ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${VMLINUX} \
> - -T ${KBUILD_VMLINUX_LDS} vmlinux.o
> + -T ${KBUILD_VMLINUX_LDS} vmlinux.o `gcc -print-libgcc-file-name` -lc
>
> if [ "${CONFIG_KALLSYMS}" = "y" ]; then
>
> @@ -133,7 +133,8 @@ if [ "${CONFIG_KALLSYMS}" = "y" ]; then
> # link in kalll symbols
> tell LD vmlinux
> ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o vmlinux \
> - -T ${KBUILD_VMLINUX_LDS} vmlinux.o .tmp_kallsyms.o
> + -T ${KBUILD_VMLINUX_LDS} vmlinux.o .tmp_kallsyms.o \
> + `gcc -print-libgcc-file-name` -lc
> fi
>
> tell SYSMAP System.map
>
> This fixes the flood of undefined symbols, but I still get this on the
> link:
> ld: warning: Cannot create .note.gnu.build-id section, --build-id ignored.
> ld: warning: cannot find entry symbol _start; defaulting to 08056320
>
> And when I run the result, I get this, which I don't understand at
> all:
>
> -bash: ./uml/linux: /usr/lib/libc.so.1: bad ELF interpreter: No
> such file or directory

Hi Jeff.
Following patch will result in a building ARCH=um kernel.
If it works I dunno.

I tried a build with allnoconfig and defconfig.

Could you please review/test this patch and let me know
if this works. It is on top of the first patch I sent.

Note: It includes a unrelated powerpc fix too (AFLAGS_KERNEL).

Thanks,
Sam

diff --git a/arch/um/Makefile b/arch/um/Makefile
index 06cbc09..4eb0b07 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -104,7 +104,7 @@ archprepare: $(ARCH_SYMLINKS) $(ARCH_DIR)/include/user_constants.h
prepare: $(ARCH_DIR)/include/kern_constants.h

LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static
-LINK-$(CONFIG_LD_SCRIPT_DYN) += -rpath /lib -rpath /usr/lib
+LINK-$(CONFIG_LD_SCRIPT_DYN) += -L/lib -L/usr/lib

CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) \
$(call cc-option, -fno-stack-protector,) \
@@ -118,7 +118,13 @@ CPPFLAGS_vmlinux.lds = -U$(SUBARCH) -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \

# The wrappers will select whether using "malloc" or the kernel allocator.
LDFLAGS_vmlinux := $(LINK-y) --wrap malloc --wrap free --wrap calloc
-KBUILD_VMLINUX_EXTRA := -lutil
+KBUILD_VMLINUX_EXTRA := \
+$(shell $(CC) -print-file-name=crt1.o) \
+$(shell $(CC) -print-file-name=crti.o) \
+$(shell $(CC) -print-file-name=libgcc_s.so) \
+$(shell $(CC) -print-file-name=ld-linux.so.2) \
+$(shell $(CC) -print-file-name=libutil.so) \
+$(shell $(CC) -print-file-name=libc.so)

# When cleaning we don't include .config, so we don't include
# TT or skas makefiles and don't clean skas_ptregs.h.
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index b9ecff5..e8fc6ab 100644
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -95,8 +95,7 @@ mksysmap()
tell LD vmlinux.o
${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -r -o vmlinux.o \
${KBUILD_VMLINUX_INIT} \
- --start-group ${KBUILD_VMLINUX_MAIN} --end-group \
- ${KBUILD_VMLINUX_EXTRA}
+ --start-group ${KBUILD_VMLINUX_MAIN} --end-group

# modpost vmlinux.o
${MAKE} -f ${srctree}/scripts/Makefile.modpost vmlinux.o
@@ -121,19 +120,19 @@ fi

# First stage of fully linked vmlinux
tell LD ${VMLINUX}
-${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${VMLINUX} \
- -T ${KBUILD_VMLINUX_LDS} vmlinux.o
+${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} ${KBUILD_VMLINUX_EXTRA} \
+ -o ${VMLINUX} -T ${KBUILD_VMLINUX_LDS} vmlinux.o

if [ "${CONFIG_KALLSYMS}" = "y" ]; then

# Do an extra pass to link in kallsyms data
${NM} -n .tmp_vmlinux | scripts/kallsyms > .tmp_kallsyms.S
- ${CC} ${KBUILD_AFLAGS} ${KBUILD_CPPFLAGS} -c -o .tmp_kallsyms.o \
- .tmp_kallsyms.S
+ ${CC} ${KBUILD_AFLAGS} ${AFLAGS_KERNEL} ${KBUILD_CPPFLAGS} -c \
+ -o .tmp_kallsyms.o .tmp_kallsyms.S
# link in kalll symbols
tell LD vmlinux
- ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o vmlinux \
- -T ${KBUILD_VMLINUX_LDS} vmlinux.o .tmp_kallsyms.o
+ ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} ${KBUILD_VMLINUX_EXTRA} \
+ -o vmlinux -T ${KBUILD_VMLINUX_LDS} vmlinux.o .tmp_kallsyms.o
fi

tell SYSMAP System.map

2008-06-12 20:13:39

by Jeff Dike

[permalink] [raw]
Subject: Re: kbuild breaks um - fails to find util when linking

On Thu, Jun 12, 2008 at 08:08:59PM +0200, Sam Ravnborg wrote:
> Following patch will result in a building ARCH=um kernel.
> If it works I dunno.

You can just try running it. Given its behavior with this patch so
far, it would be an excellent sign for it to figure out that it has no
root filesystem and panic.

Anyway, I can't get it to give me a UML binary. I see this in the
build output (and V=3 doesn't make it any more verbose):


CHK include/linux/compile.h
LINK linux

Compilation finished at Thu Jun 12 16:11:15

but no linux or vmlinux in my output directory.

Jeff

--
Work email - jdike at linux dot intel dot com

2008-06-12 21:05:46

by Sam Ravnborg

[permalink] [raw]
Subject: Re: kbuild breaks um - fails to find util when linking

On Thu, Jun 12, 2008 at 04:13:15PM -0400, Jeff Dike wrote:
> On Thu, Jun 12, 2008 at 08:08:59PM +0200, Sam Ravnborg wrote:
> > Following patch will result in a building ARCH=um kernel.
> > If it works I dunno.
>
> You can just try running it. Given its behavior with this patch so
> far, it would be an excellent sign for it to figure out that it has no
> root filesystem and panic.
>
> Anyway, I can't get it to give me a UML binary. I see this in the
> build output (and V=3 doesn't make it any more verbose):
>
>
> CHK include/linux/compile.h
> LINK linux
>
> Compilation finished at Thu Jun 12 16:11:15
>
> but no linux or vmlinux in my output directory.

So appearantly kbuild thinks you have a vmlinux
so no need to relink.
And the line "LINK linux" implies this as well.

Please double check that you do not have a vmlinux,
and try V=2" to see where LINK picks up the vmlinux.

My build finised:
$ ./linux
./linux: /usr/lib/libc.so.1: bad ELF interpreter: No such file or directory

So I will take an additional look tomorrow.

Sam

2008-06-13 23:09:37

by Gabriel C

[permalink] [raw]
Subject: Re: kbuild breaks um - fails to find util when linking

Sam Ravnborg wrote:

Hi Sam , Jeff ,

> On Thu, Jun 12, 2008 at 04:13:15PM -0400, Jeff Dike wrote:
>> On Thu, Jun 12, 2008 at 08:08:59PM +0200, Sam Ravnborg wrote:
>>> Following patch will result in a building ARCH=um kernel.
>>> If it works I dunno.
>> You can just try running it. Given its behavior with this patch so
>> far, it would be an excellent sign for it to figure out that it has no
>> root filesystem and panic.
>>
>> Anyway, I can't get it to give me a UML binary. I see this in the
>> build output (and V=3 doesn't make it any more verbose):
>>
>>
>> CHK include/linux/compile.h
>> LINK linux
>>
>> Compilation finished at Thu Jun 12 16:11:15
>>
>> but no linux or vmlinux in my output directory.
>
> So appearantly kbuild thinks you have a vmlinux
> so no need to relink.
> And the line "LINK linux" implies this as well.
>
> Please double check that you do not have a vmlinux,
> and try V=2" to see where LINK picks up the vmlinux.
>
> My build finised:
> $ ./linux
> ./linux: /usr/lib/libc.so.1: bad ELF interpreter: No such file or directory


I didn't tested this patch but I think LINK-$(CONFIG_LD_SCRIPT_DYN) should have -rpath / -rpath-link too since
libc.so.* is usually in /lib and not /usr/lib.

Another thing I noticed is this hunk :

+$(shell $(CC) -print-file-name=ld-linux.so.2) \

On 64bit that should not work since it is ld-linux-x86-64.so.2 and not ld-linux.so.2

>

> So I will take an additional look tomorrow.
>
> Sam


Regards ,

Gabriel

2008-06-18 16:52:23

by Jeff Dike

[permalink] [raw]
Subject: Re: kbuild breaks um - fails to find util when linking

On Sat, Jun 14, 2008 at 01:08:44AM +0200, Gabriel C wrote:
> Another thing I noticed is this hunk :
>
> +$(shell $(CC) -print-file-name=ld-linux.so.2) \
>
> On 64bit that should not work since it is ld-linux-x86-64.so.2 and not ld-linux.so.2

That's a good point too.

This seems like an awful lot of fragile hair to go through in order to
avoid using gcc to drive the link.

Jeff

--
Work email - jdike at linux dot intel dot com

2008-06-18 16:58:44

by Sam Ravnborg

[permalink] [raw]
Subject: Re: kbuild breaks um - fails to find util when linking

On Wed, Jun 18, 2008 at 12:51:38PM -0400, Jeff Dike wrote:
> On Sat, Jun 14, 2008 at 01:08:44AM +0200, Gabriel C wrote:
> > Another thing I noticed is this hunk :
> >
> > +$(shell $(CC) -print-file-name=ld-linux.so.2) \
> >
> > On 64bit that should not work since it is ld-linux-x86-64.so.2 and not ld-linux.so.2
>
> That's a good point too.
>
> This seems like an awful lot of fragile hair to go through in order to
> avoid using gcc to drive the link.

I agree on that. I have pulled the patch from kbuild-next.git,
and it will return only when I have found a simple way to handle um.
I think it is easy to do but I have not looked at it yet.

Sam