1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
23 type fileTest struct {
26 sections []SectionHeader
31 var fileTests = []fileTest{
33 "testdata/gcc-386-freebsd-exec",
34 FileHeader{ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_FREEBSD, 0, binary.LittleEndian, ET_EXEC, EM_386, 0x80483cc},
36 {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
37 {".interp", SHT_PROGBITS, SHF_ALLOC, 0x80480d4, 0xd4, 0x15, 0x0, 0x0, 0x1, 0x0, 0x15},
38 {".hash", SHT_HASH, SHF_ALLOC, 0x80480ec, 0xec, 0x90, 0x3, 0x0, 0x4, 0x4, 0x90},
39 {".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x804817c, 0x17c, 0x110, 0x4, 0x1, 0x4, 0x10, 0x110},
40 {".dynstr", SHT_STRTAB, SHF_ALLOC, 0x804828c, 0x28c, 0xbb, 0x0, 0x0, 0x1, 0x0, 0xbb},
41 {".rel.plt", SHT_REL, SHF_ALLOC, 0x8048348, 0x348, 0x20, 0x3, 0x7, 0x4, 0x8, 0x20},
42 {".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x8048368, 0x368, 0x11, 0x0, 0x0, 0x4, 0x0, 0x11},
43 {".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804837c, 0x37c, 0x50, 0x0, 0x0, 0x4, 0x4, 0x50},
44 {".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x80483cc, 0x3cc, 0x180, 0x0, 0x0, 0x4, 0x0, 0x180},
45 {".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804854c, 0x54c, 0xc, 0x0, 0x0, 0x4, 0x0, 0xc},
46 {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x8048558, 0x558, 0xa3, 0x0, 0x0, 0x1, 0x0, 0xa3},
47 {".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80495fc, 0x5fc, 0xc, 0x0, 0x0, 0x4, 0x0, 0xc},
48 {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x8049608, 0x608, 0x4, 0x0, 0x0, 0x4, 0x0, 0x4},
49 {".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x804960c, 0x60c, 0x98, 0x4, 0x0, 0x4, 0x8, 0x98},
50 {".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496a4, 0x6a4, 0x8, 0x0, 0x0, 0x4, 0x0, 0x8},
51 {".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496ac, 0x6ac, 0x8, 0x0, 0x0, 0x4, 0x0, 0x8},
52 {".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b4, 0x6b4, 0x4, 0x0, 0x0, 0x4, 0x0, 0x4},
53 {".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b8, 0x6b8, 0x1c, 0x0, 0x0, 0x4, 0x4, 0x1c},
54 {".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x80496d4, 0x6d4, 0x20, 0x0, 0x0, 0x4, 0x0, 0x20},
55 {".comment", SHT_PROGBITS, 0x0, 0x0, 0x6d4, 0x12d, 0x0, 0x0, 0x1, 0x0, 0x12d},
56 {".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x801, 0x20, 0x0, 0x0, 0x1, 0x0, 0x20},
57 {".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0x821, 0x1b, 0x0, 0x0, 0x1, 0x0, 0x1b},
58 {".debug_info", SHT_PROGBITS, 0x0, 0x0, 0x83c, 0x11d, 0x0, 0x0, 0x1, 0x0, 0x11d},
59 {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0x959, 0x41, 0x0, 0x0, 0x1, 0x0, 0x41},
60 {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x99a, 0x35, 0x0, 0x0, 0x1, 0x0, 0x35},
61 {".debug_frame", SHT_PROGBITS, 0x0, 0x0, 0x9d0, 0x30, 0x0, 0x0, 0x4, 0x0, 0x30},
62 {".debug_str", SHT_PROGBITS, 0x0, 0x0, 0xa00, 0xd, 0x0, 0x0, 0x1, 0x0, 0xd},
63 {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xa0d, 0xf8, 0x0, 0x0, 0x1, 0x0, 0xf8},
64 {".symtab", SHT_SYMTAB, 0x0, 0x0, 0xfb8, 0x4b0, 0x1d, 0x38, 0x4, 0x10, 0x4b0},
65 {".strtab", SHT_STRTAB, 0x0, 0x0, 0x1468, 0x206, 0x0, 0x0, 0x1, 0x0, 0x206},
68 {PT_PHDR, PF_R + PF_X, 0x34, 0x8048034, 0x8048034, 0xa0, 0xa0, 0x4},
69 {PT_INTERP, PF_R, 0xd4, 0x80480d4, 0x80480d4, 0x15, 0x15, 0x1},
70 {PT_LOAD, PF_R + PF_X, 0x0, 0x8048000, 0x8048000, 0x5fb, 0x5fb, 0x1000},
71 {PT_LOAD, PF_R + PF_W, 0x5fc, 0x80495fc, 0x80495fc, 0xd8, 0xf8, 0x1000},
72 {PT_DYNAMIC, PF_R + PF_W, 0x60c, 0x804960c, 0x804960c, 0x98, 0x98, 0x4},
74 []string{"libc.so.6"},
77 "testdata/gcc-amd64-linux-exec",
78 FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0, binary.LittleEndian, ET_EXEC, EM_X86_64, 0x4003e0},
80 {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
81 {".interp", SHT_PROGBITS, SHF_ALLOC, 0x400200, 0x200, 0x1c, 0x0, 0x0, 0x1, 0x0, 0x1c},
82 {".note.ABI-tag", SHT_NOTE, SHF_ALLOC, 0x40021c, 0x21c, 0x20, 0x0, 0x0, 0x4, 0x0, 0x20},
83 {".hash", SHT_HASH, SHF_ALLOC, 0x400240, 0x240, 0x24, 0x5, 0x0, 0x8, 0x4, 0x24},
84 {".gnu.hash", SHT_LOOS + 268435446, SHF_ALLOC, 0x400268, 0x268, 0x1c, 0x5, 0x0, 0x8, 0x0, 0x1c},
85 {".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x400288, 0x288, 0x60, 0x6, 0x1, 0x8, 0x18, 0x60},
86 {".dynstr", SHT_STRTAB, SHF_ALLOC, 0x4002e8, 0x2e8, 0x3d, 0x0, 0x0, 0x1, 0x0, 0x3d},
87 {".gnu.version", SHT_HIOS, SHF_ALLOC, 0x400326, 0x326, 0x8, 0x5, 0x0, 0x2, 0x2, 0x8},
88 {".gnu.version_r", SHT_LOOS + 268435454, SHF_ALLOC, 0x400330, 0x330, 0x20, 0x6, 0x1, 0x8, 0x0, 0x20},
89 {".rela.dyn", SHT_RELA, SHF_ALLOC, 0x400350, 0x350, 0x18, 0x5, 0x0, 0x8, 0x18, 0x18},
90 {".rela.plt", SHT_RELA, SHF_ALLOC, 0x400368, 0x368, 0x30, 0x5, 0xc, 0x8, 0x18, 0x30},
91 {".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400398, 0x398, 0x18, 0x0, 0x0, 0x4, 0x0, 0x18},
92 {".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003b0, 0x3b0, 0x30, 0x0, 0x0, 0x4, 0x10, 0x30},
93 {".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003e0, 0x3e0, 0x1b4, 0x0, 0x0, 0x10, 0x0, 0x1b4},
94 {".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400594, 0x594, 0xe, 0x0, 0x0, 0x4, 0x0, 0xe},
95 {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x4005a4, 0x5a4, 0x11, 0x0, 0x0, 0x4, 0x0, 0x11},
96 {".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC, 0x4005b8, 0x5b8, 0x24, 0x0, 0x0, 0x4, 0x0, 0x24},
97 {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x4005e0, 0x5e0, 0xa4, 0x0, 0x0, 0x8, 0x0, 0xa4},
98 {".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600688, 0x688, 0x10, 0x0, 0x0, 0x8, 0x0, 0x10},
99 {".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600698, 0x698, 0x10, 0x0, 0x0, 0x8, 0x0, 0x10},
100 {".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x6006a8, 0x6a8, 0x8, 0x0, 0x0, 0x8, 0x0, 0x8},
101 {".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x6006b0, 0x6b0, 0x1a0, 0x6, 0x0, 0x8, 0x10, 0x1a0},
102 {".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600850, 0x850, 0x8, 0x0, 0x0, 0x8, 0x8, 0x8},
103 {".got.plt", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600858, 0x858, 0x28, 0x0, 0x0, 0x8, 0x8, 0x28},
104 {".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600880, 0x880, 0x18, 0x0, 0x0, 0x8, 0x0, 0x18},
105 {".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x600898, 0x898, 0x8, 0x0, 0x0, 0x4, 0x0, 0x8},
106 {".comment", SHT_PROGBITS, 0x0, 0x0, 0x898, 0x126, 0x0, 0x0, 0x1, 0x0, 0x126},
107 {".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x9c0, 0x90, 0x0, 0x0, 0x10, 0x0, 0x90},
108 {".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0xa50, 0x25, 0x0, 0x0, 0x1, 0x0, 0x25},
109 {".debug_info", SHT_PROGBITS, 0x0, 0x0, 0xa75, 0x1a7, 0x0, 0x0, 0x1, 0x0, 0x1a7},
110 {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xc1c, 0x6f, 0x0, 0x0, 0x1, 0x0, 0x6f},
111 {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0xc8b, 0x13f, 0x0, 0x0, 0x1, 0x0, 0x13f},
112 {".debug_str", SHT_PROGBITS, SHF_MERGE + SHF_STRINGS, 0x0, 0xdca, 0xb1, 0x0, 0x0, 0x1, 0x1, 0xb1},
113 {".debug_ranges", SHT_PROGBITS, 0x0, 0x0, 0xe80, 0x90, 0x0, 0x0, 0x10, 0x0, 0x90},
114 {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xf10, 0x149, 0x0, 0x0, 0x1, 0x0, 0x149},
115 {".symtab", SHT_SYMTAB, 0x0, 0x0, 0x19a0, 0x6f0, 0x24, 0x39, 0x8, 0x18, 0x6f0},
116 {".strtab", SHT_STRTAB, 0x0, 0x0, 0x2090, 0x1fc, 0x0, 0x0, 0x1, 0x0, 0x1fc},
119 {PT_PHDR, PF_R + PF_X, 0x40, 0x400040, 0x400040, 0x1c0, 0x1c0, 0x8},
120 {PT_INTERP, PF_R, 0x200, 0x400200, 0x400200, 0x1c, 0x1c, 1},
121 {PT_LOAD, PF_R + PF_X, 0x0, 0x400000, 0x400000, 0x684, 0x684, 0x200000},
122 {PT_LOAD, PF_R + PF_W, 0x688, 0x600688, 0x600688, 0x210, 0x218, 0x200000},
123 {PT_DYNAMIC, PF_R + PF_W, 0x6b0, 0x6006b0, 0x6006b0, 0x1a0, 0x1a0, 0x8},
124 {PT_NOTE, PF_R, 0x21c, 0x40021c, 0x40021c, 0x20, 0x20, 0x4},
125 {PT_LOOS + 0x474E550, PF_R, 0x5b8, 0x4005b8, 0x4005b8, 0x24, 0x24, 0x4},
126 {PT_LOOS + 0x474E551, PF_R + PF_W, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8},
128 []string{"libc.so.6"},
131 "testdata/hello-world-core.gz",
132 FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_CORE, EM_X86_64, 0x0},
135 {Type: PT_NOTE, Flags: 0x0, Off: 0x3f8, Vaddr: 0x0, Paddr: 0x0, Filesz: 0x8ac, Memsz: 0x0, Align: 0x0},
136 {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x1000, Vaddr: 0x400000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1000, Align: 0x1000},
137 {Type: PT_LOAD, Flags: PF_R, Off: 0x1000, Vaddr: 0x401000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
138 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x2000, Vaddr: 0x402000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
139 {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3000, Vaddr: 0x7f54078b8000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1b5000, Align: 0x1000},
140 {Type: PT_LOAD, Flags: 0x0, Off: 0x3000, Vaddr: 0x7f5407a6d000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1ff000, Align: 0x1000},
141 {Type: PT_LOAD, Flags: PF_R, Off: 0x3000, Vaddr: 0x7f5407c6c000, Paddr: 0x0, Filesz: 0x4000, Memsz: 0x4000, Align: 0x1000},
142 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x7000, Vaddr: 0x7f5407c70000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000},
143 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x9000, Vaddr: 0x7f5407c72000, Paddr: 0x0, Filesz: 0x5000, Memsz: 0x5000, Align: 0x1000},
144 {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0xe000, Vaddr: 0x7f5407c77000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x22000, Align: 0x1000},
145 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0xe000, Vaddr: 0x7f5407e81000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000},
146 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x11000, Vaddr: 0x7f5407e96000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000},
147 {Type: PT_LOAD, Flags: PF_R, Off: 0x14000, Vaddr: 0x7f5407e99000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
148 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x15000, Vaddr: 0x7f5407e9a000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000},
149 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x17000, Vaddr: 0x7fff79972000, Paddr: 0x0, Filesz: 0x23000, Memsz: 0x23000, Align: 0x1000},
150 {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3a000, Vaddr: 0x7fff799f8000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
151 {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3b000, Vaddr: 0xffffffffff600000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
156 "testdata/compressed-32.obj",
157 FileHeader{ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_REL, EM_386, 0x0},
159 {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
160 {".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, 0x0, 0x34, 0x17, 0x0, 0x0, 0x1, 0x0, 0x17},
161 {".rel.text", SHT_REL, SHF_INFO_LINK, 0x0, 0x3dc, 0x10, 0x13, 0x1, 0x4, 0x8, 0x10},
162 {".data", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x4b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0},
163 {".bss", SHT_NOBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x4b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0},
164 {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x4b, 0xd, 0x0, 0x0, 0x1, 0x0, 0xd},
165 {".debug_info", SHT_PROGBITS, SHF_COMPRESSED, 0x0, 0x58, 0xb4, 0x0, 0x0, 0x1, 0x0, 0x84},
166 {".rel.debug_info", SHT_REL, SHF_INFO_LINK, 0x0, 0x3ec, 0xa0, 0x13, 0x6, 0x4, 0x8, 0xa0},
167 {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xdc, 0x5a, 0x0, 0x0, 0x1, 0x0, 0x5a},
168 {".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x136, 0x20, 0x0, 0x0, 0x1, 0x0, 0x20},
169 {".rel.debug_aranges", SHT_REL, SHF_INFO_LINK, 0x0, 0x48c, 0x10, 0x13, 0x9, 0x4, 0x8, 0x10},
170 {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x156, 0x5c, 0x0, 0x0, 0x1, 0x0, 0x5c},
171 {".rel.debug_line", SHT_REL, SHF_INFO_LINK, 0x0, 0x49c, 0x8, 0x13, 0xb, 0x4, 0x8, 0x8},
172 {".debug_str", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS | SHF_COMPRESSED, 0x0, 0x1b2, 0x10f, 0x0, 0x0, 0x1, 0x1, 0xb3},
173 {".comment", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS, 0x0, 0x265, 0x2a, 0x0, 0x0, 0x1, 0x1, 0x2a},
174 {".note.GNU-stack", SHT_PROGBITS, 0x0, 0x0, 0x28f, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0},
175 {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x290, 0x38, 0x0, 0x0, 0x4, 0x0, 0x38},
176 {".rel.eh_frame", SHT_REL, SHF_INFO_LINK, 0x0, 0x4a4, 0x8, 0x13, 0x10, 0x4, 0x8, 0x8},
177 {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0x4ac, 0xab, 0x0, 0x0, 0x1, 0x0, 0xab},
178 {".symtab", SHT_SYMTAB, 0x0, 0x0, 0x2c8, 0x100, 0x14, 0xe, 0x4, 0x10, 0x100},
179 {".strtab", SHT_STRTAB, 0x0, 0x0, 0x3c8, 0x13, 0x0, 0x0, 0x1, 0x0, 0x13},
185 "testdata/compressed-64.obj",
186 FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_REL, EM_X86_64, 0x0},
188 {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
189 {".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, 0x0, 0x40, 0x1b, 0x0, 0x0, 0x1, 0x0, 0x1b},
190 {".rela.text", SHT_RELA, SHF_INFO_LINK, 0x0, 0x488, 0x30, 0x13, 0x1, 0x8, 0x18, 0x30},
191 {".data", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x5b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0},
192 {".bss", SHT_NOBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x5b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0},
193 {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x5b, 0xd, 0x0, 0x0, 0x1, 0x0, 0xd},
194 {".debug_info", SHT_PROGBITS, SHF_COMPRESSED, 0x0, 0x68, 0xba, 0x0, 0x0, 0x1, 0x0, 0x72},
195 {".rela.debug_info", SHT_RELA, SHF_INFO_LINK, 0x0, 0x4b8, 0x1c8, 0x13, 0x6, 0x8, 0x18, 0x1c8},
196 {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xda, 0x5c, 0x0, 0x0, 0x1, 0x0, 0x5c},
197 {".debug_aranges", SHT_PROGBITS, SHF_COMPRESSED, 0x0, 0x136, 0x30, 0x0, 0x0, 0x1, 0x0, 0x2f},
198 {".rela.debug_aranges", SHT_RELA, SHF_INFO_LINK, 0x0, 0x680, 0x30, 0x13, 0x9, 0x8, 0x18, 0x30},
199 {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x165, 0x60, 0x0, 0x0, 0x1, 0x0, 0x60},
200 {".rela.debug_line", SHT_RELA, SHF_INFO_LINK, 0x0, 0x6b0, 0x18, 0x13, 0xb, 0x8, 0x18, 0x18},
201 {".debug_str", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS | SHF_COMPRESSED, 0x0, 0x1c5, 0x104, 0x0, 0x0, 0x1, 0x1, 0xc3},
202 {".comment", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS, 0x0, 0x288, 0x2a, 0x0, 0x0, 0x1, 0x1, 0x2a},
203 {".note.GNU-stack", SHT_PROGBITS, 0x0, 0x0, 0x2b2, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0},
204 {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x2b8, 0x38, 0x0, 0x0, 0x8, 0x0, 0x38},
205 {".rela.eh_frame", SHT_RELA, SHF_INFO_LINK, 0x0, 0x6c8, 0x18, 0x13, 0x10, 0x8, 0x18, 0x18},
206 {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0x6e0, 0xb0, 0x0, 0x0, 0x1, 0x0, 0xb0},
207 {".symtab", SHT_SYMTAB, 0x0, 0x0, 0x2f0, 0x180, 0x14, 0xe, 0x8, 0x18, 0x180},
208 {".strtab", SHT_STRTAB, 0x0, 0x0, 0x470, 0x13, 0x0, 0x0, 0x1, 0x0, 0x13},
215 func TestOpen(t *testing.T) {
216 for i := range fileTests {
221 if path.Ext(tt.file) == ".gz" {
223 if r, err = decompress(tt.file); err == nil {
227 f, err = Open(tt.file)
230 t.Errorf("cannot open file %s: %v", tt.file, err)
234 if f.FileHeader != tt.hdr {
235 t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)
238 for i, s := range f.Sections {
239 if i >= len(tt.sections) {
243 if s.SectionHeader != sh {
244 t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, s.SectionHeader, sh)
247 for i, p := range f.Progs {
248 if i >= len(tt.progs) {
252 if p.ProgHeader != ph {
253 t.Errorf("open %s, program %d:\n\thave %#v\n\twant %#v\n", tt.file, i, p.ProgHeader, ph)
256 tn := len(tt.sections)
257 fn := len(f.Sections)
259 t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
264 t.Errorf("open %s: len(Progs) = %d, want %d", tt.file, fn, tn)
267 fl, err := f.ImportedLibraries()
271 if !reflect.DeepEqual(tl, fl) {
272 t.Errorf("open %s: DT_NEEDED = %v, want %v", tt.file, tl, fl)
277 // elf.NewFile requires io.ReaderAt, which compress/gzip cannot
278 // provide. Decompress the file to a bytes.Reader.
279 func decompress(gz string) (io.ReaderAt, error) {
280 in, err := os.Open(gz)
285 r, err := gzip.NewReader(in)
290 _, err = io.Copy(&out, r)
291 return bytes.NewReader(out.Bytes()), err
294 type relocationTestEntry struct {
300 type relocationTest struct {
302 entries []relocationTestEntry
305 var relocationTests = []relocationTest{
307 "testdata/go-relocation-test-gcc441-x86-64.obj",
308 []relocationTestEntry{
312 Tag: dwarf.TagCompileUnit,
314 Field: []dwarf.Field{
315 {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString},
316 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
317 {Attr: dwarf.AttrName, Val: "go-relocation-test.c", Class: dwarf.ClassString},
318 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
319 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
320 {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress},
321 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
324 pcRanges: [][2]uint64{{0x0, 0x6}},
329 "testdata/go-relocation-test-gcc441-x86.obj",
330 []relocationTestEntry{
334 Tag: dwarf.TagCompileUnit,
336 Field: []dwarf.Field{
337 {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString},
338 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
339 {Attr: dwarf.AttrName, Val: "t.c", Class: dwarf.ClassString},
340 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
341 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
342 {Attr: dwarf.AttrHighpc, Val: uint64(0x5), Class: dwarf.ClassAddress},
343 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
346 pcRanges: [][2]uint64{{0x0, 0x5}},
351 "testdata/go-relocation-test-gcc424-x86-64.obj",
352 []relocationTestEntry{
356 Tag: dwarf.TagCompileUnit,
358 Field: []dwarf.Field{
359 {Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)", Class: dwarf.ClassString},
360 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
361 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c", Class: dwarf.ClassString},
362 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
363 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
364 {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress},
365 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
368 pcRanges: [][2]uint64{{0x0, 0x6}},
373 "testdata/go-relocation-test-gcc482-aarch64.obj",
374 []relocationTestEntry{
378 Tag: dwarf.TagCompileUnit,
380 Field: []dwarf.Field{
381 {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -g -fstack-protector", Class: dwarf.ClassString},
382 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
383 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482.c", Class: dwarf.ClassString},
384 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
385 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
386 {Attr: dwarf.AttrHighpc, Val: int64(0x24), Class: dwarf.ClassConstant},
387 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
390 pcRanges: [][2]uint64{{0x0, 0x24}},
395 "testdata/go-relocation-test-gcc492-arm.obj",
396 []relocationTestEntry{
400 Tag: dwarf.TagCompileUnit,
402 Field: []dwarf.Field{
403 {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 20141224 (prerelease) -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -mtls-dialect=gnu -g", Class: dwarf.ClassString},
404 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
405 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc492.c", Class: dwarf.ClassString},
406 {Attr: dwarf.AttrCompDir, Val: "/root/go/src/debug/elf/testdata", Class: dwarf.ClassString},
407 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
408 {Attr: dwarf.AttrHighpc, Val: int64(0x28), Class: dwarf.ClassConstant},
409 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
412 pcRanges: [][2]uint64{{0x0, 0x28}},
417 "testdata/go-relocation-test-clang-arm.obj",
418 []relocationTestEntry{
422 Tag: dwarf.TagCompileUnit,
424 Field: []dwarf.Field{
425 {Attr: dwarf.AttrProducer, Val: "Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)", Class: dwarf.ClassString},
426 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
427 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
428 {Attr: dwarf.AttrStmtList, Val: int64(0x0), Class: dwarf.ClassLinePtr},
429 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
430 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
431 {Attr: dwarf.AttrHighpc, Val: int64(0x30), Class: dwarf.ClassConstant},
434 pcRanges: [][2]uint64{{0x0, 0x30}},
439 "testdata/go-relocation-test-gcc5-ppc.obj",
440 []relocationTestEntry{
444 Tag: dwarf.TagCompileUnit,
446 Field: []dwarf.Field{
447 {Attr: dwarf.AttrProducer, Val: "GNU C11 5.0.0 20150116 (experimental) -Asystem=linux -Asystem=unix -Asystem=posix -g", Class: dwarf.ClassString},
448 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
449 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc5-ppc.c", Class: dwarf.ClassString},
450 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
451 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
452 {Attr: dwarf.AttrHighpc, Val: int64(0x44), Class: dwarf.ClassConstant},
453 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
456 pcRanges: [][2]uint64{{0x0, 0x44}},
461 "testdata/go-relocation-test-gcc482-ppc64le.obj",
462 []relocationTestEntry{
466 Tag: dwarf.TagCompileUnit,
468 Field: []dwarf.Field{
469 {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -Asystem=linux -Asystem=unix -Asystem=posix -msecure-plt -mtune=power8 -mcpu=power7 -gdwarf-2 -fstack-protector", Class: dwarf.ClassString},
470 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
471 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482-ppc64le.c", Class: dwarf.ClassString},
472 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
473 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
474 {Attr: dwarf.AttrHighpc, Val: uint64(0x24), Class: dwarf.ClassAddress},
475 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
478 pcRanges: [][2]uint64{{0x0, 0x24}},
483 "testdata/go-relocation-test-gcc492-mips64.obj",
484 []relocationTestEntry{
488 Tag: dwarf.TagCompileUnit,
490 Field: []dwarf.Field{
491 {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -meb -mabi=64 -march=mips3 -mtune=mips64 -mllsc -mno-shared -g", Class: dwarf.ClassString},
492 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
493 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
494 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
495 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
496 {Attr: dwarf.AttrHighpc, Val: int64(0x64), Class: dwarf.ClassConstant},
497 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
500 pcRanges: [][2]uint64{{0x0, 0x64}},
505 "testdata/go-relocation-test-gcc531-s390x.obj",
506 []relocationTestEntry{
510 Tag: dwarf.TagCompileUnit,
512 Field: []dwarf.Field{
513 {Attr: dwarf.AttrProducer, Val: "GNU C11 5.3.1 20160316 -march=zEC12 -m64 -mzarch -g -fstack-protector-strong", Class: dwarf.ClassString},
514 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
515 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
516 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
517 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
518 {Attr: dwarf.AttrHighpc, Val: int64(0x3a), Class: dwarf.ClassConstant},
519 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
522 pcRanges: [][2]uint64{{0x0, 0x3a}},
527 "testdata/go-relocation-test-gcc620-sparc64.obj",
528 []relocationTestEntry{
532 Tag: dwarf.TagCompileUnit,
534 Field: []dwarf.Field{
535 {Attr: dwarf.AttrProducer, Val: "GNU C11 6.2.0 20160914 -mcpu=v9 -g -fstack-protector-strong", Class: dwarf.ClassString},
536 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
537 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
538 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
539 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
540 {Attr: dwarf.AttrHighpc, Val: int64(0x2c), Class: dwarf.ClassConstant},
541 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
544 pcRanges: [][2]uint64{{0x0, 0x2c}},
549 "testdata/go-relocation-test-gcc492-mipsle.obj",
550 []relocationTestEntry{
554 Tag: dwarf.TagCompileUnit,
556 Field: []dwarf.Field{
557 {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -mel -march=mips2 -mtune=mips32 -mllsc -mno-shared -mabi=32 -g", Class: dwarf.ClassString},
558 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
559 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
560 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
561 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
562 {Attr: dwarf.AttrHighpc, Val: int64(0x58), Class: dwarf.ClassConstant},
563 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
566 pcRanges: [][2]uint64{{0x0, 0x58}},
571 "testdata/go-relocation-test-gcc540-mips.obj",
572 []relocationTestEntry{
576 Tag: dwarf.TagCompileUnit,
578 Field: []dwarf.Field{
579 {Attr: dwarf.AttrProducer, Val: "GNU C11 5.4.0 20160609 -meb -mips32 -mtune=mips32r2 -mfpxx -mllsc -mno-shared -mabi=32 -g -gdwarf-2", Class: dwarf.ClassString},
580 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
581 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
582 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
583 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
584 {Attr: dwarf.AttrHighpc, Val: uint64(0x5c), Class: dwarf.ClassAddress},
585 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
588 pcRanges: [][2]uint64{{0x0, 0x5c}},
593 "testdata/go-relocation-test-gcc493-mips64le.obj",
594 []relocationTestEntry{
598 Tag: dwarf.TagCompileUnit,
600 Field: []dwarf.Field{
601 {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.3 -mel -mabi=64 -mllsc -mno-shared -g -fstack-protector-strong", Class: dwarf.ClassString},
602 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
603 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
604 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
605 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
606 {Attr: dwarf.AttrHighpc, Val: int64(0x64), Class: dwarf.ClassConstant},
607 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
610 pcRanges: [][2]uint64{{0x0, 0x64}},
615 "testdata/go-relocation-test-gcc720-riscv64.obj",
616 []relocationTestEntry{
620 Tag: dwarf.TagCompileUnit,
622 Field: []dwarf.Field{
623 {Attr: dwarf.AttrProducer, Val: "GNU C11 7.2.0 -march=rv64imafdc -mabi=lp64d -g -gdwarf-2", Class: dwarf.ClassString},
624 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
625 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
626 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
627 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
628 {Attr: dwarf.AttrHighpc, Val: uint64(0x2c), Class: dwarf.ClassAddress},
629 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
632 pcRanges: [][2]uint64{{0x0, 0x2c}},
637 "testdata/go-relocation-test-clang-x86.obj",
638 []relocationTestEntry{
642 Tag: dwarf.TagCompileUnit,
644 Field: []dwarf.Field{
645 {Attr: dwarf.AttrProducer, Val: "clang version google3-trunk (trunk r209387)", Class: dwarf.ClassString},
646 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
647 {Attr: dwarf.AttrName, Val: "go-relocation-test-clang.c", Class: dwarf.ClassString},
648 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
649 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
656 "testdata/gcc-amd64-openbsd-debug-with-rela.obj",
657 []relocationTestEntry{
662 Tag: dwarf.TagMember,
664 Field: []dwarf.Field{
665 {Attr: dwarf.AttrName, Val: "it_interval", Class: dwarf.ClassString},
666 {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant},
667 {Attr: dwarf.AttrDeclLine, Val: int64(236), Class: dwarf.ClassConstant},
668 {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference},
669 {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}, Class: dwarf.ClassExprLoc},
677 Tag: dwarf.TagMember,
679 Field: []dwarf.Field{
680 {Attr: dwarf.AttrName, Val: "it_value", Class: dwarf.ClassString},
681 {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant},
682 {Attr: dwarf.AttrDeclLine, Val: int64(237), Class: dwarf.ClassConstant},
683 {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference},
684 {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}, Class: dwarf.ClassExprLoc},
691 "testdata/go-relocation-test-gcc930-ranges-no-rela-x86-64",
692 []relocationTestEntry{
696 Tag: dwarf.TagCompileUnit,
698 Field: []dwarf.Field{
699 {Attr: dwarf.AttrProducer, Val: "GNU C17 9.3.0 -mtune=generic -march=x86-64 -g -fno-asynchronous-unwind-tables", Class: dwarf.ClassString},
700 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
701 {Attr: dwarf.AttrName, Val: "multiple-code-sections.c", Class: dwarf.ClassString},
702 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
703 {Attr: dwarf.AttrRanges, Val: int64(0), Class: dwarf.ClassRangeListPtr},
704 {Attr: dwarf.AttrLowpc, Val: uint64(0), Class: dwarf.ClassAddress},
705 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
708 pcRanges: [][2]uint64{
716 "testdata/go-relocation-test-gcc930-ranges-with-rela-x86-64",
717 []relocationTestEntry{
721 Tag: dwarf.TagCompileUnit,
723 Field: []dwarf.Field{
724 {Attr: dwarf.AttrProducer, Val: "GNU C17 9.3.0 -mtune=generic -march=x86-64 -g -fno-asynchronous-unwind-tables", Class: dwarf.ClassString},
725 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
726 {Attr: dwarf.AttrName, Val: "multiple-code-sections.c", Class: dwarf.ClassString},
727 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
728 {Attr: dwarf.AttrRanges, Val: int64(0), Class: dwarf.ClassRangeListPtr},
729 {Attr: dwarf.AttrLowpc, Val: uint64(0), Class: dwarf.ClassAddress},
730 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
733 pcRanges: [][2]uint64{
742 func TestDWARFRelocations(t *testing.T) {
743 for _, test := range relocationTests {
745 t.Run(test.file, func(t *testing.T) {
747 f, err := Open(test.file)
751 dwarf, err := f.DWARF()
755 reader := dwarf.Reader()
757 for _, testEntry := range test.entries {
758 if testEntry.entryNumber < idx {
759 t.Fatalf("internal test error: %d < %d", testEntry.entryNumber, idx)
761 for ; idx < testEntry.entryNumber; idx++ {
762 entry, err := reader.Next()
763 if entry == nil || err != nil {
764 t.Fatalf("Failed to skip to entry %d: %v", testEntry.entryNumber, err)
767 entry, err := reader.Next()
772 if !reflect.DeepEqual(testEntry.entry, entry) {
773 t.Errorf("entry %d mismatch: got:%#v want:%#v", testEntry.entryNumber, entry, testEntry.entry)
775 pcRanges, err := dwarf.Ranges(entry)
779 if !reflect.DeepEqual(testEntry.pcRanges, pcRanges) {
780 t.Errorf("entry %d: PC range mismatch: got:%#v want:%#v", testEntry.entryNumber, pcRanges, testEntry.pcRanges)
787 func TestCompressedDWARF(t *testing.T) {
788 // Test file built with GCC 4.8.4 and as 2.24 using:
789 // gcc -Wa,--compress-debug-sections -g -c -o zdebug-test-gcc484-x86-64.obj hello.c
790 f, err := Open("testdata/zdebug-test-gcc484-x86-64.obj")
794 dwarf, err := f.DWARF()
798 reader := dwarf.Reader()
801 entry, err := reader.Next()
811 t.Fatalf("want %d DWARF entries, got %d", 18, n)
815 func TestCompressedSection(t *testing.T) {
816 // Test files built with gcc -g -S hello.c and assembled with
817 // --compress-debug-sections=zlib-gabi.
818 f, err := Open("testdata/compressed-64.obj")
822 sec := f.Section(".debug_info")
824 182, 0, 0, 0, 4, 0, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0,
825 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
826 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 7,
827 0, 0, 0, 0, 2, 1, 8, 0, 0, 0, 0, 2, 2, 7, 0, 0,
828 0, 0, 2, 4, 7, 0, 0, 0, 0, 2, 1, 6, 0, 0, 0, 0,
829 2, 2, 5, 0, 0, 0, 0, 3, 4, 5, 105, 110, 116, 0, 2, 8,
830 5, 0, 0, 0, 0, 2, 8, 7, 0, 0, 0, 0, 4, 8, 114, 0,
831 0, 0, 2, 1, 6, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 4,
832 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0,
833 1, 156, 179, 0, 0, 0, 6, 0, 0, 0, 0, 1, 4, 87, 0, 0,
834 0, 2, 145, 108, 6, 0, 0, 0, 0, 1, 4, 179, 0, 0, 0, 2,
835 145, 96, 0, 4, 8, 108, 0, 0, 0, 0,
843 if !bytes.Equal(wantData, b) {
844 t.Fatalf("want data %x, got %x", wantData, b)
847 // Test Open method and seeking.
848 buf, have, count := make([]byte, len(b)), make([]bool, len(b)), 0
850 if got, err := sf.Seek(0, io.SeekEnd); got != int64(len(b)) || err != nil {
851 t.Fatalf("want seek end %d, got %d error %v", len(b), got, err)
853 if n, err := sf.Read(buf); n != 0 || err != io.EOF {
854 t.Fatalf("want EOF with 0 bytes, got %v with %d bytes", err, n)
856 pos := int64(len(buf))
857 for count < len(buf) {
858 // Construct random seek arguments.
859 whence := rand.Intn(3)
860 target := rand.Int63n(int64(len(buf)))
866 offset = target - pos
868 offset = target - int64(len(buf))
870 pos, err = sf.Seek(offset, whence)
875 t.Fatalf("want position %d, got %d", target, pos)
878 // Read data from the new position.
880 if end > int64(len(buf)) {
881 end = int64(len(buf))
883 n, err := io.ReadFull(sf, buf[pos:end])
887 for i := 0; i < n; i++ {
895 if !bytes.Equal(wantData, buf) {
896 t.Fatalf("want data %x, got %x", wantData, buf)
900 func TestNoSectionOverlaps(t *testing.T) {
901 // Ensure cmd/link outputs sections without overlaps.
902 switch runtime.GOOS {
903 case "aix", "android", "darwin", "ios", "js", "plan9", "windows":
904 t.Skipf("cmd/link doesn't produce ELF binaries on %s", runtime.GOOS)
906 _ = net.ResolveIPAddr // force dynamic linkage
907 f, err := Open(os.Args[0])
912 for i, si := range f.Sections {
913 sih := si.SectionHeader
914 if sih.Type == SHT_NOBITS {
917 // checking for overlap in file
918 for j, sj := range f.Sections {
919 sjh := sj.SectionHeader
920 if i == j || sjh.Type == SHT_NOBITS || sih.Offset == sjh.Offset && sih.FileSize == 0 {
923 if sih.Offset >= sjh.Offset && sih.Offset < sjh.Offset+sjh.FileSize {
924 t.Errorf("ld produced ELF with section offset %s within %s: 0x%x <= 0x%x..0x%x < 0x%x",
925 sih.Name, sjh.Name, sjh.Offset, sih.Offset, sih.Offset+sih.FileSize, sjh.Offset+sjh.FileSize)
929 if sih.Flags&SHF_ALLOC == 0 {
933 // checking for overlap in address space
934 for j, sj := range f.Sections {
935 sjh := sj.SectionHeader
936 if i == j || sjh.Flags&SHF_ALLOC == 0 || sjh.Type == SHT_NOBITS ||
937 sih.Addr == sjh.Addr && sih.Size == 0 {
940 if sih.Addr >= sjh.Addr && sih.Addr < sjh.Addr+sjh.Size {
941 t.Errorf("ld produced ELF with section address %s within %s: 0x%x <= 0x%x..0x%x < 0x%x",
942 sih.Name, sjh.Name, sjh.Addr, sih.Addr, sih.Addr+sih.Size, sjh.Addr+sjh.Size)
948 func TestNobitsSection(t *testing.T) {
949 const testdata = "testdata/gcc-amd64-linux-exec"
950 f, err := Open(testdata)
952 t.Fatalf("could not read %s: %v", testdata, err)
956 wantError := "unexpected read from SHT_NOBITS section"
957 bss := f.Section(".bss")
960 if err == nil || err.Error() != wantError {
961 t.Fatalf("bss.Data() got error %q, want error %q", err, wantError)
967 if err == nil || err.Error() != wantError {
968 t.Fatalf("r.Read(p) got error %q, want error %q", err, wantError)
972 // TestLargeNumberOfSections tests the case that a file has greater than or
973 // equal to 65280 (0xff00) sections.
974 func TestLargeNumberOfSections(t *testing.T) {
975 // A file with >= 0xff00 sections is too big, so we will construct it on the
976 // fly. The original file "y.o" is generated by these commands:
977 // 1. generate "y.c":
978 // for i in `seq 1 65288`; do
979 // printf -v x "%04x" i;
980 // echo "int var_$x __attribute__((section(\"section_$x\"))) = $i;"
982 // 2. compile: gcc -c y.c -m32
986 // Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
988 // Data: 2's complement, little endian
989 // Version: 1 (current)
990 // OS/ABI: UNIX - System V
992 // Type: REL (Relocatable file)
993 // Machine: Intel 80386
995 // Entry point address: 0x0
996 // Start of program headers: 0 (bytes into file)
997 // Start of section headers: 3003468 (bytes into file)
999 // Size of this header: 52 (bytes)
1000 // Size of program headers: 0 (bytes)
1001 // Number of program headers: 0
1002 // Size of section headers: 40 (bytes)
1003 // Number of section headers: 0 (65298)
1004 // Section header string table index: 65535 (65297)
1007 // There are 65298 section headers, starting at offset 0x2dd44c:
1009 // [Nr] Name Type Addr Off Size ES Flg Lk Inf Al
1010 // [ 0] NULL 00000000 000000 00ff12 00 65297 0 0
1011 // [ 1] .text PROGBITS 00000000 000034 000000 00 AX 0 0 1
1012 // [ 2] .data PROGBITS 00000000 000034 000000 00 WA 0 0 1
1013 // [ 3] .bss NOBITS 00000000 000034 000000 00 WA 0 0 1
1014 // [ 4] section_0001 PROGBITS 00000000 000034 000004 00 WA 0 0 4
1015 // [ 5] section_0002 PROGBITS 00000000 000038 000004 00 WA 0 0 4
1016 // [ section_0003 ~ section_ff06 truncated ]
1017 // [65290] section_ff07 PROGBITS 00000000 03fc4c 000004 00 WA 0 0 4
1018 // [65291] section_ff08 PROGBITS 00000000 03fc50 000004 00 WA 0 0 4
1019 // [65292] .comment PROGBITS 00000000 03fc54 000027 01 MS 0 0 1
1020 // [65293] .note.GNU-stack PROGBITS 00000000 03fc7b 000000 00 0 0 1
1021 // [65294] .symtab SYMTAB 00000000 03fc7c 0ff0a0 10 65296 2 4
1022 // [65295] .symtab_shndx SYMTAB SECTION 00000000 13ed1c 03fc28 04 65294 0 4
1023 // [65296] .strtab STRTAB 00000000 17e944 08f74d 00 0 0 1
1024 // [65297] .shstrtab STRTAB 00000000 20e091 0cf3bb 00 0 0 1
1026 var buf bytes.Buffer
1029 buf.Grow(0x55AF1C) // 3003468 + 40 * 65298
1032 Ident: [16]byte{0x7F, 'E', 'L', 'F', 0x01, 0x01, 0x01},
1042 binary.Write(&buf, binary.LittleEndian, h)
1044 // Zero out sections [1]~[65294].
1045 buf.Write(bytes.Repeat([]byte{0}, 0x13ED1C-binary.Size(h)))
1047 // Write section [65295]. Section [65295] are all zeros except for the
1049 buf.Write(bytes.Repeat([]byte{0}, 0x03FC28-12*4))
1050 for i := 0; i < 12; i++ {
1051 binary.Write(&buf, binary.LittleEndian, uint32(0xFF00|i))
1054 // Write section [65296].
1055 buf.Write([]byte{0})
1056 buf.Write([]byte("y.c\x00"))
1057 for i := 1; i <= 65288; i++ {
1058 // var_0001 ~ var_ff08
1059 name := fmt.Sprintf("var_%04x", i)
1060 buf.Write([]byte(name))
1061 buf.Write([]byte{0})
1064 // Write section [65297].
1065 buf.Write([]byte{0})
1066 buf.Write([]byte(".symtab\x00"))
1067 buf.Write([]byte(".strtab\x00"))
1068 buf.Write([]byte(".shstrtab\x00"))
1069 buf.Write([]byte(".text\x00"))
1070 buf.Write([]byte(".data\x00"))
1071 buf.Write([]byte(".bss\x00"))
1072 for i := 1; i <= 65288; i++ {
1074 name := fmt.Sprintf("section_%04x", i)
1075 buf.Write([]byte(name))
1076 buf.Write([]byte{0})
1078 buf.Write([]byte(".comment\x00"))
1079 buf.Write([]byte(".note.GNU-stack\x00"))
1080 buf.Write([]byte(".symtab_shndx\x00"))
1082 // Write section header table.
1084 binary.Write(&buf, binary.LittleEndian, Section32{Name: 0, Size: 0xFF12, Link: 0xFF11})
1086 binary.Write(&buf, binary.LittleEndian, Section32{
1088 Type: uint32(SHT_PROGBITS),
1089 Flags: uint32(uint32(SHF_ALLOC | SHF_EXECINSTR)),
1094 binary.Write(&buf, binary.LittleEndian, Section32{
1096 Type: uint32(SHT_PROGBITS),
1097 Flags: uint32(SHF_WRITE | SHF_ALLOC),
1102 binary.Write(&buf, binary.LittleEndian, Section32{
1104 Type: uint32(SHT_NOBITS),
1105 Flags: uint32(SHF_WRITE | SHF_ALLOC),
1110 for i := 0; i < 65288; i++ {
1112 Name: uint32(0x2C + i*13),
1113 Type: uint32(SHT_PROGBITS),
1114 Flags: uint32(SHF_WRITE | SHF_ALLOC),
1115 Off: uint32(0x34 + i*4),
1119 binary.Write(&buf, binary.LittleEndian, s)
1122 binary.Write(&buf, binary.LittleEndian, Section32{
1124 Type: uint32(SHT_PROGBITS),
1125 Flags: uint32(SHF_MERGE | SHF_STRINGS),
1132 binary.Write(&buf, binary.LittleEndian, Section32{
1134 Type: uint32(SHT_PROGBITS),
1139 binary.Write(&buf, binary.LittleEndian, Section32{
1141 Type: uint32(SHT_SYMTAB),
1150 binary.Write(&buf, binary.LittleEndian, Section32{
1152 Type: uint32(SHT_SYMTAB_SHNDX),
1160 binary.Write(&buf, binary.LittleEndian, Section32{
1162 Type: uint32(SHT_STRTAB),
1168 binary.Write(&buf, binary.LittleEndian, Section32{
1170 Type: uint32(SHT_STRTAB),
1179 f, err := NewFile(bytes.NewReader(data))
1181 t.Errorf("cannot create file from data: %v", err)
1185 wantFileHeader := FileHeader{
1188 Version: EV_CURRENT,
1189 OSABI: ELFOSABI_NONE,
1190 ByteOrder: binary.LittleEndian,
1194 if f.FileHeader != wantFileHeader {
1195 t.Errorf("\nhave %#v\nwant %#v\n", f.FileHeader, wantFileHeader)
1198 wantSectionNum := 65298
1199 if len(f.Sections) != wantSectionNum {
1200 t.Errorf("len(Sections) = %d, want %d", len(f.Sections), wantSectionNum)
1203 wantSectionHeader := SectionHeader{
1204 Name: "section_0007",
1206 Flags: SHF_WRITE + SHF_ALLOC,
1212 if f.Sections[10].SectionHeader != wantSectionHeader {
1213 t.Errorf("\nhave %#v\nwant %#v\n", f.Sections[10].SectionHeader, wantSectionHeader)
1217 func TestIssue10996(t *testing.T) {
1218 data := []byte("\u007fELF\x02\x01\x010000000000000" +
1219 "\x010000000000000000000" +
1220 "\x00\x00\x00\x00\x00\x00\x00\x0000000000\x00\x00\x00\x00" +
1222 _, err := NewFile(bytes.NewReader(data))
1224 t.Fatalf("opening invalid ELF file unexpectedly succeeded")
1228 func TestDynValue(t *testing.T) {
1229 const testdata = "testdata/gcc-amd64-linux-exec"
1230 f, err := Open(testdata)
1232 t.Fatalf("could not read %s: %v", testdata, err)
1236 vals, err := f.DynValue(DT_VERNEEDNUM)
1238 t.Fatalf("DynValue(DT_VERNEEDNUM): got unexpected error %v", err)
1241 if len(vals) != 1 || vals[0] != 1 {
1242 t.Errorf("DynValue(DT_VERNEEDNUM): got %v, want [1]", vals)