DEBUG_INFOの解析が走り出した

readelf --debug-dumpの出力を解析して、ユーザ・プログラムに出てくる変数や関数の情報を取り出すプログラムを開発しています。

例えば、こんな二行を解析して・・・
 8ad 1 10 3 int 2 5-(signed)
 8b4 1 20 6 xt_int 1 69 <0x8ad> 1 3-byte-block:-3-53-0-(DW_OP_addr:-53)

 こんな情報を取り出します。

 xt_int 53 2 base_type 2  int 2

変数名はxt_int、アドレスは0x53で2バイトのint型変数という結果です。

base_tytpeの変数なので情報も取り出し易いのですが・・・

 

構造体変数に関する入力行はこんな感じで・・・

 91e 2 9 5 tstr 1 74 <0x95b> 3-byte-block:-3-4a-0-(DW_OP_addr:-4a)
 95b 1 21 5 <0x98f> test_struct 3 1 72
 970 2 6 3 test_c <0x844> 2-byte-block:-23-0-(DW_OP_plus_uconst:-0)
 97f 2 6 3 test_i <0x8ad> 2-byte-block:-23-1-(DW_OP_plus_uconst:-1)

出力はこうなります。
 tstr 4a 3 structure_type 6  1 test_c <test_c|null|1|base_type|unsigned-char|1> 2 test_i <test_i|null|2|base_type|int|2>

少し複雑ですが、変数名tstr、アドレスは0x4a、サイズは3バイトの構造体で、unsigned char型のtest_cと、int型のtest_iをメンバーに持つことが読み取れます。

 

<>で挟んだ文字列は構造体メンバのTYPE属性で、複雑な構造を持つ変数のTYPE属性の解析に必要な情報を記します。この例では、メンバ変数がbase_typeなので簡単な記述に留まっていますが、メンバ変数が構造体だったり、構造体配列へのポインタだったりすると、<>の中の記述がどんどん複雑になっていきます。

 

利用するときに苦労しそうですが、面倒な心配は先送り!(<==開発の基本スタンス)

 先ずは変数名からアドレスとそのサイズを調べてPICから読み出し、バイト列で表示するところから始めます。(<==構造体メンバもバイト列で表現する)

構造体メンバーの変数表示とか、配列の型変換表示とか・・・機能拡張(<==面倒だけど多分出来る)は追々考えていきたいと思います。
 

DWARFDUMPを諦めた

DWARFDUMPの出力がやけに短いと思ったら、解析が途中で止まっていました。orz

出力はこんな感じです。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

.debug_info

COMPILE_UNIT<header overall offset = 0x00000000>:
< 0><0x0000000b>  DW_TAG_compile_unit
                    DW_AT_stmt_list             0x00000000
                    DW_AT_producer              Microchip MPLAB XC8 Compiler v1.42
                    DW_AT_language              DW_LANG_C89
                    DW_AT_name                  C:\common\developement\Raspi-Pic\RaspiPic-1938.X\mcc_generated_files/pin_manager.c
                    DW_AT_low_pc                0x00000452
                    DW_AT_high_pc               0x0000046f

途中省略

< 1><0x00000344>    DW_TAG_subprogram
                      DW_AT_sibling               <0x00000377>
                      DW_AT_name                  i2c_put_into_ring_buff
                      DW_AT_external              yes(1)
                      DW_AT_decl_file             0x00000001
                      DW_AT_decl_line             0x00000049
                      DW_AT_low_pc                0x000005cd
                      DW_AT_high_pc               0x000005d6
                      DW_AT_inline                DW_INL_not_inlined
< 2><0x00000368>      DW_TAG_variable
                        DW_AT_name                  d
                        DW_AT_decl_file             0x00000001 C:\common\developement/Raspi-Pic/SRC/i2c_comm.c
                        DW_AT_decl_line             0x00000049
                        DW_AT_type                  <0x00000129>
                        
dwarfdump ERROR:  dwarf_get_loclist_c:  <==ここでエラーになったらしい  DW_DLE_DEBUG_LOC_SECTION_SHORT(194)

