linux-yocto/scripts/dtc/dtx_diff
Frank Rowand 35f3c98454 scripts/dtc: dtx_diff - 2nd update of include dts paths to match build
Update dtx_diff include paths in the same manner as:
commit b12869a8d5 ("of: remove drivers/of/testcase-data from
include search path for CPP"), commit 5ffa2aed38 ("of: remove
arch/$(SRCARCH)/boot/dts from include search path for CPP"), and
commit 50f9ddaf64 ("of: search scripts/dtc/include-prefixes path
for both CPP and DTC").

Remove proposed include path kernel/dts/, which was never implemented
for the dtb build.

For the diff case, each source file is compiled separately.  For
each of those compiles, provide the location of the source file
as an include path, not the location of both source files.

Signed-off-by: Frank Rowand <frank.rowand@sony.com>
Signed-off-by: Rob Herring <robh@kernel.org>
2017-09-20 10:13:05 -05:00

8.5 KiB
Executable File

#! /bin/bash

Copyright (C) 2015 Frank Rowand

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.

usage() {

# use spaces instead of tabs in the usage message
cat >&2 <<eod

Usage:

basename $0 DTx decompile DTx

basename $0 DTx_1 DTx_2 diff DTx_1 and DTx_2

   -f           print full dts in diff (--unified=99999)
   -h           synonym for --help
   -help        synonym for --help
  --help        print this message and exit
   -s SRCTREE   linux kernel source tree is at path SRCTREE
                    (default is current directory)
   -S           linux kernel source tree is at root of current git repo
   -u           unsorted, do not sort DTx

Each DTx is processed by the dtc compiler to produce a sorted dts source file. If DTx is a dts source file then it is pre-processed in the same manner as done for the compile of the dts source file in the Linux kernel build system ('#include' and '/include/' directives are processed).

If two DTx are provided, the resulting dts source files are diffed.

If DTx is a directory, it is treated as a DT subtree, such as /proc/device-tree.

If DTx contains the binary blob magic value in the first four bytes, it is treated as a binary blob (aka .dtb or FDT).

Otherwise DTx is treated as a dts source file (aka .dts).

If this script is not run from the root of the linux source tree, and DTx utilizes '#include' or '/include/' then the path of the linux source tree can be provided by '-s SRCTREE' or '-S' so that include paths will be set properly.

The shell variable ${ARCH} must provide the architecture containing the dts source file for include paths to be set properly for '#include' or '/include/' to be processed.

If DTx_1 and DTx_2 are in different architectures, then this script may not work since ${ARCH} is part of the include path. Two possible workarounds:

  `basename $0` \\
      <(ARCH=arch_of_dtx_1 `basename $0` DTx_1) \\
      <(ARCH=arch_of_dtx_2 `basename $0` DTx_2)

  `basename $0` ARCH=arch_of_dtx_1 DTx_1 >tmp_dtx_1.dts
  `basename $0` ARCH=arch_of_dtx_2 DTx_2 >tmp_dtx_2.dts
  `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts
  rm tmp_dtx_1.dts tmp_dtx_2.dts

If DTx_1 and DTx_2 are in different directories, then this script will add the path of DTx_1 and DTx_2 to the include paths. If DTx_2 includes a local file that exists in both the path of DTx_1 and DTx_2 then the file in the path of DTx_1 will incorrectly be included. Possible workaround:

  `basename $0` DTx_1 >tmp_dtx_1.dts
  `basename $0` DTx_2 >tmp_dtx_2.dts
  `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts
  rm tmp_dtx_1.dts tmp_dtx_2.dts

eod }

compile_to_dts() {

dtx="$1"
dtc_include="$2"

if [ -d "${dtx}" ] ; then

	# -----  input is file tree

	if ( ! ${DTC} -I fs ${dtx} ) ; then
		exit 3
	fi

elif [ -f "${dtx}" ] && [ -r "${dtx}" ] ; then

	magic=`hexdump -n 4 -e '/1 "%02x"' ${dtx}`
	if [ "${magic}" = "d00dfeed" ] ; then

		# -----  input is FDT (binary blob)

		if ( ! ${DTC} -I dtb ${dtx} ) ; then
			exit 3
		fi

		return

	fi

	# -----  input is DTS (source)

	if ( cpp ${cpp_flags} -x assembler-with-cpp ${dtx} \
		| ${DTC} ${dtc_include} -I dts ) ; then
		return
	fi

	echo ""                                                      >&2
	echo "Possible hints to resolve the above error:"            >&2
	echo "  (hints might not fix the problem)"                   >&2

	hint_given=0

	if [ "${ARCH}" = "" ] ; then
		hint_given=1
		echo ""                                              >&2
		echo "  shell variable \$ARCH not set"               >&2
	fi

	dtx_arch=`echo "/${dtx}" | sed -e 's|.*/arch/||' -e 's|/.*||'`

	if [ "${dtx_arch}" != ""  -a "${dtx_arch}" != "${ARCH}" ] ; then
		hint_given=1
		echo ""                                              >&2
		echo "  architecture ${dtx_arch} is in file path,"   >&2
		echo "  but does not match shell variable \$ARCH"    >&2
		echo "  >>\$ARCH<< is: >>${ARCH}<<"                  >&2
	fi

	if [ ! -d ${srctree}/arch/${ARCH} ] ; then
		hint_given=1
		echo ""                                              >&2
		echo "  ${srctree}/arch/${ARCH}/ does not exist"     >&2
		echo "  Is \$ARCH='${ARCH}' correct?"                >&2
		echo "  Possible fix: use '-s' option"               >&2

		git_root=`git rev-parse --show-toplevel 2>/dev/null`
		if [ -d ${git_root}/arch/ ] ; then
			echo "  Possible fix: use '-S' option"       >&2
		fi
	fi

	if [ $hint_given = 0 ] ; then
		echo ""                                              >&2
		echo "  No hints available."                         >&2
	fi

	echo ""                                                      >&2

	exit 3

else
	echo ""                                                     >&2
	echo "ERROR: ${dtx} does not exist or is not readable"      >&2
	echo ""                                                     >&2
	exit 2
fi

}

----- start of script

cmd_diff=0 diff_flags="-u" dtx_file_1="" dtx_file_2="" dtc_sort="-s" help=0 srctree=""

while [ $# -gt 0 ] ; do

case $1 in

-f )
	diff_flags="--unified=999999"
	shift
	;;

-h | -help | --help )
	help=1
	shift
	;;

-s )
	srctree="$2"
	shift 2
	;;

