さきほど、実行形式ファイルには、複数のソースファイルに分散して定義されているはずの関数や変数が1つにまとまって扱われている様子が見れました。

複数のソースファイルに記述されている内容をリンクして実行形式ファイルを作成しているからなわけですが、リンクの動きが明確にわからないので、せめてオブジェクトファイルでも眺めてみることにします。

そこでreadelfをオブジェクトファイルに食わせてみることもできるようなのでなにか発見がないか確認してみることにします。


①main.c

ELF Header:
Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, big endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Hitachi H8/300
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 496 (bytes into file)
Flags: 0x810000
Size of this header: 52 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 9
Section header string table index: 6

Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000116 00 AX 0 0 2
[ 2] .rela.text RELA 00000000 000604 00021c 0c 7 1 4
[ 3] .data PROGBITS 00000000 00014a 000004 00 WA 0 0 2
[ 4] .bss NOBITS 00000000 00014e 000002 00 WA 0 0 2
[ 5] .rodata.str1.1 PROGBITS 00000000 00014e 000062 01 AMS 0 0 1
[ 6] .shstrtab STRTAB 00000000 0001b0 000040 00 0 0 1
[ 7] .symtab SYMTAB 00000000 000358 0001e0 10 8 11 4
[ 8] .strtab STRTAB 00000000 000538 0000ca 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)

There are no program headers in this file.

There is no dynamic segment in this file.

Relocation section '.rela.text' at offset 0x604 contains 45 entries:
Offset Info Type Symbol's Value Symbol's Name Addend
00000008 00000901 R_H8_DIR32 00000000 .LC0 + 0
0000000d 0000123e R_H8_DIR24R8 00000000 _puts + 0
00000014 0000113f R_H8_DIR32A16 00000000 _global_data + 0
0000001b 0000133e R_H8_DIR24R8 00000000 _putxval + 0
00000020 00000a01 R_H8_DIR32 0000000f .LC1 + 0
00000025 0000123e R_H8_DIR24R8 00000000 _puts + 0
0000002a 00000b01 R_H8_DIR32 00000011 .LC2 + 0
0000002f 0000123e R_H8_DIR24R8 00000000 _puts + 0
00000036 0000143f R_H8_DIR32A16 00000002 _global_bss + 0
0000003d 0000133e R_H8_DIR24R8 00000000 _putxval + 0
00000042 00000a01 R_H8_DIR32 0000000f .LC1 + 0
00000047 0000123e R_H8_DIR24R8 00000000 _puts + 0
0000004c 00000c01 R_H8_DIR32 00000020 .LC3 + 0
00000051 0000123e R_H8_DIR24R8 00000000 _puts + 0
00000058 0000053f R_H8_DIR32A16 00000002 _static_data + 0
0000005f 0000133e R_H8_DIR24R8 00000000 _putxval + 0
00000064 00000a01 R_H8_DIR32 0000000f .LC1 + 0
00000069 0000123e R_H8_DIR24R8 00000000 _puts + 0
0000006e 00000d01 R_H8_DIR32 0000002f .LC4 + 0
00000073 0000123e R_H8_DIR24R8 00000000 _puts + 0
0000007a 0000083f R_H8_DIR32A16 00000000 _static_bss + 0
00000081 0000133e R_H8_DIR24R8 00000000 _putxval + 0
00000086 00000a01 R_H8_DIR32 0000000f .LC1 + 0
0000008b 0000123e R_H8_DIR24R8 00000000 _puts + 0
0000009c 00001601 R_H8_DIR32 00000000 _edata + 0
000000a2 00001701 R_H8_DIR32 00000000 _data_start + 0
000000a8 00001801 R_H8_DIR32 00000000 _erodata + 0
000000ae 00001701 R_H8_DIR32 00000000 _data_start + 0
000000b3 0000193e R_H8_DIR24R8 00000000 _memcpy + 0
000000b8 00001a01 R_H8_DIR32 00000000 _ebss + 0
000000be 00001b01 R_H8_DIR32 00000000 _bss_start + 0
000000c6 00001b01 R_H8_DIR32 00000000 _bss_start + 0
000000cb 00001c3e R_H8_DIR24R8 00000000 _memset + 0
000000d3 00001d3e R_H8_DIR24R8 00000000 _serial_init + 0
000000d8 00000e01 R_H8_DIR32 0000003e .LC5 + 0
000000dd 0000123e R_H8_DIR24R8 00000000 _puts + 0
000000e1 0000073e R_H8_DIR24R8 00000000 _printval + 0
000000e6 00000f01 R_H8_DIR32 0000004c .LC6 + 0
000000eb 0000123e R_H8_DIR24R8 00000000 _puts + 0
000000f4 0000113f R_H8_DIR32A16 00000000 _global_data + 0
000000fc 0000143f R_H8_DIR32A16 00000002 _global_bss + 0
00000104 0000053f R_H8_DIR32A16 00000002 _static_data + 0
0000010c 0000083f R_H8_DIR32A16 00000000 _static_bss + 0
00000111 0000073e R_H8_DIR24R8 00000000 _printval + 0
00000115 00001020 R_H8_PCREL8 00000114 .L4 + 0