CU Name = C:\common\developement\Raspi-Pic/SRC/i2c_comm.c
CU Producer = Microchip MPLAB XC8 Compiler v1.42
DIE OFF = 0x00000368 GOFF = 0x00000415, Low PC = 0x000005bb, High PC = 0x000005c4

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

xc32-readelf --debug-dumpなら最後まで解析できたので、インストールしたDWARFDUMPの利用は諦めることにします。

DWARFDUMPをインストールした

Maker Faire Tokyoの選考に落ちてしまいました。orz

しょげていても始まらないので、Maestronの開発は一先ず置いて、以前からやりたいと思っていた『Raspi-Pic』の開発に取り組むことにしました。

『Raspi-Pic』は、Raspberry piとPICデバイスを組み合わせた、新しい『PIC電子工作の学習、開発、アプリケーション実行環境』になる予定です。構想(<==妄想?)があれこれ膨らみ、その実現方法を思案しながら開発を進めています。


PICコンパイラが出力したELFファイルから、デバッグ情報を取り出す方法がわからず、あれこれ調べてDWARFDUMPというプログラムに行き着きました。

これ(↓)です。

www.prevanders.net

これをRaspiにインストールしたので、その手順を以下に記します。
(1) sudo apt-get install libelf-dev
(2) wget https://www.prevanders.net/libdwarf-20170416.tar.gz
(3) tar --extract -f libdwarf-20170416.tar.gz
(4) cd dwarf-20170416
(5) ./configure
(6) make
(7) sudo cp dwarfdump/dwarfdump /usr/local/bin
(8) dwarfdump -V


これを使ってelfファイルを解析するとこんな感じにデバッグ情報を取り出すことが出来ました。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
.debug_info

COMPILE_UNIT<header overall offset = 0x00000000>:
< 0><0x0000000b>  DW_TAG_compile_unit
                    DW_AT_stmt_list             0x00000000
                    DW_AT_producer              Microchip MPLAB XC8 Compiler v1.42
                    DW_AT_language              DW_LANG_C89
                    DW_AT_name                  C:\common\developement\Raspi-Pic\RaspiPic-user.X\mcc_generated_files/interrupt_manager.c
                    DW_AT_low_pc                0x00000004
                    DW_AT_high_pc               0x00000032

LOCAL_SYMBOLS:
< 1><0x00000092>    DW_TAG_subprogram
                      DW_AT_name                  INTERRUPT_InterruptManager
                      DW_AT_type                  <0x000000ba>
                      DW_AT_external              yes(1)
                      DW_AT_decl_file             0x00000001
                      DW_AT_decl_line             0x00000033
                      DW_AT_low_pc                0x00000004
                      DW_AT_high_pc               0x00000032
                      DW_AT_inline                DW_INL_not_inlined
< 1><0x000000ba>    DW_TAG_subroutine_type
以下省略
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
この出力を解析するプログラムが次の課題です。
(先はまだまだ長いなぁ~)

 

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
補足
”version 20120410-2”なら、以下のコマンドで簡単にインストールできるようです。
sudo apt-get install dwarfdump

MIDIファイル解析の良いサンプルを見つけた

MAESTRONは、MIDIファイルをRASPI側に置き、演奏データの形にしてPICに渡そうと考えています。PICは表現に関する情報(クレッシェンドとかレガートとか)に基づいて受け取った演奏データを加工(強弱、長さ、演奏タイミングetc.)して、MIDI音源に出力します。


先ずはMIDIファイルを読み取って演奏データを抽出するプログラムが必要なのですが、良いサンプルを見つけました。これ(↓)です。

Simple Analysis

JAVAで書かれているので、RASPIへの移植も簡単にできそうです。

先人達の仕事に感謝!

 

 

NoClassDefFoundErrorって何だ?

Raspiにリモート・デスクトップ接続したPC上で、PICのプログラムはC、RaspiのプログラムはJAVAを使って開発しています。現在開発中のSing-A-Ringもこんな感じです。一番上がRaspiのデスクトップで、後ろにNetBeansとMPLAB-Xのウィンドウが隠れています。

