github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/debug/elf/file_test.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 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, 1, 134512852, 0, "", ""}, 82 {"", 3, 0, 2, 134512876, 0, "", ""}, 83 {"", 3, 0, 3, 134513020, 0, "", ""}, 84 {"", 3, 0, 4, 134513292, 0, "", ""}, 85 {"", 3, 0, 5, 134513480, 0, "", ""}, 86 {"", 3, 0, 6, 134513512, 0, "", ""}, 87 {"", 3, 0, 7, 134513532, 0, "", ""}, 88 {"", 3, 0, 8, 134513612, 0, "", ""}, 89 {"", 3, 0, 9, 134513996, 0, "", ""}, 90 {"", 3, 0, 10, 134514008, 0, "", ""}, 91 {"", 3, 0, 11, 134518268, 0, "", ""}, 92 {"", 3, 0, 12, 134518280, 0, "", ""}, 93 {"", 3, 0, 13, 134518284, 0, "", ""}, 94 {"", 3, 0, 14, 134518436, 0, "", ""}, 95 {"", 3, 0, 15, 134518444, 0, "", ""}, 96 {"", 3, 0, 16, 134518452, 0, "", ""}, 97 {"", 3, 0, 17, 134518456, 0, "", ""}, 98 {"", 3, 0, 18, 134518484, 0, "", ""}, 99 {"", 3, 0, 19, 0, 0, "", ""}, 100 {"", 3, 0, 20, 0, 0, "", ""}, 101 {"", 3, 0, 21, 0, 0, "", ""}, 102 {"", 3, 0, 22, 0, 0, "", ""}, 103 {"", 3, 0, 23, 0, 0, "", ""}, 104 {"", 3, 0, 24, 0, 0, "", ""}, 105 {"", 3, 0, 25, 0, 0, "", ""}, 106 {"", 3, 0, 26, 0, 0, "", ""}, 107 {"", 3, 0, 27, 0, 0, "", ""}, 108 {"", 3, 0, 28, 0, 0, "", ""}, 109 {"", 3, 0, 29, 0, 0, "", ""}, 110 {"crt1.c", 4, 0, 65521, 0, 0, "", ""}, 111 {"/usr/src/lib/csu/i386-elf/crti.S", 4, 0, 65521, 0, 0, "", ""}, 112 {"<command line>", 4, 0, 65521, 0, 0, "", ""}, 113 {"<built-in>", 4, 0, 65521, 0, 0, "", ""}, 114 {"/usr/src/lib/csu/i386-elf/crti.S", 4, 0, 65521, 0, 0, "", ""}, 115 {"crtstuff.c", 4, 0, 65521, 0, 0, "", ""}, 116 {"__CTOR_LIST__", 1, 0, 14, 134518436, 0, "", ""}, 117 {"__DTOR_LIST__", 1, 0, 15, 134518444, 0, "", ""}, 118 {"__EH_FRAME_BEGIN__", 1, 0, 12, 134518280, 0, "", ""}, 119 {"__JCR_LIST__", 1, 0, 16, 134518452, 0, "", ""}, 120 {"p.0", 1, 0, 11, 134518276, 0, "", ""}, 121 {"completed.1", 1, 0, 18, 134518484, 1, "", ""}, 122 {"__do_global_dtors_aux", 2, 0, 8, 134513760, 0, "", ""}, 123 {"object.2", 1, 0, 18, 134518488, 24, "", ""}, 124 {"frame_dummy", 2, 0, 8, 134513836, 0, "", ""}, 125 {"crtstuff.c", 4, 0, 65521, 0, 0, "", ""}, 126 {"__CTOR_END__", 1, 0, 14, 134518440, 0, "", ""}, 127 {"__DTOR_END__", 1, 0, 15, 134518448, 0, "", ""}, 128 {"__FRAME_END__", 1, 0, 12, 134518280, 0, "", ""}, 129 {"__JCR_END__", 1, 0, 16, 134518452, 0, "", ""}, 130 {"__do_global_ctors_aux", 2, 0, 8, 134513960, 0, "", ""}, 131 {"/usr/src/lib/csu/i386-elf/crtn.S", 4, 0, 65521, 0, 0, "", ""}, 132 {"<command line>", 4, 0, 65521, 0, 0, "", ""}, 133 {"<built-in>", 4, 0, 65521, 0, 0, "", ""}, 134 {"/usr/src/lib/csu/i386-elf/crtn.S", 4, 0, 65521, 0, 0, "", ""}, 135 {"hello.c", 4, 0, 65521, 0, 0, "", ""}, 136 {"printf", 18, 0, 0, 0, 44, "", ""}, 137 {"_DYNAMIC", 17, 0, 65521, 134518284, 0, "", ""}, 138 {"__dso_handle", 17, 2, 11, 134518272, 0, "", ""}, 139 {"_init", 18, 0, 6, 134513512, 0, "", ""}, 140 {"environ", 17, 0, 18, 134518512, 4, "", ""}, 141 {"__deregister_frame_info", 32, 0, 0, 0, 0, "", ""}, 142 {"__progname", 17, 0, 11, 134518268, 4, "", ""}, 143 {"_start", 18, 0, 8, 134513612, 145, "", ""}, 144 {"__bss_start", 16, 0, 65521, 134518484, 0, "", ""}, 145 {"main", 18, 0, 8, 134513912, 46, "", ""}, 146 {"_init_tls", 18, 0, 0, 0, 5, "", ""}, 147 {"_fini", 18, 0, 9, 134513996, 0, "", ""}, 148 {"atexit", 18, 0, 0, 0, 43, "", ""}, 149 {"_edata", 16, 0, 65521, 134518484, 0, "", ""}, 150 {"_GLOBAL_OFFSET_TABLE_", 17, 0, 65521, 134518456, 0, "", ""}, 151 {"_end", 16, 0, 65521, 134518516, 0, "", ""}, 152 {"exit", 18, 0, 0, 0, 68, "", ""}, 153 {"_Jv_RegisterClasses", 32, 0, 0, 0, 0, "", ""}, 154 {"__register_frame_info", 32, 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, 1, 4194816, 0, "", ""}, 212 {"", 3, 0, 2, 4194844, 0, "", ""}, 213 {"", 3, 0, 3, 4194880, 0, "", ""}, 214 {"", 3, 0, 4, 4194920, 0, "", ""}, 215 {"", 3, 0, 5, 4194952, 0, "", ""}, 216 {"", 3, 0, 6, 4195048, 0, "", ""}, 217 {"", 3, 0, 7, 4195110, 0, "", ""}, 218 {"", 3, 0, 8, 4195120, 0, "", ""}, 219 {"", 3, 0, 9, 4195152, 0, "", ""}, 220 {"", 3, 0, 10, 4195176, 0, "", ""}, 221 {"", 3, 0, 11, 4195224, 0, "", ""}, 222 {"", 3, 0, 12, 4195248, 0, "", ""}, 223 {"", 3, 0, 13, 4195296, 0, "", ""}, 224 {"", 3, 0, 14, 4195732, 0, "", ""}, 225 {"", 3, 0, 15, 4195748, 0, "", ""}, 226 {"", 3, 0, 16, 4195768, 0, "", ""}, 227 {"", 3, 0, 17, 4195808, 0, "", ""}, 228 {"", 3, 0, 18, 6293128, 0, "", ""}, 229 {"", 3, 0, 19, 6293144, 0, "", ""}, 230 {"", 3, 0, 20, 6293160, 0, "", ""}, 231 {"", 3, 0, 21, 6293168, 0, "", ""}, 232 {"", 3, 0, 22, 6293584, 0, "", ""}, 233 {"", 3, 0, 23, 6293592, 0, "", ""}, 234 {"", 3, 0, 24, 6293632, 0, "", ""}, 235 {"", 3, 0, 25, 6293656, 0, "", ""}, 236 {"", 3, 0, 26, 0, 0, "", ""}, 237 {"", 3, 0, 27, 0, 0, "", ""}, 238 {"", 3, 0, 28, 0, 0, "", ""}, 239 {"", 3, 0, 29, 0, 0, "", ""}, 240 {"", 3, 0, 30, 0, 0, "", ""}, 241 {"", 3, 0, 31, 0, 0, "", ""}, 242 {"", 3, 0, 32, 0, 0, "", ""}, 243 {"", 3, 0, 33, 0, 0, "", ""}, 244 {"init.c", 4, 0, 65521, 0, 0, "", ""}, 245 {"initfini.c", 4, 0, 65521, 0, 0, "", ""}, 246 {"call_gmon_start", 2, 0, 13, 4195340, 0, "", ""}, 247 {"crtstuff.c", 4, 0, 65521, 0, 0, "", ""}, 248 {"__CTOR_LIST__", 1, 0, 18, 6293128, 0, "", ""}, 249 {"__DTOR_LIST__", 1, 0, 19, 6293144, 0, "", ""}, 250 {"__JCR_LIST__", 1, 0, 20, 6293160, 0, "", ""}, 251 {"__do_global_dtors_aux", 2, 0, 13, 4195376, 0, "", ""}, 252 {"completed.6183", 1, 0, 25, 6293656, 1, "", ""}, 253 {"p.6181", 1, 0, 24, 6293648, 0, "", ""}, 254 {"frame_dummy", 2, 0, 13, 4195440, 0, "", ""}, 255 {"crtstuff.c", 4, 0, 65521, 0, 0, "", ""}, 256 {"__CTOR_END__", 1, 0, 18, 6293136, 0, "", ""}, 257 {"__DTOR_END__", 1, 0, 19, 6293152, 0, "", ""}, 258 {"__FRAME_END__", 1, 0, 17, 4195968, 0, "", ""}, 259 {"__JCR_END__", 1, 0, 20, 6293160, 0, "", ""}, 260 {"__do_global_ctors_aux", 2, 0, 13, 4195680, 0, "", ""}, 261 {"initfini.c", 4, 0, 65521, 0, 0, "", ""}, 262 {"hello.c", 4, 0, 65521, 0, 0, "", ""}, 263 {"_GLOBAL_OFFSET_TABLE_", 1, 2, 23, 6293592, 0, "", ""}, 264 {"__init_array_end", 0, 2, 18, 6293124, 0, "", ""}, 265 {"__init_array_start", 0, 2, 18, 6293124, 0, "", ""}, 266 {"_DYNAMIC", 1, 2, 21, 6293168, 0, "", ""}, 267 {"data_start", 32, 0, 24, 6293632, 0, "", ""}, 268 {"__libc_csu_fini", 18, 0, 13, 4195520, 2, "", ""}, 269 {"_start", 18, 0, 13, 4195296, 0, "", ""}, 270 {"__gmon_start__", 32, 0, 0, 0, 0, "", ""}, 271 {"_Jv_RegisterClasses", 32, 0, 0, 0, 0, "", ""}, 272 {"puts@@GLIBC_2.2.5", 18, 0, 0, 0, 396, "", ""}, 273 {"_fini", 18, 0, 14, 4195732, 0, "", ""}, 274 {"__libc_start_main@@GLIBC_2.2.5", 18, 0, 0, 0, 450, "", ""}, 275 {"_IO_stdin_used", 17, 0, 15, 4195748, 4, "", ""}, 276 {"__data_start", 16, 0, 24, 6293632, 0, "", ""}, 277 {"__dso_handle", 17, 2, 24, 6293640, 0, "", ""}, 278 {"__libc_csu_init", 18, 0, 13, 4195536, 137, "", ""}, 279 {"__bss_start", 16, 0, 65521, 6293656, 0, "", ""}, 280 {"_end", 16, 0, 65521, 6293664, 0, "", ""}, 281 {"_edata", 16, 0, 65521, 6293656, 0, "", ""}, 282 {"main", 18, 0, 13, 4195480, 27, "", ""}, 283 {"_init", 18, 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, 65521, 0, 0, "", ""}, 342 {"", 3, 0, 1, 0, 0, "", ""}, 343 {"", 3, 0, 3, 0, 0, "", ""}, 344 {"", 3, 0, 4, 0, 0, "", ""}, 345 {"", 3, 0, 5, 0, 0, "", ""}, 346 {"", 3, 0, 6, 0, 0, "", ""}, 347 {"", 3, 0, 8, 0, 0, "", ""}, 348 {"", 3, 0, 9, 0, 0, "", ""}, 349 {"", 3, 0, 11, 0, 0, "", ""}, 350 {"", 3, 0, 13, 0, 0, "", ""}, 351 {"", 3, 0, 15, 0, 0, "", ""}, 352 {"", 3, 0, 16, 0, 0, "", ""}, 353 {"", 3, 0, 14, 0, 0, "", ""}, 354 {"main", 18, 0, 1, 0, 23, "", ""}, 355 {"puts", 16, 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, 65521, 0, 0, "", ""}, 388 {"", 3, 0, 1, 0, 0, "", ""}, 389 {"", 3, 0, 3, 0, 0, "", ""}, 390 {"", 3, 0, 4, 0, 0, "", ""}, 391 {"", 3, 0, 5, 0, 0, "", ""}, 392 {"", 3, 0, 6, 0, 0, "", ""}, 393 {"", 3, 0, 8, 0, 0, "", ""}, 394 {"", 3, 0, 9, 0, 0, "", ""}, 395 {"", 3, 0, 11, 0, 0, "", ""}, 396 {"", 3, 0, 13, 0, 0, "", ""}, 397 {"", 3, 0, 15, 0, 0, "", ""}, 398 {"", 3, 0, 16, 0, 0, "", ""}, 399 {"", 3, 0, 14, 0, 0, "", ""}, 400 {"main", 18, 0, 1, 0, 27, "", ""}, 401 {"puts", 16, 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, 65521, 0, 0, "", ""}, 434 {"", 3, 0, 1, 0, 0, "", ""}, 435 {"", 3, 0, 3, 0, 0, "", ""}, 436 {"", 3, 0, 4, 0, 0, "", ""}, 437 {"", 3, 0, 5, 0, 0, "", ""}, 438 {"", 3, 0, 6, 0, 0, "", ""}, 439 {"", 3, 0, 8, 0, 0, "", ""}, 440 {"", 3, 0, 9, 0, 0, "", ""}, 441 {"", 3, 0, 11, 0, 0, "", ""}, 442 {"", 3, 0, 13, 0, 0, "", ""}, 443 {"", 3, 0, 15, 0, 0, "", ""}, 444 {"", 3, 0, 16, 0, 0, "", ""}, 445 {"", 3, 0, 14, 0, 0, "", ""}, 446 {"main", 18, 0, 1, 0, 44, "", ""}, 447 {"puts", 16, 0, 0, 0, 0, "", ""}, 448 }, 449 }, 450 } 451 452 func TestOpen(t *testing.T) { 453 for i := range fileTests { 454 tt := &fileTests[i] 455 456 var f *File 457 var err error 458 if path.Ext(tt.file) == ".gz" { 459 var r io.ReaderAt 460 if r, err = decompress(tt.file); err == nil { 461 f, err = NewFile(r) 462 } 463 } else { 464 f, err = Open(tt.file) 465 } 466 if err != nil { 467 t.Errorf("cannot open file %s: %v", tt.file, err) 468 continue 469 } 470 defer f.Close() 471 if f.FileHeader != tt.hdr { 472 t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr) 473 continue 474 } 475 for i, s := range f.Sections { 476 if i >= len(tt.sections) { 477 break 478 } 479 sh := tt.sections[i] 480 if s.SectionHeader != sh { 481 t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, s.SectionHeader, sh) 482 } 483 } 484 for i, p := range f.Progs { 485 if i >= len(tt.progs) { 486 break 487 } 488 ph := tt.progs[i] 489 if p.ProgHeader != ph { 490 t.Errorf("open %s, program %d:\n\thave %#v\n\twant %#v\n", tt.file, i, p.ProgHeader, ph) 491 } 492 } 493 tn := len(tt.sections) 494 fn := len(f.Sections) 495 if tn != fn { 496 t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn) 497 } 498 tn = len(tt.progs) 499 fn = len(f.Progs) 500 if tn != fn { 501 t.Errorf("open %s: len(Progs) = %d, want %d", tt.file, fn, tn) 502 } 503 tl := tt.needed 504 fl, err := f.ImportedLibraries() 505 if err != nil { 506 t.Error(err) 507 } 508 if !reflect.DeepEqual(tl, fl) { 509 t.Errorf("open %s: DT_NEEDED = %v, want %v", tt.file, tl, fl) 510 } 511 symbols, err := f.Symbols() 512 if tt.symbols == nil { 513 if !errors.Is(err, ErrNoSymbols) { 514 t.Errorf("open %s: Symbols() expected ErrNoSymbols, have nil", tt.file) 515 } 516 if symbols != nil { 517 t.Errorf("open %s: Symbols() expected no symbols, have %v", tt.file, symbols) 518 } 519 } else { 520 if err != nil { 521 t.Errorf("open %s: Symbols() unexpected error %v", tt.file, err) 522 } 523 if !slices.Equal(symbols, tt.symbols) { 524 t.Errorf("open %s: Symbols() = %v, want %v", tt.file, symbols, tt.symbols) 525 } 526 } 527 } 528 } 529 530 // elf.NewFile requires io.ReaderAt, which compress/gzip cannot 531 // provide. Decompress the file to a bytes.Reader. 532 func decompress(gz string) (io.ReaderAt, error) { 533 in, err := os.Open(gz) 534 if err != nil { 535 return nil, err 536 } 537 defer in.Close() 538 r, err := gzip.NewReader(in) 539 if err != nil { 540 return nil, err 541 } 542 var out bytes.Buffer 543 _, err = io.Copy(&out, r) 544 return bytes.NewReader(out.Bytes()), err 545 } 546 547 type relocationTestEntry struct { 548 entryNumber int 549 entry *dwarf.Entry 550 pcRanges [][2]uint64 551 } 552 553 type relocationTest struct { 554 file string 555 entries []relocationTestEntry 556 } 557 558 var relocationTests = []relocationTest{ 559 { 560 "testdata/go-relocation-test-gcc441-x86-64.obj", 561 []relocationTestEntry{ 562 { 563 entry: &dwarf.Entry{ 564 Offset: 0xb, 565 Tag: dwarf.TagCompileUnit, 566 Children: true, 567 Field: []dwarf.Field{ 568 {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString}, 569 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, 570 {Attr: dwarf.AttrName, Val: "go-relocation-test.c", Class: dwarf.ClassString}, 571 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 572 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 573 {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress}, 574 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 575 }, 576 }, 577 pcRanges: [][2]uint64{{0x0, 0x6}}, 578 }, 579 }, 580 }, 581 { 582 "testdata/go-relocation-test-gcc441-x86.obj", 583 []relocationTestEntry{ 584 { 585 entry: &dwarf.Entry{ 586 Offset: 0xb, 587 Tag: dwarf.TagCompileUnit, 588 Children: true, 589 Field: []dwarf.Field{ 590 {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString}, 591 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, 592 {Attr: dwarf.AttrName, Val: "t.c", Class: dwarf.ClassString}, 593 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 594 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 595 {Attr: dwarf.AttrHighpc, Val: uint64(0x5), Class: dwarf.ClassAddress}, 596 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 597 }, 598 }, 599 pcRanges: [][2]uint64{{0x0, 0x5}}, 600 }, 601 }, 602 }, 603 { 604 "testdata/go-relocation-test-gcc424-x86-64.obj", 605 []relocationTestEntry{ 606 { 607 entry: &dwarf.Entry{ 608 Offset: 0xb, 609 Tag: dwarf.TagCompileUnit, 610 Children: true, 611 Field: []dwarf.Field{ 612 {Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)", Class: dwarf.ClassString}, 613 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, 614 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c", Class: dwarf.ClassString}, 615 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 616 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 617 {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress}, 618 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 619 }, 620 }, 621 pcRanges: [][2]uint64{{0x0, 0x6}}, 622 }, 623 }, 624 }, 625 { 626 "testdata/go-relocation-test-gcc482-aarch64.obj", 627 []relocationTestEntry{ 628 { 629 entry: &dwarf.Entry{ 630 Offset: 0xb, 631 Tag: dwarf.TagCompileUnit, 632 Children: true, 633 Field: []dwarf.Field{ 634 {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -g -fstack-protector", Class: dwarf.ClassString}, 635 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, 636 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482.c", Class: dwarf.ClassString}, 637 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 638 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 639 {Attr: dwarf.AttrHighpc, Val: int64(0x24), Class: dwarf.ClassConstant}, 640 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 641 }, 642 }, 643 pcRanges: [][2]uint64{{0x0, 0x24}}, 644 }, 645 }, 646 }, 647 { 648 "testdata/go-relocation-test-gcc492-arm.obj", 649 []relocationTestEntry{ 650 { 651 entry: &dwarf.Entry{ 652 Offset: 0xb, 653 Tag: dwarf.TagCompileUnit, 654 Children: true, 655 Field: []dwarf.Field{ 656 {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}, 657 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, 658 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc492.c", Class: dwarf.ClassString}, 659 {Attr: dwarf.AttrCompDir, Val: "/root/go/src/debug/elf/testdata", Class: dwarf.ClassString}, 660 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 661 {Attr: dwarf.AttrHighpc, Val: int64(0x28), Class: dwarf.ClassConstant}, 662 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 663 }, 664 }, 665 pcRanges: [][2]uint64{{0x0, 0x28}}, 666 }, 667 }, 668 }, 669 { 670 "testdata/go-relocation-test-clang-arm.obj", 671 []relocationTestEntry{ 672 { 673 entry: &dwarf.Entry{ 674 Offset: 0xb, 675 Tag: dwarf.TagCompileUnit, 676 Children: true, 677 Field: []dwarf.Field{ 678 {Attr: dwarf.AttrProducer, Val: "Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)", Class: dwarf.ClassString}, 679 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, 680 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, 681 {Attr: dwarf.AttrStmtList, Val: int64(0x0), Class: dwarf.ClassLinePtr}, 682 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 683 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 684 {Attr: dwarf.AttrHighpc, Val: int64(0x30), Class: dwarf.ClassConstant}, 685 }, 686 }, 687 pcRanges: [][2]uint64{{0x0, 0x30}}, 688 }, 689 }, 690 }, 691 { 692 "testdata/go-relocation-test-gcc5-ppc.obj", 693 []relocationTestEntry{ 694 { 695 entry: &dwarf.Entry{ 696 Offset: 0xb, 697 Tag: dwarf.TagCompileUnit, 698 Children: true, 699 Field: []dwarf.Field{ 700 {Attr: dwarf.AttrProducer, Val: "GNU C11 5.0.0 20150116 (experimental) -Asystem=linux -Asystem=unix -Asystem=posix -g", Class: dwarf.ClassString}, 701 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, 702 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc5-ppc.c", Class: dwarf.ClassString}, 703 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 704 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 705 {Attr: dwarf.AttrHighpc, Val: int64(0x44), Class: dwarf.ClassConstant}, 706 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 707 }, 708 }, 709 pcRanges: [][2]uint64{{0x0, 0x44}}, 710 }, 711 }, 712 }, 713 { 714 "testdata/go-relocation-test-gcc482-ppc64le.obj", 715 []relocationTestEntry{ 716 { 717 entry: &dwarf.Entry{ 718 Offset: 0xb, 719 Tag: dwarf.TagCompileUnit, 720 Children: true, 721 Field: []dwarf.Field{ 722 {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}, 723 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, 724 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482-ppc64le.c", Class: dwarf.ClassString}, 725 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 726 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 727 {Attr: dwarf.AttrHighpc, Val: uint64(0x24), Class: dwarf.ClassAddress}, 728 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 729 }, 730 }, 731 pcRanges: [][2]uint64{{0x0, 0x24}}, 732 }, 733 }, 734 }, 735 { 736 "testdata/go-relocation-test-gcc492-mips64.obj", 737 []relocationTestEntry{ 738 { 739 entry: &dwarf.Entry{ 740 Offset: 0xb, 741 Tag: dwarf.TagCompileUnit, 742 Children: true, 743 Field: []dwarf.Field{ 744 {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -meb -mabi=64 -march=mips3 -mtune=mips64 -mllsc -mno-shared -g", Class: dwarf.ClassString}, 745 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, 746 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, 747 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 748 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 749 {Attr: dwarf.AttrHighpc, Val: int64(0x64), Class: dwarf.ClassConstant}, 750 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 751 }, 752 }, 753 pcRanges: [][2]uint64{{0x0, 0x64}}, 754 }, 755 }, 756 }, 757 { 758 "testdata/go-relocation-test-gcc531-s390x.obj", 759 []relocationTestEntry{ 760 { 761 entry: &dwarf.Entry{ 762 Offset: 0xb, 763 Tag: dwarf.TagCompileUnit, 764 Children: true, 765 Field: []dwarf.Field{ 766 {Attr: dwarf.AttrProducer, Val: "GNU C11 5.3.1 20160316 -march=zEC12 -m64 -mzarch -g -fstack-protector-strong", Class: dwarf.ClassString}, 767 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, 768 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, 769 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 770 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 771 {Attr: dwarf.AttrHighpc, Val: int64(0x3a), Class: dwarf.ClassConstant}, 772 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 773 }, 774 }, 775 pcRanges: [][2]uint64{{0x0, 0x3a}}, 776 }, 777 }, 778 }, 779 { 780 "testdata/go-relocation-test-gcc620-sparc64.obj", 781 []relocationTestEntry{ 782 { 783 entry: &dwarf.Entry{ 784 Offset: 0xb, 785 Tag: dwarf.TagCompileUnit, 786 Children: true, 787 Field: []dwarf.Field{ 788 {Attr: dwarf.AttrProducer, Val: "GNU C11 6.2.0 20160914 -mcpu=v9 -g -fstack-protector-strong", Class: dwarf.ClassString}, 789 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, 790 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, 791 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 792 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 793 {Attr: dwarf.AttrHighpc, Val: int64(0x2c), Class: dwarf.ClassConstant}, 794 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 795 }, 796 }, 797 pcRanges: [][2]uint64{{0x0, 0x2c}}, 798 }, 799 }, 800 }, 801 { 802 "testdata/go-relocation-test-gcc492-mipsle.obj", 803 []relocationTestEntry{ 804 { 805 entry: &dwarf.Entry{ 806 Offset: 0xb, 807 Tag: dwarf.TagCompileUnit, 808 Children: true, 809 Field: []dwarf.Field{ 810 {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -mel -march=mips2 -mtune=mips32 -mllsc -mno-shared -mabi=32 -g", Class: dwarf.ClassString}, 811 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, 812 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, 813 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 814 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 815 {Attr: dwarf.AttrHighpc, Val: int64(0x58), Class: dwarf.ClassConstant}, 816 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 817 }, 818 }, 819 pcRanges: [][2]uint64{{0x0, 0x58}}, 820 }, 821 }, 822 }, 823 { 824 "testdata/go-relocation-test-gcc540-mips.obj", 825 []relocationTestEntry{ 826 { 827 entry: &dwarf.Entry{ 828 Offset: 0xb, 829 Tag: dwarf.TagCompileUnit, 830 Children: true, 831 Field: []dwarf.Field{ 832 {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}, 833 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, 834 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, 835 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 836 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 837 {Attr: dwarf.AttrHighpc, Val: uint64(0x5c), Class: dwarf.ClassAddress}, 838 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 839 }, 840 }, 841 pcRanges: [][2]uint64{{0x0, 0x5c}}, 842 }, 843 }, 844 }, 845 { 846 "testdata/go-relocation-test-gcc493-mips64le.obj", 847 []relocationTestEntry{ 848 { 849 entry: &dwarf.Entry{ 850 Offset: 0xb, 851 Tag: dwarf.TagCompileUnit, 852 Children: true, 853 Field: []dwarf.Field{ 854 {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.3 -mel -mabi=64 -mllsc -mno-shared -g -fstack-protector-strong", Class: dwarf.ClassString}, 855 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, 856 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, 857 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 858 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 859 {Attr: dwarf.AttrHighpc, Val: int64(0x64), Class: dwarf.ClassConstant}, 860 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 861 }, 862 }, 863 pcRanges: [][2]uint64{{0x0, 0x64}}, 864 }, 865 }, 866 }, 867 { 868 "testdata/go-relocation-test-gcc720-riscv64.obj", 869 []relocationTestEntry{ 870 { 871 entry: &dwarf.Entry{ 872 Offset: 0xb, 873 Tag: dwarf.TagCompileUnit, 874 Children: true, 875 Field: []dwarf.Field{ 876 {Attr: dwarf.AttrProducer, Val: "GNU C11 7.2.0 -march=rv64imafdc -mabi=lp64d -g -gdwarf-2", Class: dwarf.ClassString}, 877 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, 878 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, 879 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 880 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 881 {Attr: dwarf.AttrHighpc, Val: uint64(0x2c), Class: dwarf.ClassAddress}, 882 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 883 }, 884 }, 885 pcRanges: [][2]uint64{{0x0, 0x2c}}, 886 }, 887 }, 888 }, 889 { 890 "testdata/go-relocation-test-clang-x86.obj", 891 []relocationTestEntry{ 892 { 893 entry: &dwarf.Entry{ 894 Offset: 0xb, 895 Tag: dwarf.TagCompileUnit, 896 Children: true, 897 Field: []dwarf.Field{ 898 {Attr: dwarf.AttrProducer, Val: "clang version google3-trunk (trunk r209387)", Class: dwarf.ClassString}, 899 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, 900 {Attr: dwarf.AttrName, Val: "go-relocation-test-clang.c", Class: dwarf.ClassString}, 901 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 902 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 903 }, 904 }, 905 }, 906 }, 907 }, 908 { 909 "testdata/gcc-amd64-openbsd-debug-with-rela.obj", 910 []relocationTestEntry{ 911 { 912 entryNumber: 203, 913 entry: &dwarf.Entry{ 914 Offset: 0xc62, 915 Tag: dwarf.TagMember, 916 Children: false, 917 Field: []dwarf.Field{ 918 {Attr: dwarf.AttrName, Val: "it_interval", Class: dwarf.ClassString}, 919 {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant}, 920 {Attr: dwarf.AttrDeclLine, Val: int64(236), Class: dwarf.ClassConstant}, 921 {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference}, 922 {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}, Class: dwarf.ClassExprLoc}, 923 }, 924 }, 925 }, 926 { 927 entryNumber: 204, 928 entry: &dwarf.Entry{ 929 Offset: 0xc70, 930 Tag: dwarf.TagMember, 931 Children: false, 932 Field: []dwarf.Field{ 933 {Attr: dwarf.AttrName, Val: "it_value", Class: dwarf.ClassString}, 934 {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant}, 935 {Attr: dwarf.AttrDeclLine, Val: int64(237), Class: dwarf.ClassConstant}, 936 {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference}, 937 {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}, Class: dwarf.ClassExprLoc}, 938 }, 939 }, 940 }, 941 }, 942 }, 943 { 944 "testdata/go-relocation-test-gcc930-ranges-no-rela-x86-64", 945 []relocationTestEntry{ 946 { 947 entry: &dwarf.Entry{ 948 Offset: 0xb, 949 Tag: dwarf.TagCompileUnit, 950 Children: true, 951 Field: []dwarf.Field{ 952 {Attr: dwarf.AttrProducer, Val: "GNU C17 9.3.0 -mtune=generic -march=x86-64 -g -fno-asynchronous-unwind-tables", Class: dwarf.ClassString}, 953 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, 954 {Attr: dwarf.AttrName, Val: "multiple-code-sections.c", Class: dwarf.ClassString}, 955 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 956 {Attr: dwarf.AttrRanges, Val: int64(0), Class: dwarf.ClassRangeListPtr}, 957 {Attr: dwarf.AttrLowpc, Val: uint64(0), Class: dwarf.ClassAddress}, 958 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 959 }, 960 }, 961 pcRanges: [][2]uint64{ 962 {0x765, 0x777}, 963 {0x7e1, 0x7ec}, 964 }, 965 }, 966 }, 967 }, 968 { 969 "testdata/go-relocation-test-gcc930-ranges-with-rela-x86-64", 970 []relocationTestEntry{ 971 { 972 entry: &dwarf.Entry{ 973 Offset: 0xb, 974 Tag: dwarf.TagCompileUnit, 975 Children: true, 976 Field: []dwarf.Field{ 977 {Attr: dwarf.AttrProducer, Val: "GNU C17 9.3.0 -mtune=generic -march=x86-64 -g -fno-asynchronous-unwind-tables", Class: dwarf.ClassString}, 978 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, 979 {Attr: dwarf.AttrName, Val: "multiple-code-sections.c", Class: dwarf.ClassString}, 980 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 981 {Attr: dwarf.AttrRanges, Val: int64(0), Class: dwarf.ClassRangeListPtr}, 982 {Attr: dwarf.AttrLowpc, Val: uint64(0), Class: dwarf.ClassAddress}, 983 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 984 }, 985 }, 986 pcRanges: [][2]uint64{ 987 {0x765, 0x777}, 988 {0x7e1, 0x7ec}, 989 }, 990 }, 991 }, 992 }, 993 } 994 995 func TestDWARFRelocations(t *testing.T) { 996 for _, test := range relocationTests { 997 test := test 998 t.Run(test.file, func(t *testing.T) { 999 t.Parallel() 1000 f, err := Open(test.file) 1001 if err != nil { 1002 t.Fatal(err) 1003 } 1004 dwarf, err := f.DWARF() 1005 if err != nil { 1006 t.Fatal(err) 1007 } 1008 reader := dwarf.Reader() 1009 idx := 0 1010 for _, testEntry := range test.entries { 1011 if testEntry.entryNumber < idx { 1012 t.Fatalf("internal test error: %d < %d", testEntry.entryNumber, idx) 1013 } 1014 for ; idx < testEntry.entryNumber; idx++ { 1015 entry, err := reader.Next() 1016 if entry == nil || err != nil { 1017 t.Fatalf("Failed to skip to entry %d: %v", testEntry.entryNumber, err) 1018 } 1019 } 1020 entry, err := reader.Next() 1021 idx++ 1022 if err != nil { 1023 t.Fatal(err) 1024 } 1025 if !reflect.DeepEqual(testEntry.entry, entry) { 1026 t.Errorf("entry %d mismatch: got:%#v want:%#v", testEntry.entryNumber, entry, testEntry.entry) 1027 } 1028 pcRanges, err := dwarf.Ranges(entry) 1029 if err != nil { 1030 t.Fatal(err) 1031 } 1032 if !reflect.DeepEqual(testEntry.pcRanges, pcRanges) { 1033 t.Errorf("entry %d: PC range mismatch: got:%#v want:%#v", testEntry.entryNumber, pcRanges, testEntry.pcRanges) 1034 } 1035 } 1036 }) 1037 } 1038 } 1039 1040 func TestCompressedDWARF(t *testing.T) { 1041 // Test file built with GCC 4.8.4 and as 2.24 using: 1042 // gcc -Wa,--compress-debug-sections -g -c -o zdebug-test-gcc484-x86-64.obj hello.c 1043 f, err := Open("testdata/zdebug-test-gcc484-x86-64.obj") 1044 if err != nil { 1045 t.Fatal(err) 1046 } 1047 dwarf, err := f.DWARF() 1048 if err != nil { 1049 t.Fatal(err) 1050 } 1051 reader := dwarf.Reader() 1052 n := 0 1053 for { 1054 entry, err := reader.Next() 1055 if err != nil { 1056 t.Fatal(err) 1057 } 1058 if entry == nil { 1059 break 1060 } 1061 n++ 1062 } 1063 if n != 18 { 1064 t.Fatalf("want %d DWARF entries, got %d", 18, n) 1065 } 1066 } 1067 1068 func TestCompressedSection(t *testing.T) { 1069 // Test files built with gcc -g -S hello.c and assembled with 1070 // --compress-debug-sections=zlib-gabi. 1071 f, err := Open("testdata/compressed-64.obj") 1072 if err != nil { 1073 t.Fatal(err) 1074 } 1075 sec := f.Section(".debug_info") 1076 wantData := []byte{ 1077 182, 0, 0, 0, 4, 0, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0, 1078 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1079 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 7, 1080 0, 0, 0, 0, 2, 1, 8, 0, 0, 0, 0, 2, 2, 7, 0, 0, 1081 0, 0, 2, 4, 7, 0, 0, 0, 0, 2, 1, 6, 0, 0, 0, 0, 1082 2, 2, 5, 0, 0, 0, 0, 3, 4, 5, 105, 110, 116, 0, 2, 8, 1083 5, 0, 0, 0, 0, 2, 8, 7, 0, 0, 0, 0, 4, 8, 114, 0, 1084 0, 0, 2, 1, 6, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 4, 1085 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 1086 1, 156, 179, 0, 0, 0, 6, 0, 0, 0, 0, 1, 4, 87, 0, 0, 1087 0, 2, 145, 108, 6, 0, 0, 0, 0, 1, 4, 179, 0, 0, 0, 2, 1088 145, 96, 0, 4, 8, 108, 0, 0, 0, 0, 1089 } 1090 1091 // Test Data method. 1092 b, err := sec.Data() 1093 if err != nil { 1094 t.Fatal(err) 1095 } 1096 if !bytes.Equal(wantData, b) { 1097 t.Fatalf("want data %x, got %x", wantData, b) 1098 } 1099 1100 // Test Open method and seeking. 1101 buf, have, count := make([]byte, len(b)), make([]bool, len(b)), 0 1102 sf := sec.Open() 1103 if got, err := sf.Seek(0, io.SeekEnd); got != int64(len(b)) || err != nil { 1104 t.Fatalf("want seek end %d, got %d error %v", len(b), got, err) 1105 } 1106 if n, err := sf.Read(buf); n != 0 || err != io.EOF { 1107 t.Fatalf("want EOF with 0 bytes, got %v with %d bytes", err, n) 1108 } 1109 pos := int64(len(buf)) 1110 for count < len(buf) { 1111 // Construct random seek arguments. 1112 whence := rand.Intn(3) 1113 target := rand.Int63n(int64(len(buf))) 1114 var offset int64 1115 switch whence { 1116 case io.SeekStart: 1117 offset = target 1118 case io.SeekCurrent: 1119 offset = target - pos 1120 case io.SeekEnd: 1121 offset = target - int64(len(buf)) 1122 } 1123 pos, err = sf.Seek(offset, whence) 1124 if err != nil { 1125 t.Fatal(err) 1126 } 1127 if pos != target { 1128 t.Fatalf("want position %d, got %d", target, pos) 1129 } 1130 1131 // Read data from the new position. 1132 end := pos + 16 1133 if end > int64(len(buf)) { 1134 end = int64(len(buf)) 1135 } 1136 n, err := io.ReadFull(sf, buf[pos:end]) 1137 if err != nil { 1138 t.Fatal(err) 1139 } 1140 for i := 0; i < n; i++ { 1141 if !have[pos] { 1142 have[pos] = true 1143 count++ 1144 } 1145 pos++ 1146 } 1147 } 1148 if !bytes.Equal(wantData, buf) { 1149 t.Fatalf("want data %x, got %x", wantData, buf) 1150 } 1151 } 1152 1153 func TestNoSectionOverlaps(t *testing.T) { 1154 // Ensure cmd/link outputs sections without overlaps. 1155 switch runtime.GOOS { 1156 case "aix", "android", "darwin", "ios", "js", "plan9", "windows", "wasip1": 1157 t.Skipf("cmd/link doesn't produce ELF binaries on %s", runtime.GOOS) 1158 } 1159 _ = net.ResolveIPAddr // force dynamic linkage 1160 f, err := Open(os.Args[0]) 1161 if err != nil { 1162 t.Error(err) 1163 return 1164 } 1165 for i, si := range f.Sections { 1166 sih := si.SectionHeader 1167 if sih.Type == SHT_NOBITS { 1168 continue 1169 } 1170 // checking for overlap in file 1171 for j, sj := range f.Sections { 1172 sjh := sj.SectionHeader 1173 if i == j || sjh.Type == SHT_NOBITS || sih.Offset == sjh.Offset && sih.FileSize == 0 { 1174 continue 1175 } 1176 if sih.Offset >= sjh.Offset && sih.Offset < sjh.Offset+sjh.FileSize { 1177 t.Errorf("ld produced ELF with section offset %s within %s: 0x%x <= 0x%x..0x%x < 0x%x", 1178 sih.Name, sjh.Name, sjh.Offset, sih.Offset, sih.Offset+sih.FileSize, sjh.Offset+sjh.FileSize) 1179 } 1180 } 1181 1182 if sih.Flags&SHF_ALLOC == 0 { 1183 continue 1184 } 1185 1186 // checking for overlap in address space 1187 for j, sj := range f.Sections { 1188 sjh := sj.SectionHeader 1189 if i == j || sjh.Flags&SHF_ALLOC == 0 || sjh.Type == SHT_NOBITS || 1190 sih.Addr == sjh.Addr && sih.Size == 0 { 1191 continue 1192 } 1193 if sih.Addr >= sjh.Addr && sih.Addr < sjh.Addr+sjh.Size { 1194 t.Errorf("ld produced ELF with section address %s within %s: 0x%x <= 0x%x..0x%x < 0x%x", 1195 sih.Name, sjh.Name, sjh.Addr, sih.Addr, sih.Addr+sih.Size, sjh.Addr+sjh.Size) 1196 } 1197 } 1198 } 1199 } 1200 1201 func TestNobitsSection(t *testing.T) { 1202 const testdata = "testdata/gcc-amd64-linux-exec" 1203 f, err := Open(testdata) 1204 if err != nil { 1205 t.Fatalf("could not read %s: %v", testdata, err) 1206 } 1207 defer f.Close() 1208 1209 wantError := "unexpected read from SHT_NOBITS section" 1210 bss := f.Section(".bss") 1211 1212 _, err = bss.Data() 1213 if err == nil || err.Error() != wantError { 1214 t.Fatalf("bss.Data() got error %q, want error %q", err, wantError) 1215 } 1216 1217 r := bss.Open() 1218 p := make([]byte, 1) 1219 _, err = r.Read(p) 1220 if err == nil || err.Error() != wantError { 1221 t.Fatalf("r.Read(p) got error %q, want error %q", err, wantError) 1222 } 1223 } 1224 1225 // TestLargeNumberOfSections tests the case that a file has greater than or 1226 // equal to 65280 (0xff00) sections. 1227 func TestLargeNumberOfSections(t *testing.T) { 1228 // A file with >= 0xff00 sections is too big, so we will construct it on the 1229 // fly. The original file "y.o" is generated by these commands: 1230 // 1. generate "y.c": 1231 // for i in `seq 1 65288`; do 1232 // printf -v x "%04x" i; 1233 // echo "int var_$x __attribute__((section(\"section_$x\"))) = $i;" 1234 // done > y.c 1235 // 2. compile: gcc -c y.c -m32 1236 // 1237 // $readelf -h y.o 1238 // ELF Header: 1239 // Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 1240 // Class: ELF32 1241 // Data: 2's complement, little endian 1242 // Version: 1 (current) 1243 // OS/ABI: UNIX - System V 1244 // ABI Version: 0 1245 // Type: REL (Relocatable file) 1246 // Machine: Intel 80386 1247 // Version: 0x1 1248 // Entry point address: 0x0 1249 // Start of program headers: 0 (bytes into file) 1250 // Start of section headers: 3003468 (bytes into file) 1251 // Flags: 0x0 1252 // Size of this header: 52 (bytes) 1253 // Size of program headers: 0 (bytes) 1254 // Number of program headers: 0 1255 // Size of section headers: 40 (bytes) 1256 // Number of section headers: 0 (65298) 1257 // Section header string table index: 65535 (65297) 1258 // 1259 // $readelf -S y.o 1260 // There are 65298 section headers, starting at offset 0x2dd44c: 1261 // Section Headers: 1262 // [Nr] Name Type Addr Off Size ES Flg Lk Inf Al 1263 // [ 0] NULL 00000000 000000 00ff12 00 65297 0 0 1264 // [ 1] .text PROGBITS 00000000 000034 000000 00 AX 0 0 1 1265 // [ 2] .data PROGBITS 00000000 000034 000000 00 WA 0 0 1 1266 // [ 3] .bss NOBITS 00000000 000034 000000 00 WA 0 0 1 1267 // [ 4] section_0001 PROGBITS 00000000 000034 000004 00 WA 0 0 4 1268 // [ 5] section_0002 PROGBITS 00000000 000038 000004 00 WA 0 0 4 1269 // [ section_0003 ~ section_ff06 truncated ] 1270 // [65290] section_ff07 PROGBITS 00000000 03fc4c 000004 00 WA 0 0 4 1271 // [65291] section_ff08 PROGBITS 00000000 03fc50 000004 00 WA 0 0 4 1272 // [65292] .comment PROGBITS 00000000 03fc54 000027 01 MS 0 0 1 1273 // [65293] .note.GNU-stack PROGBITS 00000000 03fc7b 000000 00 0 0 1 1274 // [65294] .symtab SYMTAB 00000000 03fc7c 0ff0a0 10 65296 2 4 1275 // [65295] .symtab_shndx SYMTAB SECTION 00000000 13ed1c 03fc28 04 65294 0 4 1276 // [65296] .strtab STRTAB 00000000 17e944 08f74d 00 0 0 1 1277 // [65297] .shstrtab STRTAB 00000000 20e091 0cf3bb 00 0 0 1 1278 1279 var buf bytes.Buffer 1280 1281 { 1282 buf.Grow(0x55AF1C) // 3003468 + 40 * 65298 1283 1284 h := Header32{ 1285 Ident: [16]byte{0x7F, 'E', 'L', 'F', 0x01, 0x01, 0x01}, 1286 Type: 1, 1287 Machine: 3, 1288 Version: 1, 1289 Shoff: 0x2DD44C, 1290 Ehsize: 0x34, 1291 Shentsize: 0x28, 1292 Shnum: 0, 1293 Shstrndx: 0xFFFF, 1294 } 1295 binary.Write(&buf, binary.LittleEndian, h) 1296 1297 // Zero out sections [1]~[65294]. 1298 buf.Write(bytes.Repeat([]byte{0}, 0x13ED1C-binary.Size(h))) 1299 1300 // Write section [65295]. Section [65295] are all zeros except for the 1301 // last 48 bytes. 1302 buf.Write(bytes.Repeat([]byte{0}, 0x03FC28-12*4)) 1303 for i := 0; i < 12; i++ { 1304 binary.Write(&buf, binary.LittleEndian, uint32(0xFF00|i)) 1305 } 1306 1307 // Write section [65296]. 1308 buf.Write([]byte{0}) 1309 buf.Write([]byte("y.c\x00")) 1310 for i := 1; i <= 65288; i++ { 1311 // var_0001 ~ var_ff08 1312 name := fmt.Sprintf("var_%04x", i) 1313 buf.Write([]byte(name)) 1314 buf.Write([]byte{0}) 1315 } 1316 1317 // Write section [65297]. 1318 buf.Write([]byte{0}) 1319 buf.Write([]byte(".symtab\x00")) 1320 buf.Write([]byte(".strtab\x00")) 1321 buf.Write([]byte(".shstrtab\x00")) 1322 buf.Write([]byte(".text\x00")) 1323 buf.Write([]byte(".data\x00")) 1324 buf.Write([]byte(".bss\x00")) 1325 for i := 1; i <= 65288; i++ { 1326 // s_0001 ~ s_ff08 1327 name := fmt.Sprintf("section_%04x", i) 1328 buf.Write([]byte(name)) 1329 buf.Write([]byte{0}) 1330 } 1331 buf.Write([]byte(".comment\x00")) 1332 buf.Write([]byte(".note.GNU-stack\x00")) 1333 buf.Write([]byte(".symtab_shndx\x00")) 1334 1335 // Write section header table. 1336 // NULL 1337 binary.Write(&buf, binary.LittleEndian, Section32{Name: 0, Size: 0xFF12, Link: 0xFF11}) 1338 // .text 1339 binary.Write(&buf, binary.LittleEndian, Section32{ 1340 Name: 0x1B, 1341 Type: uint32(SHT_PROGBITS), 1342 Flags: uint32(SHF_ALLOC | SHF_EXECINSTR), 1343 Off: 0x34, 1344 Addralign: 0x01, 1345 }) 1346 // .data 1347 binary.Write(&buf, binary.LittleEndian, Section32{ 1348 Name: 0x21, 1349 Type: uint32(SHT_PROGBITS), 1350 Flags: uint32(SHF_WRITE | SHF_ALLOC), 1351 Off: 0x34, 1352 Addralign: 0x01, 1353 }) 1354 // .bss 1355 binary.Write(&buf, binary.LittleEndian, Section32{ 1356 Name: 0x27, 1357 Type: uint32(SHT_NOBITS), 1358 Flags: uint32(SHF_WRITE | SHF_ALLOC), 1359 Off: 0x34, 1360 Addralign: 0x01, 1361 }) 1362 // s_1 ~ s_65537 1363 for i := 0; i < 65288; i++ { 1364 s := Section32{ 1365 Name: uint32(0x2C + i*13), 1366 Type: uint32(SHT_PROGBITS), 1367 Flags: uint32(SHF_WRITE | SHF_ALLOC), 1368 Off: uint32(0x34 + i*4), 1369 Size: 0x04, 1370 Addralign: 0x04, 1371 } 1372 binary.Write(&buf, binary.LittleEndian, s) 1373 } 1374 // .comment 1375 binary.Write(&buf, binary.LittleEndian, Section32{ 1376 Name: 0x0CF394, 1377 Type: uint32(SHT_PROGBITS), 1378 Flags: uint32(SHF_MERGE | SHF_STRINGS), 1379 Off: 0x03FC54, 1380 Size: 0x27, 1381 Addralign: 0x01, 1382 Entsize: 0x01, 1383 }) 1384 // .note.GNU-stack 1385 binary.Write(&buf, binary.LittleEndian, Section32{ 1386 Name: 0x0CF39D, 1387 Type: uint32(SHT_PROGBITS), 1388 Off: 0x03FC7B, 1389 Addralign: 0x01, 1390 }) 1391 // .symtab 1392 binary.Write(&buf, binary.LittleEndian, Section32{ 1393 Name: 0x01, 1394 Type: uint32(SHT_SYMTAB), 1395 Off: 0x03FC7C, 1396 Size: 0x0FF0A0, 1397 Link: 0xFF10, 1398 Info: 0x02, 1399 Addralign: 0x04, 1400 Entsize: 0x10, 1401 }) 1402 // .symtab_shndx 1403 binary.Write(&buf, binary.LittleEndian, Section32{ 1404 Name: 0x0CF3AD, 1405 Type: uint32(SHT_SYMTAB_SHNDX), 1406 Off: 0x13ED1C, 1407 Size: 0x03FC28, 1408 Link: 0xFF0E, 1409 Addralign: 0x04, 1410 Entsize: 0x04, 1411 }) 1412 // .strtab 1413 binary.Write(&buf, binary.LittleEndian, Section32{ 1414 Name: 0x09, 1415 Type: uint32(SHT_STRTAB), 1416 Off: 0x17E944, 1417 Size: 0x08F74D, 1418 Addralign: 0x01, 1419 }) 1420 // .shstrtab 1421 binary.Write(&buf, binary.LittleEndian, Section32{ 1422 Name: 0x11, 1423 Type: uint32(SHT_STRTAB), 1424 Off: 0x20E091, 1425 Size: 0x0CF3BB, 1426 Addralign: 0x01, 1427 }) 1428 } 1429 1430 data := buf.Bytes() 1431 1432 f, err := NewFile(bytes.NewReader(data)) 1433 if err != nil { 1434 t.Errorf("cannot create file from data: %v", err) 1435 } 1436 defer f.Close() 1437 1438 wantFileHeader := FileHeader{ 1439 Class: ELFCLASS32, 1440 Data: ELFDATA2LSB, 1441 Version: EV_CURRENT, 1442 OSABI: ELFOSABI_NONE, 1443 ByteOrder: binary.LittleEndian, 1444 Type: ET_REL, 1445 Machine: EM_386, 1446 } 1447 if f.FileHeader != wantFileHeader { 1448 t.Errorf("\nhave %#v\nwant %#v\n", f.FileHeader, wantFileHeader) 1449 } 1450 1451 wantSectionNum := 65298 1452 if len(f.Sections) != wantSectionNum { 1453 t.Errorf("len(Sections) = %d, want %d", len(f.Sections), wantSectionNum) 1454 } 1455 1456 wantSectionHeader := SectionHeader{ 1457 Name: "section_0007", 1458 Type: SHT_PROGBITS, 1459 Flags: SHF_WRITE + SHF_ALLOC, 1460 Offset: 0x4c, 1461 Size: 0x4, 1462 Addralign: 0x4, 1463 FileSize: 0x4, 1464 } 1465 if f.Sections[10].SectionHeader != wantSectionHeader { 1466 t.Errorf("\nhave %#v\nwant %#v\n", f.Sections[10].SectionHeader, wantSectionHeader) 1467 } 1468 } 1469 1470 func TestIssue10996(t *testing.T) { 1471 data := []byte("\u007fELF\x02\x01\x010000000000000" + 1472 "\x010000000000000000000" + 1473 "\x00\x00\x00\x00\x00\x00\x00\x0000000000\x00\x00\x00\x00" + 1474 "0000") 1475 _, err := NewFile(bytes.NewReader(data)) 1476 if err == nil { 1477 t.Fatalf("opening invalid ELF file unexpectedly succeeded") 1478 } 1479 } 1480 1481 func TestDynValue(t *testing.T) { 1482 const testdata = "testdata/gcc-amd64-linux-exec" 1483 f, err := Open(testdata) 1484 if err != nil { 1485 t.Fatalf("could not read %s: %v", testdata, err) 1486 } 1487 defer f.Close() 1488 1489 vals, err := f.DynValue(DT_VERNEEDNUM) 1490 if err != nil { 1491 t.Fatalf("DynValue(DT_VERNEEDNUM): got unexpected error %v", err) 1492 } 1493 1494 if len(vals) != 1 || vals[0] != 1 { 1495 t.Errorf("DynValue(DT_VERNEEDNUM): got %v, want [1]", vals) 1496 } 1497 } 1498 1499 func TestIssue59208(t *testing.T) { 1500 // corrupted dwarf data should raise invalid dwarf data instead of invalid zlib 1501 const orig = "testdata/compressed-64.obj" 1502 f, err := Open(orig) 1503 if err != nil { 1504 t.Fatal(err) 1505 } 1506 sec := f.Section(".debug_info") 1507 1508 data, err := os.ReadFile(orig) 1509 if err != nil { 1510 t.Fatal(err) 1511 } 1512 1513 dn := make([]byte, len(data)) 1514 zoffset := sec.Offset + uint64(sec.compressionOffset) 1515 copy(dn, data[:zoffset]) 1516 1517 ozd, err := sec.Data() 1518 if err != nil { 1519 t.Fatal(err) 1520 } 1521 buf := bytes.NewBuffer(nil) 1522 wr := zlib.NewWriter(buf) 1523 // corrupt origin data same as COMPRESS_ZLIB 1524 copy(ozd, []byte{1, 0, 0, 0}) 1525 wr.Write(ozd) 1526 wr.Close() 1527 1528 copy(dn[zoffset:], buf.Bytes()) 1529 copy(dn[sec.Offset+sec.FileSize:], data[sec.Offset+sec.FileSize:]) 1530 1531 nf, err := NewFile(bytes.NewReader(dn)) 1532 if err != nil { 1533 t.Error(err) 1534 } 1535 1536 const want = "decoding dwarf section info" 1537 _, err = nf.DWARF() 1538 if err == nil || !strings.Contains(err.Error(), want) { 1539 t.Errorf("DWARF = %v; want %q", err, want) 1540 } 1541 } 1542 1543 func BenchmarkSymbols64(b *testing.B) { 1544 const testdata = "testdata/gcc-amd64-linux-exec" 1545 f, err := Open(testdata) 1546 if err != nil { 1547 b.Fatalf("could not read %s: %v", testdata, err) 1548 } 1549 defer f.Close() 1550 b.ResetTimer() 1551 for i := 0; i < b.N; i++ { 1552 symbols, err := f.Symbols() 1553 if err != nil { 1554 b.Fatalf("Symbols(): got unexpected error %v", err) 1555 } 1556 if len(symbols) != 73 { 1557 b.Errorf("\nhave %d symbols\nwant %d symbols\n", len(symbols), 73) 1558 } 1559 } 1560 } 1561 1562 func BenchmarkSymbols32(b *testing.B) { 1563 const testdata = "testdata/gcc-386-freebsd-exec" 1564 f, err := Open(testdata) 1565 if err != nil { 1566 b.Fatalf("could not read %s: %v", testdata, err) 1567 } 1568 defer f.Close() 1569 b.ResetTimer() 1570 for i := 0; i < b.N; i++ { 1571 symbols, err := f.Symbols() 1572 if err != nil { 1573 b.Fatalf("Symbols(): got unexpected error %v", err) 1574 } 1575 if len(symbols) != 74 { 1576 b.Errorf("\nhave %d symbols\nwant %d symbols\n", len(symbols), 74) 1577 } 1578 } 1579 }