~ubuntu-branches/ubuntu/saucy/golang/saucy

« back to all changes in this revision

Viewing changes to src/pkg/debug/elf/file_test.go

  • Committer: Package Import Robot
  • Author(s): Adam Conrad
  • Date: 2013-07-08 05:52:37 UTC
  • mfrom: (29.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20130708055237-at01839e0hp8z3ni
Tags: 2:1.1-1ubuntu1
016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
package elf
6
6
 
7
7
import (
 
8
        "bytes"
 
9
        "compress/gzip"
8
10
        "debug/dwarf"
9
11
        "encoding/binary"
 
12
        "io"
10
13
        "net"
11
14
        "os"
 
15
        "path"
12
16
        "reflect"
13
17
        "runtime"
14
18
        "testing"
19
23
        hdr      FileHeader
20
24
        sections []SectionHeader
21
25
        progs    []ProgHeader
 
26
        needed   []string
22
27
}
23
28
 
24
29
var fileTests = []fileTest{
25
30
        {
26
31
                "testdata/gcc-386-freebsd-exec",
27
 
                FileHeader{ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_FREEBSD, 0, binary.LittleEndian, ET_EXEC, EM_386},
 
32
                FileHeader{ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_FREEBSD, 0, binary.LittleEndian, ET_EXEC, EM_386, 0x80483cc},
28
33
                []SectionHeader{
29
34
                        {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
30
35
                        {".interp", SHT_PROGBITS, SHF_ALLOC, 0x80480d4, 0xd4, 0x15, 0x0, 0x0, 0x1, 0x0},
64
69
                        {PT_LOAD, PF_R + PF_W, 0x5fc, 0x80495fc, 0x80495fc, 0xd8, 0xf8, 0x1000},
65
70
                        {PT_DYNAMIC, PF_R + PF_W, 0x60c, 0x804960c, 0x804960c, 0x98, 0x98, 0x4},
66
71
                },
 
72
                []string{"libc.so.6"},
67
73
        },
68
74
        {
69
75
                "testdata/gcc-amd64-linux-exec",
70
 
                FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0, binary.LittleEndian, ET_EXEC, EM_X86_64},
 
76
                FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0, binary.LittleEndian, ET_EXEC, EM_X86_64, 0x4003e0},
71
77
                []SectionHeader{
72
78
                        {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
73
79
                        {".interp", SHT_PROGBITS, SHF_ALLOC, 0x400200, 0x200, 0x1c, 0x0, 0x0, 0x1, 0x0},
117
123
                        {PT_LOOS + 0x474E550, PF_R, 0x5b8, 0x4005b8, 0x4005b8, 0x24, 0x24, 0x4},
118
124
                        {PT_LOOS + 0x474E551, PF_R + PF_W, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8},
119
125
                },
 
126
                []string{"libc.so.6"},
 
127
        },
 
128
        {
 
129
                "testdata/hello-world-core.gz",
 
130
                FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_CORE, EM_X86_64, 0x0},
 
131
                []SectionHeader{},
 
132
                []ProgHeader{
 
133
                        {Type: PT_NOTE, Flags: 0x0, Off: 0x3f8, Vaddr: 0x0, Paddr: 0x0, Filesz: 0x8ac, Memsz: 0x0, Align: 0x0},
 
134
                        {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x1000, Vaddr: 0x400000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1000, Align: 0x1000},
 
135
                        {Type: PT_LOAD, Flags: PF_R, Off: 0x1000, Vaddr: 0x401000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
 
136
                        {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x2000, Vaddr: 0x402000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
 
137
                        {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3000, Vaddr: 0x7f54078b8000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1b5000, Align: 0x1000},
 
138
                        {Type: PT_LOAD, Flags: 0x0, Off: 0x3000, Vaddr: 0x7f5407a6d000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1ff000, Align: 0x1000},
 
139
                        {Type: PT_LOAD, Flags: PF_R, Off: 0x3000, Vaddr: 0x7f5407c6c000, Paddr: 0x0, Filesz: 0x4000, Memsz: 0x4000, Align: 0x1000},
 
140
                        {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x7000, Vaddr: 0x7f5407c70000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000},
 
141
                        {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x9000, Vaddr: 0x7f5407c72000, Paddr: 0x0, Filesz: 0x5000, Memsz: 0x5000, Align: 0x1000},
 
142
                        {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0xe000, Vaddr: 0x7f5407c77000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x22000, Align: 0x1000},
 
143
                        {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0xe000, Vaddr: 0x7f5407e81000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000},
 
144
                        {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x11000, Vaddr: 0x7f5407e96000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000},
 
145
                        {Type: PT_LOAD, Flags: PF_R, Off: 0x14000, Vaddr: 0x7f5407e99000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
 
146
                        {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x15000, Vaddr: 0x7f5407e9a000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000},
 
147
                        {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x17000, Vaddr: 0x7fff79972000, Paddr: 0x0, Filesz: 0x23000, Memsz: 0x23000, Align: 0x1000},
 
148
                        {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3a000, Vaddr: 0x7fff799f8000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
 
149
                        {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3b000, Vaddr: 0xffffffffff600000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
 
150
                },
 
151
                nil,
120
152
        },
121
153
}
122
154
 
124
156
        for i := range fileTests {
125
157
                tt := &fileTests[i]
126
158
 
127
 
                f, err := Open(tt.file)
 
159
                var f *File
 
160
                var err error
 
161
                if path.Ext(tt.file) == ".gz" {
 
162
                        var r io.ReaderAt
 
163
                        if r, err = decompress(tt.file); err == nil {
 
164
                                f, err = NewFile(r)
 
165
                        }
 
166
                } else {
 
167
                        f, err = Open(tt.file)
 
168
                }
128
169
                if err != nil {
129
 
                        t.Error(err)
 
170
                        t.Errorf("cannot open file %s: %v", tt.file, err)
130
171
                        continue
131
172
                }
132
173
                if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
161
202
                if tn != fn {
162
203
                        t.Errorf("open %s: len(Progs) = %d, want %d", tt.file, fn, tn)
163
204
                }
164
 
        }
 
205
                tl := tt.needed
 
206
                fl, err := f.ImportedLibraries()
 
207
                if err != nil {
 
208
                        t.Error(err)
 
209
                }
 
210
                if !reflect.DeepEqual(tl, fl) {
 
211
                        t.Errorf("open %s: DT_NEEDED = %v, want %v", tt.file, tl, fl)
 
212
                }
 
213
        }
 
214
}
 
215
 
 
216
// elf.NewFile requires io.ReaderAt, which compress/gzip cannot
 
217
// provide. Decompress the file to a bytes.Reader.
 
218
func decompress(gz string) (io.ReaderAt, error) {
 
219
        in, err := os.Open(gz)
 
220
        if err != nil {
 
221
                return nil, err
 
222
        }
 
223
        defer in.Close()
 
224
        r, err := gzip.NewReader(in)
 
225
        if err != nil {
 
226
                return nil, err
 
227
        }
 
228
        var out bytes.Buffer
 
229
        _, err = io.Copy(&out, r)
 
230
        return bytes.NewReader(out.Bytes()), err
 
231
}
 
232
 
 
233
type relocationTestEntry struct {
 
234
        entryNumber int
 
235
        entry       *dwarf.Entry
165
236
}
166
237
 
167
238
type relocationTest struct {
168
 
        file       string
169
 
        firstEntry *dwarf.Entry
 
239
        file    string
 
240
        entries []relocationTestEntry
170
241
}
171
242
 
172
243
var relocationTests = []relocationTest{
173
244
        {
174
245
                "testdata/go-relocation-test-gcc441-x86-64.obj",
175
 
                &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}},
 
246
                []relocationTestEntry{
 
247
                        {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
 
248
                },
176
249
        },
177
250
        {
178
251
                "testdata/go-relocation-test-gcc441-x86.obj",
179
 
                &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "t.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x5)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}},
 
252
                []relocationTestEntry{
 
253
                        {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "t.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x5)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
 
254
                },
180
255
        },
181
256
        {
182
257
                "testdata/go-relocation-test-gcc424-x86-64.obj",
183
 
                &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}},
 
258
                []relocationTestEntry{
 
259
                        {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
 
260
                },
 
261
        },
 
262
        {
 
263
                "testdata/gcc-amd64-openbsd-debug-with-rela.obj",
 
264
                []relocationTestEntry{
 
265
                        {203, &dwarf.Entry{Offset: 0xc62, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{{Attr: dwarf.AttrName, Val: "it_interval"}, {Attr: dwarf.AttrDeclFile, Val: int64(7)}, {Attr: dwarf.AttrDeclLine, Val: int64(236)}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f)}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}}}}},
 
266
                        {204, &dwarf.Entry{Offset: 0xc70, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{{Attr: dwarf.AttrName, Val: "it_value"}, {Attr: dwarf.AttrDeclFile, Val: int64(7)}, {Attr: dwarf.AttrDeclLine, Val: int64(237)}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f)}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}}}}},
 
