Armadilloフォーラム

ユーザーアプリケーションのversion管理

sakashita_spc

2019年8月4日 16時07分

Armadilloの質問では何のですが、何かアイディアを頂ければと思い、投稿しました。
ATDE5(Armadillo840向け)のアプリを開発しております。
いくつか実行ファイルを作成しているのですが、ソースコードにVersion情報(ビルド日時、コメントなど)を埋め込んで、ビルドしたELFファイルを
ATDE5で実行できるツールにそのアプリを指定すると、そのVersion情報を参照できるライブラリーなどはありますでしょうか?
(オープンソース等であれば助かるのですが。。)

実行ファイルのHelp関数でprintf等で表示させる方法が楽なのですが、そうなるとターゲット(840)がないと、調べられない。(最悪、objdumpで見る方法もありますが。。。)

以上、よろしくお願いします。

コメント

at_mizo

2019年8月21日 9時39分

溝渕です。

> いくつか実行ファイルを作成しているのですが、ソースコードにVersion情報(ビルド日時、コメントなど)を埋め込んで、ビルドしたELFファイルを
> ATDE5で実行できるツールにそのアプリを指定すると、そのVersion情報を参照できるライブラリーなどはありますでしょうか?

プログラム内に文字列としてデータを持っている場合は、次のようにstringコマンドで表示できます。

[atde]$ cat a.c
#include <stdio.h>
 
int main(void)
{
    printf("VERSION: 1.0.0("__TIME__")\n");
    return 0;
}
[atde]$ arm-linux-gnueabi-gcc a.c
[atde]$ strings a.out | grep VERSION
VERSION: 1.0.0(09:35:44)

ソースコードのコメントはプリプロセス処理で削除される為、実行ファイルか
ら参照することはできないと思います。

at_hanada

2019年8月21日 21時33分

花田です。

> printf("VERSION: 1.0.0("__TIME__")\n");

> ビルド日時
であれば__DATE__が適切かなと(__TIME__はそのソースの編集日時)

> ソースコードのコメントはプリプロセス処理で削除される為、実行ファイルか
> ら参照することはできないと思います。

ソースコードのコメントは消えますが、実行ファイル内には.commentというセクションが残されていたりします(stripなどで消していなければ)。
適当なソースファイルをgccでコンパイルして見てみると…

atmark@debian:~/tmp$ objdump -sj .comment a.out
 
a.out:     ファイル形式 elf64-x86-64
 
セクション .comment の内容:
 0000 4743433a 20284465 6269616e 20382e33  GCC: (Debian 8.3
 0010 2e302d36 2920382e 332e3000           .0-6) 8.3.0.  

このように、コンパイラのバージョンが入っています。

以下はこれを応用して、こんなことができたらいいのかな?という手順を。
(わかりやすくPC環境のコマンドで行っていますので、arm用を対象にするときはgcc/objcopy/objdumpをarm-linux-gnuebaihf-付きに読み替えてください)

独自のセクションを作ることもできまして、例えばこんなソースコードtest.cを作ります。

#include <stdio.h>
#include <string.h>
 
#define BUFSIZE 16
 
extern char __start_mycomment;
extern char __stop_mycomment;
 
int main(void)
{
//for debug
    char mycomment[BUFSIZE];
    int len = 0;
 
    if (&__stop_mycomment > &__start_mycomment) {
        len = &__stop_mycomment - &__start_mycomment;
        if (len >= BUFSIZE)
            len = BUFSIZE - 1;
        memcpy(mycomment, &__start_mycomment, len);
    }
    mycomment[len] = '\0';
    printf("mycomment: %s\n", mycomment);
//for debug end
 
    return 0;
}

これをただ普通にビルドすると「undefined reference to `__start_mycomment'」になってしまいますが、これは独自セクション「mycomment」が埋まっていないから。
ビルドに一工夫を加えます。

atmark@debian:~/tmp$ echo -n "Test comment" >mycomment.dat
atmark@debian:~/tmp$ gcc -c test.c
atmark@debian:~/tmp$ objcopy --add-section=mycomment=mycomment.dat --set-section-flags=mycomment=contents,alloc,load,readonly,data test.o test_mycomment.o
atmark@debian:~/tmp$ gcc test_mycomment.o -o test_mycomment

今回はビルドが通ります。上記のソースコードに「for debug」部分がありますので、対応アーキテクチャ環境で実行すると

atmark@debian:~/tmp$ ./test_mycomment 
mycomment: Test comment

のように「mycomment」が埋め込まれたことが確認できます。

そして、このようにビルドされた実行ファイルであれば

atmark@debian:~/tmp$ objdump -sj mycomment test_mycomment
 
test_mycomment:     ファイル形式 elf64-x86-64
 
セクション mycomment の内容:
 2013 54657374 20636f6d 6d656e74           Test comment    

のようにobjdumpコマンドでもmycommentセクション内の文字列が確認できるわけです。

こんな方法では、やりたいことの足しになるでしょうか?

at_hanada

2019年8月21日 21時50分

花田です。

> > ビルド日時
> であれば__DATE__が適切かなと(__TIME__はそのソースの編集日時)

別の環境と混同してました、これはANSIどおり__DATE__が日で__TIME__が時です…

sakashita_spc

2019年8月22日 17時25分

溝渕様
花田様

情報ありがとうございます。

双方のアプローチで、いろいろ検討してみます。

以上、よろしくお願いします。