-S )
	git_root=`git rev-parse --show-toplevel 2>/dev/null`
	srctree="${git_root}"
	shift
	;;

-u )
	dtc_sort=""
	shift
	;;

*)
	if [ "${dtx_file_1}"  = "" ] ; then
		dtx_file_1="$1"
	elif [ "${dtx_file_2}" = "" ] ; then
		dtx_file_2="$1"
	else
		echo ""                                             >&2
		echo "ERROR: Unexpected parameter: $1"              >&2
		echo ""                                             >&2
		exit 2
	fi
	shift
	;;

esac

done

if [ "${srctree}" = "" ] ; then srctree="." fi

if [ "${dtx_file_2}" != "" ]; then cmd_diff=1 fi

if (( ${help} )) ; then usage exit 1 fi

this must follow check for ${help}

if [ "${dtx_file_1}" = "" ]; then echo "" >&2 echo "ERROR: parameter DTx required" >&2 echo "" >&2 exit 2 fi

----- prefer dtc from linux kernel, allow fallback to dtc in $PATH

if [ "${KBUILD_OUTPUT:0:2}" = ".." ] ; then __KBUILD_OUTPUT="${srctree}/${KBUILD_OUTPUT}" elif [ "${KBUILD_OUTPUT}" = "" ] ; then __KBUILD_OUTPUT="." else __KBUILD_OUTPUT="${KBUILD_OUTPUT}" fi

DTC="${__KBUILD_OUTPUT}/scripts/dtc/dtc"

if [ ! -x ${DTC} ] ; then __DTC="dtc" if grep -q "^CONFIG_DTC=y" ${__KBUILD_OUTPUT}/.config 2>/dev/null; then make_command=' make scripts' else make_command=' Enable CONFIG_DTC in the kernel configuration make scripts' fi if ( ! which ${__DTC} >/dev/null ) ; then

	# use spaces instead of tabs in the error message
	cat >&2 <<eod

ERROR: unable to find a 'dtc' program

Preferred 'dtc' (built from Linux kernel source tree) was not found or is not executable.

  'dtc' is: ${DTC}

  If it does not exist, create it from the root of the Linux source tree:

${make_command}

  If not at the root of the Linux kernel source tree -s SRCTREE or -S
  may need to be specified to find 'dtc'.

  If 'O=\${dir}' is specified in your Linux builds, this script requires
  'export KBUILD_OUTPUT=\${dir}' or add \${dir}/scripts/dtc to \$PATH
  before running.

  If \${KBUILD_OUTPUT} is a relative path, then '-s SRCDIR', -S, or run
  this script from the root of the Linux kernel source tree is required.

Fallback '${__DTC}' was also not in ${PATH} or is not executable.

eod exit 2 fi DTC=${__DTC} fi

----- cpp and dtc flags same as for linux source tree build of .dtb files,

plus directories of the dtx file(s)

dtx_path_1_dtc_include="-i dirname ${dtx_file_1}"

dtx_path_2_dtc_include="" if (( ${cmd_diff} )) ; then dtx_path_2_dtc_include="-i dirname ${dtx_file_2}" fi

cpp_flags="
-nostdinc
-I${srctree}/scripts/dtc/include-prefixes
-undef -D__DTS__"

DTC="
${DTC}
-i ${srctree}/scripts/dtc/include-prefixes
-O dts -qq -f ${dtc_sort} -o -"

----- do the diff or decompile

if (( ${cmd_diff} )) ; then

diff ${diff_flags} --label "${dtx_file_1}" --label "${dtx_file_2}" \
	<(compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}") \
	<(compile_to_dts "${dtx_file_2}" "${dtx_path_2_dtc_include}")

else

compile_to_dts "${dtx_file_1}" "${dtx_path_1_dtc_include}"

fi