267
                },
184
268
        },
185
269
}
186
270
 
196
280
                        t.Error(err)
197
281
                        continue
198
282
                }
199
 
                reader := dwarf.Reader()
200
 
                // Checking only the first entry is sufficient since it has
201
 
                // many different strings. If the relocation had failed, all
202
 
                // the string offsets would be zero and all the strings would
203
 
                // end up being the same.
204
 
                firstEntry, err := reader.Next()
205
 
                if err != nil {
206
 
                        t.Error(err)
207
 
                        continue
208
 
                }
209
 
 
210
 
                if !reflect.DeepEqual(test.firstEntry, firstEntry) {
211
 
                        t.Errorf("#%d: mismatch: got:%#v want:%#v", i, firstEntry, test.firstEntry)
212
 
                        continue
 
283
                for _, testEntry := range test.entries {
 
284
                        reader := dwarf.Reader()
 
285
                        for j := 0; j < testEntry.entryNumber; j++ {
 
286
                                entry, err := reader.Next()
 
287
                                if entry == nil || err != nil {
 
288
                                        t.Errorf("Failed to skip to entry %d: %v", testEntry.entryNumber, err)
 
289
                                        continue
 
290
                                }
 
291
                        }
 
292
                        entry, err := reader.Next()
 
293
                        if err != nil {
 
294
                                t.Error(err)
 
295
                                continue
 
296
                        }
 
297
                        if !reflect.DeepEqual(testEntry.entry, entry) {
 
298
                                t.Errorf("#%d/%d: mismatch: got:%#v want:%#v", i, testEntry.entryNumber, entry, testEntry.entry)
 
299
                                continue
 
300
                        }
213
301
                }
214
302
        }
215
303
}