2012-03-27 23:13:14 +00:00
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
2014-09-21 17:33:12 +00:00
package elf
2012-03-27 23:13:14 +00:00
import (
2014-09-21 17:33:12 +00:00
"bytes"
"compress/gzip"
2012-03-27 23:13:14 +00:00
"debug/dwarf"
"encoding/binary"
2014-09-21 17:33:12 +00:00
"io"
2012-03-27 23:13:14 +00:00
"net"
"os"
2014-09-21 17:33:12 +00:00
"path"
2012-03-27 23:13:14 +00:00
"reflect"
"runtime"
"testing"
)
type fileTest struct {
file string
hdr FileHeader
sections [ ] SectionHeader
progs [ ] ProgHeader
2014-09-21 17:33:12 +00:00
needed [ ] string
2012-03-27 23:13:14 +00:00
}
var fileTests = [ ] fileTest {
{
"testdata/gcc-386-freebsd-exec" ,
2014-09-21 17:33:12 +00:00
FileHeader { ELFCLASS32 , ELFDATA2LSB , EV_CURRENT , ELFOSABI_FREEBSD , 0 , binary . LittleEndian , ET_EXEC , EM_386 , 0x80483cc } ,
2012-03-27 23:13:14 +00:00
[ ] SectionHeader {
{ "" , SHT_NULL , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
{ ".interp" , SHT_PROGBITS , SHF_ALLOC , 0x80480d4 , 0xd4 , 0x15 , 0x0 , 0x0 , 0x1 , 0x0 } ,
{ ".hash" , SHT_HASH , SHF_ALLOC , 0x80480ec , 0xec , 0x90 , 0x3 , 0x0 , 0x4 , 0x4 } ,
{ ".dynsym" , SHT_DYNSYM , SHF_ALLOC , 0x804817c , 0x17c , 0x110 , 0x4 , 0x1 , 0x4 , 0x10 } ,
{ ".dynstr" , SHT_STRTAB , SHF_ALLOC , 0x804828c , 0x28c , 0xbb , 0x0 , 0x0 , 0x1 , 0x0 } ,
{ ".rel.plt" , SHT_REL , SHF_ALLOC , 0x8048348 , 0x348 , 0x20 , 0x3 , 0x7 , 0x4 , 0x8 } ,
{ ".init" , SHT_PROGBITS , SHF_ALLOC + SHF_EXECINSTR , 0x8048368 , 0x368 , 0x11 , 0x0 , 0x0 , 0x4 , 0x0 } ,
{ ".plt" , SHT_PROGBITS , SHF_ALLOC + SHF_EXECINSTR , 0x804837c , 0x37c , 0x50 , 0x0 , 0x0 , 0x4 , 0x4 } ,
{ ".text" , SHT_PROGBITS , SHF_ALLOC + SHF_EXECINSTR , 0x80483cc , 0x3cc , 0x180 , 0x0 , 0x0 , 0x4 , 0x0 } ,
{ ".fini" , SHT_PROGBITS , SHF_ALLOC + SHF_EXECINSTR , 0x804854c , 0x54c , 0xc , 0x0 , 0x0 , 0x4 , 0x0 } ,
{ ".rodata" , SHT_PROGBITS , SHF_ALLOC , 0x8048558 , 0x558 , 0xa3 , 0x0 , 0x0 , 0x1 , 0x0 } ,
{ ".data" , SHT_PROGBITS , SHF_WRITE + SHF_ALLOC , 0x80495fc , 0x5fc , 0xc , 0x0 , 0x0 , 0x4 , 0x0 } ,
{ ".eh_frame" , SHT_PROGBITS , SHF_ALLOC , 0x8049608 , 0x608 , 0x4 , 0x0 , 0x0 , 0x4 , 0x0 } ,
{ ".dynamic" , SHT_DYNAMIC , SHF_WRITE + SHF_ALLOC , 0x804960c , 0x60c , 0x98 , 0x4 , 0x0 , 0x4 , 0x8 } ,
{ ".ctors" , SHT_PROGBITS , SHF_WRITE + SHF_ALLOC , 0x80496a4 , 0x6a4 , 0x8 , 0x0 , 0x0 , 0x4 , 0x0 } ,
{ ".dtors" , SHT_PROGBITS , SHF_WRITE + SHF_ALLOC , 0x80496ac , 0x6ac , 0x8 , 0x0 , 0x0 , 0x4 , 0x0 } ,
{ ".jcr" , SHT_PROGBITS , SHF_WRITE + SHF_ALLOC , 0x80496b4 , 0x6b4 , 0x4 , 0x0 , 0x0 , 0x4 , 0x0 } ,
{ ".got" , SHT_PROGBITS , SHF_WRITE + SHF_ALLOC , 0x80496b8 , 0x6b8 , 0x1c , 0x0 , 0x0 , 0x4 , 0x4 } ,
{ ".bss" , SHT_NOBITS , SHF_WRITE + SHF_ALLOC , 0x80496d4 , 0x6d4 , 0x20 , 0x0 , 0x0 , 0x4 , 0x0 } ,
{ ".comment" , SHT_PROGBITS , 0x0 , 0x0 , 0x6d4 , 0x12d , 0x0 , 0x0 , 0x1 , 0x0 } ,
{ ".debug_aranges" , SHT_PROGBITS , 0x0 , 0x0 , 0x801 , 0x20 , 0x0 , 0x0 , 0x1 , 0x0 } ,
{ ".debug_pubnames" , SHT_PROGBITS , 0x0 , 0x0 , 0x821 , 0x1b , 0x0 , 0x0 , 0x1 , 0x0 } ,
{ ".debug_info" , SHT_PROGBITS , 0x0 , 0x0 , 0x83c , 0x11d , 0x0 , 0x0 , 0x1 , 0x0 } ,
{ ".debug_abbrev" , SHT_PROGBITS , 0x0 , 0x0 , 0x959 , 0x41 , 0x0 , 0x0 , 0x1 , 0x0 } ,
{ ".debug_line" , SHT_PROGBITS , 0x0 , 0x0 , 0x99a , 0x35 , 0x0 , 0x0 , 0x1 , 0x0 } ,
{ ".debug_frame" , SHT_PROGBITS , 0x0 , 0x0 , 0x9d0 , 0x30 , 0x0 , 0x0 , 0x4 , 0x0 } ,
{ ".debug_str" , SHT_PROGBITS , 0x0 , 0x0 , 0xa00 , 0xd , 0x0 , 0x0 , 0x1 , 0x0 } ,
{ ".shstrtab" , SHT_STRTAB , 0x0 , 0x0 , 0xa0d , 0xf8 , 0x0 , 0x0 , 0x1 , 0x0 } ,
{ ".symtab" , SHT_SYMTAB , 0x0 , 0x0 , 0xfb8 , 0x4b0 , 0x1d , 0x38 , 0x4 , 0x10 } ,
{ ".strtab" , SHT_STRTAB , 0x0 , 0x0 , 0x1468 , 0x206 , 0x0 , 0x0 , 0x1 , 0x0 } ,
} ,
[ ] ProgHeader {
{ PT_PHDR , PF_R + PF_X , 0x34 , 0x8048034 , 0x8048034 , 0xa0 , 0xa0 , 0x4 } ,
{ PT_INTERP , PF_R , 0xd4 , 0x80480d4 , 0x80480d4 , 0x15 , 0x15 , 0x1 } ,
{ PT_LOAD , PF_R + PF_X , 0x0 , 0x8048000 , 0x8048000 , 0x5fb , 0x5fb , 0x1000 } ,
{ PT_LOAD , PF_R + PF_W , 0x5fc , 0x80495fc , 0x80495fc , 0xd8 , 0xf8 , 0x1000 } ,
{ PT_DYNAMIC , PF_R + PF_W , 0x60c , 0x804960c , 0x804960c , 0x98 , 0x98 , 0x4 } ,
} ,
2014-09-21 17:33:12 +00:00
[ ] string { "libc.so.6" } ,
2012-03-27 23:13:14 +00:00
} ,
{
"testdata/gcc-amd64-linux-exec" ,
2014-09-21 17:33:12 +00:00
FileHeader { ELFCLASS64 , ELFDATA2LSB , EV_CURRENT , ELFOSABI_NONE , 0 , binary . LittleEndian , ET_EXEC , EM_X86_64 , 0x4003e0 } ,
2012-03-27 23:13:14 +00:00
[ ] SectionHeader {
{ "" , SHT_NULL , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ,
{ ".interp" , SHT_PROGBITS , SHF_ALLOC , 0x400200 , 0x200 , 0x1c , 0x0 , 0x0 , 0x1 , 0x0 } ,
{ ".note.ABI-tag" , SHT_NOTE , SHF_ALLOC , 0x40021c , 0x21c , 0x20 , 0x0 , 0x0 , 0x4 , 0x0 } ,
{ ".hash" , SHT_HASH , SHF_ALLOC , 0x400240 , 0x240 , 0x24 , 0x5 , 0x0 , 0x8 , 0x4 } ,
{ ".gnu.hash" , SHT_LOOS + 268435446 , SHF_ALLOC , 0x400268 , 0x268 , 0x1c , 0x5 , 0x0 , 0x8 , 0x0 } ,
{ ".dynsym" , SHT_DYNSYM , SHF_ALLOC , 0x400288 , 0x288 , 0x60 , 0x6 , 0x1 , 0x8 , 0x18 } ,
{ ".dynstr" , SHT_STRTAB , SHF_ALLOC , 0x4002e8 , 0x2e8 , 0x3d , 0x0 , 0x0 , 0x1 , 0x0 } ,
{ ".gnu.version" , SHT_HIOS , SHF_ALLOC , 0x400326 , 0x326 , 0x8 , 0x5 , 0x0 , 0x2 , 0x2 } ,
{ ".gnu.version_r" , SHT_LOOS + 268435454 , SHF_ALLOC , 0x400330 , 0x330 , 0x20 , 0x6 , 0x1 , 0x8 , 0x0 } ,
{ ".rela.dyn" , SHT_RELA , SHF_ALLOC , 0x400350 , 0x350 , 0x18 , 0x5 , 0x0 , 0x8 , 0x18 } ,
{ ".rela.plt" , SHT_RELA , SHF_ALLOC , 0x400368 , 0x368 , 0x30 , 0x5 , 0xc , 0x8 , 0x18 } ,
{ ".init" , SHT_PROGBITS , SHF_ALLOC + SHF_EXECINSTR , 0x400398 , 0x398 , 0x18 , 0x0 , 0x0 , 0x4 , 0x0 } ,
{ ".plt" , SHT_PROGBITS , SHF_ALLOC + SHF_EXECINSTR , 0x4003b0 , 0x3b0 , 0x30 , 0x0 , 0x0 , 0x4 , 0x10 } ,
{ ".text" , SHT_PROGBITS , SHF_ALLOC + SHF_EXECINSTR , 0x4003e0 , 0x3e0 , 0x1b4 , 0x0 , 0x0 , 0x10 , 0x0 } ,
{ ".fini" , SHT_PROGBITS , SHF_ALLOC + SHF_EXECINSTR , 0x400594 , 0x594 , 0xe , 0x0 , 0x0 , 0x4 , 0x0 } ,
{ ".rodata" , SHT_PROGBITS , SHF_ALLOC , 0x4005a4 , 0x5a4 , 0x11 , 0x0 , 0x0 , 0x4 , 0x0 } ,
{ ".eh_frame_hdr" , SHT_PROGBITS , SHF_ALLOC , 0x4005b8 , 0x5b8 , 0x24 , 0x0 , 0x0 , 0x4 , 0x0 } ,
{ ".eh_frame" , SHT_PROGBITS , SHF_ALLOC , 0x4005e0 , 0x5e0 , 0xa4 , 0x0 , 0x0 , 0x8 , 0x0 } ,
{ ".ctors" , SHT_PROGBITS , SHF_WRITE + SHF_ALLOC , 0x600688 , 0x688 , 0x10 , 0x0 , 0x0 , 0x8 , 0x0 } ,
{ ".dtors" , SHT_PROGBITS , SHF_WRITE + SHF_ALLOC , 0x600698 , 0x698 , 0x10 , 0x0 , 0x0 , 0x8 , 0x0 } ,
{ ".jcr" , SHT_PROGBITS , SHF_WRITE + SHF_ALLOC , 0x6006a8 , 0x6a8 , 0x8 , 0x0 , 0x0 , 0x8 , 0x0 } ,
{ ".dynamic" , SHT_DYNAMIC , SHF_WRITE + SHF_ALLOC , 0x6006b0 , 0x6b0 , 0x1a0 , 0x6 , 0x0 , 0x8 , 0x10 } ,
{ ".got" , SHT_PROGBITS , SHF_WRITE + SHF_ALLOC , 0x600850 , 0x850 , 0x8 , 0x0 , 0x0 , 0x8 , 0x8 } ,
{ ".got.plt" , SHT_PROGBITS , SHF_WRITE + SHF_ALLOC , 0x600858 , 0x858 , 0x28 , 0x0 , 0x0 , 0x8 , 0x8 } ,
{ ".data" , SHT_PROGBITS , SHF_WRITE + SHF_ALLOC , 0x600880 , 0x880 , 0x18 , 0x0 , 0x0 , 0x8 , 0x0 } ,
{ ".bss" , SHT_NOBITS , SHF_WRITE + SHF_ALLOC , 0x600898 , 0x898 , 0x8 , 0x0 , 0x0 , 0x4 , 0x0 } ,
{ ".comment" , SHT_PROGBITS , 0x0 , 0x0 , 0x898 , 0x126 , 0x0 , 0x0 , 0x1 , 0x0 } ,
{ ".debug_aranges" , SHT_PROGBITS , 0x0 , 0x0 , 0x9c0 , 0x90 , 0x0 , 0x0 , 0x10 , 0x0 } ,
{ ".debug_pubnames" , SHT_PROGBITS , 0x0 , 0x0 , 0xa50 , 0x25 , 0x0 , 0x0 , 0x1 , 0x0 } ,
{ ".debug_info" , SHT_PROGBITS , 0x0 , 0x0 , 0xa75 , 0x1a7 , 0x0 , 0x0 , 0x1 , 0x0 } ,
{ ".debug_abbrev" , SHT_PROGBITS , 0x0 , 0x0 , 0xc1c , 0x6f , 0x0 , 0x0 , 0x1 , 0x0 } ,
{ ".debug_line" , SHT_PROGBITS , 0x0 , 0x0 , 0xc8b , 0x13f , 0x0 , 0x0 , 0x1 , 0x0 } ,
{ ".debug_str" , SHT_PROGBITS , SHF_MERGE + SHF_STRINGS , 0x0 , 0xdca , 0xb1 , 0x0 , 0x0 , 0x1 , 0x1 } ,
{ ".debug_ranges" , SHT_PROGBITS , 0x0 , 0x0 , 0xe80 , 0x90 , 0x0 , 0x0 , 0x10 , 0x0 } ,
{ ".shstrtab" , SHT_STRTAB , 0x0 , 0x0 , 0xf10 , 0x149 , 0x0 , 0x0 , 0x1 , 0x0 } ,
{ ".symtab" , SHT_SYMTAB , 0x0 , 0x0 , 0x19a0 , 0x6f0 , 0x24 , 0x39 , 0x8 , 0x18 } ,
{ ".strtab" , SHT_STRTAB , 0x0 , 0x0 , 0x2090 , 0x1fc , 0x0 , 0x0 , 0x1 , 0x0 } ,
} ,
[ ] ProgHeader {
{ PT_PHDR , PF_R + PF_X , 0x40 , 0x400040 , 0x400040 , 0x1c0 , 0x1c0 , 0x8 } ,
{ PT_INTERP , PF_R , 0x200 , 0x400200 , 0x400200 , 0x1c , 0x1c , 1 } ,
{ PT_LOAD , PF_R + PF_X , 0x0 , 0x400000 , 0x400000 , 0x684 , 0x684 , 0x200000 } ,
{ PT_LOAD , PF_R + PF_W , 0x688 , 0x600688 , 0x600688 , 0x210 , 0x218 , 0x200000 } ,
{ PT_DYNAMIC , PF_R + PF_W , 0x6b0 , 0x6006b0 , 0x6006b0 , 0x1a0 , 0x1a0 , 0x8 } ,
{ PT_NOTE , PF_R , 0x21c , 0x40021c , 0x40021c , 0x20 , 0x20 , 0x4 } ,
{ PT_LOOS + 0x474E550 , PF_R , 0x5b8 , 0x4005b8 , 0x4005b8 , 0x24 , 0x24 , 0x4 } ,
{ PT_LOOS + 0x474E551 , PF_R + PF_W , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x8 } ,
} ,
2014-09-21 17:33:12 +00:00
[ ] string { "libc.so.6" } ,
} ,
{
"testdata/hello-world-core.gz" ,
FileHeader { ELFCLASS64 , ELFDATA2LSB , EV_CURRENT , ELFOSABI_NONE , 0x0 , binary . LittleEndian , ET_CORE , EM_X86_64 , 0x0 } ,
[ ] SectionHeader { } ,
[ ] ProgHeader {
{ Type : PT_NOTE , Flags : 0x0 , Off : 0x3f8 , Vaddr : 0x0 , Paddr : 0x0 , Filesz : 0x8ac , Memsz : 0x0 , Align : 0x0 } ,
{ Type : PT_LOAD , Flags : PF_X + PF_R , Off : 0x1000 , Vaddr : 0x400000 , Paddr : 0x0 , Filesz : 0x0 , Memsz : 0x1000 , Align : 0x1000 } ,
{ Type : PT_LOAD , Flags : PF_R , Off : 0x1000 , Vaddr : 0x401000 , Paddr : 0x0 , Filesz : 0x1000 , Memsz : 0x1000 , Align : 0x1000 } ,
{ Type : PT_LOAD , Flags : PF_W + PF_R , Off : 0x2000 , Vaddr : 0x402000 , Paddr : 0x0 , Filesz : 0x1000 , Memsz : 0x1000 , Align : 0x1000 } ,
{ Type : PT_LOAD , Flags : PF_X + PF_R , Off : 0x3000 , Vaddr : 0x7f54078b8000 , Paddr : 0x0 , Filesz : 0x0 , Memsz : 0x1b5000 , Align : 0x1000 } ,
{ Type : PT_LOAD , Flags : 0x0 , Off : 0x3000 , Vaddr : 0x7f5407a6d000 , Paddr : 0x0 , Filesz : 0x0 , Memsz : 0x1ff000 , Align : 0x1000 } ,
{ Type : PT_LOAD , Flags : PF_R , Off : 0x3000 , Vaddr : 0x7f5407c6c000 , Paddr : 0x0 , Filesz : 0x4000 , Memsz : 0x4000 , Align : 0x1000 } ,
{ Type : PT_LOAD , Flags : PF_W + PF_R , Off : 0x7000 , Vaddr : 0x7f5407c70000 , Paddr : 0x0 , Filesz : 0x2000 , Memsz : 0x2000 , Align : 0x1000 } ,
{ Type : PT_LOAD , Flags : PF_W + PF_R , Off : 0x9000 , Vaddr : 0x7f5407c72000 , Paddr : 0x0 , Filesz : 0x5000 , Memsz : 0x5000 , Align : 0x1000 } ,
{ Type : PT_LOAD , Flags : PF_X + PF_R , Off : 0xe000 , Vaddr : 0x7f5407c77000 , Paddr : 0x0 , Filesz : 0x0 , Memsz : 0x22000 , Align : 0x1000 } ,
{ Type : PT_LOAD , Flags : PF_W + PF_R , Off : 0xe000 , Vaddr : 0x7f5407e81000 , Paddr : 0x0 , Filesz : 0x3000 , Memsz : 0x3000 , Align : 0x1000 } ,
{ Type : PT_LOAD , Flags : PF_W + PF_R , Off : 0x11000 , Vaddr : 0x7f5407e96000 , Paddr : 0x0 , Filesz : 0x3000 , Memsz : 0x3000 , Align : 0x1000 } ,
{ Type : PT_LOAD , Flags : PF_R , Off : 0x14000 , Vaddr : 0x7f5407e99000 , Paddr : 0x0 , Filesz : 0x1000 , Memsz : 0x1000 , Align : 0x1000 } ,
{ Type : PT_LOAD , Flags : PF_W + PF_R , Off : 0x15000 , Vaddr : 0x7f5407e9a000 , Paddr : 0x0 , Filesz : 0x2000 , Memsz : 0x2000 , Align : 0x1000 } ,
{ Type : PT_LOAD , Flags : PF_W + PF_R , Off : 0x17000 , Vaddr : 0x7fff79972000 , Paddr : 0x0 , Filesz : 0x23000 , Memsz : 0x23000 , Align : 0x1000 } ,
{ Type : PT_LOAD , Flags : PF_X + PF_R , Off : 0x3a000 , Vaddr : 0x7fff799f8000 , Paddr : 0x0 , Filesz : 0x1000 , Memsz : 0x1000 , Align : 0x1000 } ,
{ Type : PT_LOAD , Flags : PF_X + PF_R , Off : 0x3b000 , Vaddr : 0xffffffffff600000 , Paddr : 0x0 , Filesz : 0x1000 , Memsz : 0x1000 , Align : 0x1000 } ,
} ,
nil ,
2012-03-27 23:13:14 +00:00
} ,
}
func TestOpen ( t * testing . T ) {
for i := range fileTests {
tt := & fileTests [ i ]
2014-09-21 17:33:12 +00:00
var f * File
var err error
if path . Ext ( tt . file ) == ".gz" {
var r io . ReaderAt
if r , err = decompress ( tt . file ) ; err == nil {
f , err = NewFile ( r )
}
} else {
f , err = Open ( tt . file )
}
defer f . Close ( )
2012-03-27 23:13:14 +00:00
if err != nil {
2014-09-21 17:33:12 +00:00
t . Errorf ( "cannot open file %s: %v" , tt . file , err )
2012-03-27 23:13:14 +00:00
continue
}
if ! reflect . DeepEqual ( f . FileHeader , tt . hdr ) {
t . Errorf ( "open %s:\n\thave %#v\n\twant %#v\n" , tt . file , f . FileHeader , tt . hdr )
continue
}
for i , s := range f . Sections {
if i >= len ( tt . sections ) {
break
}
sh := & tt . sections [ i ]
if ! reflect . DeepEqual ( & s . SectionHeader , sh ) {
t . Errorf ( "open %s, section %d:\n\thave %#v\n\twant %#v\n" , tt . file , i , & s . SectionHeader , sh )
}
}
for i , p := range f . Progs {
if i >= len ( tt . progs ) {
break
}
ph := & tt . progs [ i ]
if ! reflect . DeepEqual ( & p . ProgHeader , ph ) {
t . Errorf ( "open %s, program %d:\n\thave %#v\n\twant %#v\n" , tt . file , i , & p . ProgHeader , ph )
}
}
tn := len ( tt . sections )
fn := len ( f . Sections )
if tn != fn {
t . Errorf ( "open %s: len(Sections) = %d, want %d" , tt . file , fn , tn )
}
tn = len ( tt . progs )
fn = len ( f . Progs )
if tn != fn {
t . Errorf ( "open %s: len(Progs) = %d, want %d" , tt . file , fn , tn )
}
2014-09-21 17:33:12 +00:00
tl := tt . needed
fl , err := f . ImportedLibraries ( )
if err != nil {
t . Error ( err )
}
if ! reflect . DeepEqual ( tl , fl ) {
t . Errorf ( "open %s: DT_NEEDED = %v, want %v" , tt . file , tl , fl )
}
2012-03-27 23:13:14 +00:00
}
}
2014-09-21 17:33:12 +00:00
// elf.NewFile requires io.ReaderAt, which compress/gzip cannot
// provide. Decompress the file to a bytes.Reader.
func decompress ( gz string ) ( io . ReaderAt , error ) {
in , err := os . Open ( gz )
if err != nil {
return nil , err
}
defer in . Close ( )
r , err := gzip . NewReader ( in )
if err != nil {
return nil , err
}
var out bytes . Buffer
_ , err = io . Copy ( & out , r )
return bytes . NewReader ( out . Bytes ( ) ) , err
}
type relocationTestEntry struct {
entryNumber int
entry * dwarf . Entry
}
2012-03-27 23:13:14 +00:00
type relocationTest struct {
2014-09-21 17:33:12 +00:00
file string
entries [ ] relocationTestEntry
2012-03-27 23:13:14 +00:00
}
var relocationTests = [ ] relocationTest {
{
"testdata/go-relocation-test-gcc441-x86-64.obj" ,
2014-09-21 17:33:12 +00:00
[ ] relocationTestEntry {
{ 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 ) } } } } ,
} ,
2012-03-27 23:13:14 +00:00
} ,
{
"testdata/go-relocation-test-gcc441-x86.obj" ,
2014-09-21 17:33:12 +00:00
[ ] relocationTestEntry {
{ 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 ) } } } } ,
} ,
2012-03-27 23:13:14 +00:00
} ,
{
"testdata/go-relocation-test-gcc424-x86-64.obj" ,
2014-09-21 17:33:12 +00:00
[ ] relocationTestEntry {
{ 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 ) } } } } ,
} ,
} ,
{
"testdata/gcc-amd64-openbsd-debug-with-rela.obj" ,
[ ] relocationTestEntry {
{ 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 } } } } } ,
{ 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 } } } } } ,
} ,
2012-03-27 23:13:14 +00:00
} ,
}
func TestDWARFRelocations ( t * testing . T ) {
for i , test := range relocationTests {
f , err := Open ( test . file )
if err != nil {
t . Error ( err )
continue
}
dwarf , err := f . DWARF ( )
if err != nil {
t . Error ( err )
continue
}
2014-09-21 17:33:12 +00:00
for _ , testEntry := range test . entries {
reader := dwarf . Reader ( )
for j := 0 ; j < testEntry . entryNumber ; j ++ {
entry , err := reader . Next ( )
if entry == nil || err != nil {
t . Errorf ( "Failed to skip to entry %d: %v" , testEntry . entryNumber , err )
continue
}
}
entry , err := reader . Next ( )
if err != nil {
t . Error ( err )
continue
}
if ! reflect . DeepEqual ( testEntry . entry , entry ) {
t . Errorf ( "#%d/%d: mismatch: got:%#v want:%#v" , i , testEntry . entryNumber , entry , testEntry . entry )
continue
}
2012-03-27 23:13:14 +00:00
}
}
}
func TestNoSectionOverlaps ( t * testing . T ) {
// Ensure 6l outputs sections without overlaps.
if runtime . GOOS != "linux" && runtime . GOOS != "freebsd" {
return // not ELF
}
_ = net . ResolveIPAddr // force dynamic linkage
f , err := Open ( os . Args [ 0 ] )
if err != nil {
t . Error ( err )
return
}
for i , si := range f . Sections {
sih := si . SectionHeader
if sih . Type == SHT_NOBITS {
continue
}
for j , sj := range f . Sections {
sjh := sj . SectionHeader
if i == j || sjh . Type == SHT_NOBITS || sih . Offset == sjh . Offset && sih . Size == 0 {
continue
}
if sih . Offset >= sjh . Offset && sih . Offset < sjh . Offset + sjh . Size {
t . Errorf ( "ld produced ELF with section %s within %s: 0x%x <= 0x%x..0x%x < 0x%x" ,
sih . Name , sjh . Name , sjh . Offset , sih . Offset , sih . Offset + sih . Size , sjh . Offset + sjh . Size )
}
}
}
}