one click support!

This commit is contained in:
Josh Poimboeuf 2013-01-17 18:09:26 -06:00
parent 4feb144e98
commit e9e4563a80
9 changed files with 169 additions and 44 deletions

View File

@ -1,13 +1,2 @@
KDIR ?= /home/jpoimboe/git/linux
KPATCH_GENERATED ?= kpatch-generated.o
KMOD_DIR ?= /home/jpoimboe/kpatch/kmod
OBJ_ORIG = /home/jpoimboe/kpatch-test/meminfo.o
OBJ_PATCHED = /home/jpoimboe/kpatch-test/meminfo.o.patched
VMLINUX_ORIG = /home/jpoimboe/kpatch-test/vmlinux
all:
$(MAKE) -C elf-diff-copy
elf-diff-copy/elf-diff-copy $(OBJ_ORIG) $(OBJ_PATCHED) -v $(VMLINUX_ORIG) -o $(KMOD_DIR)/$(KPATCH_GENERATED)
$(MAKE) -C $(KDIR) M=$(KMOD_DIR) kpatch-module.o
ld -m elf_x86_64 -r -o $(KMOD_DIR)/kpatch-combined.o $(KMOD_DIR)/kpatch-module.o $(KMOD_DIR)/$(KPATCH_GENERATED) $(KMOD_DIR)/kpatch.lds
$(MAKE) -C $(KDIR) M=$(KMOD_DIR)
$(MAKE) -C kpatch-gen

View File

@ -1,26 +0,0 @@
#!/bin/sh
yo="this/is/a/test"
case yo in
"*test")
echo yo
;;
esac
KSRC=/home/jpoimboe/git/linux/
for i in `find $KSRC -newer /tmp/kpatch_timestamp -name "*.o" -not -name "*.mod.o" -not -name "built-in.o" -not -name "vmlinux.o"`; do
case ${i##$KSRC} in
.tmp_kallsyms1.o|.tmp_kallsyms2.o|init/version.o|arch/x86/boot/version.o|arch/x86/boot/compressed/eboot.o|arch/x86/boot/header.o|arch/x86/boot/compressed/efi_stub_64.o|arch/x86/boot/compressed/piggy.o)
continue
;;
esac
num=`readelf -s $i |awk '{print $4}' |grep FILE |wc -l`
[[ $num -gt 1 ]] && continue
[[ $num == 0 ]] && {
echo "ERROR: unsupported assembly file ${i##$KSRC} changed"
exit 1
}
[[ $num == 1 ]] && echo ${i##$KSRC}
done

View File

@ -1,7 +1,8 @@
obj-m += dummy.o kpatch-patch.o kpatch.o
obj-m += kpatch.o
obj-m += dummy.o
obj-m += kpatch-patch.o
kpatch-objs += base.o trampoline.o
kpatch-patch-objs += kpatch-patch-foo.o
dummy-objs += kpatch-patch-hook.o
kpatch-patch-objs += kpatch-combined.o
dummy-objs += kpatch-module.o

126
kpatch-create Executable file
View File

@ -0,0 +1,126 @@
#!/bin/bash
# vim: tabstop=4 shiftwidth=4 expandtab
set -o nounset
set -o errexit
set -o pipefail
CUR_DIR="$PWD"
SCRIPT="`basename $BASH_SOURCE`"
SCRIPT_DIR="`dirname $BASH_SOURCE`"
KMOD_DIR="$SCRIPT_DIR/kmod"
KPATCH_REG="$KMOD_DIR/kpatch-register.o"
KPATCH_LDS="$KMOD_DIR/kpatch.lds"
KPATCH_GEN="$SCRIPT_DIR/kpatch-gen/kpatch-gen"
KPATCHGCC="$SCRIPT_DIR/kpatch-gcc"
JOBS=4
MAKE_CMD="make -j$JOBS vmlinux"
export CROSS_COMPILE="$KPATCHGCC "
# TODO make in function
PROGRESS_FILE="kpatch-in-progress"
PATCHED=
PATCH=
KERNEL_DIR=
scriptecho ()
{
echo "$SCRIPT: $*"
}
cleanup_objs ()
{
find "$KERNEL_DIR" -name "*.orig_kpatch" -o -name "*.kpatch_gen" | while read file; do
rm -f $file
done
}
cleanup ()
{
scriptecho "cleaning up..."
rm -f "$PROGRESS_FILE"
cleanup_objs
if [ $PATCHED ]; then
cd "$KERNEL_DIR"
patch -p1 -R < "$PATCH"
export CROSS_COMPILE="$KPATCHGCC "
$MAKE_CMD > /dev/null
fi
#rm -rf "$TMPDIR"
}
die ()
{
echo "$SCRIPT: error: $*" >&2
exit 1
}
usage ()
{
echo "usage: $SCRIPT -p [patch] -k [KERNEL_DIR]" >&2
exit 1
}
while getopts "p:k:" arg; do
case "$arg" in
p) PATCH="$OPTARG" ;;
k) KERNEL_DIR="$OPTARG" ;;
*) usage ;;
esac
done
[ ! "$PATCH" ] || [ ! "$KERNEL_DIR" ] && usage
[ ! -f "$PATCH" ] && die "$PATCH doesn't exist"
[ ! -d "$KERNEL_DIR" ] && die "$KERNEL_DIR doesn't exist"
PATCH="`readlink -f \"$PATCH\"`"
KERNEL_DIR="`readlink -f \"$KERNEL_DIR\"`"
TMPDIR="`mktemp -d`"
trap cleanup exit
scriptecho "compiling original kernel"
rm -f "$PROGRESS_FILE"
cleanup_objs
cd "$KERNEL_DIR"
$MAKE_CMD > /dev/null
cp vmlinux vmlinux.orig_kpatch
scriptecho "patching kernel"
patch -p1 < "$PATCH"
PATCHED=1
scriptecho "compiling patched kernel"
touch "$PROGRESS_FILE"
$MAKE_CMD > /dev/null
rm -f "$PROGRESS_FILE"
scriptecho "generating kpatch binaries"
find . -type f -name '*.o.orig_kpatch' | while read file; do
origfile="${file#./}"
newfile="${origfile%.orig_kpatch}"
[ ! -f "$newfile" ] && die "can't find \"$newfile\""
num="`readelf -s \"$file\" |awk '{print $4}' |grep -c FILE`"
[ "$num" = 0 ] && die "unsupported change in (assembly?) file \"$file\""
[ "$num" -gt 1 ] && die "\"$newfile\" has too many FILE symbols"
scriptecho "object changed: \"$newfile\""
"$KPATCH_GEN" "$origfile" "$newfile" -v vmlinux.orig_kpatch -o "$newfile.kpatch_gen"
done
unset CROSS_COMPILE
cp -a "$KMOD_DIR" "$TMPDIR/kmod"
make -C "$KERNEL_DIR" M="$TMPDIR/kmod" kpatch-patch-hook.o
cd $TMPDIR/kmod
find "$KERNEL_DIR" -name "*.kpatch_gen" -exec ld -m elf_x86_64 -r -o kpatch-patch-foo.o kpatch-patch-hook.o kpatch.lds {} +
make -C "$KERNEL_DIR" M="$TMPDIR/kmod" kpatch.ko
make -C "$KERNEL_DIR" M="$TMPDIR/kmod" kpatch-patch.ko
scriptecho success

