Source file
src/debug/elf/file_test.go
1
2
3
4
5 package elf
6
7 import (
8 "bytes"
9 "compress/gzip"
10 "compress/zlib"
11 "debug/dwarf"
12 "encoding/binary"
13 "errors"
14 "fmt"
15 "io"
16 "math/rand"
17 "net"
18 "os"
19 "path"
20 "reflect"
21 "runtime"
22 "slices"
23 "strings"
24 "testing"
25 )
26
27 type fileTest struct {
28 file string
29 hdr FileHeader
30 sections []SectionHeader
31 progs []ProgHeader
32 needed []string
33 symbols []Symbol
34 }
35
36 var fileTests = []fileTest{
37 {
38 "testdata/gcc-386-freebsd-exec",
39 FileHeader{ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_FREEBSD, 0, binary.LittleEndian, ET_EXEC, EM_386, 0x80483cc},
40 []SectionHeader{
41 {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
42 {".interp", SHT_PROGBITS, SHF_ALLOC, 0x80480d4, 0xd4, 0x15, 0x0, 0x0, 0x1, 0x0, 0x15},
43 {".hash", SHT_HASH, SHF_ALLOC, 0x80480ec, 0xec, 0x90, 0x3, 0x0, 0x4, 0x4, 0x90},
44 {".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x804817c, 0x17c, 0x110, 0x4, 0x1, 0x4, 0x10, 0x110},
45 {".dynstr", SHT_STRTAB, SHF_ALLOC, 0x804828c, 0x28c, 0xbb, 0x0, 0x0, 0x1, 0x0, 0xbb},
46 {".rel.plt", SHT_REL, SHF_ALLOC, 0x8048348, 0x348, 0x20, 0x3, 0x7, 0x4, 0x8, 0x20},
47 {".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x8048368, 0x368, 0x11, 0x0, 0x0, 0x4, 0x0, 0x11},
48 {".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804837c, 0x37c, 0x50, 0x0, 0x0, 0x4, 0x4, 0x50},
49 {".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x80483cc, 0x3cc, 0x180, 0x0, 0x0, 0x4, 0x0, 0x180},
50 {".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804854c, 0x54c, 0xc, 0x0, 0x0, 0x4, 0x0, 0xc},
51 {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x8048558, 0x558, 0xa3, 0x0, 0x0, 0x1, 0x0, 0xa3},
52 {".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80495fc, 0x5fc, 0xc, 0x0, 0x0, 0x4, 0x0, 0xc},
53 {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x8049608, 0x608, 0x4, 0x0, 0x0, 0x4, 0x0, 0x4},
54 {".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x804960c, 0x60c, 0x98, 0x4, 0x0, 0x4, 0x8, 0x98},
55 {".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496a4, 0x6a4, 0x8, 0x0, 0x0, 0x4, 0x0, 0x8},
56 {".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496ac, 0x6ac, 0x8, 0x0, 0x0, 0x4, 0x0, 0x8},
57 {".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b4, 0x6b4, 0x4, 0x0, 0x0, 0x4, 0x0, 0x4},
58 {".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b8, 0x6b8, 0x1c, 0x0, 0x0, 0x4, 0x4, 0x1c},
59 {".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x80496d4, 0x6d4, 0x20, 0x0, 0x0, 0x4, 0x0, 0x20},
60 {".comment", SHT_PROGBITS, 0x0, 0x0, 0x6d4, 0x12d, 0x0, 0x0, 0x1, 0x0, 0x12d},
61 {".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x801, 0x20, 0x0, 0x0, 0x1, 0x0, 0x20},
62 {".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0x821, 0x1b, 0x0, 0x0, 0x1, 0x0, 0x1b},
63 {".debug_info", SHT_PROGBITS, 0x0, 0x0, 0x83c, 0x11d, 0x0, 0x0, 0x1, 0x0, 0x11d},
64 {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0x959, 0x41, 0x0, 0x0, 0x1, 0x0, 0x41},
65 {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x99a, 0x35, 0x0, 0x0, 0x1, 0x0, 0x35},
66 {".debug_frame", SHT_PROGBITS, 0x0, 0x0, 0x9d0, 0x30, 0x0, 0x0, 0x4, 0x0, 0x30},
67 {".debug_str", SHT_PROGBITS, 0x0, 0x0, 0xa00, 0xd, 0x0, 0x0, 0x1, 0x0, 0xd},
68 {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xa0d, 0xf8, 0x0, 0x0, 0x1, 0x0, 0xf8},
69 {".symtab", SHT_SYMTAB, 0x0, 0x0, 0xfb8, 0x4b0, 0x1d, 0x38, 0x4, 0x10, 0x4b0},
70 {".strtab", SHT_STRTAB, 0x0, 0x0, 0x1468, 0x206, 0x0, 0x0, 0x1, 0x0, 0x206},
71 },
72 []ProgHeader{
73 {PT_PHDR, PF_R + PF_X, 0x34, 0x8048034, 0x8048034, 0xa0, 0xa0, 0x4},
74 {PT_INTERP, PF_R, 0xd4, 0x80480d4, 0x80480d4, 0x15, 0x15, 0x1},
75 {PT_LOAD, PF_R + PF_X, 0x0, 0x8048000, 0x8048000, 0x5fb, 0x5fb, 0x1000},
76 {PT_LOAD, PF_R + PF_W, 0x5fc, 0x80495fc, 0x80495fc, 0xd8, 0xf8, 0x1000},
77 {PT_DYNAMIC, PF_R + PF_W, 0x60c, 0x804960c, 0x804960c, 0x98, 0x98, 0x4},
78 },
79 []string{"libc.so.6"},
80 []Symbol{
81 {"", 3, 0, false, 0, 1, 134512852, 0, "", ""},
82 {"", 3, 0, false, 0, 2, 134512876, 0, "", ""},
83 {"", 3, 0, false, 0, 3, 134513020, 0, "", ""},
84 {"", 3, 0, false, 0, 4, 134513292, 0, "", ""},
85 {"", 3, 0, false, 0, 5, 134513480, 0, "", ""},
86 {"", 3, 0, false, 0, 6, 134513512, 0, "", ""},
87 {"", 3, 0, false, 0, 7, 134513532, 0, "", ""},
88 {"", 3, 0, false, 0, 8, 134513612, 0, "", ""},
89 {"", 3, 0, false, 0, 9, 134513996, 0, "", ""},
90 {"", 3, 0, false, 0, 10, 134514008, 0, "", ""},
91 {"", 3, 0, false, 0, 11, 134518268, 0, "", ""},
92 {"", 3, 0, false, 0, 12, 134518280, 0, "", ""},
93 {"", 3, 0, false, 0, 13, 134518284, 0, "", ""},
94 {"", 3, 0, false, 0, 14, 134518436, 0, "", ""},
95 {"", 3, 0, false, 0, 15, 134518444, 0, "", ""},
96 {"", 3, 0, false, 0, 16, 134518452, 0, "", ""},
97 {"", 3, 0, false, 0, 17, 134518456, 0, "", ""},
98 {"", 3, 0, false, 0, 18, 134518484, 0, "", ""},
99 {"", 3, 0, false, 0, 19, 0, 0, "", ""},
100 {"", 3, 0, false, 0, 20, 0, 0, "", ""},
101 {"", 3, 0, false, 0, 21, 0, 0, "", ""},
102 {"", 3, 0, false, 0, 22, 0, 0, "", ""},
103 {"", 3, 0, false, 0, 23, 0, 0, "", ""},
104 {"", 3, 0, false, 0, 24, 0, 0, "", ""},
105 {"", 3, 0, false, 0, 25, 0, 0, "", ""},
106 {"", 3, 0, false, 0, 26, 0, 0, "", ""},
107 {"", 3, 0, false, 0, 27, 0, 0, "", ""},
108 {"", 3, 0, false, 0, 28, 0, 0, "", ""},
109 {"", 3, 0, false, 0, 29, 0, 0, "", ""},
110 {"crt1.c", 4, 0, false, 0, 65521, 0, 0, "", ""},
111 {"/usr/src/lib/csu/i386-elf/crti.S", 4, 0, false, 0, 65521, 0, 0, "", ""},
112 {"<command line>", 4, 0, false, 0, 65521, 0, 0, "", ""},
113 {"<built-in>", 4, 0, false, 0, 65521, 0, 0, "", ""},
114 {"/usr/src/lib/csu/i386-elf/crti.S", 4, 0, false, 0, 65521, 0, 0, "", ""},
115 {"crtstuff.c", 4, 0, false, 0, 65521, 0, 0, "", ""},
116 {"__CTOR_LIST__", 1, 0, false, 0, 14, 134518436, 0, "", ""},
117 {"__DTOR_LIST__", 1, 0, false, 0, 15, 134518444, 0, "", ""},
118 {"__EH_FRAME_BEGIN__", 1, 0, false, 0, 12, 134518280, 0, "", ""},
119 {"__JCR_LIST__", 1, 0, false, 0, 16, 134518452, 0, "", ""},
120 {"p.0", 1, 0, false, 0, 11, 134518276, 0, "", ""},
121 {"completed.1", 1, 0, false, 0, 18, 134518484, 1, "", ""},
122 {"__do_global_dtors_aux", 2, 0, false, 0, 8, 134513760, 0, "", ""},
123 {"object.2", 1, 0, false, 0, 18, 134518488, 24, "", ""},
124 {"frame_dummy", 2, 0, false, 0, 8, 134513836, 0, "", ""},
125 {"crtstuff.c", 4, 0, false, 0, 65521, 0, 0, "", ""},
126 {"__CTOR_END__", 1, 0, false, 0, 14, 134518440, 0, "", ""},
127 {"__DTOR_END__", 1, 0, false, 0, 15, 134518448, 0, "", ""},
128 {"__FRAME_END__", 1, 0, false, 0, 12, 134518280, 0, "", ""},
129 {"__JCR_END__", 1, 0, false, 0, 16, 134518452, 0, "", ""},
130 {"__do_global_ctors_aux", 2, 0, false, 0, 8, 134513960, 0, "", ""},
131 {"/usr/src/lib/csu/i386-elf/crtn.S", 4, 0, false, 0, 65521, 0, 0, "", ""},
132 {"<command line>", 4, 0, false, 0, 65521, 0, 0, "", ""},
133 {"<built-in>", 4, 0, false, 0, 65521, 0, 0, "", ""},
134 {"/usr/src/lib/csu/i386-elf/crtn.S", 4, 0, false, 0, 65521, 0, 0, "", ""},
135 {"hello.c", 4, 0, false, 0, 65521, 0, 0, "", ""},
136 {"printf", 18, 0, false, 0, 0, 0, 44, "", ""},
137 {"_DYNAMIC", 17, 0, false, 0, 65521, 134518284, 0, "", ""},
138 {"__dso_handle", 17, 2, false, 0, 11, 134518272, 0, "", ""},
139 {"_init", 18, 0, false, 0, 6, 134513512, 0, "", ""},
140 {"environ", 17, 0, false, 0, 18, 134518512, 4, "", ""},
141 {"__deregister_frame_info", 32, 0, false, 0, 0, 0, 0, "", ""},
142 {"__progname", 17, 0, false, 0, 11, 134518268, 4, "", ""},
143 {"_start", 18, 0, false, 0, 8, 134513612, 145, "", ""},
144 {"__bss_start", 16, 0, false, 0, 65521, 134518484, 0, "", ""},
145 {"main", 18, 0, false, 0, 8, 134513912, 46, "", ""},
146 {"_init_tls", 18, 0, false, 0, 0, 0, 5, "", ""},
147 {"_fini", 18, 0, false, 0, 9, 134513996, 0, "", ""},
148 {"atexit", 18, 0, false, 0, 0, 0, 43, "", ""},
149 {"_edata", 16, 0, false, 0, 65521, 134518484, 0, "", ""},
150 {"_GLOBAL_OFFSET_TABLE_", 17, 0, false, 0, 65521, 134518456, 0, "", ""},
151 {"_end", 16, 0, false, 0, 65521, 134518516, 0, "", ""},
152 {"exit", 18, 0, false, 0, 0, 0, 68, "", ""},
153 {"_Jv_RegisterClasses", 32, 0, false, 0, 0, 0, 0, "", ""},
154 {"__register_frame_info", 32, 0, false, 0, 0, 0, 0, "", ""},
155 },
156 },
157 {
158 "testdata/gcc-amd64-linux-exec",
159 FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0, binary.LittleEndian, ET_EXEC, EM_X86_64, 0x4003e0},
160 []SectionHeader{
161 {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
162 {".interp", SHT_PROGBITS, SHF_ALLOC, 0x400200, 0x200, 0x1c, 0x0, 0x0, 0x1, 0x0, 0x1c},
163 {".note.ABI-tag", SHT_NOTE, SHF_ALLOC, 0x40021c, 0x21c, 0x20, 0x0, 0x0, 0x4, 0x0, 0x20},
164 {".hash", SHT_HASH, SHF_ALLOC, 0x400240, 0x240, 0x24, 0x5, 0x0, 0x8, 0x4, 0x24},
165 {".gnu.hash", SHT_LOOS + 268435446, SHF_ALLOC, 0x400268, 0x268, 0x1c, 0x5, 0x0, 0x8, 0x0, 0x1c},
166 {".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x400288, 0x288, 0x60, 0x6, 0x1, 0x8, 0x18, 0x60},
167 {".dynstr", SHT_STRTAB, SHF_ALLOC, 0x4002e8, 0x2e8, 0x3d, 0x0, 0x0, 0x1, 0x0, 0x3d},
168 {".gnu.version", SHT_HIOS, SHF_ALLOC, 0x400326, 0x326, 0x8, 0x5, 0x0, 0x2, 0x2, 0x8},
169 {".gnu.version_r", SHT_LOOS + 268435454, SHF_ALLOC, 0x400330, 0x330, 0x20, 0x6, 0x1, 0x8, 0x0, 0x20},
170 {".rela.dyn", SHT_RELA, SHF_ALLOC, 0x400350, 0x350, 0x18, 0x5, 0x0, 0x8, 0x18, 0x18},
171 {".rela.plt", SHT_RELA, SHF_ALLOC, 0x400368, 0x368, 0x30, 0x5, 0xc, 0x8, 0x18, 0x30},
172 {".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400398, 0x398, 0x18, 0x0, 0x0, 0x4, 0x0, 0x18},
173 {".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003b0, 0x3b0, 0x30, 0x0, 0x0, 0x4, 0x10, 0x30},
174 {".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003e0, 0x3e0, 0x1b4, 0x0, 0x0, 0x10, 0x0, 0x1b4},
175 {".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400594, 0x594, 0xe, 0x0, 0x0, 0x4, 0x0, 0xe},
176 {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x4005a4, 0x5a4, 0x11, 0x0, 0x0, 0x4, 0x0, 0x11},
177 {".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC, 0x4005b8, 0x5b8, 0x24, 0x0, 0x0, 0x4, 0x0, 0x24},
178 {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x4005e0, 0x5e0, 0xa4, 0x0, 0x0, 0x8, 0x0, 0xa4},
179 {".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600688, 0x688, 0x10, 0x0, 0x0, 0x8, 0x0, 0x10},
180 {".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600698, 0x698, 0x10, 0x0, 0x0, 0x8, 0x0, 0x10},
181 {".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x6006a8, 0x6a8, 0x8, 0x0, 0x0, 0x8, 0x0, 0x8},
182 {".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x6006b0, 0x6b0, 0x1a0, 0x6, 0x0, 0x8, 0x10, 0x1a0},
183 {".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600850, 0x850, 0x8, 0x0, 0x0, 0x8, 0x8, 0x8},
184 {".got.plt", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600858, 0x858, 0x28, 0x0, 0x0, 0x8, 0x8, 0x28},
185 {".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600880, 0x880, 0x18, 0x0, 0x0, 0x8, 0x0, 0x18},
186 {".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x600898, 0x898, 0x8, 0x0, 0x0, 0x4, 0x0, 0x8},
187 {".comment", SHT_PROGBITS, 0x0, 0x0, 0x898, 0x126, 0x0, 0x0, 0x1, 0x0, 0x126},
188 {".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x9c0, 0x90, 0x0, 0x0, 0x10, 0x0, 0x90},
189 {".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0xa50, 0x25, 0x0, 0x0, 0x1, 0x0, 0x25},
190 {".debug_info", SHT_PROGBITS, 0x0, 0x0, 0xa75, 0x1a7, 0x0, 0x0, 0x1, 0x0, 0x1a7},
191 {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xc1c, 0x6f, 0x0, 0x0, 0x1, 0x0, 0x6f},
192 {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0xc8b, 0x13f, 0x0, 0x0, 0x1, 0x0, 0x13f},
193 {".debug_str", SHT_PROGBITS, SHF_MERGE + SHF_STRINGS, 0x0, 0xdca, 0xb1, 0x0, 0x0, 0x1, 0x1, 0xb1},
194 {".debug_ranges", SHT_PROGBITS, 0x0, 0x0, 0xe80, 0x90, 0x0, 0x0, 0x10, 0x0, 0x90},
195 {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xf10, 0x149, 0x0, 0x0, 0x1, 0x0, 0x149},
196 {".symtab", SHT_SYMTAB, 0x0, 0x0, 0x19a0, 0x6f0, 0x24, 0x39, 0x8, 0x18, 0x6f0},
197 {".strtab", SHT_STRTAB, 0x0, 0x0, 0x2090, 0x1fc, 0x0, 0x0, 0x1, 0x0, 0x1fc},
198 },
199 []ProgHeader{
200 {PT_PHDR, PF_R + PF_X, 0x40, 0x400040, 0x400040, 0x1c0, 0x1c0, 0x8},
201 {PT_INTERP, PF_R, 0x200, 0x400200, 0x400200, 0x1c, 0x1c, 1},
202 {PT_LOAD, PF_R + PF_X, 0x0, 0x400000, 0x400000, 0x684, 0x684, 0x200000},
203 {PT_LOAD, PF_R + PF_W, 0x688, 0x600688, 0x600688, 0x210, 0x218, 0x200000},
204 {PT_DYNAMIC, PF_R + PF_W, 0x6b0, 0x6006b0, 0x6006b0, 0x1a0, 0x1a0, 0x8},
205 {PT_NOTE, PF_R, 0x21c, 0x40021c, 0x40021c, 0x20, 0x20, 0x4},
206 {PT_LOOS + 0x474E550, PF_R, 0x5b8, 0x4005b8, 0x4005b8, 0x24, 0x24, 0x4},
207 {PT_LOOS + 0x474E551, PF_R + PF_W, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8},
208 },
209 []string{"libc.so.6"},
210 []Symbol{
211 {"", 3, 0, false, 0, 1, 4194816, 0, "", ""},
212 {"", 3, 0, false, 0, 2, 4194844, 0, "", ""},
213 {"", 3, 0, false, 0, 3, 4194880, 0, "", ""},
214 {"", 3, 0, false, 0, 4, 4194920, 0, "", ""},
215 {"", 3, 0, false, 0, 5, 4194952, 0, "", ""},
216 {"", 3, 0, false, 0, 6, 4195048, 0, "", ""},
217 {"", 3, 0, false, 0, 7, 4195110, 0, "", ""},
218 {"", 3, 0, false, 0, 8, 4195120, 0, "", ""},
219 {"", 3, 0, false, 0, 9, 4195152, 0, "", ""},
220 {"", 3, 0, false, 0, 10, 4195176, 0, "", ""},
221 {"", 3, 0, false, 0, 11, 4195224, 0, "", ""},
222 {"", 3, 0, false, 0, 12, 4195248, 0, "", ""},
223 {"", 3, 0, false, 0, 13, 4195296, 0, "", ""},
224 {"", 3, 0, false, 0, 14, 4195732, 0, "", ""},
225 {"", 3, 0, false, 0, 15, 4195748, 0, "", ""},
226 {"", 3, 0, false, 0, 16, 4195768, 0, "", ""},
227 {"", 3, 0, false, 0, 17, 4195808, 0, "", ""},
228 {"", 3, 0, false, 0, 18, 6293128, 0, "", ""},
229 {"", 3, 0, false, 0, 19, 6293144, 0, "", ""},
230 {"", 3, 0, false, 0, 20, 6293160, 0, "", ""},
231 {"", 3, 0, false, 0, 21, 6293168, 0, "", ""},
232 {"", 3, 0, false, 0, 22, 6293584, 0, "", ""},
233 {"", 3, 0, false, 0, 23, 6293592, 0, "", ""},
234 {"", 3, 0, false, 0, 24, 6293632, 0, "", ""},
235 {"", 3, 0, false, 0, 25, 6293656, 0, "", ""},
236 {"", 3, 0, false, 0, 26, 0, 0, "", ""},
237 {"", 3, 0, false, 0, 27, 0, 0, "", ""},
238 {"", 3, 0, false, 0, 28, 0, 0, "", ""},
239 {"", 3, 0, false, 0, 29, 0, 0, "", ""},
240 {"", 3, 0, false, 0, 30, 0, 0, "", ""},
241 {"", 3, 0, false, 0, 31, 0, 0, "", ""},
242 {"", 3, 0, false, 0, 32, 0, 0, "", ""},
243 {"", 3, 0, false, 0, 33, 0, 0, "", ""},
244 {"init.c", 4, 0, false, 0, 65521, 0, 0, "", ""},
245 {"initfini.c", 4, 0, false, 0, 65521, 0, 0, "", ""},
246 {"call_gmon_start", 2, 0, false, 0, 13, 4195340, 0, "", ""},
247 {"crtstuff.c", 4, 0, false, 0, 65521, 0, 0, "", ""},
248 {"__CTOR_LIST__", 1, 0, false, 0, 18, 6293128, 0, "", ""},
249 {"__DTOR_LIST__", 1, 0, false, 0, 19, 6293144, 0, "", ""},
250 {"__JCR_LIST__", 1, 0, false, 0, 20, 6293160, 0, "", ""},
251 {"__do_global_dtors_aux", 2, 0, false, 0, 13, 4195376, 0, "", ""},
252 {"completed.6183", 1, 0, false, 0, 25, 6293656, 1, "", ""},
253 {"p.6181", 1, 0, false, 0, 24, 6293648, 0, "", ""},
254 {"frame_dummy", 2, 0, false, 0, 13, 4195440, 0, "", ""},
255 {"crtstuff.c", 4, 0, false, 0, 65521, 0, 0, "", ""},
256 {"__CTOR_END__", 1, 0, false, 0, 18, 6293136, 0, "", ""},
257 {"__DTOR_END__", 1, 0, false, 0, 19, 6293152, 0, "", ""},
258 {"__FRAME_END__", 1, 0, false, 0, 17, 4195968, 0, "", ""},
259 {"__JCR_END__", 1, 0, false, 0, 20, 6293160, 0, "", ""},
260 {"__do_global_ctors_aux", 2, 0, false, 0, 13, 4195680, 0, "", ""},
261 {"initfini.c", 4, 0, false, 0, 65521, 0, 0, "", ""},
262 {"hello.c", 4, 0, false, 0, 65521, 0, 0, "", ""},
263 {"_GLOBAL_OFFSET_TABLE_", 1, 2, false, 0, 23, 6293592, 0, "", ""},
264 {"__init_array_end", 0, 2, false, 0, 18, 6293124, 0, "", ""},
265 {"__init_array_start", 0, 2, false, 0, 18, 6293124, 0, "", ""},
266 {"_DYNAMIC", 1, 2, false, 0, 21, 6293168, 0, "", ""},
267 {"data_start", 32, 0, false, 0, 24, 6293632, 0, "", ""},
268 {"__libc_csu_fini", 18, 0, false, 0, 13, 4195520, 2, "", ""},
269 {"_start", 18, 0, false, 0, 13, 4195296, 0, "", ""},
270 {"__gmon_start__", 32, 0, false, 0, 0, 0, 0, "", ""},
271 {"_Jv_RegisterClasses", 32, 0, false, 0, 0, 0, 0, "", ""},
272 {"puts@@GLIBC_2.2.5", 18, 0, false, 0, 0, 0, 396, "", ""},
273 {"_fini", 18, 0, false, 0, 14, 4195732, 0, "", ""},
274 {"__libc_start_main@@GLIBC_2.2.5", 18, 0, false, 0, 0, 0, 450, "", ""},
275 {"_IO_stdin_used", 17, 0, false, 0, 15, 4195748, 4, "", ""},
276 {"__data_start", 16, 0, false, 0, 24, 6293632, 0, "", ""},
277 {"__dso_handle", 17, 2, false, 0, 24, 6293640, 0, "", ""},
278 {"__libc_csu_init", 18, 0, false, 0, 13, 4195536, 137, "", ""},
279 {"__bss_start", 16, 0, false, 0, 65521, 6293656, 0, "", ""},
280 {"_end", 16, 0, false, 0, 65521, 6293664, 0, "", ""},
281 {"_edata", 16, 0, false, 0, 65521, 6293656, 0, "", ""},
282 {"main", 18, 0, false, 0, 13, 4195480, 27, "", ""},
283 {"_init", 18, 0, false, 0, 11, 4195224, 0, "", ""},
284 },
285 },
286 {
287 "testdata/hello-world-core.gz",
288 FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_CORE, EM_X86_64, 0x0},
289 []SectionHeader{},
290 []ProgHeader{
291 {Type: PT_NOTE, Flags: 0x0, Off: 0x3f8, Vaddr: 0x0, Paddr: 0x0, Filesz: 0x8ac, Memsz: 0x0, Align: 0x0},
292 {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x1000, Vaddr: 0x400000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1000, Align: 0x1000},
293 {Type: PT_LOAD, Flags: PF_R, Off: 0x1000, Vaddr: 0x401000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
294 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x2000, Vaddr: 0x402000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
295 {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3000, Vaddr: 0x7f54078b8000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1b5000, Align: 0x1000},
296 {Type: PT_LOAD, Flags: 0x0, Off: 0x3000, Vaddr: 0x7f5407a6d000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1ff000, Align: 0x1000},
297 {Type: PT_LOAD, Flags: PF_R, Off: 0x3000, Vaddr: 0x7f5407c6c000, Paddr: 0x0, Filesz: 0x4000, Memsz: 0x4000, Align: 0x1000},
298 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x7000, Vaddr: 0x7f5407c70000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000},
299 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x9000, Vaddr: 0x7f5407c72000, Paddr: 0x0, Filesz: 0x5000, Memsz: 0x5000, Align: 0x1000},
300 {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0xe000, Vaddr: 0x7f5407c77000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x22000, Align: 0x1000},
301 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0xe000, Vaddr: 0x7f5407e81000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000},
302 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x11000, Vaddr: 0x7f5407e96000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000},
303 {Type: PT_LOAD, Flags: PF_R, Off: 0x14000, Vaddr: 0x7f5407e99000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
304 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x15000, Vaddr: 0x7f5407e9a000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000},
305 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x17000, Vaddr: 0x7fff79972000, Paddr: 0x0, Filesz: 0x23000, Memsz: 0x23000, Align: 0x1000},
306 {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3a000, Vaddr: 0x7fff799f8000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
307 {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3b000, Vaddr: 0xffffffffff600000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
308 },
309 nil,
310 nil,
311 },
312 {
313 "testdata/compressed-32.obj",
314 FileHeader{ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_REL, EM_386, 0x0},
315 []SectionHeader{
316 {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
317 {".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, 0x0, 0x34, 0x17, 0x0, 0x0, 0x1, 0x0, 0x17},
318 {".rel.text", SHT_REL, SHF_INFO_LINK, 0x0, 0x3dc, 0x10, 0x13, 0x1, 0x4, 0x8, 0x10},
319 {".data", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x4b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0},
320 {".bss", SHT_NOBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x4b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0},
321 {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x4b, 0xd, 0x0, 0x0, 0x1, 0x0, 0xd},
322 {".debug_info", SHT_PROGBITS, SHF_COMPRESSED, 0x0, 0x58, 0xb4, 0x0, 0x0, 0x1, 0x0, 0x84},
323 {".rel.debug_info", SHT_REL, SHF_INFO_LINK, 0x0, 0x3ec, 0xa0, 0x13, 0x6, 0x4, 0x8, 0xa0},
324 {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xdc, 0x5a, 0x0, 0x0, 0x1, 0x0, 0x5a},
325 {".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x136, 0x20, 0x0, 0x0, 0x1, 0x0, 0x20},
326 {".rel.debug_aranges", SHT_REL, SHF_INFO_LINK, 0x0, 0x48c, 0x10, 0x13, 0x9, 0x4, 0x8, 0x10},
327 {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x156, 0x5c, 0x0, 0x0, 0x1, 0x0, 0x5c},
328 {".rel.debug_line", SHT_REL, SHF_INFO_LINK, 0x0, 0x49c, 0x8, 0x13, 0xb, 0x4, 0x8, 0x8},
329 {".debug_str", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS | SHF_COMPRESSED, 0x0, 0x1b2, 0x10f, 0x0, 0x0, 0x1, 0x1, 0xb3},
330 {".comment", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS, 0x0, 0x265, 0x2a, 0x0, 0x0, 0x1, 0x1, 0x2a},
331 {".note.GNU-stack", SHT_PROGBITS, 0x0, 0x0, 0x28f, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0},
332 {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x290, 0x38, 0x0, 0x0, 0x4, 0x0, 0x38},
333 {".rel.eh_frame", SHT_REL, SHF_INFO_LINK, 0x0, 0x4a4, 0x8, 0x13, 0x10, 0x4, 0x8, 0x8},
334 {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0x4ac, 0xab, 0x0, 0x0, 0x1, 0x0, 0xab},
335 {".symtab", SHT_SYMTAB, 0x0, 0x0, 0x2c8, 0x100, 0x14, 0xe, 0x4, 0x10, 0x100},
336 {".strtab", SHT_STRTAB, 0x0, 0x0, 0x3c8, 0x13, 0x0, 0x0, 0x1, 0x0, 0x13},
337 },
338 []ProgHeader{},
339 nil,
340 []Symbol{
341 {"hello.c", 4, 0, false, 0, 65521, 0, 0, "", ""},
342 {"", 3, 0, false, 0, 1, 0, 0, "", ""},
343 {"", 3, 0, false, 0, 3, 0, 0, "", ""},
344 {"", 3, 0, false, 0, 4, 0, 0, "", ""},
345 {"", 3, 0, false, 0, 5, 0, 0, "", ""},
346 {"", 3, 0, false, 0, 6, 0, 0, "", ""},
347 {"", 3, 0, false, 0, 8, 0, 0, "", ""},
348 {"", 3, 0, false, 0, 9, 0, 0, "", ""},
349 {"", 3, 0, false, 0, 11, 0, 0, "", ""},
350 {"", 3, 0, false, 0, 13, 0, 0, "", ""},
351 {"", 3, 0, false, 0, 15, 0, 0, "", ""},
352 {"", 3, 0, false, 0, 16, 0, 0, "", ""},
353 {"", 3, 0, false, 0, 14, 0, 0, "", ""},
354 {"main", 18, 0, false, 0, 1, 0, 23, "", ""},
355 {"puts", 16, 0, false, 0, 0, 0, 0, "", ""},
356 },
357 },
358 {
359 "testdata/compressed-64.obj",
360 FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_REL, EM_X86_64, 0x0},
361 []SectionHeader{
362 {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
363 {".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, 0x0, 0x40, 0x1b, 0x0, 0x0, 0x1, 0x0, 0x1b},
364 {".rela.text", SHT_RELA, SHF_INFO_LINK, 0x0, 0x488, 0x30, 0x13, 0x1, 0x8, 0x18, 0x30},
365 {".data", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x5b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0},
366 {".bss", SHT_NOBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x5b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0},
367 {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x5b, 0xd, 0x0, 0x0, 0x1, 0x0, 0xd},
368 {".debug_info", SHT_PROGBITS, SHF_COMPRESSED, 0x0, 0x68, 0xba, 0x0, 0x0, 0x1, 0x0, 0x72},
369 {".rela.debug_info", SHT_RELA, SHF_INFO_LINK, 0x0, 0x4b8, 0x1c8, 0x13, 0x6, 0x8, 0x18, 0x1c8},
370 {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xda, 0x5c, 0x0, 0x0, 0x1, 0x0, 0x5c},
371 {".debug_aranges", SHT_PROGBITS, SHF_COMPRESSED, 0x0, 0x136, 0x30, 0x0, 0x0, 0x1, 0x0, 0x2f},
372 {".rela.debug_aranges", SHT_RELA, SHF_INFO_LINK, 0x0, 0x680, 0x30, 0x13, 0x9, 0x8, 0x18, 0x30},
373 {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x165, 0x60, 0x0, 0x0, 0x1, 0x0, 0x60},
374 {".rela.debug_line", SHT_RELA, SHF_INFO_LINK, 0x0, 0x6b0, 0x18, 0x13, 0xb, 0x8, 0x18, 0x18},
375 {".debug_str", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS | SHF_COMPRESSED, 0x0, 0x1c5, 0x104, 0x0, 0x0, 0x1, 0x1, 0xc3},
376 {".comment", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS, 0x0, 0x288, 0x2a, 0x0, 0x0, 0x1, 0x1, 0x2a},
377 {".note.GNU-stack", SHT_PROGBITS, 0x0, 0x0, 0x2b2, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0},
378 {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x2b8, 0x38, 0x0, 0x0, 0x8, 0x0, 0x38},
379 {".rela.eh_frame", SHT_RELA, SHF_INFO_LINK, 0x0, 0x6c8, 0x18, 0x13, 0x10, 0x8, 0x18, 0x18},
380 {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0x6e0, 0xb0, 0x0, 0x0, 0x1, 0x0, 0xb0},
381 {".symtab", SHT_SYMTAB, 0x0, 0x0, 0x2f0, 0x180, 0x14, 0xe, 0x8, 0x18, 0x180},
382 {".strtab", SHT_STRTAB, 0x0, 0x0, 0x470, 0x13, 0x0, 0x0, 0x1, 0x0, 0x13},
383 },
384 []ProgHeader{},
385 nil,
386 []Symbol{
387 {"hello.c", 4, 0, false, 0, 65521, 0, 0, "", ""},
388 {"", 3, 0, false, 0, 1, 0, 0, "", ""},
389 {"", 3, 0, false, 0, 3, 0, 0, "", ""},
390 {"", 3, 0, false, 0, 4, 0, 0, "", ""},
391 {"", 3, 0, false, 0, 5, 0, 0, "", ""},
392 {"", 3, 0, false, 0, 6, 0, 0, "", ""},
393 {"", 3, 0, false, 0, 8, 0, 0, "", ""},
394 {"", 3, 0, false, 0, 9, 0, 0, "", ""},
395 {"", 3, 0, false, 0, 11, 0, 0, "", ""},
396 {"", 3, 0, false, 0, 13, 0, 0, "", ""},
397 {"", 3, 0, false, 0, 15, 0, 0, "", ""},
398 {"", 3, 0, false, 0, 16, 0, 0, "", ""},
399 {"", 3, 0, false, 0, 14, 0, 0, "", ""},
400 {"main", 18, 0, false, 0, 1, 0, 27, "", ""},
401 {"puts", 16, 0, false, 0, 0, 0, 0, "", ""},
402 },
403 },
404 {
405 "testdata/go-relocation-test-gcc620-sparc64.obj",
406 FileHeader{Class: ELFCLASS64, Data: ELFDATA2MSB, Version: EV_CURRENT, OSABI: ELFOSABI_NONE, ABIVersion: 0x0, ByteOrder: binary.BigEndian, Type: ET_REL, Machine: EM_SPARCV9, Entry: 0x0},
407 []SectionHeader{
408 {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
409 {".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x0, 0x40, 0x2c, 0x0, 0x0, 0x4, 0x0, 0x2c},
410 {".rela.text", SHT_RELA, SHF_INFO_LINK, 0x0, 0xa58, 0x48, 0x13, 0x1, 0x8, 0x18, 0x48},
411 {".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x0, 0x6c, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0},
412 {".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x0, 0x6c, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0},
413 {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x70, 0xd, 0x0, 0x0, 0x8, 0x0, 0xd},
414 {".debug_info", SHT_PROGBITS, 0x0, 0x0, 0x7d, 0x346, 0x0, 0x0, 0x1, 0x0, 0x346},
415 {".rela.debug_info", SHT_RELA, SHF_INFO_LINK, 0x0, 0xaa0, 0x630, 0x13, 0x6, 0x8, 0x18, 0x630},
416 {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0x3c3, 0xf1, 0x0, 0x0, 0x1, 0x0, 0xf1},
417 {".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x4b4, 0x30, 0x0, 0x0, 0x1, 0x0, 0x30},
418 {".rela.debug_aranges", SHT_RELA, SHF_INFO_LINK, 0x0, 0x10d0, 0x30, 0x13, 0x9, 0x8, 0x18, 0x30},
419 {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x4e4, 0xd3, 0x0, 0x0, 0x1, 0x0, 0xd3},
420 {".rela.debug_line", SHT_RELA, SHF_INFO_LINK, 0x0, 0x1100, 0x18, 0x13, 0xb, 0x8, 0x18, 0x18},
421 {".debug_str", SHT_PROGBITS, SHF_MERGE + SHF_STRINGS, 0x0, 0x5b7, 0x2a3, 0x0, 0x0, 0x1, 0x1, 0x2a3},
422 {".comment", SHT_PROGBITS, SHF_MERGE + SHF_STRINGS, 0x0, 0x85a, 0x2e, 0x0, 0x0, 0x1, 0x1, 0x2e},
423 {".note.GNU-stack", SHT_PROGBITS, 0x0, 0x0, 0x888, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0},
424 {".debug_frame", SHT_PROGBITS, 0x0, 0x0, 0x888, 0x38, 0x0, 0x0, 0x8, 0x0, 0x38},
425 {".rela.debug_frame", SHT_RELA, SHF_INFO_LINK, 0x0, 0x1118, 0x30, 0x13, 0x10, 0x8, 0x18, 0x30},
426 {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0x1148, 0xb3, 0x0, 0x0, 0x1, 0x0, 0xb3},
427 {".symtab", SHT_SYMTAB, 0x0, 0x0, 0x8c0, 0x180, 0x14, 0xe, 0x8, 0x18, 0x180},
428 {".strtab", SHT_STRTAB, 0x0, 0x0, 0xa40, 0x13, 0x0, 0x0, 0x1, 0x0, 0x13},
429 },
430 []ProgHeader{},
431 nil,
432 []Symbol{
433 {"hello.c", 4, 0, false, 0, 65521, 0, 0, "", ""},
434 {"", 3, 0, false, 0, 1, 0, 0, "", ""},
435 {"", 3, 0, false, 0, 3, 0, 0, "", ""},
436 {"", 3, 0, false, 0, 4, 0, 0, "", ""},
437 {"", 3, 0, false, 0, 5, 0, 0, "", ""},
438 {"", 3, 0, false, 0, 6, 0, 0, "", ""},
439 {"", 3, 0, false, 0, 8, 0, 0, "", ""},
440 {"", 3, 0, false, 0, 9, 0, 0, "", ""},
441 {"", 3, 0, false, 0, 11, 0, 0, "", ""},
442 {"", 3, 0, false, 0, 13, 0, 0, "", ""},
443 {"", 3, 0, false, 0, 15, 0, 0, "", ""},
444 {"", 3, 0, false, 0, 16, 0, 0, "", ""},
445 {"", 3, 0, false, 0, 14, 0, 0, "", ""},
446 {"main", 18, 0, false, 0, 1, 0, 44, "", ""},
447 {"puts", 16, 0, false, 0, 0, 0, 0, "", ""},
448 },
449 },
450 {
451 "testdata/gcc-riscv64-linux-exec",
452 FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0, binary.LittleEndian, ET_EXEC, EM_RISCV, 0x10460},
453 []SectionHeader{
454 {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
455 {".interp", SHT_PROGBITS, SHF_ALLOC, 0x10270, 0x270, 0x21, 0x0, 0x0, 0x1, 0x0, 0x21},
456 {".note.gnu.build-id", SHT_NOTE, SHF_ALLOC, 0x10294, 0x294, 0x24, 0x0, 0x0, 0x4, 0x0, 0x24},
457 {".note.ABI-tag", SHT_NOTE, SHF_ALLOC, 0x102b8, 0x2b8, 0x20, 0x0, 0x0, 0x4, 0x0, 0x20},
458 {".gnu.hash", SHT_GNU_HASH, SHF_ALLOC, 0x102d8, 0x2d8, 0x30, 0x5, 0x0, 0x8, 0x0, 0x30},
459 {".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x10308, 0x308, 0x60, 0x6, 0x1, 0x8, 0x18, 0x60},
460 {".dynstr", SHT_STRTAB, SHF_ALLOC, 0x10368, 0x368, 0x4a, 0x0, 0x0, 0x1, 0x0, 0x4a},
461 {".gnu.version", SHT_GNU_VERSYM, SHF_ALLOC, 0x103b2, 0x3b2, 0x8, 0x5, 0x0, 0x2, 0x2, 0x8},
462 {".gnu.version_r", SHT_GNU_VERNEED, SHF_ALLOC, 0x103c0, 0x3c0, 0x30, 0x6, 0x1, 0x8, 0x0, 0x30},
463 {".rela.plt", SHT_RELA, SHF_ALLOC + SHF_INFO_LINK, 0x103f0, 0x3f0, 0x30, 0x5, 0x14, 0x8, 0x18, 0x30},
464 {".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x10420, 0x420, 0x40, 0x0, 0x0, 0x10, 0x10, 0x40},
465 {".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x10460, 0x460, 0xd8, 0x0, 0x0, 0x4, 0x0, 0xd8},
466 {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x10538, 0x538, 0x15, 0x0, 0x0, 0x8, 0x0, 0x15},
467 {".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC, 0x10550, 0x550, 0x24, 0x0, 0x0, 0x4, 0x0, 0x24},
468 {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x10578, 0x578, 0x6c, 0x0, 0x0, 0x8, 0x0, 0x6c},
469 {".preinit_array", SHT_PREINIT_ARRAY, SHF_WRITE + SHF_ALLOC, 0x11e00, 0xe00, 0x8, 0x0, 0x0, 0x1, 0x8, 0x8},
470 {".init_array", SHT_INIT_ARRAY, SHF_WRITE + SHF_ALLOC, 0x11e08, 0xe08, 0x8, 0x0, 0x0, 0x8, 0x8, 0x8},
471 {".fini_array", SHT_FINI_ARRAY, SHF_WRITE + SHF_ALLOC, 0x11e10, 0xe10, 0x8, 0x0, 0x0, 0x8, 0x8, 0x8},
472 {".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x11e18, 0xe18, 0x1d0, 0x6, 0x0, 0x8, 0x10, 0x1d0},
473 {".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x11fe8, 0xfe8, 0x8, 0x0, 0x0, 0x8, 0x8, 0x8},
474 {".got.plt", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x11ff0, 0xff0, 0x20, 0x0, 0x0, 0x8, 0x8, 0x20},
475 {".sdata", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x12010, 0x1010, 0x8, 0x0, 0x0, 0x8, 0x0, 0x8},
476 {".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x12018, 0x1018, 0x8, 0x0, 0x0, 0x1, 0x0, 0x8},
477 {".comment", SHT_PROGBITS, SHF_MERGE + SHF_STRINGS, 0x0, 0x1018, 0x26, 0x0, 0x0, 0x1, 0x1, 0x26},
478 {".riscv.attributes", SHT_RISCV_ATTRIBUTES, 0x0, 0x0, 0x103e, 0x66, 0x0, 0x0, 0x1, 0x0, 0x66},
479 {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0x10a4, 0xff, 0x0, 0x0, 0x1, 0x0, 0xff},
480 },
481 []ProgHeader{
482 {PT_PHDR, PF_R, 0x40, 0x10040, 0x10040, 0x230, 0x230, 0x8},
483 {PT_INTERP, PF_R, 0x270, 0x10270, 0x10270, 0x21, 0x21, 0x1},
484 {PT_RISCV_ATTRIBUTES, PF_R, 0x103e, 0x0, 0x0, 0x66, 0x0, 0x1},
485 {PT_LOAD, PF_X + PF_R, 0x0, 0x10000, 0x10000, 0x5e4, 0x5e4, 0x1000},
486 {PT_LOAD, PF_W + PF_R, 0xe00, 0x11e00, 0x11e00, 0x218, 0x220, 0x1000},
487 {PT_DYNAMIC, PF_W + PF_R, 0xe18, 0x11e18, 0x11e18, 0x1d0, 0x1d0, 0x8},
488 {PT_NOTE, PF_R, 0x294, 0x10294, 0x10294, 0x44, 0x44, 0x4},
489 {PT_GNU_EH_FRAME, PF_R, 0x550, 0x10550, 0x10550, 0x24, 0x24, 0x4},
490 {PT_GNU_STACK, PF_W + PF_R, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10},
491 {PT_GNU_RELRO, PF_R, 0xe00, 0x11e00, 0x11e00, 0x200, 0x200, 0x1},
492 },
493 []string{"libc.so.6"},
494 nil,
495 },
496 }
497
498 func TestOpen(t *testing.T) {
499 for i := range fileTests {
500 tt := &fileTests[i]
501
502 var f *File
503 var err error
504 if path.Ext(tt.file) == ".gz" {
505 var r io.ReaderAt
506 if r, err = decompress(tt.file); err == nil {
507 f, err = NewFile(r)
508 }
509 } else {
510 f, err = Open(tt.file)
511 }
512 if err != nil {
513 t.Errorf("cannot open file %s: %v", tt.file, err)
514 continue
515 }
516 defer f.Close()
517 if f.FileHeader != tt.hdr {
518 t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)
519 continue
520 }
521 for i, s := range f.Sections {
522 if i >= len(tt.sections) {
523 break
524 }
525 sh := tt.sections[i]
526 if s.SectionHeader != sh {
527 t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, s.SectionHeader, sh)
528 }
529 }
530 for i, p := range f.Progs {
531 if i >= len(tt.progs) {
532 break
533 }
534 ph := tt.progs[i]
535 if p.ProgHeader != ph {
536 t.Errorf("open %s, program %d:\n\thave %#v\n\twant %#v\n", tt.file, i, p.ProgHeader, ph)
537 }
538 }
539 tn := len(tt.sections)
540 fn := len(f.Sections)
541 if tn != fn {
542 t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
543 }
544 tn = len(tt.progs)
545 fn = len(f.Progs)
546 if tn != fn {
547 t.Errorf("open %s: len(Progs) = %d, want %d", tt.file, fn, tn)
548 }
549 tl := tt.needed
550 fl, err := f.ImportedLibraries()
551 if err != nil {
552 t.Error(err)
553 }
554 if !reflect.DeepEqual(tl, fl) {
555 t.Errorf("open %s: DT_NEEDED = %v, want %v", tt.file, tl, fl)
556 }
557 symbols, err := f.Symbols()
558 if tt.symbols == nil {
559 if !errors.Is(err, ErrNoSymbols) {
560 t.Errorf("open %s: Symbols() expected ErrNoSymbols, have nil", tt.file)
561 }
562 if symbols != nil {
563 t.Errorf("open %s: Symbols() expected no symbols, have %v", tt.file, symbols)
564 }
565 } else {
566 if err != nil {
567 t.Errorf("open %s: Symbols() unexpected error %v", tt.file, err)
568 }
569 if !slices.Equal(symbols, tt.symbols) {
570 t.Errorf("open %s: Symbols() = %v, want %v", tt.file, symbols, tt.symbols)
571 }
572 }
573 }
574 }
575
576
577
578 func decompress(gz string) (io.ReaderAt, error) {
579 in, err := os.Open(gz)
580 if err != nil {
581 return nil, err
582 }
583 defer in.Close()
584 r, err := gzip.NewReader(in)
585 if err != nil {
586 return nil, err
587 }
588 var out bytes.Buffer
589 _, err = io.Copy(&out, r)
590 return bytes.NewReader(out.Bytes()), err
591 }
592
593 type relocationTestEntry struct {
594 entryNumber int
595 entry *dwarf.Entry
596 pcRanges [][2]uint64
597 }
598
599 type relocationTest struct {
600 file string
601 entries []relocationTestEntry
602 }
603
604 var relocationTests = []relocationTest{
605 {
606 "testdata/go-relocation-test-gcc441-x86-64.obj",
607 []relocationTestEntry{
608 {
609 entry: &dwarf.Entry{
610 Offset: 0xb,
611 Tag: dwarf.TagCompileUnit,
612 Children: true,
613 Field: []dwarf.Field{
614 {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString},
615 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
616 {Attr: dwarf.AttrName, Val: "go-relocation-test.c", Class: dwarf.ClassString},
617 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
618 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
619 {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress},
620 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
621 },
622 },
623 pcRanges: [][2]uint64{{0x0, 0x6}},
624 },
625 },
626 },
627 {
628 "testdata/go-relocation-test-gcc441-x86.obj",
629 []relocationTestEntry{
630 {
631 entry: &dwarf.Entry{
632 Offset: 0xb,
633 Tag: dwarf.TagCompileUnit,
634 Children: true,
635 Field: []dwarf.Field{
636 {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString},
637 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
638 {Attr: dwarf.AttrName, Val: "t.c", Class: dwarf.ClassString},
639 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
640 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
641 {Attr: dwarf.AttrHighpc, Val: uint64(0x5), Class: dwarf.ClassAddress},
642 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
643 },
644 },
645 pcRanges: [][2]uint64{{0x0, 0x5}},
646 },
647 },
648 },
649 {
650 "testdata/go-relocation-test-gcc424-x86-64.obj",
651 []relocationTestEntry{
652 {
653 entry: &dwarf.Entry{
654 Offset: 0xb,
655 Tag: dwarf.TagCompileUnit,
656 Children: true,
657 Field: []dwarf.Field{
658 {Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)", Class: dwarf.ClassString},
659 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
660 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c", Class: dwarf.ClassString},
661 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
662 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
663 {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress},
664 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
665 },
666 },
667 pcRanges: [][2]uint64{{0x0, 0x6}},
668 },
669 },
670 },
671 {
672 "testdata/go-relocation-test-gcc482-aarch64.obj",
673 []relocationTestEntry{
674 {
675 entry: &dwarf.Entry{
676 Offset: 0xb,
677 Tag: dwarf.TagCompileUnit,
678 Children: true,
679 Field: []dwarf.Field{
680 {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -g -fstack-protector", Class: dwarf.ClassString},
681 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
682 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482.c", Class: dwarf.ClassString},
683 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
684 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
685 {Attr: dwarf.AttrHighpc, Val: int64(0x24), Class: dwarf.ClassConstant},
686 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
687 },
688 },
689 pcRanges: [][2]uint64{{0x0, 0x24}},
690 },
691 },
692 },
693 {
694 "testdata/go-relocation-test-gcc492-arm.obj",
695 []relocationTestEntry{
696 {
697 entry: &dwarf.Entry{
698 Offset: 0xb,
699 Tag: dwarf.TagCompileUnit,
700 Children: true,
701 Field: []dwarf.Field{
702 {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},
703 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
704 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc492.c", Class: dwarf.ClassString},
705 {Attr: dwarf.AttrCompDir, Val: "/root/go/src/debug/elf/testdata", Class: dwarf.ClassString},
706 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
707 {Attr: dwarf.AttrHighpc, Val: int64(0x28), Class: dwarf.ClassConstant},
708 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
709 },
710 },
711 pcRanges: [][2]uint64{{0x0, 0x28}},
712 },
713 },
714 },
715 {
716 "testdata/go-relocation-test-clang-arm.obj",
717 []relocationTestEntry{
718 {
719 entry: &dwarf.Entry{
720 Offset: 0xb,
721 Tag: dwarf.TagCompileUnit,
722 Children: true,
723 Field: []dwarf.Field{
724 {Attr: dwarf.AttrProducer, Val: "Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)", Class: dwarf.ClassString},
725 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
726 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
727 {Attr: dwarf.AttrStmtList, Val: int64(0x0), Class: dwarf.ClassLinePtr},
728 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
729 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
730 {Attr: dwarf.AttrHighpc, Val: int64(0x30), Class: dwarf.ClassConstant},
731 },
732 },
733 pcRanges: [][2]uint64{{0x0, 0x30}},
734 },
735 },
736 },
737 {
738 "testdata/go-relocation-test-gcc5-ppc.obj",
739 []relocationTestEntry{
740 {
741 entry: &dwarf.Entry{
742 Offset: 0xb,
743 Tag: dwarf.TagCompileUnit,
744 Children: true,
745 Field: []dwarf.Field{
746 {Attr: dwarf.AttrProducer, Val: "GNU C11 5.0.0 20150116 (experimental) -Asystem=linux -Asystem=unix -Asystem=posix -g", Class: dwarf.ClassString},
747 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
748 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc5-ppc.c", Class: dwarf.ClassString},
749 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
750 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
751 {Attr: dwarf.AttrHighpc, Val: int64(0x44), Class: dwarf.ClassConstant},
752 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
753 },
754 },
755 pcRanges: [][2]uint64{{0x0, 0x44}},
756 },
757 },
758 },
759 {
760 "testdata/go-relocation-test-gcc482-ppc64le.obj",
761 []relocationTestEntry{
762 {
763 entry: &dwarf.Entry{
764 Offset: 0xb,
765 Tag: dwarf.TagCompileUnit,
766 Children: true,
767 Field: []dwarf.Field{
768 {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},
769 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
770 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482-ppc64le.c", Class: dwarf.ClassString},
771 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
772 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
773 {Attr: dwarf.AttrHighpc, Val: uint64(0x24), Class: dwarf.ClassAddress},
774 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
775 },
776 },
777 pcRanges: [][2]uint64{{0x0, 0x24}},
778 },
779 },
780 },
781 {
782 "testdata/go-relocation-test-gcc492-mips64.obj",
783 []relocationTestEntry{
784 {
785 entry: &dwarf.Entry{
786 Offset: 0xb,
787 Tag: dwarf.TagCompileUnit,
788 Children: true,
789 Field: []dwarf.Field{
790 {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -meb -mabi=64 -march=mips3 -mtune=mips64 -mllsc -mno-shared -g", Class: dwarf.ClassString},
791 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
792 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
793 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
794 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
795 {Attr: dwarf.AttrHighpc, Val: int64(0x64), Class: dwarf.ClassConstant},
796 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
797 },
798 },
799 pcRanges: [][2]uint64{{0x0, 0x64}},
800 },
801 },
802 },
803 {
804 "testdata/go-relocation-test-gcc531-s390x.obj",
805 []relocationTestEntry{
806 {
807 entry: &dwarf.Entry{
808 Offset: 0xb,
809 Tag: dwarf.TagCompileUnit,
810 Children: true,
811 Field: []dwarf.Field{
812 {Attr: dwarf.AttrProducer, Val: "GNU C11 5.3.1 20160316 -march=zEC12 -m64 -mzarch -g -fstack-protector-strong", Class: dwarf.ClassString},
813 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
814 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
815 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
816 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
817 {Attr: dwarf.AttrHighpc, Val: int64(0x3a), Class: dwarf.ClassConstant},
818 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
819 },
820 },
821 pcRanges: [][2]uint64{{0x0, 0x3a}},
822 },
823 },
824 },
825 {
826 "testdata/go-relocation-test-gcc620-sparc64.obj",
827 []relocationTestEntry{
828 {
829 entry: &dwarf.Entry{
830 Offset: 0xb,
831 Tag: dwarf.TagCompileUnit,
832 Children: true,
833 Field: []dwarf.Field{
834 {Attr: dwarf.AttrProducer, Val: "GNU C11 6.2.0 20160914 -mcpu=v9 -g -fstack-protector-strong", Class: dwarf.ClassString},
835 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
836 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
837 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
838 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
839 {Attr: dwarf.AttrHighpc, Val: int64(0x2c), Class: dwarf.ClassConstant},
840 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
841 },
842 },
843 pcRanges: [][2]uint64{{0x0, 0x2c}},
844 },
845 },
846 },
847 {
848 "testdata/go-relocation-test-gcc492-mipsle.obj",
849 []relocationTestEntry{
850 {
851 entry: &dwarf.Entry{
852 Offset: 0xb,
853 Tag: dwarf.TagCompileUnit,
854 Children: true,
855 Field: []dwarf.Field{
856 {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -mel -march=mips2 -mtune=mips32 -mllsc -mno-shared -mabi=32 -g", Class: dwarf.ClassString},
857 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
858 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
859 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
860 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
861 {Attr: dwarf.AttrHighpc, Val: int64(0x58), Class: dwarf.ClassConstant},
862 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
863 },
864 },
865 pcRanges: [][2]uint64{{0x0, 0x58}},
866 },
867 },
868 },
869 {
870 "testdata/go-relocation-test-gcc540-mips.obj",
871 []relocationTestEntry{
872 {
873 entry: &dwarf.Entry{
874 Offset: 0xb,
875 Tag: dwarf.TagCompileUnit,
876 Children: true,
877 Field: []dwarf.Field{
878 {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},
879 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
880 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
881 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
882 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
883 {Attr: dwarf.AttrHighpc, Val: uint64(0x5c), Class: dwarf.ClassAddress},
884 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
885 },
886 },
887 pcRanges: [][2]uint64{{0x0, 0x5c}},
888 },
889 },
890 },
891 {
892 "testdata/go-relocation-test-gcc493-mips64le.obj",
893 []relocationTestEntry{
894 {
895 entry: &dwarf.Entry{
896 Offset: 0xb,
897 Tag: dwarf.TagCompileUnit,
898 Children: true,
899 Field: []dwarf.Field{
900 {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.3 -mel -mabi=64 -mllsc -mno-shared -g -fstack-protector-strong", Class: dwarf.ClassString},
901 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
902 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
903 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
904 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
905 {Attr: dwarf.AttrHighpc, Val: int64(0x64), Class: dwarf.ClassConstant},
906 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
907 },
908 },
909 pcRanges: [][2]uint64{{0x0, 0x64}},
910 },
911 },
912 },
913 {
914 "testdata/go-relocation-test-gcc720-riscv64.obj",
915 []relocationTestEntry{
916 {
917 entry: &dwarf.Entry{
918 Offset: 0xb,
919 Tag: dwarf.TagCompileUnit,
920 Children: true,
921 Field: []dwarf.Field{
922 {Attr: dwarf.AttrProducer, Val: "GNU C11 7.2.0 -march=rv64imafdc -mabi=lp64d -g -gdwarf-2", Class: dwarf.ClassString},
923 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
924 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
925 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
926 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
927 {Attr: dwarf.AttrHighpc, Val: uint64(0x2c), Class: dwarf.ClassAddress},
928 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
929 },
930 },
931 pcRanges: [][2]uint64{{0x0, 0x2c}},
932 },
933 },
934 },
935 {
936 "testdata/go-relocation-test-clang-x86.obj",
937 []relocationTestEntry{
938 {
939 entry: &dwarf.Entry{
940 Offset: 0xb,
941 Tag: dwarf.TagCompileUnit,
942 Children: true,
943 Field: []dwarf.Field{
944 {Attr: dwarf.AttrProducer, Val: "clang version google3-trunk (trunk r209387)", Class: dwarf.ClassString},
945 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
946 {Attr: dwarf.AttrName, Val: "go-relocation-test-clang.c", Class: dwarf.ClassString},
947 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
948 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
949 },
950 },
951 },
952 },
953 },
954 {
955 "testdata/gcc-amd64-openbsd-debug-with-rela.obj",
956 []relocationTestEntry{
957 {
958 entryNumber: 203,
959 entry: &dwarf.Entry{
960 Offset: 0xc62,
961 Tag: dwarf.TagMember,
962 Children: false,
963 Field: []dwarf.Field{
964 {Attr: dwarf.AttrName, Val: "it_interval", Class: dwarf.ClassString},
965 {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant},
966 {Attr: dwarf.AttrDeclLine, Val: int64(236), Class: dwarf.ClassConstant},
967 {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference},
968 {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}, Class: dwarf.ClassExprLoc},
969 },
970 },
971 },
972 {
973 entryNumber: 204,
974 entry: &dwarf.Entry{
975 Offset: 0xc70,
976 Tag: dwarf.TagMember,
977 Children: false,
978 Field: []dwarf.Field{
979 {Attr: dwarf.AttrName, Val: "it_value", Class: dwarf.ClassString},
980 {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant},
981 {Attr: dwarf.AttrDeclLine, Val: int64(237), Class: dwarf.ClassConstant},
982 {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference},
983 {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}, Class: dwarf.ClassExprLoc},
984 },
985 },
986 },
987 },
988 },
989 {
990 "testdata/go-relocation-test-gcc930-ranges-no-rela-x86-64",
991 []relocationTestEntry{
992 {
993 entry: &dwarf.Entry{
994 Offset: 0xb,
995 Tag: dwarf.TagCompileUnit,
996 Children: true,
997 Field: []dwarf.Field{
998 {Attr: dwarf.AttrProducer, Val: "GNU C17 9.3.0 -mtune=generic -march=x86-64 -g -fno-asynchronous-unwind-tables", Class: dwarf.ClassString},
999 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
1000 {Attr: dwarf.AttrName, Val: "multiple-code-sections.c", Class: dwarf.ClassString},
1001 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
1002 {Attr: dwarf.AttrRanges, Val: int64(0), Class: dwarf.ClassRangeListPtr},
1003 {Attr: dwarf.AttrLowpc, Val: uint64(0), Class: dwarf.ClassAddress},
1004 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
1005 },
1006 },
1007 pcRanges: [][2]uint64{
1008 {0x765, 0x777},
1009 {0x7e1, 0x7ec},
1010 },
1011 },
1012 },
1013 },
1014 {
1015 "testdata/go-relocation-test-gcc930-ranges-with-rela-x86-64",
1016 []relocationTestEntry{
1017 {
1018 entry: &dwarf.Entry{
1019 Offset: 0xb,
1020 Tag: dwarf.TagCompileUnit,
1021 Children: true,
1022 Field: []dwarf.Field{
1023 {Attr: dwarf.AttrProducer, Val: "GNU C17 9.3.0 -mtune=generic -march=x86-64 -g -fno-asynchronous-unwind-tables", Class: dwarf.ClassString},
1024 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
1025 {Attr: dwarf.AttrName, Val: "multiple-code-sections.c", Class: dwarf.ClassString},
1026 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
1027 {Attr: dwarf.AttrRanges, Val: int64(0), Class: dwarf.ClassRangeListPtr},
1028 {Attr: dwarf.AttrLowpc, Val: uint64(0), Class: dwarf.ClassAddress},
1029 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
1030 },
1031 },
1032 pcRanges: [][2]uint64{
1033 {0x765, 0x777},
1034 {0x7e1, 0x7ec},
1035 },
1036 },
1037 },
1038 },
1039 }
1040
1041 func TestDWARFRelocations(t *testing.T) {
1042 for _, test := range relocationTests {
1043 t.Run(test.file, func(t *testing.T) {
1044 t.Parallel()
1045 f, err := Open(test.file)
1046 if err != nil {
1047 t.Fatal(err)
1048 }
1049 dwarf, err := f.DWARF()
1050 if err != nil {
1051 t.Fatal(err)
1052 }
1053 reader := dwarf.Reader()
1054 idx := 0
1055 for _, testEntry := range test.entries {
1056 if testEntry.entryNumber < idx {
1057 t.Fatalf("internal test error: %d < %d", testEntry.entryNumber, idx)
1058 }
1059 for ; idx < testEntry.entryNumber; idx++ {
1060 entry, err := reader.Next()
1061 if entry == nil || err != nil {
1062 t.Fatalf("Failed to skip to entry %d: %v", testEntry.entryNumber, err)
1063 }
1064 }
1065 entry, err := reader.Next()
1066 idx++
1067 if err != nil {
1068 t.Fatal(err)
1069 }
1070 if !reflect.DeepEqual(testEntry.entry, entry) {
1071 t.Errorf("entry %d mismatch: got:%#v want:%#v", testEntry.entryNumber, entry, testEntry.entry)
1072 }
1073 pcRanges, err := dwarf.Ranges(entry)
1074 if err != nil {
1075 t.Fatal(err)
1076 }
1077 if !reflect.DeepEqual(testEntry.pcRanges, pcRanges) {
1078 t.Errorf("entry %d: PC range mismatch: got:%#v want:%#v", testEntry.entryNumber, pcRanges, testEntry.pcRanges)
1079 }
1080 }
1081 })
1082 }
1083 }
1084
1085 func TestCompressedDWARF(t *testing.T) {
1086
1087
1088 f, err := Open("testdata/zdebug-test-gcc484-x86-64.obj")
1089 if err != nil {
1090 t.Fatal(err)
1091 }
1092 dwarf, err := f.DWARF()
1093 if err != nil {
1094 t.Fatal(err)
1095 }
1096 reader := dwarf.Reader()
1097 n := 0
1098 for {
1099 entry, err := reader.Next()
1100 if err != nil {
1101 t.Fatal(err)
1102 }
1103 if entry == nil {
1104 break
1105 }
1106 n++
1107 }
1108 if n != 18 {
1109 t.Fatalf("want %d DWARF entries, got %d", 18, n)
1110 }
1111 }
1112
1113 func TestCompressedSection(t *testing.T) {
1114
1115
1116 f, err := Open("testdata/compressed-64.obj")
1117 if err != nil {
1118 t.Fatal(err)
1119 }
1120 sec := f.Section(".debug_info")
1121 wantData := []byte{
1122 182, 0, 0, 0, 4, 0, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0,
1123 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1124 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 7,
1125 0, 0, 0, 0, 2, 1, 8, 0, 0, 0, 0, 2, 2, 7, 0, 0,
1126 0, 0, 2, 4, 7, 0, 0, 0, 0, 2, 1, 6, 0, 0, 0, 0,
1127 2, 2, 5, 0, 0, 0, 0, 3, 4, 5, 105, 110, 116, 0, 2, 8,
1128 5, 0, 0, 0, 0, 2, 8, 7, 0, 0, 0, 0, 4, 8, 114, 0,
1129 0, 0, 2, 1, 6, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 4,
1130 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0,
1131 1, 156, 179, 0, 0, 0, 6, 0, 0, 0, 0, 1, 4, 87, 0, 0,
1132 0, 2, 145, 108, 6, 0, 0, 0, 0, 1, 4, 179, 0, 0, 0, 2,
1133 145, 96, 0, 4, 8, 108, 0, 0, 0, 0,
1134 }
1135
1136
1137 b, err := sec.Data()
1138 if err != nil {
1139 t.Fatal(err)
1140 }
1141 if !bytes.Equal(wantData, b) {
1142 t.Fatalf("want data %x, got %x", wantData, b)
1143 }
1144
1145
1146 buf, have, count := make([]byte, len(b)), make([]bool, len(b)), 0
1147 sf := sec.Open()
1148 if got, err := sf.Seek(0, io.SeekEnd); got != int64(len(b)) || err != nil {
1149 t.Fatalf("want seek end %d, got %d error %v", len(b), got, err)
1150 }
1151 if n, err := sf.Read(buf); n != 0 || err != io.EOF {
1152 t.Fatalf("want EOF with 0 bytes, got %v with %d bytes", err, n)
1153 }
1154 pos := int64(len(buf))
1155 for count < len(buf) {
1156
1157 whence := rand.Intn(3)
1158 target := rand.Int63n(int64(len(buf)))
1159 var offset int64
1160 switch whence {
1161 case io.SeekStart:
1162 offset = target
1163 case io.SeekCurrent:
1164 offset = target - pos
1165 case io.SeekEnd:
1166 offset = target - int64(len(buf))
1167 }
1168 pos, err = sf.Seek(offset, whence)
1169 if err != nil {
1170 t.Fatal(err)
1171 }
1172 if pos != target {
1173 t.Fatalf("want position %d, got %d", target, pos)
1174 }
1175
1176
1177 end := pos + 16
1178 if end > int64(len(buf)) {
1179 end = int64(len(buf))
1180 }
1181 n, err := io.ReadFull(sf, buf[pos:end])
1182 if err != nil {
1183 t.Fatal(err)
1184 }
1185 for i := 0; i < n; i++ {
1186 if !have[pos] {
1187 have[pos] = true
1188 count++
1189 }
1190 pos++
1191 }
1192 }
1193 if !bytes.Equal(wantData, buf) {
1194 t.Fatalf("want data %x, got %x", wantData, buf)
1195 }
1196 }
1197
1198 func TestNoSectionOverlaps(t *testing.T) {
1199
1200 switch runtime.GOOS {
1201 case "aix", "android", "darwin", "ios", "js", "plan9", "windows", "wasip1":
1202 t.Skipf("cmd/link doesn't produce ELF binaries on %s", runtime.GOOS)
1203 }
1204 _ = net.ResolveIPAddr
1205 f, err := Open(os.Args[0])
1206 if err != nil {
1207 t.Error(err)
1208 return
1209 }
1210 for i, si := range f.Sections {
1211 sih := si.SectionHeader
1212 if sih.Type == SHT_NOBITS {
1213 continue
1214 }
1215
1216 for j, sj := range f.Sections {
1217 sjh := sj.SectionHeader
1218 if i == j || sjh.Type == SHT_NOBITS || sih.Offset == sjh.Offset && sih.FileSize == 0 {
1219 continue
1220 }
1221 if sih.Offset >= sjh.Offset && sih.Offset < sjh.Offset+sjh.FileSize {
1222 t.Errorf("ld produced ELF with section offset %s within %s: 0x%x <= 0x%x..0x%x < 0x%x",
1223 sih.Name, sjh.Name, sjh.Offset, sih.Offset, sih.Offset+sih.FileSize, sjh.Offset+sjh.FileSize)
1224 }
1225 }
1226
1227 if sih.Flags&SHF_ALLOC == 0 {
1228 continue
1229 }
1230
1231
1232 for j, sj := range f.Sections {
1233 sjh := sj.SectionHeader
1234 if i == j || sjh.Flags&SHF_ALLOC == 0 || sjh.Type == SHT_NOBITS ||
1235 sih.Addr == sjh.Addr && sih.Size == 0 {
1236 continue
1237 }
1238 if sih.Addr >= sjh.Addr && sih.Addr < sjh.Addr+sjh.Size {
1239 t.Errorf("ld produced ELF with section address %s within %s: 0x%x <= 0x%x..0x%x < 0x%x",
1240 sih.Name, sjh.Name, sjh.Addr, sih.Addr, sih.Addr+sih.Size, sjh.Addr+sjh.Size)
1241 }
1242 }
1243 }
1244 }
1245
1246 func TestNobitsSection(t *testing.T) {
1247 const testdata = "testdata/gcc-amd64-linux-exec"
1248 f, err := Open(testdata)
1249 if err != nil {
1250 t.Fatalf("could not read %s: %v", testdata, err)
1251 }
1252 defer f.Close()
1253
1254 wantError := "unexpected read from SHT_NOBITS section"
1255 bss := f.Section(".bss")
1256
1257 _, err = bss.Data()
1258 if err == nil || err.Error() != wantError {
1259 t.Fatalf("bss.Data() got error %q, want error %q", err, wantError)
1260 }
1261
1262 r := bss.Open()
1263 p := make([]byte, 1)
1264 _, err = r.Read(p)
1265 if err == nil || err.Error() != wantError {
1266 t.Fatalf("r.Read(p) got error %q, want error %q", err, wantError)
1267 }
1268 }
1269
1270
1271
1272 func TestLargeNumberOfSections(t *testing.T) {
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324 var buf bytes.Buffer
1325
1326 {
1327 buf.Grow(0x55AF1C)
1328
1329 h := Header32{
1330 Ident: [16]byte{0x7F, 'E', 'L', 'F', 0x01, 0x01, 0x01},
1331 Type: 1,
1332 Machine: 3,
1333 Version: 1,
1334 Shoff: 0x2DD44C,
1335 Ehsize: 0x34,
1336 Shentsize: 0x28,
1337 Shnum: 0,
1338 Shstrndx: 0xFFFF,
1339 }
1340 binary.Write(&buf, binary.LittleEndian, h)
1341
1342
1343 buf.Write(bytes.Repeat([]byte{0}, 0x13ED1C-binary.Size(h)))
1344
1345
1346
1347 buf.Write(bytes.Repeat([]byte{0}, 0x03FC28-12*4))
1348 for i := 0; i < 12; i++ {
1349 binary.Write(&buf, binary.LittleEndian, uint32(0xFF00|i))
1350 }
1351
1352
1353 buf.Write([]byte{0})
1354 buf.Write([]byte("y.c\x00"))
1355 for i := 1; i <= 65288; i++ {
1356
1357 name := fmt.Sprintf("var_%04x", i)
1358 buf.Write([]byte(name))
1359 buf.Write([]byte{0})
1360 }
1361
1362
1363 buf.Write([]byte{0})
1364 buf.Write([]byte(".symtab\x00"))
1365 buf.Write([]byte(".strtab\x00"))
1366 buf.Write([]byte(".shstrtab\x00"))
1367 buf.Write([]byte(".text\x00"))
1368 buf.Write([]byte(".data\x00"))
1369 buf.Write([]byte(".bss\x00"))
1370 for i := 1; i <= 65288; i++ {
1371
1372 name := fmt.Sprintf("section_%04x", i)
1373 buf.Write([]byte(name))
1374 buf.Write([]byte{0})
1375 }
1376 buf.Write([]byte(".comment\x00"))
1377 buf.Write([]byte(".note.GNU-stack\x00"))
1378 buf.Write([]byte(".symtab_shndx\x00"))
1379
1380
1381
1382 binary.Write(&buf, binary.LittleEndian, Section32{Name: 0, Size: 0xFF12, Link: 0xFF11})
1383
1384 binary.Write(&buf, binary.LittleEndian, Section32{
1385 Name: 0x1B,
1386 Type: uint32(SHT_PROGBITS),
1387 Flags: uint32(SHF_ALLOC | SHF_EXECINSTR),
1388 Off: 0x34,
1389 Addralign: 0x01,
1390 })
1391
1392 binary.Write(&buf, binary.LittleEndian, Section32{
1393 Name: 0x21,
1394 Type: uint32(SHT_PROGBITS),
1395 Flags: uint32(SHF_WRITE | SHF_ALLOC),
1396 Off: 0x34,
1397 Addralign: 0x01,
1398 })
1399
1400 binary.Write(&buf, binary.LittleEndian, Section32{
1401 Name: 0x27,
1402 Type: uint32(SHT_NOBITS),
1403 Flags: uint32(SHF_WRITE | SHF_ALLOC),
1404 Off: 0x34,
1405 Addralign: 0x01,
1406 })
1407
1408 for i := 0; i < 65288; i++ {
1409 s := Section32{
1410 Name: uint32(0x2C + i*13),
1411 Type: uint32(SHT_PROGBITS),
1412 Flags: uint32(SHF_WRITE | SHF_ALLOC),
1413 Off: uint32(0x34 + i*4),
1414 Size: 0x04,
1415 Addralign: 0x04,
1416 }
1417 binary.Write(&buf, binary.LittleEndian, s)
1418 }
1419
1420 binary.Write(&buf, binary.LittleEndian, Section32{
1421 Name: 0x0CF394,
1422 Type: uint32(SHT_PROGBITS),
1423 Flags: uint32(SHF_MERGE | SHF_STRINGS),
1424 Off: 0x03FC54,
1425 Size: 0x27,
1426 Addralign: 0x01,
1427 Entsize: 0x01,
1428 })
1429
1430 binary.Write(&buf, binary.LittleEndian, Section32{
1431 Name: 0x0CF39D,
1432 Type: uint32(SHT_PROGBITS),
1433 Off: 0x03FC7B,
1434 Addralign: 0x01,
1435 })
1436
1437 binary.Write(&buf, binary.LittleEndian, Section32{
1438 Name: 0x01,
1439 Type: uint32(SHT_SYMTAB),
1440 Off: 0x03FC7C,
1441 Size: 0x0FF0A0,
1442 Link: 0xFF10,
1443 Info: 0x02,
1444 Addralign: 0x04,
1445 Entsize: 0x10,
1446 })
1447
1448 binary.Write(&buf, binary.LittleEndian, Section32{
1449 Name: 0x0CF3AD,
1450 Type: uint32(SHT_SYMTAB_SHNDX),
1451 Off: 0x13ED1C,
1452 Size: 0x03FC28,
1453 Link: 0xFF0E,
1454 Addralign: 0x04,
1455 Entsize: 0x04,
1456 })
1457
1458 binary.Write(&buf, binary.LittleEndian, Section32{
1459 Name: 0x09,
1460 Type: uint32(SHT_STRTAB),
1461 Off: 0x17E944,
1462 Size: 0x08F74D,
1463 Addralign: 0x01,
1464 })
1465
1466 binary.Write(&buf, binary.LittleEndian, Section32{
1467 Name: 0x11,
1468 Type: uint32(SHT_STRTAB),
1469 Off: 0x20E091,
1470 Size: 0x0CF3BB,
1471 Addralign: 0x01,
1472 })
1473 }
1474
1475 data := buf.Bytes()
1476
1477 f, err := NewFile(bytes.NewReader(data))
1478 if err != nil {
1479 t.Errorf("cannot create file from data: %v", err)
1480 }
1481 defer f.Close()
1482
1483 wantFileHeader := FileHeader{
1484 Class: ELFCLASS32,
1485 Data: ELFDATA2LSB,
1486 Version: EV_CURRENT,
1487 OSABI: ELFOSABI_NONE,
1488 ByteOrder: binary.LittleEndian,
1489 Type: ET_REL,
1490 Machine: EM_386,
1491 }
1492 if f.FileHeader != wantFileHeader {
1493 t.Errorf("\nhave %#v\nwant %#v\n", f.FileHeader, wantFileHeader)
1494 }
1495
1496 wantSectionNum := 65298
1497 if len(f.Sections) != wantSectionNum {
1498 t.Errorf("len(Sections) = %d, want %d", len(f.Sections), wantSectionNum)
1499 }
1500
1501 wantSectionHeader := SectionHeader{
1502 Name: "section_0007",
1503 Type: SHT_PROGBITS,
1504 Flags: SHF_WRITE + SHF_ALLOC,
1505 Offset: 0x4c,
1506 Size: 0x4,
1507 Addralign: 0x4,
1508 FileSize: 0x4,
1509 }
1510 if f.Sections[10].SectionHeader != wantSectionHeader {
1511 t.Errorf("\nhave %#v\nwant %#v\n", f.Sections[10].SectionHeader, wantSectionHeader)
1512 }
1513 }
1514
1515 func TestIssue10996(t *testing.T) {
1516 data := []byte("\u007fELF\x02\x01\x010000000000000" +
1517 "\x010000000000000000000" +
1518 "\x00\x00\x00\x00\x00\x00\x00\x0000000000\x00\x00\x00\x00" +
1519 "0000")
1520 _, err := NewFile(bytes.NewReader(data))
1521 if err == nil {
1522 t.Fatalf("opening invalid ELF file unexpectedly succeeded")
1523 }
1524 }
1525
1526 func TestDynValue(t *testing.T) {
1527 const testdata = "testdata/gcc-amd64-linux-exec"
1528 f, err := Open(testdata)
1529 if err != nil {
1530 t.Fatalf("could not read %s: %v", testdata, err)
1531 }
1532 defer f.Close()
1533
1534 vals, err := f.DynValue(DT_VERNEEDNUM)
1535 if err != nil {
1536 t.Fatalf("DynValue(DT_VERNEEDNUM): got unexpected error %v", err)
1537 }
1538
1539 if len(vals) != 1 || vals[0] != 1 {
1540 t.Errorf("DynValue(DT_VERNEEDNUM): got %v, want [1]", vals)
1541 }
1542 }
1543
1544 func TestIssue59208(t *testing.T) {
1545
1546 const orig = "testdata/compressed-64.obj"
1547 f, err := Open(orig)
1548 if err != nil {
1549 t.Fatal(err)
1550 }
1551 sec := f.Section(".debug_info")
1552
1553 data, err := os.ReadFile(orig)
1554 if err != nil {
1555 t.Fatal(err)
1556 }
1557
1558 dn := make([]byte, len(data))
1559 zoffset := sec.Offset + uint64(sec.compressionOffset)
1560 copy(dn, data[:zoffset])
1561
1562 ozd, err := sec.Data()
1563 if err != nil {
1564 t.Fatal(err)
1565 }
1566 buf := bytes.NewBuffer(nil)
1567 wr := zlib.NewWriter(buf)
1568
1569 copy(ozd, []byte{1, 0, 0, 0})
1570 wr.Write(ozd)
1571 wr.Close()
1572
1573 copy(dn[zoffset:], buf.Bytes())
1574 copy(dn[sec.Offset+sec.FileSize:], data[sec.Offset+sec.FileSize:])
1575
1576 nf, err := NewFile(bytes.NewReader(dn))
1577 if err != nil {
1578 t.Error(err)
1579 }
1580
1581 const want = "decoding dwarf section info"
1582 _, err = nf.DWARF()
1583 if err == nil || !strings.Contains(err.Error(), want) {
1584 t.Errorf("DWARF = %v; want %q", err, want)
1585 }
1586 }
1587
1588 func BenchmarkSymbols64(b *testing.B) {
1589 const testdata = "testdata/gcc-amd64-linux-exec"
1590 f, err := Open(testdata)
1591 if err != nil {
1592 b.Fatalf("could not read %s: %v", testdata, err)
1593 }
1594 defer f.Close()
1595 b.ResetTimer()
1596 for i := 0; i < b.N; i++ {
1597 symbols, err := f.Symbols()
1598 if err != nil {
1599 b.Fatalf("Symbols(): got unexpected error %v", err)
1600 }
1601 if len(symbols) != 73 {
1602 b.Errorf("\nhave %d symbols\nwant %d symbols\n", len(symbols), 73)
1603 }
1604 }
1605 }
1606
1607 func BenchmarkSymbols32(b *testing.B) {
1608 const testdata = "testdata/gcc-386-freebsd-exec"
1609 f, err := Open(testdata)
1610 if err != nil {
1611 b.Fatalf("could not read %s: %v", testdata, err)
1612 }
1613 defer f.Close()
1614 b.ResetTimer()
1615 for i := 0; i < b.N; i++ {
1616 symbols, err := f.Symbols()
1617 if err != nil {
1618 b.Fatalf("Symbols(): got unexpected error %v", err)
1619 }
1620 if len(symbols) != 74 {
1621 b.Errorf("\nhave %d symbols\nwant %d symbols\n", len(symbols), 74)
1622 }
1623 }
1624 }
1625
View as plain text