There are no unwind sections in this file.

Symbol table '.symtab' contains 30 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS main.c
2: 00000000 0 SECTION LOCAL DEFAULT 1
3: 00000000 0 SECTION LOCAL DEFAULT 3
4: 00000000 0 SECTION LOCAL DEFAULT 4
5: 00000002 2 OBJECT LOCAL DEFAULT 3 _static_data
6: 00000000 0 SECTION LOCAL DEFAULT 5
7: 00000000 148 NOTYPE LOCAL DEFAULT 1 _printval
8: 00000000 2 OBJECT LOCAL DEFAULT 4 _static_bss
9: 00000000 0 NOTYPE LOCAL DEFAULT 5 .LC0
10: 0000000f 0 NOTYPE LOCAL DEFAULT 5 .LC1
11: 00000011 0 NOTYPE LOCAL DEFAULT 5 .LC2
12: 00000020 0 NOTYPE LOCAL DEFAULT 5 .LC3
13: 0000002f 0 NOTYPE LOCAL DEFAULT 5 .LC4
14: 0000003e 0 NOTYPE LOCAL DEFAULT 5 .LC5
15: 0000004c 0 NOTYPE LOCAL DEFAULT 5 .LC6
16: 00000114 0 NOTYPE LOCAL DEFAULT 1 .L4
17: 00000000 2 OBJECT GLOBAL DEFAULT 3 _global_data
18: 00000000 0 NOTYPE GLOBAL DEFAULT UND _puts
19: 00000000 0 NOTYPE GLOBAL DEFAULT UND _putxval
20: 00000002 2 OBJECT GLOBAL DEFAULT COM _global_bss
21: 00000094 130 NOTYPE GLOBAL DEFAULT 1 _main
22: 00000000 0 NOTYPE GLOBAL DEFAULT UND _edata
23: 00000000 0 NOTYPE GLOBAL DEFAULT UND _data_start
24: 00000000 0 NOTYPE GLOBAL DEFAULT UND _erodata
25: 00000000 0 NOTYPE GLOBAL DEFAULT UND _memcpy
26: 00000000 0 NOTYPE GLOBAL DEFAULT UND _ebss
27: 00000000 0 NOTYPE GLOBAL DEFAULT UND _bss_start
28: 00000000 0 NOTYPE GLOBAL DEFAULT UND _memset
29: 00000000 0 NOTYPE GLOBAL DEFAULT UND _serial_init

No version information found in this file.



②serial.c

ELF Header:
Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, big endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Hitachi H8/300
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 292 (bytes into file)
Flags: 0x810000
Size of this header: 52 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 8
Section header string table index: 5

Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 0000b0 00 AX 0 0 2
[ 2] .rela.text RELA 00000000 000350 00003c 0c 6 1 4
[ 3] .data PROGBITS 00000000 0000e4 00000c 00 WA 0 0 4
[ 4] .bss NOBITS 00000000 0000f0 000000 00 WA 0 0 1
[ 5] .shstrtab STRTAB 00000000 0000f0 000031 00 0 0 1
[ 6] .symtab SYMTAB 00000000 000264 0000a0 10 7 7 4
[ 7] .strtab STRTAB 00000000 000304 00004a 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)

There are no program headers in this file.

There is no dynamic segment in this file.

