This utility is used as part of Linux ACPICA release process. It may be a
good idea to add it to kernel scripts, since it may be generally usefull for
verifying small kernel changes, like coding style cleanups etc.

Signed-off-by: Lv Zheng <lv.zh...@intel.com>
---
 scripts/diffvmlinux.sh |  227 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 227 insertions(+)
 create mode 100755 scripts/diffvmlinux.sh

Index: linux-pm/scripts/diffvmlinux.sh
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ linux-pm/scripts/diffvmlinux.sh     2012-12-19 13:40:21.000000000 +0800
@@ -0,0 +1,226 @@
+#!/bin/sh
+#
+# Copyright (c) 2012, Intel Corporation
+# Author: Lv Zheng <lv.zh...@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; version 2 of the License.
+#
+# NAME
+#   diffvmlinux.sh - Generating vmlinux assembly differences before/after
+#                    applying a quilt patch
+# SYNOPSIS
+#   diffvmlinux.sh [-f assembly-diff] [-p patch-file] [-o object-file]
+#                  <linux-dir>
+
+
+# FIXME: More Useless Sections
+#
+# Please add other sections that would appear as executable but should get
+# removed for the comparision.
+USELESS_SECTIONS=".notes"
+
+fulldir() {
+       lpath=$1
+       (
+               cd $lpath; pwd
+       )
+}
+
+getdir() {
+       lpath=`dirname $1`
+       fulldir $lpath
+}
+
+fatal() {
+       echo $1
+       exit -1
+}
+
+usage() {
+       echo "Usage: `basename $0` [-p patch] <linux>"
+       echo "Where:"
+       echo " linux: Specify the linux source tree."
+       echo " patch: Specify the patch file name."
+}
+
+fatal_usage() {
+       usage
+       exit -1
+}
+
+quilt_applied() {
+       c=$1
+       applied_patches=`quilt applied 2>/dev/null`
+
+       for a in $applied_patches; do
+               if [ "x$a" = "x$c" ]; then
+                       return 0
+               fi
+       done
+       return -1
+}
+
+remove_sections() {
+       binary2=$1
+       binary3=$2
+
+       for section in $USELESS_SECTIONS; do
+               echo "Removing $section section..."
+               objcopy -R $section $binary2 $binary3
+               mv $binary3 $binary2
+       done
+}
+
+quilt_push() {
+       quilt push > /dev/null || fatal "failed to push quilt stack"
+}
+
+quilt_pop() {
+       quilt pop > /dev/null || fatal "failed to pop quilt stack"
+}
+
+detect_patch() {
+       quilt_push
+       detected_patches=`quilt applied 2>/dev/null`
+       quilt_pop
+       for d in $detected_patches; do
+               quilt_applied $d || echo $d
+       done
+}
+
+quilt_forward() {
+       l=$1
+       patches=`quilt unapplied 2>/dev/null`
+       for i in $patches; do
+               quilt_push
+               quilt_applied $l
+               if [ $? -eq 0 ]; then
+                       quilt_pop
+                       return 0;
+               fi
+       done
+       fatal "Cannot find $locate in the unapplied patches."
+}
+
+quilt_backward() {
+       l=$1
+       patches=`quilt applied 2>/dev/null`
+       for i in $patches; do
+               quilt_pop
+               quilt_applied $l || return 0
+       done
+       fatal "Cannot find $locate in the applied patches."
+}
+
+locate_patch() {
+       t=$1
+       quilt_applied $t
+       if [ $? -eq 0 ]; then
+               echo "Locating $t in the applied patches..."
+               quilt_backward $t
+       else
+               echo "Locating $t in the unapplied patches..."
+               quilt_forward $t
+       fi
+}
+
+while getopts "f:p:o:" opt
+do
+       case $opt in
+       f) ASMDIFF=$OPTARG;;
+       o) BINARY=$OPTARG;;
+       p) PATCH=$OPTARG;;
+       ?) echo "Invalid argument $opt"
+          fatal_usage;;
+       esac
+done
+shift $(($OPTIND - 1))
+
+if [ "x$1" = "x" ]; then
+       echo "Missing <linux> paraemter."
+       fatal_usage
+fi
+
+CURDIR=`pwd`
+LINUX=`getdir $1`
+LINUX_BASE=`basename $LINUX`/vmlinux
+AFTER=$CURDIR/after.dump
+BEFORE=$CURDIR/before.dump
+
+if [ "x$BINARY" = "x" ]; then
+       BINARY=vmlinux
+fi
+echo "Diffing $BINARY..."
+BINARY0=$LINUX/$BINARY
+BINARY1=$LINUX/diffvmlinux
+BINARY2=$LINUX/diffvmlinux-nosections
+BINARY3=$LINUX/diffvmlinux-nosection
+
+# Prepare quilt stack
+if [ "x$PATCH" != "x" ]; then
+       echo "Locating patch $PATCH..."
+       locate_patch $PATCH
+else
+       PATCH=`detect_patch`
+       echo "Detected patch $PATCH."
+fi
+if [ "x$PATCH" = "x" ]; then
+       echo "Missing patch file"
+       fatal_usage
+fi
+
+# Allow overloading of ASMDIFF
+if [ "x$ASMDIFF" = "x" ]; then
+       ASMDIFF=$CURDIR/bin.diff
+fi
+
+(
+       cd $LINUX
+
+       # Assertion in case the above locating/detecting failed.
+       quilt_applied $PATCH && fatal "patch $PATCH should not be applied"
+       quilt_push
+       quilt_applied $PATCH || fatal "patch $PATCH should be the next patch"
+       quilt_pop
+
+       echo "Building $BINARY before applying $PATCH..."
+       rm -f $BINARY
+       make > /dev/null || fatal "failed to build $LINUX"
+       echo "Disassembling $BINARY before applying $PATCH..."
+       cp -f $BINARY0 $BINARY1
+       cp -f $BINARY1 $BINARY2 && remove_sections $BINARY2 $BINARY3
+       objdump -d $BINARY2 > $BEFORE
+
+       echo "Pushing $PATCH to $LINUX_BASE..."
+       quilt_push
+
+       echo "Building $BINARY after applying $PATCH..."
+       rm -f $BINARY
+       make > /dev/null || fatal "failed to build $LINUX"
+       echo "Disassembling $BINARY after applying $PATCH..."
+       cp -f $BINARY0 $BINARY1
+       cp -f $BINARY1 $BINARY2 && remove_sections $BINARY2 $BINARY3
+       objdump -d $BINARY2 > $AFTER
+
+       echo "Popping $PATCH from $LINUX_BASE..."
+       quilt_pop
+)
+
+# XXX: Fatal Error for the Sub-shell
+#
+# We'll reach here even in the case of fatal due to the sub-shell.
+# Thus we do cleanup here and the relative path of ASMDIFF is correct.
+
+if [ -f $BEFORE ] && [ -f $AFTER ]; then
+       echo "Generating assembly differences..."
+       diff -u $BEFORE $AFTER > $ASMDIFF
+       echo "$ASMDIFF is ready."
+fi
+
+rm -f $BINARY1
+rm -f $BINARY2
+rm -f $BINARY3
+rm -f $BEFORE
+rm -f $AFTER
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to