With this change, doing 'make vdso_install' and telling gdb: set debug-file-directory /lib/modules/KVER/vdso will enable vdso debugging with symbols. This is useful for testing, but kernel RPM builds will probably want to manually delete these symlinks or otherwise do something sensible when they strip the vdso/*.so files. If ld does not support --build-id, then the symlinks will not be created. Note that kernel packagers that use vdso_install may need to adjust their packaging scripts to accomdate this change. For example, Fedora's scripts create build-id symlinks themselves in a different location, so the spec should probably be updated to remove the symlinks created by make vdso_install. Signed-off-by: Andy Lutomirski <luto@amacapital.net> Link: http://lkml.kernel.org/r/a424b189ce3ced85fe1e82d032a20e765e0fe0d3.1403291930.git.luto@amacapital.net Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
202 lines
6.1 KiB
Makefile
202 lines
6.1 KiB
Makefile
#
|
|
# Building vDSO images for x86.
|
|
#
|
|
|
|
KBUILD_CFLAGS += $(DISABLE_LTO)
|
|
|
|
VDSO64-$(CONFIG_X86_64) := y
|
|
VDSOX32-$(CONFIG_X86_X32_ABI) := y
|
|
VDSO32-$(CONFIG_X86_32) := y
|
|
VDSO32-$(CONFIG_COMPAT) := y
|
|
|
|
# files to link into the vdso
|
|
vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o vdso-fakesections.o
|
|
|
|
# files to link into kernel
|
|
obj-y += vma.o
|
|
|
|
# vDSO images to build
|
|
vdso_img-$(VDSO64-y) += 64
|
|
vdso_img-$(VDSOX32-y) += x32
|
|
vdso_img-$(VDSO32-y) += 32-int80
|
|
vdso_img-$(CONFIG_COMPAT) += 32-syscall
|
|
vdso_img-$(VDSO32-y) += 32-sysenter
|
|
|
|
obj-$(VDSO32-y) += vdso32-setup.o
|
|
|
|
vobjs := $(foreach F,$(vobjs-y),$(obj)/$F)
|
|
|
|
$(obj)/vdso.o: $(obj)/vdso.so
|
|
|
|
targets += vdso.lds $(vobjs-y)
|
|
|
|
# Build the vDSO image C files and link them in.
|
|
vdso_img_objs := $(vdso_img-y:%=vdso-image-%.o)
|
|
vdso_img_cfiles := $(vdso_img-y:%=vdso-image-%.c)
|
|
vdso_img_sodbg := $(vdso_img-y:%=vdso%.so.dbg)
|
|
obj-y += $(vdso_img_objs)
|
|
targets += $(vdso_img_cfiles)
|
|
targets += $(vdso_img_sodbg)
|
|
.SECONDARY: $(vdso_img-y:%=$(obj)/vdso-image-%.c)
|
|
|
|
export CPPFLAGS_vdso.lds += -P -C
|
|
|
|
VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \
|
|
-Wl,--no-undefined \
|
|
-Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 \
|
|
$(DISABLE_LTO)
|
|
|
|
$(obj)/vdso64.so.dbg: $(src)/vdso.lds $(vobjs) FORCE
|
|
$(call if_changed,vdso)
|
|
|
|
HOST_EXTRACFLAGS += -I$(srctree)/tools/include
|
|
hostprogs-y += vdso2c
|
|
|
|
quiet_cmd_vdso2c = VDSO2C $@
|
|
define cmd_vdso2c
|
|
$(obj)/vdso2c $< $@
|
|
endef
|
|
|
|
$(obj)/vdso-image-%.c: $(obj)/vdso%.so.dbg $(obj)/vdso2c FORCE
|
|
$(call if_changed,vdso2c)
|
|
|
|
#
|
|
# Don't omit frame pointers for ease of userspace debugging, but do
|
|
# optimize sibling calls.
|
|
#
|
|
CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \
|
|
$(filter -g%,$(KBUILD_CFLAGS)) $(call cc-option, -fno-stack-protector) \
|
|
-fno-omit-frame-pointer -foptimize-sibling-calls
|
|
|
|
$(vobjs): KBUILD_CFLAGS += $(CFL)
|
|
|
|
#
|
|
# vDSO code runs in userspace and -pg doesn't help with profiling anyway.
|
|
#
|
|
CFLAGS_REMOVE_vdso-note.o = -pg
|
|
CFLAGS_REMOVE_vclock_gettime.o = -pg
|
|
CFLAGS_REMOVE_vgetcpu.o = -pg
|
|
CFLAGS_REMOVE_vvar.o = -pg
|
|
|
|
#
|
|
# X32 processes use x32 vDSO to access 64bit kernel data.
|
|
#
|
|
# Build x32 vDSO image:
|
|
# 1. Compile x32 vDSO as 64bit.
|
|
# 2. Convert object files to x32.
|
|
# 3. Build x32 VDSO image with x32 objects, which contains 64bit codes
|
|
# so that it can reach 64bit address space with 64bit pointers.
|
|
#
|
|
|
|
CPPFLAGS_vdsox32.lds = $(CPPFLAGS_vdso.lds)
|
|
VDSO_LDFLAGS_vdsox32.lds = -Wl,-m,elf32_x86_64 \
|
|
-Wl,-soname=linux-vdso.so.1 \
|
|
-Wl,-z,max-page-size=4096 \
|
|
-Wl,-z,common-page-size=4096
|
|
|
|
# 64-bit objects to re-brand as x32
|
|
vobjs64-for-x32 := $(filter-out $(vobjs-nox32),$(vobjs-y))
|
|
|
|
# x32-rebranded versions
|
|
vobjx32s-y := $(vobjs64-for-x32:.o=-x32.o)
|
|
|
|
# same thing, but in the output directory
|
|
vobjx32s := $(foreach F,$(vobjx32s-y),$(obj)/$F)
|
|
|
|
# Convert 64bit object file to x32 for x32 vDSO.
|
|
quiet_cmd_x32 = X32 $@
|
|
cmd_x32 = $(OBJCOPY) -O elf32-x86-64 $< $@
|
|
|
|
$(obj)/%-x32.o: $(obj)/%.o FORCE
|
|
$(call if_changed,x32)
|
|
|
|
targets += vdsox32.lds $(vobjx32s-y)
|
|
|
|
$(obj)/vdsox32.so.dbg: $(src)/vdsox32.lds $(vobjx32s) FORCE
|
|
$(call if_changed,vdso)
|
|
|
|
#
|
|
# Build multiple 32-bit vDSO images to choose from at boot time.
|
|
#
|
|
vdso32.so-$(VDSO32-y) += int80
|
|
vdso32.so-$(CONFIG_COMPAT) += syscall
|
|
vdso32.so-$(VDSO32-y) += sysenter
|
|
|
|
vdso32-images = $(vdso32.so-y:%=vdso32-%.so)
|
|
|
|
CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds)
|
|
VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-m,elf_i386 -Wl,-soname=linux-gate.so.1
|
|
|
|
# This makes sure the $(obj) subdirectory exists even though vdso32/
|
|
# is not a kbuild sub-make subdirectory.
|
|
override obj-dirs = $(dir $(obj)) $(obj)/vdso32/
|
|
|
|
targets += vdso32/vdso32.lds
|
|
targets += vdso32/note.o vdso32/vclock_gettime.o $(vdso32.so-y:%=vdso32/%.o)
|
|
targets += vdso32/vclock_gettime.o vdso32/vdso-fakesections.o
|
|
|
|
$(obj)/vdso32.o: $(vdso32-images:%=$(obj)/%)
|
|
|
|
KBUILD_AFLAGS_32 := $(filter-out -m64,$(KBUILD_AFLAGS))
|
|
$(vdso32-images:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_32)
|
|
$(vdso32-images:%=$(obj)/%.dbg): asflags-$(CONFIG_X86_64) += -m32
|
|
|
|
KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS))
|
|
KBUILD_CFLAGS_32 := $(filter-out -mcmodel=kernel,$(KBUILD_CFLAGS_32))
|
|
KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32))
|
|
KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32))
|
|
KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic
|
|
KBUILD_CFLAGS_32 += $(call cc-option, -fno-stack-protector)
|
|
KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls)
|
|
KBUILD_CFLAGS_32 += -fno-omit-frame-pointer
|
|
$(vdso32-images:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_32)
|
|
|
|
$(vdso32-images:%=$(obj)/%.dbg): $(obj)/vdso32-%.so.dbg: FORCE \
|
|
$(obj)/vdso32/vdso32.lds \
|
|
$(obj)/vdso32/vclock_gettime.o \
|
|
$(obj)/vdso32/vdso-fakesections.o \
|
|
$(obj)/vdso32/note.o \
|
|
$(obj)/vdso32/%.o
|
|
$(call if_changed,vdso)
|
|
|
|
#
|
|
# The DSO images are built using a special linker script.
|
|
#
|
|
quiet_cmd_vdso = VDSO $@
|
|
cmd_vdso = $(CC) -nostdlib -o $@ \
|
|
$(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
|
|
-Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \
|
|
sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
|
|
|
|
VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv) \
|
|
$(call cc-ldoption, -Wl$(comma)--build-id) -Wl,-Bsymbolic $(LTO_CFLAGS)
|
|
GCOV_PROFILE := n
|
|
|
|
#
|
|
# Install the unstripped copies of vdso*.so. If our toolchain supports
|
|
# build-id, install .build-id links as well.
|
|
#
|
|
quiet_cmd_vdso_install = INSTALL $(@:install_%=%)
|
|
define cmd_vdso_install
|
|
cp $< "$(MODLIB)/vdso/$(@:install_%=%)"; \
|
|
if readelf -n $< |grep -q 'Build ID'; then \
|
|
buildid=`readelf -n $< |grep 'Build ID' |sed -e 's/^.*Build ID: \(.*\)$$/\1/'`; \
|
|
first=`echo $$buildid | cut -b-2`; \
|
|
last=`echo $$buildid | cut -b3-`; \
|
|
mkdir -p "$(MODLIB)/vdso/.build-id/$$first"; \
|
|
ln -sf "../../$(@:install_%=%)" "$(MODLIB)/vdso/.build-id/$$first/$$last.debug"; \
|
|
fi
|
|
endef
|
|
|
|
vdso_img_insttargets := $(vdso_img_sodbg:%.dbg=install_%)
|
|
|
|
$(MODLIB)/vdso: FORCE
|
|
@mkdir -p $(MODLIB)/vdso
|
|
|
|
$(vdso_img_insttargets): install_%: $(obj)/%.dbg $(MODLIB)/vdso FORCE
|
|
$(call cmd,vdso_install)
|
|
|
|
PHONY += vdso_install $(vdso_img_insttargets)
|
|
vdso_install: $(vdso_img_insttargets) FORCE
|
|
|
|
clean-files := vdso32-syscall* vdso32-sysenter* vdso32-int80*
|