Relocation section '.rela.text' at offset 0x350 contains 5 entries:
Offset Info Type Symbol's Value Symbol's Name Addend
00000012 00000501 R_H8_DIR32 00000000 _regs + 0
00000048 00000501 R_H8_DIR32 00000000 _regs + 0
0000007e 00000501 R_H8_DIR32 00000000 _regs + 0
00000085 0000083e R_H8_DIR24R8 00000036 _serial_is_send_enable + 0
0000008b 00000620 R_H8_PCREL8 00000082 .L4 + 0

There are no unwind sections in this file.

Symbol table '.symtab' contains 10 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS serial.c
2: 00000000 0 SECTION LOCAL DEFAULT 1
3: 00000000 0 SECTION LOCAL DEFAULT 3
4: 00000000 0 SECTION LOCAL DEFAULT 4
5: 00000000 12 OBJECT LOCAL DEFAULT 3 _regs
6: 00000082 0 NOTYPE LOCAL DEFAULT 1 .L4
7: 00000000 54 NOTYPE GLOBAL DEFAULT 1 _serial_init
8: 00000036 36 NOTYPE GLOBAL DEFAULT 1 _serial_is_send_enable
9: 0000005a 86 NOTYPE GLOBAL DEFAULT 1 _serial_send_byte

No version information found in this file.




■実行形式ファイルと比較しての気付き

1.以下のセグメントは実行形式ファイルの中にはなかった。
[ 2] .rela.text RELA 00000000 000604 00021c 0c 7 1 4
[ 5] .rodata.str1.1 PROGBITS 00000000 00014e 000062 01 AMS 0 0 1

2.オブジェクトファイルにはprogram headersはない。OK.
There are no program headers in this file.
先術した通りロードできるファイルではないからのようです。

3.オブジェクトファイルにはRelocation sectionがあるぞ。
Offsetという用語から推測して実行形式ファイルでアドレスを付与するときの相対的な配置を示していそうだがなんか資料ないかな。

4.Symbol tableのアドレスは意味なさげ。
自分のところで定義した情報だけValueとSizeを出している模様。
変数と関数はそれぞれ独立して相対的な配置を表現しているようだ。
5: 00000000 12 OBJECT LOCAL DEFAULT 3 _regs
 ←★regs変数のValueは0
6: 00000082 0 NOTYPE LOCAL DEFAULT 1 .L4
7: 00000000 54 NOTYPE GLOBAL DEFAULT 1 _serial_init
←★serial_init関数のValueは0
←★0x0+54(0x36)=0x36
8: 00000036 36 NOTYPE GLOBAL DEFAULT 1 _serial_is_send_enable
 ←★0x36+36(0x24)=0x36=0x5a
9: 0000005a 86 NOTYPE GLOBAL DEFAULT 1 _serial_send_byte



他のソースファイルで定義したものに関してはシンボルを明示しているがValueとSizeは0になっている。
21: 00000094 130 NOTYPE GLOBAL DEFAULT 1 _main ←★自分で定義
22: 00000000 0 NOTYPE GLOBAL DEFAULT UND _edata ←★他で定義した変数(extern)
23: 00000000 0 NOTYPE GLOBAL DEFAULT UND _data_start
24: 00000000 0 NOTYPE GLOBAL DEFAULT UND _erodata
25: 00000000 0 NOTYPE GLOBAL DEFAULT UND _memcpy ←★他で定義した関数(extern)
26: 00000000 0 NOTYPE GLOBAL DEFAULT UND _ebss
27: 00000000 0 NOTYPE GLOBAL DEFAULT UND _bss_start
28: 00000000 0 NOTYPE GLOBAL DEFAULT UND _memset
29: 00000000 0 NOTYPE GLOBAL DEFAULT UND _serial_init



■Program Headersのところ
大きな観点でみると実行形式ファイルには「Program Headers」はありますが、オブジェクトファイルには「Program Headers」がありません。

5章のELFフォーマットの展開で明らかになり、重要なポイントになりますが、ここは実行形式ファイルをメモリ上に展開するローダという機能で使用されます。

ローダはプログラム実行時に、ここの「Program Headers」を参照しメモリ展開するようです。
セグメントという用語がキーワードになります。

それなので、オブジェクトファイルはメモリに情報を展開するためのファイルには対応していないことを示しています。

メモリに展開できないということはCPUで情報を読み取り実行できる情報ではないということを意味していてシステムを動かすためのファイルとしては不十分であることを示しているようです。