ELFファイルのDWARF情報から、構造体のメンバのアドレスを求める方法

いつもお世話になっております。

マイコン内のROM/RAM内の任意の変数の値をモニタする
PCアプリを作成しようとしています。
手順としては下記を考えています。 

①ビルドして出来上がったabsファイル(ELF形式)に対して、
 objdumpを実行しDWARF情報を取り出す。

②取り出したDWARF情報から、変数のアドレスを求める。

③PCアプリから、求めた変数のアドレスを参照し、
 UARTでマイコンのROM/RAMの変数の値を取得する。

mapファイルからでなく、DWARF情報から変数のアドレスを求めるのは、
他のマイコンでも同じ方法で、アドレスを求めたいからです。

②を効率よくやる方法をご存知であれば、教えていただけないでしょうか?

例えば、下記のようなネストされた構造体の各メンバや、
多次元の配列の各要素のアドレスをDWARF情報から求めたいです。
具体例を出すと、struct2.struct1[10][1][2].b[3][1]
のアドレスを求めたいです。

何かいい方法はありますか?
地道にDWARF情報を解析するしかないのでしょうか。
よろしくお願いいたします。


typedef struct{
unsigned char a[10];
unsigned short b[10][10];
unsigned int c;
unsigned char d;
}struct1_t;

 

typedef struct{
unsigned long e;
unsigned char f[10][3][12][3];
float g;
double h[40];
struct1_t struct1[34][2][3];
}struct2_t;


struct2_t struct2;


参考にしているサイト
https://qiita.com/tobira-code/items/de16088be23021e75c74

 

 

 

Parents
  • dracenさん、こんにちは。NoMaYです。

    そういうことでしたか。あとは、私が出せる情報となると、以下の辺りかなと思いました。

    (1) gdbの中でもPythonコマンドを実行させることが出来ます。Pythonスクリプトを実行させることや、そのスクリプトの中でgdbコマンドを実行して実行結果を文字列変数に格納することも出来るのでないだろうかとは思っているのですが、踏み込んだ調査をしたことまではないです。(gdbで今回の件に使えそうなコマンドとしては以下のウェブページのコマンドが考えられます。)

    (2) 或いは、普通にPython(或いは他の種類のスクリプト実行環境や自作のプログラム)からgdbをバックグランドで実行して、gdbの標準入出力をスクリプト実行環境側や自作のプログラム側へリダイレクトすることで、スクリプトからをgdbを制御する手も考えられます。(同上)

    (3) Python上でELF/DWARFを読むPyelftoolsというものがあります。(以下のリンクを参照して下さい。)

    (4) たぶんGCC向けですがELF/DWARFを読むC言語ライブラリのLibdwarfというものがあります。(以下のリンクを参照して下さい。)

    ●Pyelftools

    User's guide
    github.com/eliben/pyelftools/wiki/User's-guide

    Source code
    github.com/eliben/pyelftools

    PyPI
    pypi.org/project/pyelftools

    ●Libdwarf

    Home page
    www.prevanders.net/dwarf.html

    ●GDB
    www.asahi-net.or.jp/~wg5k-ickw/html/online/gdb-4.18/gdb_11.html

    シンボル・テーブルの検査
    ここで説明するコマンドによって、 ユーザ・プログラムの中で定義されているシンボル情報 (変数名、 関数名、 型名) に関する問い合わせを行うことができます。 …以後省略…


    info address symbol → 少し試してみましたが構造体メンバや配列要素には print &symbol を使わないとエラーになりました
    symbolで指定されるシンボルのデータがどこに格納されているかを示します。 …以後省略…


    ptype exp
    式expの型に関する説明を表示します。 単に型の名前を表示するだけではなく、 詳細な説明も表示するという点で、 ptypeはwhatisと異なります。 …以後省略…


    info variables
    関数の外部で宣言されているすべての変数 (つまり、 ローカル変数を除く変数) の名前とデータ型を表示します。


    実行例の画面コピー (なお、ICEにもSimulatorにも接続していません)



     

Reply
  • dracenさん、こんにちは。NoMaYです。

    そういうことでしたか。あとは、私が出せる情報となると、以下の辺りかなと思いました。

    (1) gdbの中でもPythonコマンドを実行させることが出来ます。Pythonスクリプトを実行させることや、そのスクリプトの中でgdbコマンドを実行して実行結果を文字列変数に格納することも出来るのでないだろうかとは思っているのですが、踏み込んだ調査をしたことまではないです。(gdbで今回の件に使えそうなコマンドとしては以下のウェブページのコマンドが考えられます。)

    (2) 或いは、普通にPython(或いは他の種類のスクリプト実行環境や自作のプログラム)からgdbをバックグランドで実行して、gdbの標準入出力をスクリプト実行環境側や自作のプログラム側へリダイレクトすることで、スクリプトからをgdbを制御する手も考えられます。(同上)

    (3) Python上でELF/DWARFを読むPyelftoolsというものがあります。(以下のリンクを参照して下さい。)

    (4) たぶんGCC向けですがELF/DWARFを読むC言語ライブラリのLibdwarfというものがあります。(以下のリンクを参照して下さい。)

    ●Pyelftools

    User's guide
    github.com/eliben/pyelftools/wiki/User's-guide

    Source code
    github.com/eliben/pyelftools

    PyPI
    pypi.org/project/pyelftools

    ●Libdwarf

    Home page
    www.prevanders.net/dwarf.html

    ●GDB
    www.asahi-net.or.jp/~wg5k-ickw/html/online/gdb-4.18/gdb_11.html

    シンボル・テーブルの検査
    ここで説明するコマンドによって、 ユーザ・プログラムの中で定義されているシンボル情報 (変数名、 関数名、 型名) に関する問い合わせを行うことができます。 …以後省略…


    info address symbol → 少し試してみましたが構造体メンバや配列要素には print &symbol を使わないとエラーになりました
    symbolで指定されるシンボルのデータがどこに格納されているかを示します。 …以後省略…


    ptype exp
    式expの型に関する説明を表示します。 単に型の名前を表示するだけではなく、 詳細な説明も表示するという点で、 ptypeはwhatisと異なります。 …以後省略…


    info variables
    関数の外部で宣言されているすべての変数 (つまり、 ローカル変数を除く変数) の名前とデータ型を表示します。


    実行例の画面コピー (なお、ICEにもSimulatorにも接続していません)



     

Children
  • こんばんは。お久しぶりです。

    教えていただいた情報をもとに試行錯誤したのですが、
    結局DWARF情報を地道にパースして
    全構造体の全メンバのアドレスのリストを取得しました。

    ありがとうございました!