kubo39's blog

ただの雑記です。

Dで生成したバイナリ自身のシンボルをみる

完全ではないが、モジュール情報や関数名や型情報などは .symtab をみればとれる。もう少しまじめにsections_elf_shared.dを読めば意味のあるものになるかもしれません。

import core.demangle;

import std.algorithm : map;
import std.file : thisExePath;
import std.format : format;
import std.range : walkLength;
import std.stdio;

import elf;


void main()
{
    auto bin = thisExePath;
    ELF elf = ELF.fromFile(bin);

    ELFSection s = elf.getSection(".symtab");
    writeln("  Symbol table .dynsym contains: ", SymbolTable(s).symbols().walkLength());
    writefln("%-(    %s\n%)", SymbolTable(s)
             .symbols()
             .map!(s => "%s\t%s\t%s".format(s.binding, s.type,
                                            demangle(s.name))));
}

今回はelf-dというライブラリを使用している。これはELFフォーマットのパーサ+一部DWARF(.debug_abbrevとか.debug_lineとか)あたりをサポートしている、Dでは貴重な静的ライブラリを扱うためのライブラリなんですがDWARF対応が中途半端なので本格的にごにょごにょやろうと思うと.debug_infoというかcompilation unitsを自前でがんばる、みたいになるのでかなりめんどくさい。Rustはgoblin/gimli-rsあってこのへんやるのに向いてるような気がする。Sentryとかでも利用実績あるしなあ。。