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 test := test
1044 t.Run(test.file, func(t *testing.T) {
1045 t.Parallel()
1046 f, err := Open(test.file)
1047 if err != nil {
1048 t.Fatal(err)
1049 }
1050 dwarf, err := f.DWARF()
1051 if err != nil {
1052 t.Fatal(err)
1053 }
1054 reader := dwarf.Reader()
1055 idx := 0
1056 for _, testEntry := range test.entries {
1057 if testEntry.entryNumber < idx {
1058 t.Fatalf("internal test error: %d < %d", testEntry.entryNumber, idx)
1059 }
1060 for ; idx < testEntry.entryNumber; idx++ {
1061 entry, err := reader.Next()
1062 if entry == nil || err != nil {
1063 t.Fatalf("Failed to skip to entry %d: %v", testEntry.entryNumber, err)
1064 }
1065 }
1066 entry, err := reader.Next()
1067 idx++
1068 if err != nil {
1069 t.Fatal(err)
1070 }
1071 if !reflect.DeepEqual(testEntry.entry, entry) {
1072 t.Errorf("entry %d mismatch: got:%#v want:%#v", testEntry.entryNumber, entry, testEntry.entry)
1073 }
1074 pcRanges, err := dwarf.Ranges(entry)
1075 if err != nil {
1076 t.Fatal(err)
1077 }
1078 if !reflect.DeepEqual(testEntry.pcRanges, pcRanges) {
1079 t.Errorf("entry %d: PC range mismatch: got:%#v want:%#v", testEntry.entryNumber, pcRanges, testEntry.pcRanges)
1080 }
1081 }
1082 })
1083 }
1084 }
1085
1086 func TestCompressedDWARF(t *testing.T) {
1087
1088
1089 f, err := Open("testdata/zdebug-test-gcc484-x86-64.obj")
1090 if err != nil {
1091 t.Fatal(err)
1092 }
1093 dwarf, err := f.DWARF()
1094 if err != nil {
1095 t.Fatal(err)
1096 }
1097 reader := dwarf.Reader()
1098 n := 0
1099 for {
1100 entry, err := reader.Next()
1101 if err != nil {
1102 t.Fatal(err)
1103 }
1104 if entry == nil {
1105 break
1106 }
1107 n++
1108 }
1109 if n != 18 {
1110 t.Fatalf("want %d DWARF entries, got %d", 18, n)
1111 }
1112 }
1113
1114 func TestCompressedSection(t *testing.T) {
1115
1116
1117 f, err := Open("testdata/compressed-64.obj")
1118 if err != nil {
1119 t.Fatal(err)
1120 }
1121 sec := f.Section(".debug_info")
1122 wantData := []byte{
1123 182, 0, 0, 0, 4, 0, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0,
1124 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1125 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 7,
1126 0, 0, 0, 0, 2, 1, 8, 0, 0, 0, 0, 2, 2, 7, 0, 0,
1127 0, 0, 2, 4, 7, 0, 0, 0, 0, 2, 1, 6, 0, 0, 0, 0,
1128 2, 2, 5, 0, 0, 0, 0, 3, 4, 5, 105, 110, 116, 0, 2, 8,
1129 5, 0, 0, 0, 0, 2, 8, 7, 0, 0, 0, 0, 4, 8, 114, 0,
1130 0, 0, 2, 1, 6, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 4,
1131 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0,
1132 1, 156, 179, 0, 0, 0, 6, 0, 0, 0, 0, 1, 4, 87, 0, 0,
1133 0, 2, 145, 108, 6, 0, 0, 0, 0, 1, 4, 179, 0, 0, 0, 2,
1134 145, 96, 0, 4, 8, 108, 0, 0, 0, 0,
1135 }
1136
1137
1138 b, err := sec.Data()
1139 if err != nil {
1140 t.Fatal(err)
1141 }
1142 if !bytes.Equal(wantData, b) {
1143 t.Fatalf("want data %x, got %x", wantData, b)
1144 }
1145
1146
1147 buf, have, count := make([]byte, len(b)), make([]bool, len(b)), 0
1148 sf := sec.Open()
1149 if got, err := sf.Seek(0, io.SeekEnd); got != int64(len(b)) || err != nil {
1150 t.Fatalf("want seek end %d, got %d error %v", len(b), got, err)
1151 }
1152 if n, err := sf.Read(buf); n != 0 || err != io.EOF {
1153 t.Fatalf("want EOF with 0 bytes, got %v with %d bytes", err, n)
1154 }
1155 pos := int64(len(buf))
1156 for count < len(buf) {
1157
1158 whence := rand.Intn(3)
1159 target := rand.Int63n(int64(len(buf)))
1160 var offset int64
1161 switch whence {
1162 case io.SeekStart:
1163 offset = target
1164 case io.SeekCurrent:
1165 offset = target - pos
1166 case io.SeekEnd:
1167 offset = target - int64(len(buf))
1168 }
1169 pos, err = sf.Seek(offset, whence)
1170 if err != nil {
1171 t.Fatal(err)
1172 }
1173 if pos != target {
1174 t.Fatalf("want position %d, got %d", target, pos)
1175 }
1176
1177
1178 end := pos + 16
1179 if end > int64(len(buf)) {
1180 end = int64(len(buf))
1181 }
1182 n, err := io.ReadFull(sf, buf[pos:end])
1183 if err != nil {
1184 t.Fatal(err)
1185 }
1186 for i := 0; i < n; i++ {
1187 if !have[pos] {
1188 have[pos] = true
1189 count++
1190 }
1191 pos++
1192 }
1193 }
1194 if !bytes.Equal(wantData, buf) {
1195 t.Fatalf("want data %x, got %x", wantData, buf)
1196 }
1197 }
1198
1199 func TestNoSectionOverlaps(t *testing.T) {
1200
1201 switch runtime.GOOS {
1202 case "aix", "android", "darwin", "ios", "js", "plan9", "windows", "wasip1":
1203 t.Skipf("cmd/link doesn't produce ELF binaries on %s", runtime.GOOS)
1204 }
1205 _ = net.ResolveIPAddr
1206 f, err := Open(os.Args[0])
1207 if err != nil {
1208 t.Error(err)
1209 return
1210 }
1211 for i, si := range f.Sections {
1212 sih := si.SectionHeader
1213 if sih.Type == SHT_NOBITS {
1214 continue
1215 }
1216
1217 for j, sj := range f.Sections {
1218 sjh := sj.SectionHeader
1219 if i == j || sjh.Type == SHT_NOBITS || sih.Offset == sjh.Offset && sih.FileSize == 0 {
1220 continue
1221 }
1222 if sih.Offset >= sjh.Offset && sih.Offset < sjh.Offset+sjh.FileSize {
1223 t.Errorf("ld produced ELF with section offset %s within %s: 0x%x <= 0x%x..0x%x < 0x%x",
1224 sih.Name, sjh.Name, sjh.Offset, sih.Offset, sih.Offset+sih.FileSize, sjh.Offset+sjh.FileSize)
1225 }
1226 }
1227
1228 if sih.Flags&SHF_ALLOC == 0 {
1229 continue
1230 }
1231
1232
1233 for j, sj := range f.Sections {
1234 sjh := sj.SectionHeader
1235 if i == j || sjh.Flags&SHF_ALLOC == 0 || sjh.Type == SHT_NOBITS ||
1236 sih.Addr == sjh.Addr && sih.Size == 0 {
1237 continue
1238 }
1239 if sih.Addr >= sjh.Addr && sih.Addr < sjh.Addr+sjh.Size {
1240 t.Errorf("ld produced ELF with section address %s within %s: 0x%x <= 0x%x..0x%x < 0x%x",
1241 sih.Name, sjh.Name, sjh.Addr, sih.Addr, sih.Addr+sih.Size, sjh.Addr+sjh.Size)
1242 }
1243 }
1244 }
1245 }
1246
1247 func TestNobitsSection(t *testing.T) {
1248 const testdata = "testdata/gcc-amd64-linux-exec"
1249 f, err := Open(testdata)
1250 if err != nil {
1251 t.Fatalf("could not read %s: %v", testdata, err)
1252 }
1253 defer f.Close()
1254
1255 wantError := "unexpected read from SHT_NOBITS section"
1256 bss := f.Section(".bss")
1257
1258 _, err = bss.Data()
1259 if err == nil || err.Error() != wantError {
1260 t.Fatalf("bss.Data() got error %q, want error %q", err, wantError)
1261 }
1262
1263 r := bss.Open()
1264 p := make([]byte, 1)
1265 _, err = r.Read(p)
1266 if err == nil || err.Error() != wantError {
1267 t.Fatalf("r.Read(p) got error %q, want error %q", err, wantError)
1268 }
1269 }
1270
1271
1272
1273 func TestLargeNumberOfSections(t *testing.T) {
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
1325 var buf bytes.Buffer
1326
1327 {
1328 buf.Grow(0x55AF1C)
1329
1330 h := Header32{
1331 Ident: [16]byte{0x7F, 'E', 'L', 'F', 0x01, 0x01, 0x01},
1332 Type: 1,
1333 Machine: 3,
1334 Version: 1,
1335 Shoff: 0x2DD44C,
1336 Ehsize: 0x34,
1337 Shentsize: 0x28,
1338 Shnum: 0,
1339 Shstrndx: 0xFFFF,
1340 }
1341 binary.Write(&buf, binary.LittleEndian, h)
1342
1343
1344 buf.Write(bytes.Repeat([]byte{0}, 0x13ED1C-binary.Size(h)))
1345
1346
1347
1348 buf.Write(bytes.Repeat([]byte{0}, 0x03FC28-12*4))
1349 for i := 0; i < 12; i++ {
1350 binary.Write(&buf, binary.LittleEndian, uint32(0xFF00|i))
1351 }
1352
1353
1354 buf.Write([]byte{0})
1355 buf.Write([]byte("y.c\x00"))
1356 for i := 1; i <= 65288; i++ {
1357
1358 name := fmt.Sprintf("var_%04x", i)
1359 buf.Write([]byte(name))
1360 buf.Write([]byte{0})
1361 }
1362
1363
1364 buf.Write([]byte{0})
1365 buf.Write([]byte(".symtab\x00"))
1366 buf.Write([]byte(".strtab\x00"))
1367 buf.Write([]byte(".shstrtab\x00"))
1368 buf.Write([]byte(".text\x00"))
1369 buf.Write([]byte(".data\x00"))
1370 buf.Write([]byte(".bss\x00"))
1371 for i := 1; i <= 65288; i++ {
1372
1373 name := fmt.Sprintf("section_%04x", i)
1374 buf.Write([]byte(name))
1375 buf.Write([]byte{0})
1376 }
1377 buf.Write([]byte(".comment\x00"))
1378 buf.Write([]byte(".note.GNU-stack\x00"))
1379 buf.Write([]byte(".symtab_shndx\x00"))
1380
1381
1382
1383 binary.Write(&buf, binary.LittleEndian, Section32{Name: 0, Size: 0xFF12, Link: 0xFF11})
1384
1385 binary.Write(&buf, binary.LittleEndian, Section32{
1386 Name: 0x1B,
1387 Type: uint32(SHT_PROGBITS),
1388 Flags: uint32(SHF_ALLOC | SHF_EXECINSTR),
1389 Off: 0x34,
1390 Addralign: 0x01,
1391 })
1392
1393 binary.Write(&buf, binary.LittleEndian, Section32{
1394 Name: 0x21,
1395 Type: uint32(SHT_PROGBITS),
1396 Flags: uint32(SHF_WRITE | SHF_ALLOC),
1397 Off: 0x34,
1398 Addralign: 0x01,
1399 })
1400
1401 binary.Write(&buf, binary.LittleEndian, Section32{
1402 Name: 0x27,
1403 Type: uint32(SHT_NOBITS),
1404 Flags: uint32(SHF_WRITE | SHF_ALLOC),
1405 Off: 0x34,
1406 Addralign: 0x01,
1407 })
1408
1409 for i := 0; i < 65288; i++ {
1410 s := Section32{
1411 Name: uint32(0x2C + i*13),
1412 Type: uint32(SHT_PROGBITS),
1413 Flags: uint32(SHF_WRITE | SHF_ALLOC),
1414 Off: uint32(0x34 + i*4),
1415 Size: 0x04,
1416 Addralign: 0x04,
1417 }
1418 binary.Write(&buf, binary.LittleEndian, s)
1419 }
1420
1421 binary.Write(&buf, binary.LittleEndian, Section32{
1422 Name: 0x0CF394,
1423 Type: uint32(SHT_PROGBITS),
1424 Flags: uint32(SHF_MERGE | SHF_STRINGS),
1425 Off: 0x03FC54,
1426 Size: 0x27,
1427 Addralign: 0x01,
1428 Entsize: 0x01,
1429 })
1430
1431 binary.Write(&buf, binary.LittleEndian, Section32{
1432 Name: 0x0CF39D,
1433 Type: uint32(SHT_PROGBITS),
1434 Off: 0x03FC7B,
1435 Addralign: 0x01,
1436 })
1437
1438 binary.Write(&buf, binary.LittleEndian, Section32{
1439 Name: 0x01,
1440 Type: uint32(SHT_SYMTAB),
1441 Off: 0x03FC7C,
1442 Size: 0x0FF0A0,
1443 Link: 0xFF10,
1444 Info: 0x02,
1445 Addralign: 0x04,
1446 Entsize: 0x10,
1447 })
1448
1449 binary.Write(&buf, binary.LittleEndian, Section32{
1450 Name: 0x0CF3AD,
1451 Type: uint32(SHT_SYMTAB_SHNDX),
1452 Off: 0x13ED1C,
1453 Size: 0x03FC28,
1454 Link: 0xFF0E,
1455 Addralign: 0x04,
1456 Entsize: 0x04,
1457 })
1458
1459 binary.Write(&buf, binary.LittleEndian, Section32{
1460 Name: 0x09,
1461 Type: uint32(SHT_STRTAB),
1462 Off: 0x17E944,
1463 Size: 0x08F74D,
1464 Addralign: 0x01,
1465 })
1466
1467 binary.Write(&buf, binary.LittleEndian, Section32{
1468 Name: 0x11,
1469 Type: uint32(SHT_STRTAB),
1470 Off: 0x20E091,
1471 Size: 0x0CF3BB,
1472 Addralign: 0x01,
1473 })
1474 }
1475
1476 data := buf.Bytes()
1477
1478 f, err := NewFile(bytes.NewReader(data))
1479 if err != nil {
1480 t.Errorf("cannot create file from data: %v", err)
1481 }
1482 defer f.Close()
1483
1484 wantFileHeader := FileHeader{
1485 Class: ELFCLASS32,
1486 Data: ELFDATA2LSB,
1487 Version: EV_CURRENT,
1488 OSABI: ELFOSABI_NONE,
1489 ByteOrder: binary.LittleEndian,
1490 Type: ET_REL,
1491 Machine: EM_386,
1492 }
1493 if f.FileHeader != wantFileHeader {
1494 t.Errorf("\nhave %#v\nwant %#v\n", f.FileHeader, wantFileHeader)
1495 }
1496
1497 wantSectionNum := 65298
1498 if len(f.Sections) != wantSectionNum {
1499 t.Errorf("len(Sections) = %d, want %d", len(f.Sections), wantSectionNum)
1500 }
1501
1502 wantSectionHeader := SectionHeader{
1503 Name: "section_0007",
1504 Type: SHT_PROGBITS,
1505 Flags: SHF_WRITE + SHF_ALLOC,
1506 Offset: 0x4c,
1507 Size: 0x4,
1508 Addralign: 0x4,
1509 FileSize: 0x4,
1510 }
1511 if f.Sections[10].SectionHeader != wantSectionHeader {
1512 t.Errorf("\nhave %#v\nwant %#v\n", f.Sections[10].SectionHeader, wantSectionHeader)
1513 }
1514 }
1515
1516 func TestIssue10996(t *testing.T) {
1517 data := []byte("\u007fELF\x02\x01\x010000000000000" +
1518 "\x010000000000000000000" +
1519 "\x00\x00\x00\x00\x00\x00\x00\x0000000000\x00\x00\x00\x00" +
1520 "0000")
1521 _, err := NewFile(bytes.NewReader(data))
1522 if err == nil {
1523 t.Fatalf("opening invalid ELF file unexpectedly succeeded")
1524 }
1525 }
1526
1527 func TestDynValue(t *testing.T) {
1528 const testdata = "testdata/gcc-amd64-linux-exec"
1529 f, err := Open(testdata)
1530 if err != nil {
1531 t.Fatalf("could not read %s: %v", testdata, err)
1532 }
1533 defer f.Close()
1534
1535 vals, err := f.DynValue(DT_VERNEEDNUM)
1536 if err != nil {
1537 t.Fatalf("DynValue(DT_VERNEEDNUM): got unexpected error %v", err)
1538 }
1539
1540 if len(vals) != 1 || vals[0] != 1 {
1541 t.Errorf("DynValue(DT_VERNEEDNUM): got %v, want [1]", vals)
1542 }
1543 }
1544
1545 func TestIssue59208(t *testing.T) {
1546
1547 const orig = "testdata/compressed-64.obj"
1548 f, err := Open(orig)
1549 if err != nil {
1550 t.Fatal(err)
1551 }
1552 sec := f.Section(".debug_info")
1553
1554 data, err := os.ReadFile(orig)
1555 if err != nil {
1556 t.Fatal(err)
1557 }
1558
1559 dn := make([]byte, len(data))
1560 zoffset := sec.Offset + uint64(sec.compressionOffset)
1561 copy(dn, data[:zoffset])
1562
1563 ozd, err := sec.Data()
1564 if err != nil {
1565 t.Fatal(err)
1566 }
1567 buf := bytes.NewBuffer(nil)
1568 wr := zlib.NewWriter(buf)
1569
1570 copy(ozd, []byte{1, 0, 0, 0})
1571 wr.Write(ozd)
1572 wr.Close()
1573
1574 copy(dn[zoffset:], buf.Bytes())
1575 copy(dn[sec.Offset+sec.FileSize:], data[sec.Offset+sec.FileSize:])
1576
1577 nf, err := NewFile(bytes.NewReader(dn))
1578 if err != nil {
1579 t.Error(err)
1580 }
1581
1582 const want = "decoding dwarf section info"
1583 _, err = nf.DWARF()
1584 if err == nil || !strings.Contains(err.Error(), want) {
1585 t.Errorf("DWARF = %v; want %q", err, want)
1586 }
1587 }
1588
1589 func BenchmarkSymbols64(b *testing.B) {
1590 const testdata = "testdata/gcc-amd64-linux-exec"
1591 f, err := Open(testdata)
1592 if err != nil {
1593 b.Fatalf("could not read %s: %v", testdata, err)
1594 }
1595 defer f.Close()
1596 b.ResetTimer()
1597 for i := 0; i < b.N; i++ {
1598 symbols, err := f.Symbols()
1599 if err != nil {
1600 b.Fatalf("Symbols(): got unexpected error %v", err)
1601 }
1602 if len(symbols) != 73 {
1603 b.Errorf("\nhave %d symbols\nwant %d symbols\n", len(symbols), 73)
1604 }
1605 }
1606 }
1607
1608 func BenchmarkSymbols32(b *testing.B) {
1609 const testdata = "testdata/gcc-386-freebsd-exec"
1610 f, err := Open(testdata)
1611 if err != nil {
1612 b.Fatalf("could not read %s: %v", testdata, err)
1613 }
1614 defer f.Close()
1615 b.ResetTimer()
1616 for i := 0; i < b.N; i++ {
1617 symbols, err := f.Symbols()
1618 if err != nil {
1619 b.Fatalf("Symbols(): got unexpected error %v", err)
1620 }
1621 if len(symbols) != 74 {
1622 b.Errorf("\nhave %d symbols\nwant %d symbols\n", len(symbols), 74)
1623 }
1624 }
1625 }
1626
View as plain text