f:id:RASPI-PIC-CLUB:20170517163514j:plain


JAVA Swingで書いたGUIアプリは、リモート・デスクトップ接続したPCの画面にも表示されるので重宝しています。ただし、JAVAが得意な訳では無いので、Google先生のお世話になることもしばしばです。

 

今回は、新しくHex関数を使ったところで”NoClassDefFoundError”が起きました。早速、ググってこちら(↓)の説明を見つけました。

java.lang.NoClassDefFoundError

<以下引用>

 NoClassDefFoundErrorは、通常のメソッド呼出し、あるいはnew式を使った新しいインスタンスの生成で Java VMまたはクラスローダがクラス定義をロードしようとしたとき、クラス定義が見つからない場合に  スローされるものです。
 現在実行中のクラスをコンパイルする時点では存在していましたが、その後見つからなくなっている場合などがあります。

 

ふむ!

 

どうやら、コンパイル環境にあった”org.apache.commons.codec”が実行環境には見つからなかったようです。Raspi上の実行環境(/opt/samba/bcmlib_for_java/example)を覗いてみると・・・

 

ビンゴ~、org.apache.commons.codecが有りません。(<==喜んでいる場合ではない)

 

あれこれ不具合に遭遇しても解決策がすぐに見つかるのは、ネット上に多くの情報が蓄積されているJAVAならではなのかもしれません。

 

表面実装部品を使った分圧回路

2.54mmピッチのコネクタのピン間に2012がぴったり収まるって、知ってましたか?こんな感じ(↓)です。

 

f:id:RASPI-PIC-CLUB:20170514170452j:plain

ユニバーサル基板に2.54mmピッチのコネクタを差して、表面実装部品(2012サイズの抵抗)を2個並べてみました。説明用なのではんだ付けしていません。

 

Sing-A-RingとMaestronの接続基板の下で、同じことをやっています。

f:id:RASPI-PIC-CLUB:20170514170410j:plain

基板を組み立ててから、超音波センサーの出力(5V信号)をPIC32(3.3V動作)に入力するには分圧回路が必要だということに気付き、慌ててコネクタの下に先の分圧回路を組み込んだのです。

知っていて損の無い技だと思います。


注意すべきことが一つあって、はんだ付けしたコネクに後から表面実装部品を取り付けようとしても、上の写真のように奇麗には並びません。今回は、部品を後付けすることになったので仕上がりは酷いものです。orz

 

新たに開発環境を構築中

新しいPCが届いたので、Raspicの開発環境を構築することにしました。Netbeans、JDK8、MPLAB-X、xc8,16,32etc.をダウンロードしてインストールするだけなので作業は簡単です。

 

ただし、今回はWindow版とLinux版の開発環境を併せて構築する(どちらでもできるようにする)計画です。しかもLinux版は仮想環境なので上手くできるのかちょっと心配でした。が、特に問題もなく構築作業は完了しました。

使ったのはこれ(↓)です。

VMware Player 12

そこにubuntuこれ(↓)をインストールしました。

http://cdimage.ubuntulinux.jp/releases/16.04/ubuntu-ja-16.04-desktop-amd64.iso

 

手順に関してはこちらの方(↓)が詳しく記されているのでご参照ください。

Windows 10 でVMware Workstation Player With Ubuntu

やってみる前は、仮想環境にあるubuntuのネット接続がどうなるのか気になりましたが杞憂でした。設定を弄ることもなく(NAT接続設定のまま)するするとubuntuのインストールが進み、updateも時間こそ掛りましたが何事もなく完了しました。


仮想環境のubuntuと外部との間でイーサネット接続できたので、最近覚えた技(cifsマウント)を使い、ホストPCとubuntu間でファイルの受け渡しが出来るようにしました。これで、開発作業のバックアップ体制もバッチリです。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
(2017.05.14)
ホストPC上のフォルダであれば、cifsマウントしなくてもファイル共有できることを後で知りました。:-p