34
kpatch-gcc Executable file
View File

@ -0,0 +1,34 @@
#!/bin/bash
# vim: tabstop=4 shiftwidth=4 expandtab
set -o nounset
set -o errexit
set -o pipefail
SCRIPT="`basename $BASH_SOURCE`"
args="$*"
outfile=
die ()
{
echo "$SCRIPT: error: $*" >&2
exit 1
}
if [ -f kpatch-in-progress ] && [ "$#" -gt 0 ] && [ "$1" = "gcc" ]; then
while [ "$#" -gt 0 ]; do
if [ "$1" = "-o" ]; then
case "$2" in
*.mod.o|*built-in.o|vmlinux.o|.tmp_kallsyms1.o|.tmp_kallsyms2.o|init/version.o|arch/x86/boot/version.o|arch/x86/boot/compressed/eboot.o|arch/x86/boot/header.o|arch/x86/boot/compressed/efi_stub_64.o|arch/x86/boot/compressed/piggy.o)
;;
*.o)
cp -f "$2" "$2.orig_kpatch"
;;
esac
break
fi
shift
done
fi
exec $args

View File

@ -1,10 +1,11 @@
CC=gcc
CFLAGS=-g -Wall
PROG=kpatch-gen
.PHONY: all
all: elf-diff-copy
all: $(PROG)
elf-diff-copy: elf-diff-copy.c
$(PROG): $(PROG).c
$(CC) $(CFLAGS) -o $@ $^ -lelf -ludis86

BIN
kpatch-gen/kpatch-gen Executable file

Binary file not shown.