Skip to content

Instantly share code, notes, and snippets.

@xigh
Created February 5, 2019 08:12
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save xigh/56193ce2d7e741731e08a5f0eb2d3a01 to your computer and use it in GitHub Desktop.
Save xigh/56193ce2d7e741731e08a5f0eb2d3a01 to your computer and use it in GitHub Desktop.
Extracting LLVM bitcode from ELF files generated with -fembed-bitcode.
#!/bin/sh
if [ "*$1" == "*" ]; then
echo "usage: extract.sh src dst"
fi
if [ "*$2" == "*" ]; then
echo "usage: extract.sh src dst"
fi
section=.llvmbc
if [ "*$3" != "*" ]; then
section=$3
fi
echo "extracting llvm bitcode from $1 to $2"
bc=`objdump -h $1 | grep $section`
if [ "*$bc" == "*" ]; then
echo " - llvmbc section not found"
exit
fi
sb=$((`echo $bc | awk '{print "0x" $6}'` + 0))
ss=$((`echo $bc | awk '{print "0x" $3}'` + 0))
echo "found llvm section at $sb [$ss bytes]"
dd if=$1 of=$2 bs=1 count=$ss skip=$sb 2> /dev/null
if [ ! -f $2 ]; then
echo " - failed"
exit
fi
if [ "*$section" != "*.llvmbc" ]; then
echo "done"
exit
fi
list=`hexdump -v -C $2 |
grep '42 43 c0 de 35' |
awk '{print "0x"$1 }'`
n=0
p=""
for i in $list; do
if [ "*$p" != "*" ]; then
n=$(($n + 1))
l=$(($i - $p))
echo "$n - $p, $l bytes"
dd if="$2" of="$n-$2" bs=1 count=$(($l)) skip=$(($p)) 2> /dev/null
fi
p=$i
done
size=$(($(wc -c < "$2") +0))
echo "$2 [$size bytes]:"
if [ "*p" != "" ]; then
n=$(($n + 1))
l=$(($size - $p))
echo "$n - $p, $l bytes"
dd if="$2" of="$n-$2" bs=1 count=$(($l)) skip=$(($p)) 2> /dev/null
fi
for i in *.bc; do
hasPadding=`hexdump -v -C $i | tail -2 | head -1 | grep '00 00 00 00 00 00 00' | wc -l`
pad=$(($hasPadding + 0))
echo $i pad="$pad";
if [ $pad == 1 ]; then
echo " - removing trailing zeros"
mv $i tmp-$i
s1=$(($(wc -c < "tmp-$i") - 4))
dd if="tmp-$i" of="$i" bs=1 count=$s1 skip=0 2> /dev/null
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment