github.com/sbinet/go@v0.0.0-20160827155028-54d7de7dd62b/src/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 "debug/dwarf" 11 "encoding/binary" 12 "io" 13 "math/rand" 14 "net" 15 "os" 16 "path" 17 "reflect" 18 "runtime" 19 "testing" 20 ) 21 22 type fileTest struct { 23 file string 24 hdr FileHeader 25 sections []SectionHeader 26 progs []ProgHeader 27 needed []string 28 } 29 30 var fileTests = []fileTest{ 31 { 32 "testdata/gcc-386-freebsd-exec", 33 FileHeader{ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_FREEBSD, 0, binary.LittleEndian, ET_EXEC, EM_386, 0x80483cc}, 34 []SectionHeader{ 35 {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 36 {".interp", SHT_PROGBITS, SHF_ALLOC, 0x80480d4, 0xd4, 0x15, 0x0, 0x0, 0x1, 0x0, 0x15}, 37 {".hash", SHT_HASH, SHF_ALLOC, 0x80480ec, 0xec, 0x90, 0x3, 0x0, 0x4, 0x4, 0x90}, 38 {".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x804817c, 0x17c, 0x110, 0x4, 0x1, 0x4, 0x10, 0x110}, 39 {".dynstr", SHT_STRTAB, SHF_ALLOC, 0x804828c, 0x28c, 0xbb, 0x0, 0x0, 0x1, 0x0, 0xbb}, 40 {".rel.plt", SHT_REL, SHF_ALLOC, 0x8048348, 0x348, 0x20, 0x3, 0x7, 0x4, 0x8, 0x20}, 41 {".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x8048368, 0x368, 0x11, 0x0, 0x0, 0x4, 0x0, 0x11}, 42 {".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804837c, 0x37c, 0x50, 0x0, 0x0, 0x4, 0x4, 0x50}, 43 {".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x80483cc, 0x3cc, 0x180, 0x0, 0x0, 0x4, 0x0, 0x180}, 44 {".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804854c, 0x54c, 0xc, 0x0, 0x0, 0x4, 0x0, 0xc}, 45 {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x8048558, 0x558, 0xa3, 0x0, 0x0, 0x1, 0x0, 0xa3}, 46 {".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80495fc, 0x5fc, 0xc, 0x0, 0x0, 0x4, 0x0, 0xc}, 47 {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x8049608, 0x608, 0x4, 0x0, 0x0, 0x4, 0x0, 0x4}, 48 {".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x804960c, 0x60c, 0x98, 0x4, 0x0, 0x4, 0x8, 0x98}, 49 {".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496a4, 0x6a4, 0x8, 0x0, 0x0, 0x4, 0x0, 0x8}, 50 {".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496ac, 0x6ac, 0x8, 0x0, 0x0, 0x4, 0x0, 0x8}, 51 {".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b4, 0x6b4, 0x4, 0x0, 0x0, 0x4, 0x0, 0x4}, 52 {".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b8, 0x6b8, 0x1c, 0x0, 0x0, 0x4, 0x4, 0x1c}, 53 {".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x80496d4, 0x6d4, 0x20, 0x0, 0x0, 0x4, 0x0, 0x20}, 54 {".comment", SHT_PROGBITS, 0x0, 0x0, 0x6d4, 0x12d, 0x0, 0x0, 0x1, 0x0, 0x12d}, 55 {".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x801, 0x20, 0x0, 0x0, 0x1, 0x0, 0x20}, 56 {".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0x821, 0x1b, 0x0, 0x0, 0x1, 0x0, 0x1b}, 57 {".debug_info", SHT_PROGBITS, 0x0, 0x0, 0x83c, 0x11d, 0x0, 0x0, 0x1, 0x0, 0x11d}, 58 {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0x959, 0x41, 0x0, 0x0, 0x1, 0x0, 0x41}, 59 {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x99a, 0x35, 0x0, 0x0, 0x1, 0x0, 0x35}, 60 {".debug_frame", SHT_PROGBITS, 0x0, 0x0, 0x9d0, 0x30, 0x0, 0x0, 0x4, 0x0, 0x30}, 61 {".debug_str", SHT_PROGBITS, 0x0, 0x0, 0xa00, 0xd, 0x0, 0x0, 0x1, 0x0, 0xd}, 62 {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xa0d, 0xf8, 0x0, 0x0, 0x1, 0x0, 0xf8}, 63 {".symtab", SHT_SYMTAB, 0x0, 0x0, 0xfb8, 0x4b0, 0x1d, 0x38, 0x4, 0x10, 0x4b0}, 64 {".strtab", SHT_STRTAB, 0x0, 0x0, 0x1468, 0x206, 0x0, 0x0, 0x1, 0x0, 0x206}, 65 }, 66 []ProgHeader{ 67 {PT_PHDR, PF_R + PF_X, 0x34, 0x8048034, 0x8048034, 0xa0, 0xa0, 0x4}, 68 {PT_INTERP, PF_R, 0xd4, 0x80480d4, 0x80480d4, 0x15, 0x15, 0x1}, 69 {PT_LOAD, PF_R + PF_X, 0x0, 0x8048000, 0x8048000, 0x5fb, 0x5fb, 0x1000}, 70 {PT_LOAD, PF_R + PF_W, 0x5fc, 0x80495fc, 0x80495fc, 0xd8, 0xf8, 0x1000}, 71 {PT_DYNAMIC, PF_R + PF_W, 0x60c, 0x804960c, 0x804960c, 0x98, 0x98, 0x4}, 72 }, 73 []string{"libc.so.6"}, 74 }, 75 { 76 "testdata/gcc-amd64-linux-exec", 77 FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0, binary.LittleEndian, ET_EXEC, EM_X86_64, 0x4003e0}, 78 []SectionHeader{ 79 {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 80 {".interp", SHT_PROGBITS, SHF_ALLOC, 0x400200, 0x200, 0x1c, 0x0, 0x0, 0x1, 0x0, 0x1c}, 81 {".note.ABI-tag", SHT_NOTE, SHF_ALLOC, 0x40021c, 0x21c, 0x20, 0x0, 0x0, 0x4, 0x0, 0x20}, 82 {".hash", SHT_HASH, SHF_ALLOC, 0x400240, 0x240, 0x24, 0x5, 0x0, 0x8, 0x4, 0x24}, 83 {".gnu.hash", SHT_LOOS + 268435446, SHF_ALLOC, 0x400268, 0x268, 0x1c, 0x5, 0x0, 0x8, 0x0, 0x1c}, 84 {".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x400288, 0x288, 0x60, 0x6, 0x1, 0x8, 0x18, 0x60}, 85 {".dynstr", SHT_STRTAB, SHF_ALLOC, 0x4002e8, 0x2e8, 0x3d, 0x0, 0x0, 0x1, 0x0, 0x3d}, 86 {".gnu.version", SHT_HIOS, SHF_ALLOC, 0x400326, 0x326, 0x8, 0x5, 0x0, 0x2, 0x2, 0x8}, 87 {".gnu.version_r", SHT_LOOS + 268435454, SHF_ALLOC, 0x400330, 0x330, 0x20, 0x6, 0x1, 0x8, 0x0, 0x20}, 88 {".rela.dyn", SHT_RELA, SHF_ALLOC, 0x400350, 0x350, 0x18, 0x5, 0x0, 0x8, 0x18, 0x18}, 89 {".rela.plt", SHT_RELA, SHF_ALLOC, 0x400368, 0x368, 0x30, 0x5, 0xc, 0x8, 0x18, 0x30}, 90 {".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400398, 0x398, 0x18, 0x0, 0x0, 0x4, 0x0, 0x18}, 91 {".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003b0, 0x3b0, 0x30, 0x0, 0x0, 0x4, 0x10, 0x30}, 92 {".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003e0, 0x3e0, 0x1b4, 0x0, 0x0, 0x10, 0x0, 0x1b4}, 93 {".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400594, 0x594, 0xe, 0x0, 0x0, 0x4, 0x0, 0xe}, 94 {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x4005a4, 0x5a4, 0x11, 0x0, 0x0, 0x4, 0x0, 0x11}, 95 {".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC, 0x4005b8, 0x5b8, 0x24, 0x0, 0x0, 0x4, 0x0, 0x24}, 96 {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x4005e0, 0x5e0, 0xa4, 0x0, 0x0, 0x8, 0x0, 0xa4}, 97 {".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600688, 0x688, 0x10, 0x0, 0x0, 0x8, 0x0, 0x10}, 98 {".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600698, 0x698, 0x10, 0x0, 0x0, 0x8, 0x0, 0x10}, 99 {".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x6006a8, 0x6a8, 0x8, 0x0, 0x0, 0x8, 0x0, 0x8}, 100 {".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x6006b0, 0x6b0, 0x1a0, 0x6, 0x0, 0x8, 0x10, 0x1a0}, 101 {".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600850, 0x850, 0x8, 0x0, 0x0, 0x8, 0x8, 0x8}, 102 {".got.plt", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600858, 0x858, 0x28, 0x0, 0x0, 0x8, 0x8, 0x28}, 103 {".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600880, 0x880, 0x18, 0x0, 0x0, 0x8, 0x0, 0x18}, 104 {".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x600898, 0x898, 0x8, 0x0, 0x0, 0x4, 0x0, 0x8}, 105 {".comment", SHT_PROGBITS, 0x0, 0x0, 0x898, 0x126, 0x0, 0x0, 0x1, 0x0, 0x126}, 106 {".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x9c0, 0x90, 0x0, 0x0, 0x10, 0x0, 0x90}, 107 {".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0xa50, 0x25, 0x0, 0x0, 0x1, 0x0, 0x25}, 108 {".debug_info", SHT_PROGBITS, 0x0, 0x0, 0xa75, 0x1a7, 0x0, 0x0, 0x1, 0x0, 0x1a7}, 109 {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xc1c, 0x6f, 0x0, 0x0, 0x1, 0x0, 0x6f}, 110 {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0xc8b, 0x13f, 0x0, 0x0, 0x1, 0x0, 0x13f}, 111 {".debug_str", SHT_PROGBITS, SHF_MERGE + SHF_STRINGS, 0x0, 0xdca, 0xb1, 0x0, 0x0, 0x1, 0x1, 0xb1}, 112 {".debug_ranges", SHT_PROGBITS, 0x0, 0x0, 0xe80, 0x90, 0x0, 0x0, 0x10, 0x0, 0x90}, 113 {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xf10, 0x149, 0x0, 0x0, 0x1, 0x0, 0x149}, 114 {".symtab", SHT_SYMTAB, 0x0, 0x0, 0x19a0, 0x6f0, 0x24, 0x39, 0x8, 0x18, 0x6f0}, 115 {".strtab", SHT_STRTAB, 0x0, 0x0, 0x2090, 0x1fc, 0x0, 0x0, 0x1, 0x0, 0x1fc}, 116 }, 117 []ProgHeader{ 118 {PT_PHDR, PF_R + PF_X, 0x40, 0x400040, 0x400040, 0x1c0, 0x1c0, 0x8}, 119 {PT_INTERP, PF_R, 0x200, 0x400200, 0x400200, 0x1c, 0x1c, 1}, 120 {PT_LOAD, PF_R + PF_X, 0x0, 0x400000, 0x400000, 0x684, 0x684, 0x200000}, 121 {PT_LOAD, PF_R + PF_W, 0x688, 0x600688, 0x600688, 0x210, 0x218, 0x200000}, 122 {PT_DYNAMIC, PF_R + PF_W, 0x6b0, 0x6006b0, 0x6006b0, 0x1a0, 0x1a0, 0x8}, 123 {PT_NOTE, PF_R, 0x21c, 0x40021c, 0x40021c, 0x20, 0x20, 0x4}, 124 {PT_LOOS + 0x474E550, PF_R, 0x5b8, 0x4005b8, 0x4005b8, 0x24, 0x24, 0x4}, 125 {PT_LOOS + 0x474E551, PF_R + PF_W, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8}, 126 }, 127 []string{"libc.so.6"}, 128 }, 129 { 130 "testdata/hello-world-core.gz", 131 FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_CORE, EM_X86_64, 0x0}, 132 []SectionHeader{}, 133 []ProgHeader{ 134 {Type: PT_NOTE, Flags: 0x0, Off: 0x3f8, Vaddr: 0x0, Paddr: 0x0, Filesz: 0x8ac, Memsz: 0x0, Align: 0x0}, 135 {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x1000, Vaddr: 0x400000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1000, Align: 0x1000}, 136 {Type: PT_LOAD, Flags: PF_R, Off: 0x1000, Vaddr: 0x401000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000}, 137 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x2000, Vaddr: 0x402000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000}, 138 {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3000, Vaddr: 0x7f54078b8000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1b5000, Align: 0x1000}, 139 {Type: PT_LOAD, Flags: 0x0, Off: 0x3000, Vaddr: 0x7f5407a6d000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1ff000, Align: 0x1000}, 140 {Type: PT_LOAD, Flags: PF_R, Off: 0x3000, Vaddr: 0x7f5407c6c000, Paddr: 0x0, Filesz: 0x4000, Memsz: 0x4000, Align: 0x1000}, 141 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x7000, Vaddr: 0x7f5407c70000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000}, 142 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x9000, Vaddr: 0x7f5407c72000, Paddr: 0x0, Filesz: 0x5000, Memsz: 0x5000, Align: 0x1000}, 143 {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0xe000, Vaddr: 0x7f5407c77000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x22000, Align: 0x1000}, 144 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0xe000, Vaddr: 0x7f5407e81000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000}, 145 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x11000, Vaddr: 0x7f5407e96000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000}, 146 {Type: PT_LOAD, Flags: PF_R, Off: 0x14000, Vaddr: 0x7f5407e99000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000}, 147 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x15000, Vaddr: 0x7f5407e9a000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000}, 148 {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x17000, Vaddr: 0x7fff79972000, Paddr: 0x0, Filesz: 0x23000, Memsz: 0x23000, Align: 0x1000}, 149 {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3a000, Vaddr: 0x7fff799f8000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000}, 150 {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3b000, Vaddr: 0xffffffffff600000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000}, 151 }, 152 nil, 153 }, 154 { 155 "testdata/compressed-32.obj", 156 FileHeader{ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_REL, EM_386, 0x0}, 157 []SectionHeader{ 158 {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 159 {".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, 0x0, 0x34, 0x17, 0x0, 0x0, 0x1, 0x0, 0x17}, 160 {".rel.text", SHT_REL, SHF_INFO_LINK, 0x0, 0x3dc, 0x10, 0x13, 0x1, 0x4, 0x8, 0x10}, 161 {".data", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x4b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0}, 162 {".bss", SHT_NOBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x4b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0}, 163 {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x4b, 0xd, 0x0, 0x0, 0x1, 0x0, 0xd}, 164 {".debug_info", SHT_PROGBITS, SHF_COMPRESSED, 0x0, 0x58, 0xb4, 0x0, 0x0, 0x1, 0x0, 0x84}, 165 {".rel.debug_info", SHT_REL, SHF_INFO_LINK, 0x0, 0x3ec, 0xa0, 0x13, 0x6, 0x4, 0x8, 0xa0}, 166 {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xdc, 0x5a, 0x0, 0x0, 0x1, 0x0, 0x5a}, 167 {".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x136, 0x20, 0x0, 0x0, 0x1, 0x0, 0x20}, 168 {".rel.debug_aranges", SHT_REL, SHF_INFO_LINK, 0x0, 0x48c, 0x10, 0x13, 0x9, 0x4, 0x8, 0x10}, 169 {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x156, 0x5c, 0x0, 0x0, 0x1, 0x0, 0x5c}, 170 {".rel.debug_line", SHT_REL, SHF_INFO_LINK, 0x0, 0x49c, 0x8, 0x13, 0xb, 0x4, 0x8, 0x8}, 171 {".debug_str", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS | SHF_COMPRESSED, 0x0, 0x1b2, 0x10f, 0x0, 0x0, 0x1, 0x1, 0xb3}, 172 {".comment", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS, 0x0, 0x265, 0x2a, 0x0, 0x0, 0x1, 0x1, 0x2a}, 173 {".note.GNU-stack", SHT_PROGBITS, 0x0, 0x0, 0x28f, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0}, 174 {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x290, 0x38, 0x0, 0x0, 0x4, 0x0, 0x38}, 175 {".rel.eh_frame", SHT_REL, SHF_INFO_LINK, 0x0, 0x4a4, 0x8, 0x13, 0x10, 0x4, 0x8, 0x8}, 176 {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0x4ac, 0xab, 0x0, 0x0, 0x1, 0x0, 0xab}, 177 {".symtab", SHT_SYMTAB, 0x0, 0x0, 0x2c8, 0x100, 0x14, 0xe, 0x4, 0x10, 0x100}, 178 {".strtab", SHT_STRTAB, 0x0, 0x0, 0x3c8, 0x13, 0x0, 0x0, 0x1, 0x0, 0x13}, 179 }, 180 []ProgHeader{}, 181 nil, 182 }, 183 { 184 "testdata/compressed-64.obj", 185 FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_REL, EM_X86_64, 0x0}, 186 []SectionHeader{ 187 {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 188 {".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, 0x0, 0x40, 0x1b, 0x0, 0x0, 0x1, 0x0, 0x1b}, 189 {".rela.text", SHT_RELA, SHF_INFO_LINK, 0x0, 0x488, 0x30, 0x13, 0x1, 0x8, 0x18, 0x30}, 190 {".data", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x5b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0}, 191 {".bss", SHT_NOBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x5b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0}, 192 {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x5b, 0xd, 0x0, 0x0, 0x1, 0x0, 0xd}, 193 {".debug_info", SHT_PROGBITS, SHF_COMPRESSED, 0x0, 0x68, 0xba, 0x0, 0x0, 0x1, 0x0, 0x72}, 194 {".rela.debug_info", SHT_RELA, SHF_INFO_LINK, 0x0, 0x4b8, 0x1c8, 0x13, 0x6, 0x8, 0x18, 0x1c8}, 195 {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xda, 0x5c, 0x0, 0x0, 0x1, 0x0, 0x5c}, 196 {".debug_aranges", SHT_PROGBITS, SHF_COMPRESSED, 0x0, 0x136, 0x30, 0x0, 0x0, 0x1, 0x0, 0x2f}, 197 {".rela.debug_aranges", SHT_RELA, SHF_INFO_LINK, 0x0, 0x680, 0x30, 0x13, 0x9, 0x8, 0x18, 0x30}, 198 {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x165, 0x60, 0x0, 0x0, 0x1, 0x0, 0x60}, 199 {".rela.debug_line", SHT_RELA, SHF_INFO_LINK, 0x0, 0x6b0, 0x18, 0x13, 0xb, 0x8, 0x18, 0x18}, 200 {".debug_str", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS | SHF_COMPRESSED, 0x0, 0x1c5, 0x104, 0x0, 0x0, 0x1, 0x1, 0xc3}, 201 {".comment", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS, 0x0, 0x288, 0x2a, 0x0, 0x0, 0x1, 0x1, 0x2a}, 202 {".note.GNU-stack", SHT_PROGBITS, 0x0, 0x0, 0x2b2, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0}, 203 {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x2b8, 0x38, 0x0, 0x0, 0x8, 0x0, 0x38}, 204 {".rela.eh_frame", SHT_RELA, SHF_INFO_LINK, 0x0, 0x6c8, 0x18, 0x13, 0x10, 0x8, 0x18, 0x18}, 205 {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0x6e0, 0xb0, 0x0, 0x0, 0x1, 0x0, 0xb0}, 206 {".symtab", SHT_SYMTAB, 0x0, 0x0, 0x2f0, 0x180, 0x14, 0xe, 0x8, 0x18, 0x180}, 207 {".strtab", SHT_STRTAB, 0x0, 0x0, 0x470, 0x13, 0x0, 0x0, 0x1, 0x0, 0x13}, 208 }, 209 []ProgHeader{}, 210 nil, 211 }, 212 } 213 214 func TestOpen(t *testing.T) { 215 for i := range fileTests { 216 tt := &fileTests[i] 217 218 var f *File 219 var err error 220 if path.Ext(tt.file) == ".gz" { 221 var r io.ReaderAt 222 if r, err = decompress(tt.file); err == nil { 223 f, err = NewFile(r) 224 } 225 } else { 226 f, err = Open(tt.file) 227 } 228 if err != nil { 229 t.Errorf("cannot open file %s: %v", tt.file, err) 230 continue 231 } 232 defer f.Close() 233 if !reflect.DeepEqual(f.FileHeader, tt.hdr) { 234 t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr) 235 continue 236 } 237 for i, s := range f.Sections { 238 if i >= len(tt.sections) { 239 break 240 } 241 sh := &tt.sections[i] 242 if !reflect.DeepEqual(&s.SectionHeader, sh) { 243 t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, &s.SectionHeader, sh) 244 } 245 } 246 for i, p := range f.Progs { 247 if i >= len(tt.progs) { 248 break 249 } 250 ph := &tt.progs[i] 251 if !reflect.DeepEqual(&p.ProgHeader, ph) { 252 t.Errorf("open %s, program %d:\n\thave %#v\n\twant %#v\n", tt.file, i, &p.ProgHeader, ph) 253 } 254 } 255 tn := len(tt.sections) 256 fn := len(f.Sections) 257 if tn != fn { 258 t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn) 259 } 260 tn = len(tt.progs) 261 fn = len(f.Progs) 262 if tn != fn { 263 t.Errorf("open %s: len(Progs) = %d, want %d", tt.file, fn, tn) 264 } 265 tl := tt.needed 266 fl, err := f.ImportedLibraries() 267 if err != nil { 268 t.Error(err) 269 } 270 if !reflect.DeepEqual(tl, fl) { 271 t.Errorf("open %s: DT_NEEDED = %v, want %v", tt.file, tl, fl) 272 } 273 } 274 } 275 276 // elf.NewFile requires io.ReaderAt, which compress/gzip cannot 277 // provide. Decompress the file to a bytes.Reader. 278 func decompress(gz string) (io.ReaderAt, error) { 279 in, err := os.Open(gz) 280 if err != nil { 281 return nil, err 282 } 283 defer in.Close() 284 r, err := gzip.NewReader(in) 285 if err != nil { 286 return nil, err 287 } 288 var out bytes.Buffer 289 _, err = io.Copy(&out, r) 290 return bytes.NewReader(out.Bytes()), err 291 } 292 293 type relocationTestEntry struct { 294 entryNumber int 295 entry *dwarf.Entry 296 } 297 298 type relocationTest struct { 299 file string 300 entries []relocationTestEntry 301 } 302 303 var relocationTests = []relocationTest{ 304 { 305 "testdata/go-relocation-test-gcc441-x86-64.obj", 306 []relocationTestEntry{ 307 {0, &dwarf.Entry{ 308 Offset: 0xb, 309 Tag: dwarf.TagCompileUnit, 310 Children: true, 311 Field: []dwarf.Field{ 312 {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString}, 313 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, 314 {Attr: dwarf.AttrName, Val: "go-relocation-test.c", Class: dwarf.ClassString}, 315 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 316 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 317 {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress}, 318 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 319 }, 320 }}, 321 }, 322 }, 323 { 324 "testdata/go-relocation-test-gcc441-x86.obj", 325 []relocationTestEntry{ 326 {0, &dwarf.Entry{ 327 Offset: 0xb, 328 Tag: dwarf.TagCompileUnit, 329 Children: true, 330 Field: []dwarf.Field{ 331 {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString}, 332 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, 333 {Attr: dwarf.AttrName, Val: "t.c", Class: dwarf.ClassString}, 334 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 335 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 336 {Attr: dwarf.AttrHighpc, Val: uint64(0x5), Class: dwarf.ClassAddress}, 337 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 338 }, 339 }}, 340 }, 341 }, 342 { 343 "testdata/go-relocation-test-gcc424-x86-64.obj", 344 []relocationTestEntry{ 345 {0, &dwarf.Entry{ 346 Offset: 0xb, 347 Tag: dwarf.TagCompileUnit, 348 Children: true, 349 Field: []dwarf.Field{ 350 {Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)", Class: dwarf.ClassString}, 351 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, 352 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c", Class: dwarf.ClassString}, 353 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 354 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 355 {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress}, 356 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 357 }, 358 }}, 359 }, 360 }, 361 { 362 "testdata/go-relocation-test-gcc482-aarch64.obj", 363 []relocationTestEntry{ 364 {0, &dwarf.Entry{ 365 Offset: 0xb, 366 Tag: dwarf.TagCompileUnit, 367 Children: true, 368 Field: []dwarf.Field{ 369 {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -g -fstack-protector", Class: dwarf.ClassString}, 370 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, 371 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482.c", Class: dwarf.ClassString}, 372 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 373 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 374 {Attr: dwarf.AttrHighpc, Val: int64(0x24), Class: dwarf.ClassConstant}, 375 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 376 }, 377 }}, 378 }, 379 }, 380 { 381 "testdata/go-relocation-test-gcc492-arm.obj", 382 []relocationTestEntry{ 383 {0, &dwarf.Entry{ 384 Offset: 0xb, 385 Tag: dwarf.TagCompileUnit, 386 Children: true, 387 Field: []dwarf.Field{ 388 {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}, 389 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, 390 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc492.c", Class: dwarf.ClassString}, 391 {Attr: dwarf.AttrCompDir, Val: "/root/go/src/debug/elf/testdata", Class: dwarf.ClassString}, 392 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 393 {Attr: dwarf.AttrHighpc, Val: int64(0x28), Class: dwarf.ClassConstant}, 394 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 395 }, 396 }}, 397 }, 398 }, 399 { 400 "testdata/go-relocation-test-clang-arm.obj", 401 []relocationTestEntry{ 402 {0, &dwarf.Entry{ 403 Offset: 0xb, 404 Tag: dwarf.TagCompileUnit, 405 Children: true, 406 Field: []dwarf.Field{ 407 {Attr: dwarf.AttrProducer, Val: "Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)", Class: dwarf.ClassString}, 408 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, 409 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, 410 {Attr: dwarf.AttrStmtList, Val: int64(0x0), Class: dwarf.ClassLinePtr}, 411 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 412 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 413 {Attr: dwarf.AttrHighpc, Val: int64(48), Class: dwarf.ClassConstant}, 414 }, 415 }}, 416 }, 417 }, 418 { 419 "testdata/go-relocation-test-gcc5-ppc.obj", 420 []relocationTestEntry{ 421 {0, &dwarf.Entry{ 422 Offset: 0xb, 423 Tag: dwarf.TagCompileUnit, 424 Children: true, 425 Field: []dwarf.Field{ 426 {Attr: dwarf.AttrProducer, Val: "GNU C11 5.0.0 20150116 (experimental) -Asystem=linux -Asystem=unix -Asystem=posix -g", Class: dwarf.ClassString}, 427 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, 428 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc5-ppc.c", Class: dwarf.ClassString}, 429 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 430 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 431 {Attr: dwarf.AttrHighpc, Val: int64(0x44), Class: dwarf.ClassConstant}, 432 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 433 }, 434 }}, 435 }, 436 }, 437 { 438 "testdata/go-relocation-test-gcc482-ppc64le.obj", 439 []relocationTestEntry{ 440 {0, &dwarf.Entry{ 441 Offset: 0xb, 442 Tag: dwarf.TagCompileUnit, 443 Children: true, 444 Field: []dwarf.Field{ 445 {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}, 446 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, 447 {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482-ppc64le.c", Class: dwarf.ClassString}, 448 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 449 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 450 {Attr: dwarf.AttrHighpc, Val: uint64(0x24), Class: dwarf.ClassAddress}, 451 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 452 }, 453 }}, 454 }, 455 }, 456 { 457 "testdata/go-relocation-test-gcc492-mips64.obj", 458 []relocationTestEntry{ 459 {0, &dwarf.Entry{ 460 Offset: 0xb, 461 Tag: dwarf.TagCompileUnit, 462 Children: true, 463 Field: []dwarf.Field{ 464 {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -meb -mabi=64 -march=mips3 -mtune=mips64 -mllsc -mno-shared -g", Class: dwarf.ClassString}, 465 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, 466 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, 467 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 468 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 469 {Attr: dwarf.AttrHighpc, Val: int64(100), Class: dwarf.ClassConstant}, 470 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 471 }, 472 }}, 473 }, 474 }, 475 { 476 "testdata/go-relocation-test-gcc531-s390x.obj", 477 []relocationTestEntry{ 478 {0, &dwarf.Entry{ 479 Offset: 0xb, 480 Tag: dwarf.TagCompileUnit, 481 Children: true, 482 Field: []dwarf.Field{ 483 {Attr: dwarf.AttrProducer, Val: "GNU C11 5.3.1 20160316 -march=zEC12 -m64 -mzarch -g -fstack-protector-strong", Class: dwarf.ClassString}, 484 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, 485 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, 486 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 487 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 488 {Attr: dwarf.AttrHighpc, Val: int64(58), Class: dwarf.ClassConstant}, 489 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 490 }, 491 }}, 492 }, 493 }, 494 { 495 "testdata/go-relocation-test-gcc493-mips64le.obj", 496 []relocationTestEntry{ 497 {0, &dwarf.Entry{ 498 Offset: 0xb, 499 Tag: dwarf.TagCompileUnit, 500 Children: true, 501 Field: []dwarf.Field{ 502 {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.3 -mel -mabi=64 -mllsc -mno-shared -g -fstack-protector-strong", Class: dwarf.ClassString}, 503 {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, 504 {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, 505 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 506 {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, 507 {Attr: dwarf.AttrHighpc, Val: int64(100), Class: dwarf.ClassConstant}, 508 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 509 }, 510 }}, 511 }, 512 }, 513 { 514 "testdata/go-relocation-test-clang-x86.obj", 515 []relocationTestEntry{ 516 {0, &dwarf.Entry{ 517 Offset: 0xb, 518 Tag: dwarf.TagCompileUnit, 519 Children: true, 520 Field: []dwarf.Field{ 521 {Attr: dwarf.AttrProducer, Val: "clang version google3-trunk (trunk r209387)", Class: dwarf.ClassString}, 522 {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, 523 {Attr: dwarf.AttrName, Val: "go-relocation-test-clang.c", Class: dwarf.ClassString}, 524 {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, 525 {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, 526 }, 527 }}, 528 }, 529 }, 530 { 531 "testdata/gcc-amd64-openbsd-debug-with-rela.obj", 532 []relocationTestEntry{ 533 {203, &dwarf.Entry{ 534 Offset: 0xc62, 535 Tag: dwarf.TagMember, 536 Children: false, 537 Field: []dwarf.Field{ 538 {Attr: dwarf.AttrName, Val: "it_interval", Class: dwarf.ClassString}, 539 {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant}, 540 {Attr: dwarf.AttrDeclLine, Val: int64(236), Class: dwarf.ClassConstant}, 541 {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference}, 542 {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}, Class: dwarf.ClassExprLoc}, 543 }, 544 }}, 545 {204, &dwarf.Entry{ 546 Offset: 0xc70, 547 Tag: dwarf.TagMember, 548 Children: false, 549 Field: []dwarf.Field{ 550 {Attr: dwarf.AttrName, Val: "it_value", Class: dwarf.ClassString}, 551 {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant}, 552 {Attr: dwarf.AttrDeclLine, Val: int64(237), Class: dwarf.ClassConstant}, 553 {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference}, 554 {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}, Class: dwarf.ClassExprLoc}, 555 }, 556 }}, 557 }, 558 }, 559 } 560 561 func TestDWARFRelocations(t *testing.T) { 562 for i, test := range relocationTests { 563 f, err := Open(test.file) 564 if err != nil { 565 t.Error(err) 566 continue 567 } 568 dwarf, err := f.DWARF() 569 if err != nil { 570 t.Error(err) 571 continue 572 } 573 for _, testEntry := range test.entries { 574 reader := dwarf.Reader() 575 for j := 0; j < testEntry.entryNumber; j++ { 576 entry, err := reader.Next() 577 if entry == nil || err != nil { 578 t.Errorf("Failed to skip to entry %d: %v", testEntry.entryNumber, err) 579 continue 580 } 581 } 582 entry, err := reader.Next() 583 if err != nil { 584 t.Error(err) 585 continue 586 } 587 if !reflect.DeepEqual(testEntry.entry, entry) { 588 t.Errorf("#%d/%d: mismatch: got:%#v want:%#v", i, testEntry.entryNumber, entry, testEntry.entry) 589 continue 590 } 591 } 592 } 593 } 594 595 func TestCompressedDWARF(t *testing.T) { 596 // Test file built with GCC 4.8.4 and as 2.24 using: 597 // gcc -Wa,--compress-debug-sections -g -c -o zdebug-test-gcc484-x86-64.obj hello.c 598 f, err := Open("testdata/zdebug-test-gcc484-x86-64.obj") 599 if err != nil { 600 t.Fatal(err) 601 } 602 dwarf, err := f.DWARF() 603 if err != nil { 604 t.Fatal(err) 605 } 606 reader := dwarf.Reader() 607 n := 0 608 for { 609 entry, err := reader.Next() 610 if err != nil { 611 t.Fatal(err) 612 } 613 if entry == nil { 614 break 615 } 616 n++ 617 } 618 if n != 18 { 619 t.Fatalf("want %d DWARF entries, got %d", 18, n) 620 } 621 } 622 623 func TestCompressedSection(t *testing.T) { 624 // Test files built with gcc -g -S hello.c and assembled with 625 // --compress-debug-sections=zlib-gabi. 626 f, err := Open("testdata/compressed-64.obj") 627 if err != nil { 628 t.Fatal(err) 629 } 630 sec := f.Section(".debug_info") 631 wantData := []byte{ 632 182, 0, 0, 0, 4, 0, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0, 633 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 634 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 7, 635 0, 0, 0, 0, 2, 1, 8, 0, 0, 0, 0, 2, 2, 7, 0, 0, 636 0, 0, 2, 4, 7, 0, 0, 0, 0, 2, 1, 6, 0, 0, 0, 0, 637 2, 2, 5, 0, 0, 0, 0, 3, 4, 5, 105, 110, 116, 0, 2, 8, 638 5, 0, 0, 0, 0, 2, 8, 7, 0, 0, 0, 0, 4, 8, 114, 0, 639 0, 0, 2, 1, 6, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 4, 640 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 641 1, 156, 179, 0, 0, 0, 6, 0, 0, 0, 0, 1, 4, 87, 0, 0, 642 0, 2, 145, 108, 6, 0, 0, 0, 0, 1, 4, 179, 0, 0, 0, 2, 643 145, 96, 0, 4, 8, 108, 0, 0, 0, 0, 644 } 645 646 // Test Data method. 647 b, err := sec.Data() 648 if err != nil { 649 t.Fatal(err) 650 } 651 if !bytes.Equal(wantData, b) { 652 t.Fatalf("want data %x, got %x", wantData, b) 653 } 654 655 // Test Open method and seeking. 656 buf, have, count := make([]byte, len(b)), make([]bool, len(b)), 0 657 sf := sec.Open() 658 if got, err := sf.Seek(0, io.SeekEnd); got != int64(len(b)) || err != nil { 659 t.Fatalf("want seek end %d, got %d error %v", len(b), got, err) 660 } 661 if n, err := sf.Read(buf); n != 0 || err != io.EOF { 662 t.Fatalf("want EOF with 0 bytes, got %v with %d bytes", err, n) 663 } 664 pos := int64(len(buf)) 665 for count < len(buf) { 666 // Construct random seek arguments. 667 whence := rand.Intn(3) 668 target := rand.Int63n(int64(len(buf))) 669 var offset int64 670 switch whence { 671 case io.SeekStart: 672 offset = target 673 case io.SeekCurrent: 674 offset = target - pos 675 case io.SeekEnd: 676 offset = target - int64(len(buf)) 677 } 678 pos, err = sf.Seek(offset, whence) 679 if err != nil { 680 t.Fatal(err) 681 } 682 if pos != target { 683 t.Fatalf("want position %d, got %d", target, pos) 684 } 685 686 // Read data from the new position. 687 end := pos + 16 688 if end > int64(len(buf)) { 689 end = int64(len(buf)) 690 } 691 n, err := io.ReadFull(sf, buf[pos:end]) 692 if err != nil { 693 t.Fatal(err) 694 } 695 for i := 0; i < n; i++ { 696 if !have[pos] { 697 have[pos] = true 698 count++ 699 } 700 pos++ 701 } 702 } 703 if !bytes.Equal(wantData, buf) { 704 t.Fatalf("want data %x, got %x", wantData, buf) 705 } 706 } 707 708 func TestNoSectionOverlaps(t *testing.T) { 709 // Ensure 6l outputs sections without overlaps. 710 if runtime.GOOS != "linux" && runtime.GOOS != "freebsd" { 711 return // not ELF 712 } 713 _ = net.ResolveIPAddr // force dynamic linkage 714 f, err := Open(os.Args[0]) 715 if err != nil { 716 t.Error(err) 717 return 718 } 719 for i, si := range f.Sections { 720 sih := si.SectionHeader 721 if sih.Type == SHT_NOBITS { 722 continue 723 } 724 for j, sj := range f.Sections { 725 sjh := sj.SectionHeader 726 if i == j || sjh.Type == SHT_NOBITS || sih.Offset == sjh.Offset && sih.Size == 0 { 727 continue 728 } 729 if sih.Offset >= sjh.Offset && sih.Offset < sjh.Offset+sjh.Size { 730 t.Errorf("ld produced ELF with section %s within %s: 0x%x <= 0x%x..0x%x < 0x%x", 731 sih.Name, sjh.Name, sjh.Offset, sih.Offset, sih.Offset+sih.Size, sjh.Offset+sjh.Size) 732 } 733 } 734 } 735 }