ELFヘッダのe_identについて調べました。

ELFはメジャーなオブジェクトファイルのフォーマット。
今回は、そのELFファイルの最初の16バイトであるe_identについて調べる。
e_identは、ELFヘッダの一部なので、readelf -hで確認することができる。

$readelf -h a.out                                                                                                                                                                                   0 < 02:49:50
ELF ヘッダ:
  マジック:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  クラス:                            ELF64
  データ:                            2 の補数、リトルエンディアン
  バージョン:                        1 (current)
  OS/ABI:                            UNIX - System V
  ABI バージョン:                    0
  型:                                DYN (共有オブジェクトファイル)
  マシン:                            Advanced Micro Devices X86-64
  バージョン:                        0x1
  エントリポイントアドレス:               0x570
  プログラムの開始ヘッダ:          64 (バイト)
  セクションヘッダ始点:          6560 (バイト)
  フラグ:                            0x0
  このヘッダのサイズ:                64 (バイト)
  プログラムヘッダサイズ:            56 (バイト)
  プログラムヘッダ数:                9
  セクションヘッダ:                  64 (バイト)
  セクションヘッダサイズ:            29
  セクションヘッダ文字列表索引:      28



中身が分かったので、ひとつづつ確認していく。
頭から16バイトをとりだす。

 $od -An -tx1 -N16 a.out                                                                                                                                                         
 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00



最初の4バイト(7f 45 4c 46)はマジックナンバー
0x7f ‘E’ ‘L’ ‘F'となっているね。

次の1バイト(02)は32bitか64bitかの区別。
/usr/include/elf.hによると02なので64-bit object。

#define ELFCLASSNONE  0    /* Invalid class */
#define ELFCLASS32  1    /* 32-bit objects */                                                                                                                                                                      
#define ELFCLASS64  2    /* 64-bit objects */
#define ELFCLASSNUM  3



次の1バイト(01)は、エンディアン
同様に確認すると、2の補数、little endianとなっている。

#define ELFDATANONE  0    /* Invalid data encoding */
#define ELFDATA2LSB  1    /* 2's complement, little endian */
#define ELFDATA2MSB  2    /* 2's complement, big endian */                                                                                                                                                         
#define ELFDATANUM  3



次の1バイト(01)はバージョン。
必ず1になっていなくてはいけないっぽい

#define EV_NONE    0    /* Invalid ELF version */
#define EV_CURRENT  1    /* Current version */                                                                                                                                                                     
#define EV_NUM    2



次の1バイト(00)は、ABI。
ABIについては、ちゃんと理解してないのだけどWikipediaでも見ればいいかな。
後回し。
00なので、ABIがSYSVであることは分かった。

#define ELFOSABI_NONE    0  /* UNIX System V ABI */
#define ELFOSABI_SYSV    0  /* Alias.  */
#define ELFOSABI_HPUX    1  /* HP-UX */
#define ELFOSABI_NETBSD    2  /* NetBSD.  */
#define ELFOSABI_GNU    3  /* Object uses GNU ELF extensions.  */
#define ELFOSABI_LINUX    ELFOSABI_GNU /* Compatibility alias.  */
#define ELFOSABI_SOLARIS  6  /* Sun Solaris.  */
#define ELFOSABI_AIX    7  /* IBM AIX.  */
#define ELFOSABI_IRIX    8  /* SGI Irix.  */
#define ELFOSABI_FREEBSD  9  /* FreeBSD.  */
#define ELFOSABI_TRU64    10  /* Compaq TRU64 UNIX.  */
#define ELFOSABI_MODESTO  11  /* Novell Modesto.  */
#define ELFOSABI_OPENBSD  12  /* OpenBSD.  */
#define ELFOSABI_ARM_AEABI  64  /* ARM EABI */
#define ELFOSABI_ARM    97  /* ARM */
#define ELFOSABI_STANDALONE  255  /* Standalone (embedded) application */

のこりの8バイトは、ABIバージョンと予約で開けられている。
ABIバージョンの形式は、ABI依存。