kubo39's blog

ただの雑記です。

Linux環境でSharedObjectsを使う

とくになにかあるわけじゃなくてSharedObjectsの使い方の備忘録として。まあこういうのドキュメントないので。。

SharedObjectsというのはLinuxでだけ使えるやつで、実行プログラムがロードしている共有ライブラリを取得するために使うものである。 ようは dl_iterate_phdr(3) といえば通じる人には通じる。

以下はプロセスがロードしている共有ライブラリの名前と各セグメントの仮想メモリ上の位置を表示するプログラム。 界隈あるあるとして(??)、relocationを考慮して実際の仮想アドレスを表示するようにしている。

// druntimeのSharedObjectsを使えるのはLinuxだけ
version(linux):

import core.stdc.stdio;

// SharedObjectsを定義している
import core.internal.elf.dl;

// プログラムヘッダの定義とかが欲しいので
import core.sys.linux.elf;

void main()
{
    foreach (object; SharedObjects)
    {
        // std.stdioはここでは使えない
        printf("%s\n", object.name.ptr);

        foreach (ref phdr; object)
        {
            string name = () {
                final switch (phdr.p_type)
                {
                case PT_NULL: return "NULL";
                case PT_LOAD: return "LOAD";
                case PT_DYNAMIC: return "DYNAMIC";
                case PT_INTERP: return "INTERP";
                case PT_NOTE: return "NOTE";
                case PT_SHLIB: return "SHLIB";
                case PT_PHDR: return "PHDR";
                case PT_TLS: return "TLS";
                case PT_NUM: return "NUM";
                case PT_LOOS: return "LOOS";
                case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
                case PT_GNU_STACK: return "GNU_STACK";
                case PT_GNU_RELRO: return "GNU_RELRO";
                }
                assert(false);
            } ();

            // dl_iterate_phdr(3) を参照
            ulong actualVMA = phdr.p_vaddr + object.info.dlpi_addr;
            printf("    %p: segment %s\n", cast(void*)actualVMA, name.ptr);
        }
    }
}