18c2ecf20Sopenharmony_ci#!/bin/sh
28c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0-only
38c2ecf20Sopenharmony_ci# ----------------------------------------------------------------------
48c2ecf20Sopenharmony_ci# extract-vmlinux - Extract uncompressed vmlinux from a kernel image
58c2ecf20Sopenharmony_ci#
68c2ecf20Sopenharmony_ci# Inspired from extract-ikconfig
78c2ecf20Sopenharmony_ci# (c) 2009,2010 Dick Streefland <dick@streefland.net>
88c2ecf20Sopenharmony_ci#
98c2ecf20Sopenharmony_ci# (c) 2011      Corentin Chary <corentin.chary@gmail.com>
108c2ecf20Sopenharmony_ci#
118c2ecf20Sopenharmony_ci# ----------------------------------------------------------------------
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_cicheck_vmlinux()
148c2ecf20Sopenharmony_ci{
158c2ecf20Sopenharmony_ci	# Use readelf to check if it's a valid ELF
168c2ecf20Sopenharmony_ci	# TODO: find a better to way to check that it's really vmlinux
178c2ecf20Sopenharmony_ci	#       and not just an elf
188c2ecf20Sopenharmony_ci	readelf -h $1 > /dev/null 2>&1 || return 1
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci	cat $1
218c2ecf20Sopenharmony_ci	exit 0
228c2ecf20Sopenharmony_ci}
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_citry_decompress()
258c2ecf20Sopenharmony_ci{
268c2ecf20Sopenharmony_ci	# The obscure use of the "tr" filter is to work around older versions of
278c2ecf20Sopenharmony_ci	# "grep" that report the byte offset of the line instead of the pattern.
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci	# Try to find the header ($1) and decompress from here
308c2ecf20Sopenharmony_ci	for	pos in `tr "$1\n$2" "\n$2=" < "$img" | grep -abo "^$2"`
318c2ecf20Sopenharmony_ci	do
328c2ecf20Sopenharmony_ci		pos=${pos%%:*}
338c2ecf20Sopenharmony_ci		tail -c+$pos "$img" | $3 > $tmp 2> /dev/null
348c2ecf20Sopenharmony_ci		check_vmlinux $tmp
358c2ecf20Sopenharmony_ci	done
368c2ecf20Sopenharmony_ci}
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci# Check invocation:
398c2ecf20Sopenharmony_cime=${0##*/}
408c2ecf20Sopenharmony_ciimg=$1
418c2ecf20Sopenharmony_ciif	[ $# -ne 1 -o ! -s "$img" ]
428c2ecf20Sopenharmony_cithen
438c2ecf20Sopenharmony_ci	echo "Usage: $me <kernel-image>" >&2
448c2ecf20Sopenharmony_ci	exit 2
458c2ecf20Sopenharmony_cifi
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci# Prepare temp files:
488c2ecf20Sopenharmony_citmp=$(mktemp /tmp/vmlinux-XXX)
498c2ecf20Sopenharmony_citrap "rm -f $tmp" 0
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci# That didn't work, so retry after decompression.
528c2ecf20Sopenharmony_citry_decompress '\037\213\010' xy    gunzip
538c2ecf20Sopenharmony_citry_decompress '\3757zXZ\000' abcde unxz
548c2ecf20Sopenharmony_citry_decompress 'BZh'          xy    bunzip2
558c2ecf20Sopenharmony_citry_decompress '\135\0\0\0'   xxx   unlzma
568c2ecf20Sopenharmony_citry_decompress '\211\114\132' xy    'lzop -d'
578c2ecf20Sopenharmony_citry_decompress '\002!L\030'   xxx   'lz4 -d'
588c2ecf20Sopenharmony_citry_decompress '(\265/\375'   xxx   unzstd
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci# Finally check for uncompressed images or objects:
618c2ecf20Sopenharmony_cicheck_vmlinux $img
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci# Bail out:
648c2ecf20Sopenharmony_ciecho "$me: Cannot find vmlinux." >&2
65