7

現在、ELF形式を勉強しています。単純なnm関数(オプションなし)をコーディングする必要があります。シンボルの値とシンボルの名前を出力にすでに印刷しています。

nm出力は次のとおりです。

value             type    name
0000000000600e30  D       __DTOR_END__

私は同じものを持っていますが、「タイプ」はありません。次のように、ELF64_Sym構造を使用しています。

typedef struct {
    Elf64_Word      st_name;
    unsigned char   st_info;
    unsigned char   st_other;
    Elf64_Half      st_shndx;
    Elf64_Addr      st_value;
    Elf64_Xword     st_size; 
} Elf64_Sym;

st_info変数とこのマクロを使用する必要があることを知っています:

#define ELF64_ST_TYPE(info)          ((info) & 0xf)

シンボルのタイプを取得します。ただし、シンボルタイプは次のようにマクロにすることができます。

NAME            VALUE
STT_NOTYPE      0
STT_OBJECT      1
STT_FUNC        2
STT_SECTION     3
STT_FILE        4
STT_LOPROC      13
STT_HIOPROC     15

そして、私が知りたいのは、これらのマクロからnmで印刷された文字をどのように取得できるかです。例:

 U, u, A, a, T, t, R, r, W, w
4

2 に答える 2

7

さて、私はいくつかの調査を行いました。これが、記号に応じて正しい文字を取得するための私の関数です。いくつかの文字を自由に追加/編集してください。

char            print_type(Elf64_Sym sym, Elf64_Shdr *shdr)
{
  char  c;

  if (ELF64_ST_BIND(sym.st_info) == STB_GNU_UNIQUE)
    c = 'u';
  else if (ELF64_ST_BIND(sym.st_info) == STB_WEAK)
    {
      c = 'W';
      if (sym.st_shndx == SHN_UNDEF)
        c = 'w';
    }
  else if (ELF64_ST_BIND(sym.st_info) == STB_WEAK && ELF64_ST_TYPE(sym.st_info) == STT_OBJECT)
    {
      c = 'V';
      if (sym.st_shndx == SHN_UNDEF)
        c = 'v';
    }
  else if (sym.st_shndx == SHN_UNDEF)
    c = 'U';
  else if (sym.st_shndx == SHN_ABS)
    c = 'A';
  else if (sym.st_shndx == SHN_COMMON)
    c = 'C';
  else if (shdr[sym.st_shndx].sh_type == SHT_NOBITS
       && shdr[sym.st_shndx].sh_flags == (SHF_ALLOC | SHF_WRITE))
    c = 'B';
  else if (shdr[sym.st_shndx].sh_type == SHT_PROGBITS
       && shdr[sym.st_shndx].sh_flags == SHF_ALLOC)
    c = 'R';
  else if (shdr[sym.st_shndx].sh_type == SHT_PROGBITS
       && shdr[sym.st_shndx].sh_flags == (SHF_ALLOC | SHF_WRITE))
    c = 'D';
  else if (shdr[sym.st_shndx].sh_type == SHT_PROGBITS
       && shdr[sym.st_shndx].sh_flags == (SHF_ALLOC | SHF_EXECINSTR))
    c = 'T';
  else if (shdr[sym.st_shndx].sh_type == SHT_DYNAMIC)
    c = 'D';
  else
    c = '?';
  if (ELF64_ST_BIND(sym.st_info) == STB_LOCAL && c != '?')
    c += 32;
  return c;
}

s、n、p、iがありません。「R」は良くないと確信しています。見つけたら編集します。

于 2013-03-07T09:42:54.013 に答える
3

は、印刷される文字に直接マップされELF64_ST_TYPEません。nm

マッピングを実行するには、とシンボルが参照するセクションの両方ELF64_ST_BINDに注意する必要があります。例えば:

bool weak = (ELF64_ST_BIND(sym) == STB_WEAK);
bool unresolved = (sym->st_shndx == SHN_UNDEF);

if (unresolved) {
   printf(" %c ", weak ? 'w' : 'U');
}

tvsの場合TELF64_ST_BIND(sym) == STB_LOCALまたはを確認し、によって参照されるセクションが「テキスト」セクションであるかどうかを確認する必要がELF64_ST_BIND(sym) == STB_GLOBALあります(フラグに含まれています)。st_shndxSHF_EXECINSTR

PS私が知る限り、ありませんu。あなたのnmマニュアルページにリストがある場合u、私はそれがどんなタイプのシンボルであるか知りたいです。

于 2013-03-05T16:07:23.827 に答える