grep-ccopt - Cコンパイル時の引数にgrepする(特定コンパイラのみ)

目的

とあるコンパイラ*1が、コンパイル時の引数をオブジェクトファイルの特定セクション*2に埋め込んでいる。
これにgrepをかけることで、コンパイル引数が意図通りかどうか、チェックしたい。

結果

特定セクションを取り出してgrepするスクリプトを作成。

例)

% find . -name '*.o' | xargs grep-ccopt -mam33 | head -10
./init/version.o: -mam33
./init/initramfs.o: -mam33
./init/do_mounts.o: -mam33
./init/calibrate.o: -mam33
./mm/rmap.o: -mam33
...


(特定クロスコンパイラだけの話なので、さらっと書く)

処理スクリプト

特定セクションを取りだして、そこにgrepをかける、だけ。

grep-ccopt
https://sssvn.jp/svn/spikelet/utils/grep-ccopt
#!/bin/sh
# grep C compiler command line option from object file
#  (require ".note.GCC-command-line" section by compiler)
# usage: cd somewhere ; ./grep-ccopt.sh '-mam33' `find . -name "*.o"`
READELF=${READELF-am33_2.0-linux-gnu-readelf}
TARGET_SECTION='\.note\.GCC-command'
TARGET_OPTION="$1"
shift

if [ $# = 0 ]
then
  echo >&2 "usage: $0 <pattern> <obj-files...>"
  exit 1
fi

TMPFILE=dd.result.$$
trap 'rm -f $TMPFILE' 0

for objfile
do
  ## extract ".note.GCC-command-line" section to TMPFILE
  $READELF -S $objfile | awk "/$TARGET_SECTION/{ print \$6, \$7 }" |\
    (read offset size; \
     dd if=$objfile of=$TMPFILE bs=1 skip=$((0x$offset)) count=$((0x$size)) 2>/dev/null)
  ## check if CFLAGS matches?
  result=`grep -- "$TARGET_OPTION" $TMPFILE`
  if [ $? = 0 ] ; then echo "$objfile": $result; fi
done

readelfコマンドを変えたい場合は、環境変数 READELF を設定しておく。

疑問

objcopyかobjdumpを使って、特定セクションの中身をヘッダ抜きで取り出す方法を模索したのだが、どうにもできず。
objcopy -O binary -j .note.GCC-command-line foo.o foo とすると foo のサイズが 0 になるのはなんでだろう…

*1:am33_2.0-linux-gnu-

*2:.note.GCC-command-line