aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/debug
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2011-09-16 15:47:21 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-09-16 15:47:21 +0000
commitadb0401dac41c81571722312d4586b2693f95aa6 (patch)
treeea2b52e3c258d6b6d9356977c683c7f72a4a5fd5 /libgo/go/debug
parent5548ca3540bccbc908a45942896d635ea5f1c23f (diff)
downloadgcc-adb0401dac41c81571722312d4586b2693f95aa6.zip
gcc-adb0401dac41c81571722312d4586b2693f95aa6.tar.gz
gcc-adb0401dac41c81571722312d4586b2693f95aa6.tar.bz2
Update Go library to r60.
From-SVN: r178910
Diffstat (limited to 'libgo/go/debug')
-rw-r--r--libgo/go/debug/dwarf/type.go17
-rw-r--r--libgo/go/debug/dwarf/type_test.go1
-rw-r--r--libgo/go/debug/elf/elf.go2
-rw-r--r--libgo/go/debug/elf/file.go81
-rw-r--r--libgo/go/debug/elf/file_test.go70
-rw-r--r--libgo/go/debug/elf/testdata/go-relocation-test-gcc424-x86-64.obj (renamed from libgo/go/debug/elf/testdata/go-relocation-test-gcc424-x86-64.o)bin3088 -> 3088 bytes
-rw-r--r--libgo/go/debug/elf/testdata/go-relocation-test-gcc441-x86-64.obj (renamed from libgo/go/debug/elf/testdata/go-relocation-test-gcc441-x86-64.o)bin2936 -> 2936 bytes
-rw-r--r--libgo/go/debug/elf/testdata/go-relocation-test-gcc441-x86.obj (renamed from libgo/go/debug/elf/testdata/go-relocation-test-gcc441-x86.o)bin1884 -> 1884 bytes
-rw-r--r--libgo/go/debug/macho/file.go2
-rw-r--r--libgo/go/debug/pe/file.go41
-rw-r--r--libgo/go/debug/proc/proc.go222
-rw-r--r--libgo/go/debug/proc/proc_darwin.go17
-rw-r--r--libgo/go/debug/proc/proc_freebsd.go17
-rw-r--r--libgo/go/debug/proc/proc_linux.go1322
-rw-r--r--libgo/go/debug/proc/proc_windows.go17
-rw-r--r--libgo/go/debug/proc/regs_darwin_386.go5
-rw-r--r--libgo/go/debug/proc/regs_darwin_amd64.go5
-rw-r--r--libgo/go/debug/proc/regs_freebsd_386.go5
-rw-r--r--libgo/go/debug/proc/regs_freebsd_amd64.go5
-rw-r--r--libgo/go/debug/proc/regs_linux_386.go143
-rw-r--r--libgo/go/debug/proc/regs_linux_amd64.go191
-rw-r--r--libgo/go/debug/proc/regs_linux_arm.go39
-rw-r--r--libgo/go/debug/proc/regs_windows_386.go5
-rw-r--r--libgo/go/debug/proc/regs_windows_amd64.go5
24 files changed, 172 insertions, 2040 deletions
diff --git a/libgo/go/debug/dwarf/type.go b/libgo/go/debug/dwarf/type.go
index 902a545..f35365e 100644
--- a/libgo/go/debug/dwarf/type.go
+++ b/libgo/go/debug/dwarf/type.go
@@ -352,8 +352,8 @@ func (d *Data) Type(off Offset) (Type, os.Error) {
}
}
if ndim == 0 {
- err = DecodeError{"info", e.Offset, "missing dimension for array"}
- goto Error
+ // LLVM generates this for x[].
+ t.Count = -1
}
case TagBaseType:
@@ -523,7 +523,7 @@ func (d *Data) Type(off Offset) (Type, os.Error) {
// Attributes:
// AttrType: type of return value if any
// AttrName: possible name of type [ignored]
- // AttrPrototyped: whether used ANSI C prototye [ignored]
+ // AttrPrototyped: whether used ANSI C prototype [ignored]
// Children:
// TagFormalParameter: typed parameter
// AttrType: type of parameter
@@ -566,12 +566,13 @@ func (d *Data) Type(off Offset) (Type, os.Error) {
goto Error
}
- b, ok := e.Val(AttrByteSize).(int64)
- if !ok {
- b = -1
+ {
+ b, ok := e.Val(AttrByteSize).(int64)
+ if !ok {
+ b = -1
+ }
+ typ.Common().ByteSize = b
}
- typ.Common().ByteSize = b
-
return typ, nil
Error:
diff --git a/libgo/go/debug/dwarf/type_test.go b/libgo/go/debug/dwarf/type_test.go
index e01f735..b9470a4 100644
--- a/libgo/go/debug/dwarf/type_test.go
+++ b/libgo/go/debug/dwarf/type_test.go
@@ -58,7 +58,6 @@ func machoData(t *testing.T, name string) *Data {
return d
}
-
func TestTypedefsELF(t *testing.T) { testTypedefs(t, elfData(t, "testdata/typedef.elf")) }
func TestTypedefsMachO(t *testing.T) {
diff --git a/libgo/go/debug/elf/elf.go b/libgo/go/debug/elf/elf.go
index 5d45b24..c71b230 100644
--- a/libgo/go/debug/elf/elf.go
+++ b/libgo/go/debug/elf/elf.go
@@ -1289,7 +1289,6 @@ func (i R_SPARC) GoString() string { return stringName(uint32(i), rsparcStrings,
// Magic number for the elf trampoline, chosen wisely to be an immediate value.
const ARM_MAGIC_TRAMP_NUMBER = 0x5c000003
-
// ELF32 File header.
type Header32 struct {
Ident [EI_NIDENT]byte /* File identification. */
@@ -1455,7 +1454,6 @@ func R_SYM64(info uint64) uint32 { return uint32(info >> 32) }
func R_TYPE64(info uint64) uint32 { return uint32(info) }
func R_INFO(sym, typ uint32) uint64 { return uint64(sym)<<32 | uint64(typ) }
-
// ELF64 symbol table entries.
type Sym64 struct {
Name uint32 /* String table index of name. */
diff --git a/libgo/go/debug/elf/file.go b/libgo/go/debug/elf/file.go
index 9ae8b41..a0ddb1f 100644
--- a/libgo/go/debug/elf/file.go
+++ b/libgo/go/debug/elf/file.go
@@ -81,7 +81,7 @@ func (s *Section) Data() ([]byte, os.Error) {
// specified link value.
func (f *File) stringTable(link uint32) ([]byte, os.Error) {
if link <= 0 || link >= uint32(len(f.Sections)) {
- return nil, os.ErrorString("section has invalid string table link")
+ return nil, os.NewError("section has invalid string table link")
}
return f.Sections[link].Data()
}
@@ -93,6 +93,7 @@ func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<
type ProgHeader struct {
Type ProgType
Flags ProgFlag
+ Off uint64
Vaddr uint64
Paddr uint64
Filesz uint64
@@ -224,6 +225,8 @@ func NewFile(r io.ReaderAt) (*File, os.Error) {
f.ABIVersion = ident[EI_ABIVERSION]
// Read ELF file header
+ var phoff int64
+ var phentsize, phnum int
var shoff int64
var shentsize, shnum, shstrndx int
shstrndx = -1
@@ -239,6 +242,9 @@ func NewFile(r io.ReaderAt) (*File, os.Error) {
if v := Version(hdr.Version); v != f.Version {
return nil, &FormatError{0, "mismatched ELF version", v}
}
+ phoff = int64(hdr.Phoff)
+ phentsize = int(hdr.Phentsize)
+ phnum = int(hdr.Phnum)
shoff = int64(hdr.Shoff)
shentsize = int(hdr.Shentsize)
shnum = int(hdr.Shnum)
@@ -254,6 +260,9 @@ func NewFile(r io.ReaderAt) (*File, os.Error) {
if v := Version(hdr.Version); v != f.Version {
return nil, &FormatError{0, "mismatched ELF version", v}
}
+ phoff = int64(hdr.Phoff)
+ phentsize = int(hdr.Phentsize)
+ phnum = int(hdr.Phnum)
shoff = int64(hdr.Shoff)
shentsize = int(hdr.Shentsize)
shnum = int(hdr.Shnum)
@@ -264,7 +273,47 @@ func NewFile(r io.ReaderAt) (*File, os.Error) {
}
// Read program headers
- // TODO
+ f.Progs = make([]*Prog, phnum)
+ for i := 0; i < phnum; i++ {
+ off := phoff + int64(i)*int64(phentsize)
+ sr.Seek(off, os.SEEK_SET)
+ p := new(Prog)
+ switch f.Class {
+ case ELFCLASS32:
+ ph := new(Prog32)
+ if err := binary.Read(sr, f.ByteOrder, ph); err != nil {
+ return nil, err
+ }
+ p.ProgHeader = ProgHeader{
+ Type: ProgType(ph.Type),
+ Flags: ProgFlag(ph.Flags),
+ Off: uint64(ph.Off),
+ Vaddr: uint64(ph.Vaddr),
+ Paddr: uint64(ph.Paddr),
+ Filesz: uint64(ph.Filesz),
+ Memsz: uint64(ph.Memsz),
+ Align: uint64(ph.Align),
+ }
+ case ELFCLASS64:
+ ph := new(Prog64)
+ if err := binary.Read(sr, f.ByteOrder, ph); err != nil {
+ return nil, err
+ }
+ p.ProgHeader = ProgHeader{
+ Type: ProgType(ph.Type),
+ Flags: ProgFlag(ph.Flags),
+ Off: uint64(ph.Off),
+ Vaddr: uint64(ph.Vaddr),
+ Paddr: uint64(ph.Paddr),
+ Filesz: uint64(ph.Filesz),
+ Memsz: uint64(ph.Memsz),
+ Align: uint64(ph.Align),
+ }
+ }
+ p.sr = io.NewSectionReader(r, int64(p.Off), int64(p.Filesz))
+ p.ReaderAt = p.sr
+ f.Progs[i] = p
+ }
// Read section headers
f.Sections = make([]*Section, shnum)
@@ -341,27 +390,27 @@ func (f *File) getSymbols(typ SectionType) ([]Symbol, []byte, os.Error) {
return f.getSymbols32(typ)
}
- return nil, nil, os.ErrorString("not implemented")
+ return nil, nil, os.NewError("not implemented")
}
func (f *File) getSymbols32(typ SectionType) ([]Symbol, []byte, os.Error) {
symtabSection := f.SectionByType(typ)
if symtabSection == nil {
- return nil, nil, os.ErrorString("no symbol section")
+ return nil, nil, os.NewError("no symbol section")
}
data, err := symtabSection.Data()
if err != nil {
- return nil, nil, os.ErrorString("cannot load symbol section")
+ return nil, nil, os.NewError("cannot load symbol section")
}
symtab := bytes.NewBuffer(data)
if symtab.Len()%Sym32Size != 0 {
- return nil, nil, os.ErrorString("length of symbol section is not a multiple of SymSize")
+ return nil, nil, os.NewError("length of symbol section is not a multiple of SymSize")
}
strdata, err := f.stringTable(symtabSection.Link)
if err != nil {
- return nil, nil, os.ErrorString("cannot load string table section")
+ return nil, nil, os.NewError("cannot load string table section")
}
// The first entry is all zeros.
@@ -390,21 +439,21 @@ func (f *File) getSymbols32(typ SectionType) ([]Symbol, []byte, os.Error) {
func (f *File) getSymbols64(typ SectionType) ([]Symbol, []byte, os.Error) {
symtabSection := f.SectionByType(typ)
if symtabSection == nil {
- return nil, nil, os.ErrorString("no symbol section")
+ return nil, nil, os.NewError("no symbol section")
}
data, err := symtabSection.Data()
if err != nil {
- return nil, nil, os.ErrorString("cannot load symbol section")
+ return nil, nil, os.NewError("cannot load symbol section")
}
symtab := bytes.NewBuffer(data)
if symtab.Len()%Sym64Size != 0 {
- return nil, nil, os.ErrorString("length of symbol section is not a multiple of Sym64Size")
+ return nil, nil, os.NewError("length of symbol section is not a multiple of Sym64Size")
}
strdata, err := f.stringTable(symtabSection.Link)
if err != nil {
- return nil, nil, os.ErrorString("cannot load string table section")
+ return nil, nil, os.NewError("cannot load string table section")
}
// The first entry is all zeros.
@@ -462,12 +511,12 @@ func (f *File) applyRelocations(dst []byte, rels []byte) os.Error {
return f.applyRelocationsAMD64(dst, rels)
}
- return os.ErrorString("not implemented")
+ return os.NewError("not implemented")
}
func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) os.Error {
if len(rels)%Sym64Size != 0 {
- return os.ErrorString("length of relocation section is not a multiple of Sym64Size")
+ return os.NewError("length of relocation section is not a multiple of Sym64Size")
}
symbols, _, err := f.getSymbols(SHT_SYMTAB)
@@ -546,6 +595,12 @@ func (f *File) DWARF() (*dwarf.Data, os.Error) {
return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str)
}
+// Symbols returns the symbol table for f.
+func (f *File) Symbols() ([]Symbol, os.Error) {
+ sym, _, err := f.getSymbols(SHT_SYMTAB)
+ return sym, err
+}
+
type ImportedSymbol struct {
Name string
Version string
diff --git a/libgo/go/debug/elf/file_test.go b/libgo/go/debug/elf/file_test.go
index 84068ea..98f2723c 100644
--- a/libgo/go/debug/elf/file_test.go
+++ b/libgo/go/debug/elf/file_test.go
@@ -7,7 +7,10 @@ package elf
import (
"debug/dwarf"
"encoding/binary"
+ "net"
+ "os"
"reflect"
+ "runtime"
"testing"
)
@@ -15,6 +18,7 @@ type fileTest struct {
file string
hdr FileHeader
sections []SectionHeader
+ progs []ProgHeader
}
var fileTests = []fileTest{
@@ -53,6 +57,13 @@ var fileTests = []fileTest{
{".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},
+ },
},
{
"testdata/gcc-amd64-linux-exec",
@@ -96,6 +107,16 @@ var fileTests = []fileTest{
{".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},
+ },
},
}
@@ -121,11 +142,25 @@ func TestOpen(t *testing.T) {
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)
+ }
}
}
@@ -136,15 +171,15 @@ type relocationTest struct {
var relocationTests = []relocationTest{
{
- "testdata/go-relocation-test-gcc441-x86-64.o",
+ "testdata/go-relocation-test-gcc441-x86-64.obj",
&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)}}},
},
{
- "testdata/go-relocation-test-gcc441-x86.o",
+ "testdata/go-relocation-test-gcc441-x86.obj",
&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)}}},
},
{
- "testdata/go-relocation-test-gcc424-x86-64.o",
+ "testdata/go-relocation-test-gcc424-x86-64.obj",
&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)}}},
},
}
@@ -178,3 +213,32 @@ func TestDWARFRelocations(t *testing.T) {
}
}
}
+
+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)
+ }
+ }
+ }
+}
diff --git a/libgo/go/debug/elf/testdata/go-relocation-test-gcc424-x86-64.o b/libgo/go/debug/elf/testdata/go-relocation-test-gcc424-x86-64.obj
index a7c6d6e..a7c6d6e 100644
--- a/libgo/go/debug/elf/testdata/go-relocation-test-gcc424-x86-64.o
+++ b/libgo/go/debug/elf/testdata/go-relocation-test-gcc424-x86-64.obj
Binary files differ
diff --git a/libgo/go/debug/elf/testdata/go-relocation-test-gcc441-x86-64.o b/libgo/go/debug/elf/testdata/go-relocation-test-gcc441-x86-64.obj
index 2d37ab6..2d37ab6 100644
--- a/libgo/go/debug/elf/testdata/go-relocation-test-gcc441-x86-64.o
+++ b/libgo/go/debug/elf/testdata/go-relocation-test-gcc441-x86-64.obj
Binary files differ
diff --git a/libgo/go/debug/elf/testdata/go-relocation-test-gcc441-x86.o b/libgo/go/debug/elf/testdata/go-relocation-test-gcc441-x86.obj
index 0d59fe3..0d59fe3 100644
--- a/libgo/go/debug/elf/testdata/go-relocation-test-gcc441-x86.o
+++ b/libgo/go/debug/elf/testdata/go-relocation-test-gcc441-x86.obj
Binary files differ
diff --git a/libgo/go/debug/macho/file.go b/libgo/go/debug/macho/file.go
index a777d87..721a4c4 100644
--- a/libgo/go/debug/macho/file.go
+++ b/libgo/go/debug/macho/file.go
@@ -184,7 +184,7 @@ func (f *File) Close() os.Error {
return err
}
-// NewFile creates a new File for acecssing a Mach-O binary in an underlying reader.
+// NewFile creates a new File for accessing a Mach-O binary in an underlying reader.
// The Mach-O binary is expected to start at position 0 in the ReaderAt.
func NewFile(r io.ReaderAt) (*File, os.Error) {
f := new(File)
diff --git a/libgo/go/debug/pe/file.go b/libgo/go/debug/pe/file.go
index 6a14e50..d86d916 100644
--- a/libgo/go/debug/pe/file.go
+++ b/libgo/go/debug/pe/file.go
@@ -35,7 +35,6 @@ type SectionHeader struct {
Characteristics uint32
}
-
type Section struct {
SectionHeader
@@ -69,7 +68,6 @@ func (s *Section) Data() ([]byte, os.Error) {
// Open returns a new ReadSeeker reading the PE section.
func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
-
type FormatError struct {
off int64
msg string
@@ -112,7 +110,7 @@ func (f *File) Close() os.Error {
return err
}
-// NewFile creates a new File for acecssing a PE binary in an underlying reader.
+// NewFile creates a new File for accessing a PE binary in an underlying reader.
func NewFile(r io.ReaderAt) (*File, os.Error) {
f := new(File)
sr := io.NewSectionReader(r, 0, 1<<63-1)
@@ -245,6 +243,7 @@ func (f *File) DWARF() (*dwarf.Data, os.Error) {
// satisfied by other libraries at dynamic load time.
// It does not return weak symbols.
func (f *File) ImportedSymbols() ([]string, os.Error) {
+ pe64 := f.Machine == IMAGE_FILE_MACHINE_AMD64
ds := f.Section(".idata")
if ds == nil {
// not dynamic, so no libraries
@@ -274,17 +273,31 @@ func (f *File) ImportedSymbols() ([]string, os.Error) {
// seek to OriginalFirstThunk
d = d[dt.OriginalFirstThunk-ds.VirtualAddress:]
for len(d) > 0 {
- va := binary.LittleEndian.Uint32(d[0:4])
- d = d[4:]
- if va == 0 {
- break
- }
- if va&0x80000000 > 0 { // is Ordinal
- // TODO add dynimport ordinal support.
- //ord := va&0x0000FFFF
- } else {
- fn, _ := getString(names, int(va-ds.VirtualAddress+2))
- all = append(all, fn+":"+dt.dll)
+ if pe64 { // 64bit
+ va := binary.LittleEndian.Uint64(d[0:8])
+ d = d[8:]
+ if va == 0 {
+ break
+ }
+ if va&0x8000000000000000 > 0 { // is Ordinal
+ // TODO add dynimport ordinal support.
+ } else {
+ fn, _ := getString(names, int(uint32(va)-ds.VirtualAddress+2))
+ all = append(all, fn+":"+dt.dll)
+ }
+ } else { // 32bit
+ va := binary.LittleEndian.Uint32(d[0:4])
+ d = d[4:]
+ if va == 0 {
+ break
+ }
+ if va&0x80000000 > 0 { // is Ordinal
+ // TODO add dynimport ordinal support.
+ //ord := va&0x0000FFFF
+ } else {
+ fn, _ := getString(names, int(va-ds.VirtualAddress+2))
+ all = append(all, fn+":"+dt.dll)
+ }
}
}
}
diff --git a/libgo/go/debug/proc/proc.go b/libgo/go/debug/proc/proc.go
deleted file mode 100644
index d89649c..0000000
--- a/libgo/go/debug/proc/proc.go
+++ /dev/null
@@ -1,222 +0,0 @@
-// 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.
-
-// Package proc provides a platform-independent interface for
-// tracing and controlling running processes. It supports
-// multi-threaded processes and provides typical low-level debugging
-// controls such as breakpoints, single stepping, and manipulating
-// memory and registers.
-package proc
-
-// TODO(rsc): Have to import everything that proc_linux.go
-// and proc_darwin.go do, because deps.bash only looks at
-// this file.
-import (
- _ "container/vector"
- _ "fmt"
- _ "io"
- "os"
- _ "runtime"
- "strconv"
- _ "strings"
- _ "sync"
- _ "syscall"
-)
-
-type Word uint64
-
-// A Cause explains why a thread is stopped.
-type Cause interface {
- String() string
-}
-
-// Regs is a set of named machine registers, including a program
-// counter, link register, and stack pointer.
-//
-// TODO(austin) There's quite a proliferation of methods here. We
-// could make a Reg interface with Get and Set and make this just PC,
-// Link, SP, Names, and Reg. We could also put Index in Reg and that
-// makes it easy to get the index of things like the PC (currently
-// there's just no way to know that). This would also let us include
-// other per-register information like how to print it.
-type Regs interface {
- // PC returns the value of the program counter.
- PC() Word
-
- // SetPC sets the program counter to val.
- SetPC(val Word) os.Error
-
- // Link returns the link register, if any.
- Link() Word
-
- // SetLink sets the link register to val.
- SetLink(val Word) os.Error
-
- // SP returns the value of the stack pointer.
- SP() Word
-
- // SetSP sets the stack pointer register to val.
- SetSP(val Word) os.Error
-
- // Names returns the names of all of the registers.
- Names() []string
-
- // Get returns the value of a register, where i corresponds to
- // the index of the register's name in the array returned by
- // Names.
- Get(i int) Word
-
- // Set sets the value of a register.
- Set(i int, val Word) os.Error
-}
-
-// Thread is a thread in the process being traced.
-type Thread interface {
- // Step steps this thread by a single instruction. The thread
- // must be stopped. If the thread is currently stopped on a
- // breakpoint, this will step over the breakpoint.
- //
- // XXX What if it's stopped because of a signal?
- Step() os.Error
-
- // Stopped returns the reason that this thread is stopped. It
- // is an error is the thread not stopped.
- Stopped() (Cause, os.Error)
-
- // Regs retrieves the current register values from this
- // thread. The thread must be stopped.
- Regs() (Regs, os.Error)
-
- // Peek reads len(out) bytes from the address addr in this
- // thread into out. The thread must be stopped. It returns
- // the number of bytes successfully read. If an error occurs,
- // such as attempting to read unmapped memory, this count
- // could be short and an error will be returned. If this does
- // encounter unmapped memory, it will read up to the byte
- // preceding the unmapped area.
- Peek(addr Word, out []byte) (int, os.Error)
-
- // Poke writes b to the address addr in this thread. The
- // thread must be stopped. It returns the number of bytes
- // successfully written. If an error occurs, such as
- // attempting to write to unmapped memory, this count could be
- // short and an error will be returned. If this does
- // encounter unmapped memory, it will write up to the byte
- // preceding the unmapped area.
- Poke(addr Word, b []byte) (int, os.Error)
-}
-
-// Process is a process being traced. It consists of a set of
-// threads. A process can be running, stopped, or terminated. The
-// process's state extends to all of its threads.
-type Process interface {
- // Threads returns an array of all threads in this process.
- Threads() []Thread
-
- // AddBreakpoint creates a new breakpoint at program counter
- // pc. Breakpoints can only be created when the process is
- // stopped. It is an error if a breakpoint already exists at
- // pc.
- AddBreakpoint(pc Word) os.Error
-
- // RemoveBreakpoint removes the breakpoint at the program
- // counter pc. It is an error if no breakpoint exists at pc.
- RemoveBreakpoint(pc Word) os.Error
-
- // Stop stops all running threads in this process before
- // returning.
- Stop() os.Error
-
- // Continue resumes execution of all threads in this process.
- // Any thread that is stopped on a breakpoint will be stepped
- // over that breakpoint. Any thread that is stopped because
- // of a signal (other than SIGSTOP or SIGTRAP) will receive
- // the pending signal.
- Continue() os.Error
-
- // WaitStop waits until all threads in process p are stopped
- // as a result of some thread hitting a breakpoint, receiving
- // a signal, creating a new thread, or exiting.
- WaitStop() os.Error
-
- // Detach detaches from this process. All stopped threads
- // will be resumed.
- Detach() os.Error
-}
-
-// Stopped is a stop cause used for threads that are stopped either by
-// user request (e.g., from the Stop method or after single stepping),
-// or that are stopped because some other thread caused the program to
-// stop.
-type Stopped struct{}
-
-func (c Stopped) String() string { return "stopped" }
-
-// Breakpoint is a stop cause resulting from a thread reaching a set
-// breakpoint.
-type Breakpoint Word
-
-// PC returns the program counter that the program is stopped at.
-func (c Breakpoint) PC() Word { return Word(c) }
-
-func (c Breakpoint) String() string {
- return "breakpoint at 0x" + strconv.Uitob64(uint64(c.PC()), 16)
-}
-
-// Signal is a stop cause resulting from a thread receiving a signal.
-// When the process is continued, the signal will be delivered.
-type Signal string
-
-// Signal returns the signal being delivered to the thread.
-func (c Signal) Name() string { return string(c) }
-
-func (c Signal) String() string { return c.Name() }
-
-// ThreadCreate is a stop cause returned from an existing thread when
-// it creates a new thread. The new thread exists in a primordial
-// form at this point and will begin executing in earnest when the
-// process is continued.
-type ThreadCreate struct {
- thread Thread
-}
-
-func (c *ThreadCreate) NewThread() Thread { return c.thread }
-
-func (c *ThreadCreate) String() string { return "thread create" }
-
-// ThreadExit is a stop cause resulting from a thread exiting. When
-// this cause first arises, the thread will still be in the list of
-// process threads and its registers and memory will still be
-// accessible.
-type ThreadExit struct {
- exitStatus int
- signal string
-}
-
-// Exited returns true if the thread exited normally.
-func (c *ThreadExit) Exited() bool { return c.exitStatus != -1 }
-
-// ExitStatus returns the exit status of the thread if it exited
-// normally or -1 otherwise.
-func (c *ThreadExit) ExitStatus() int { return c.exitStatus }
-
-// Signaled returns true if the thread was terminated by a signal.
-func (c *ThreadExit) Signaled() bool { return c.exitStatus == -1 }
-
-// StopSignal returns the signal that terminated the thread, or "" if
-// it was not terminated by a signal.
-func (c *ThreadExit) StopSignal() string { return c.signal }
-
-func (c *ThreadExit) String() string {
- res := "thread exited "
- switch {
- case c.Exited():
- res += "with status " + strconv.Itoa(c.ExitStatus())
- case c.Signaled():
- res += "from signal " + c.StopSignal()
- default:
- res += "from unknown cause"
- }
- return res
-}
diff --git a/libgo/go/debug/proc/proc_darwin.go b/libgo/go/debug/proc/proc_darwin.go
deleted file mode 100644
index 49f0a53..0000000
--- a/libgo/go/debug/proc/proc_darwin.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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.
-
-package proc
-
-import "os"
-
-// Process tracing is not supported on OS X yet.
-
-func Attach(pid int) (Process, os.Error) {
- return nil, os.NewError("debug/proc not implemented on OS X")
-}
-
-func StartProcess(argv0 string, argv []string, attr *os.ProcAttr) (Process, os.Error) {
- return Attach(0)
-}
diff --git a/libgo/go/debug/proc/proc_freebsd.go b/libgo/go/debug/proc/proc_freebsd.go
deleted file mode 100644
index 4df07c3..0000000
--- a/libgo/go/debug/proc/proc_freebsd.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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.
-
-package proc
-
-import "os"
-
-// Process tracing is not supported on FreeBSD yet.
-
-func Attach(pid int) (Process, os.Error) {
- return nil, os.NewError("debug/proc not implemented on FreeBSD")
-}
-
-func StartProcess(argv0 string, argv []string, attr *os.ProcAttr) (Process, os.Error) {
- return Attach(0)
-}
diff --git a/libgo/go/debug/proc/proc_linux.go b/libgo/go/debug/proc/proc_linux.go
deleted file mode 100644
index 17c8fa5..0000000
--- a/libgo/go/debug/proc/proc_linux.go
+++ /dev/null
@@ -1,1322 +0,0 @@
-// 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.
-
-package proc
-
-// TODO(rsc): Imports here after to be in proc.go too in order
-// for deps.bash to get the right answer.
-import (
- "container/vector"
- "fmt"
- "io/ioutil"
- "os"
- "runtime"
- "strconv"
- "strings"
- "sync"
- "syscall"
-)
-
-// This is an implementation of the process tracing interface using
-// Linux's ptrace(2) interface. The implementation is multi-threaded.
-// Each attached process has an associated monitor thread, and each
-// running attached thread has an associated "wait" thread. The wait
-// thread calls wait4 on the thread's TID and reports any wait events
-// or errors via "debug events". The monitor thread consumes these
-// wait events and updates the internally maintained state of each
-// thread. All ptrace calls must run in the monitor thread, so the
-// monitor executes closures received on the debugReq channel.
-//
-// As ptrace's documentation is somewhat light, this is heavily based
-// on information gleaned from the implementation of ptrace found at
-// http://lxr.linux.no/linux+v2.6.30/kernel/ptrace.c
-// http://lxr.linux.no/linux+v2.6.30/arch/x86/kernel/ptrace.c#L854
-// as well as experimentation and examination of gdb's behavior.
-
-const (
- trace = false
- traceIP = false
- traceMem = false
-)
-
-/*
- * Thread state
- */
-
-// Each thread can be in one of the following set of states.
-// Each state satisfies
-// isRunning() || isStopped() || isZombie() || isTerminal().
-//
-// Running threads can be sent signals and must be waited on, but they
-// cannot be inspected using ptrace.
-//
-// Stopped threads can be inspected and continued, but cannot be
-// meaningfully waited on. They can be sent signals, but the signals
-// will be queued until they are running again.
-//
-// Zombie threads cannot be inspected, continued, or sent signals (and
-// therefore they cannot be stopped), but they must be waited on.
-//
-// Terminal threads no longer exist in the OS and thus you can't do
-// anything with them.
-type threadState string
-
-const (
- running threadState = "Running"
- singleStepping threadState = "SingleStepping" // Transient
- stopping threadState = "Stopping" // Transient
- stopped threadState = "Stopped"
- stoppedBreakpoint threadState = "StoppedBreakpoint"
- stoppedSignal threadState = "StoppedSignal"
- stoppedThreadCreate threadState = "StoppedThreadCreate"
- stoppedExiting threadState = "StoppedExiting"
- exiting threadState = "Exiting" // Transient (except main thread)
- exited threadState = "Exited"
- detached threadState = "Detached"
-)
-
-func (ts threadState) isRunning() bool {
- return ts == running || ts == singleStepping || ts == stopping
-}
-
-func (ts threadState) isStopped() bool {
- return ts == stopped || ts == stoppedBreakpoint || ts == stoppedSignal || ts == stoppedThreadCreate || ts == stoppedExiting
-}
-
-func (ts threadState) isZombie() bool { return ts == exiting }
-
-func (ts threadState) isTerminal() bool { return ts == exited || ts == detached }
-
-func (ts threadState) String() string { return string(ts) }
-
-/*
- * Basic types
- */
-
-// A breakpoint stores information about a single breakpoint,
-// including its program counter, the overwritten text if the
-// breakpoint is installed.
-type breakpoint struct {
- pc uintptr
- olddata []byte
-}
-
-func (bp *breakpoint) String() string {
- if bp == nil {
- return "<nil>"
- }
- return fmt.Sprintf("%#x", bp.pc)
-}
-
-// bpinst386 is the breakpoint instruction used on 386 and amd64.
-var bpinst386 = []byte{0xcc}
-
-// A debugEvent represents a reason a thread stopped or a wait error.
-type debugEvent struct {
- *os.Waitmsg
- t *thread
- err os.Error
-}
-
-// A debugReq is a request to execute a closure in the monitor thread.
-type debugReq struct {
- f func() os.Error
- res chan os.Error
-}
-
-// A transitionHandler specifies a function to be called when a thread
-// changes state and a function to be called when an error occurs in
-// the monitor. Both run in the monitor thread. Before the monitor
-// invokes a handler, it removes the handler from the handler queue.
-// The handler should re-add itself if needed.
-type transitionHandler struct {
- handle func(*thread, threadState, threadState)
- onErr func(os.Error)
-}
-
-// A process is a Linux process, which consists of a set of threads.
-// Each running process has one monitor thread, which processes
-// messages from the debugEvents, debugReqs, and stopReq channels and
-// calls transition handlers.
-//
-// To send a message to the monitor thread, first receive from the
-// ready channel. If the ready channel returns true, the monitor is
-// still running and will accept a message. If the ready channel
-// returns false, the monitor is not running (the ready channel has
-// been closed), and the reason it is not running will be stored in err.
-type process struct {
- pid int
- threads map[int]*thread
- breakpoints map[uintptr]*breakpoint
- ready chan bool
- debugEvents chan *debugEvent
- debugReqs chan *debugReq
- stopReq chan os.Error
- transitionHandlers vector.Vector
- err os.Error
-}
-
-// A thread represents a Linux thread in another process that is being
-// debugged. Each running thread has an associated goroutine that
-// waits for thread updates and sends them to the process monitor.
-type thread struct {
- tid int
- proc *process
- // Whether to ignore the next SIGSTOP received by wait.
- ignoreNextSigstop bool
-
- // Thread state. Only modified via setState.
- state threadState
- // If state == StoppedBreakpoint
- breakpoint *breakpoint
- // If state == StoppedSignal or state == Exited
- signal int
- // If state == StoppedThreadCreate
- newThread *thread
- // If state == Exited
- exitStatus int
-}
-
-/*
- * Errors
- */
-
-type badState struct {
- thread *thread
- message string
- state threadState
-}
-
-func (e *badState) String() string {
- return fmt.Sprintf("Thread %d %s from state %v", e.thread.tid, e.message, e.state)
-}
-
-type breakpointExistsError Word
-
-func (e breakpointExistsError) String() string {
- return fmt.Sprintf("breakpoint already exists at PC %#x", e)
-}
-
-type noBreakpointError Word
-
-func (e noBreakpointError) String() string { return fmt.Sprintf("no breakpoint at PC %#x", e) }
-
-type newThreadError struct {
- *os.Waitmsg
- wantPid int
- wantSig int
-}
-
-func (e *newThreadError) String() string {
- return fmt.Sprintf("newThread wait wanted pid %v and signal %v, got %v and %v", e.Pid, e.StopSignal(), e.wantPid, e.wantSig)
-}
-
-type ProcessExited struct{}
-
-func (p ProcessExited) String() string { return "process exited" }
-
-/*
- * Ptrace wrappers
- */
-
-func (t *thread) ptracePeekText(addr uintptr, out []byte) (int, os.Error) {
- c, err := syscall.PtracePeekText(t.tid, addr, out)
- if traceMem {
- fmt.Printf("peek(%#x) => %v, %v\n", addr, out, err)
- }
- return c, os.NewSyscallError("ptrace(PEEKTEXT)", err)
-}
-
-func (t *thread) ptracePokeText(addr uintptr, out []byte) (int, os.Error) {
- c, err := syscall.PtracePokeText(t.tid, addr, out)
- if traceMem {
- fmt.Printf("poke(%#x, %v) => %v\n", addr, out, err)
- }
- return c, os.NewSyscallError("ptrace(POKETEXT)", err)
-}
-
-func (t *thread) ptraceGetRegs(regs *syscall.PtraceRegs) os.Error {
- err := syscall.PtraceGetRegs(t.tid, regs)
- return os.NewSyscallError("ptrace(GETREGS)", err)
-}
-
-func (t *thread) ptraceSetRegs(regs *syscall.PtraceRegs) os.Error {
- err := syscall.PtraceSetRegs(t.tid, regs)
- return os.NewSyscallError("ptrace(SETREGS)", err)
-}
-
-func (t *thread) ptraceSetOptions(options int) os.Error {
- err := syscall.PtraceSetOptions(t.tid, options)
- return os.NewSyscallError("ptrace(SETOPTIONS)", err)
-}
-
-func (t *thread) ptraceGetEventMsg() (uint, os.Error) {
- msg, err := syscall.PtraceGetEventMsg(t.tid)
- return msg, os.NewSyscallError("ptrace(GETEVENTMSG)", err)
-}
-
-func (t *thread) ptraceCont() os.Error {
- err := syscall.PtraceCont(t.tid, 0)
- return os.NewSyscallError("ptrace(CONT)", err)
-}
-
-func (t *thread) ptraceContWithSignal(sig int) os.Error {
- err := syscall.PtraceCont(t.tid, sig)
- return os.NewSyscallError("ptrace(CONT)", err)
-}
-
-func (t *thread) ptraceStep() os.Error {
- err := syscall.PtraceSingleStep(t.tid)
- return os.NewSyscallError("ptrace(SINGLESTEP)", err)
-}
-
-func (t *thread) ptraceDetach() os.Error {
- err := syscall.PtraceDetach(t.tid)
- return os.NewSyscallError("ptrace(DETACH)", err)
-}
-
-/*
- * Logging utilties
- */
-
-var logLock sync.Mutex
-
-func (t *thread) logTrace(format string, args ...interface{}) {
- if !trace {
- return
- }
- logLock.Lock()
- defer logLock.Unlock()
- fmt.Fprintf(os.Stderr, "Thread %d", t.tid)
- if traceIP {
- var regs syscall.PtraceRegs
- err := t.ptraceGetRegs(&regs)
- if err == nil {
- fmt.Fprintf(os.Stderr, "@%x", regs.PC())
- }
- }
- fmt.Fprint(os.Stderr, ": ")
- fmt.Fprintf(os.Stderr, format, args...)
- fmt.Fprint(os.Stderr, "\n")
-}
-
-func (t *thread) warn(format string, args ...interface{}) {
- logLock.Lock()
- defer logLock.Unlock()
- fmt.Fprintf(os.Stderr, "Thread %d: WARNING ", t.tid)
- fmt.Fprintf(os.Stderr, format, args...)
- fmt.Fprint(os.Stderr, "\n")
-}
-
-func (p *process) logTrace(format string, args ...interface{}) {
- if !trace {
- return
- }
- logLock.Lock()
- defer logLock.Unlock()
- fmt.Fprintf(os.Stderr, "Process %d: ", p.pid)
- fmt.Fprintf(os.Stderr, format, args...)
- fmt.Fprint(os.Stderr, "\n")
-}
-
-/*
- * State utilities
- */
-
-// someStoppedThread returns a stopped thread from the process.
-// Returns nil if no threads are stopped.
-//
-// Must be called from the monitor thread.
-func (p *process) someStoppedThread() *thread {
- for _, t := range p.threads {
- if t.state.isStopped() {
- return t
- }
- }
- return nil
-}
-
-// someRunningThread returns a running thread from the process.
-// Returns nil if no threads are running.
-//
-// Must be called from the monitor thread.
-func (p *process) someRunningThread() *thread {
- for _, t := range p.threads {
- if t.state.isRunning() {
- return t
- }
- }
- return nil
-}
-
-/*
- * Breakpoint utilities
- */
-
-// installBreakpoints adds breakpoints to the attached process.
-//
-// Must be called from the monitor thread.
-func (p *process) installBreakpoints() os.Error {
- n := 0
- main := p.someStoppedThread()
- for _, b := range p.breakpoints {
- if b.olddata != nil {
- continue
- }
-
- b.olddata = make([]byte, len(bpinst386))
- _, err := main.ptracePeekText(uintptr(b.pc), b.olddata)
- if err != nil {
- b.olddata = nil
- return err
- }
-
- _, err = main.ptracePokeText(uintptr(b.pc), bpinst386)
- if err != nil {
- b.olddata = nil
- return err
- }
- n++
- }
- if n > 0 {
- p.logTrace("installed %d/%d breakpoints", n, len(p.breakpoints))
- }
-
- return nil
-}
-
-// uninstallBreakpoints removes the installed breakpoints from p.
-//
-// Must be called from the monitor thread.
-func (p *process) uninstallBreakpoints() os.Error {
- if len(p.threads) == 0 {
- return nil
- }
- n := 0
- main := p.someStoppedThread()
- for _, b := range p.breakpoints {
- if b.olddata == nil {
- continue
- }
-
- _, err := main.ptracePokeText(uintptr(b.pc), b.olddata)
- if err != nil {
- return err
- }
- b.olddata = nil
- n++
- }
- if n > 0 {
- p.logTrace("uninstalled %d/%d breakpoints", n, len(p.breakpoints))
- }
-
- return nil
-}
-
-/*
- * Debug event handling
- */
-
-// wait waits for a wait event from this thread and sends it on the
-// debug events channel for this thread's process. This should be
-// started in its own goroutine when the attached thread enters a
-// running state. The goroutine will exit as soon as it sends a debug
-// event.
-func (t *thread) wait() {
- for {
- var ev debugEvent
- ev.t = t
- t.logTrace("beginning wait")
- ev.Waitmsg, ev.err = os.Wait(t.tid, syscall.WALL)
- if ev.err == nil && ev.Pid != t.tid {
- panic(fmt.Sprint("Wait returned pid ", ev.Pid, " wanted ", t.tid))
- }
- if ev.StopSignal() == syscall.SIGSTOP && t.ignoreNextSigstop {
- // Spurious SIGSTOP. See Thread.Stop().
- t.ignoreNextSigstop = false
- err := t.ptraceCont()
- if err == nil {
- continue
- }
- // If we failed to continue, just let
- // the stop go through so we can
- // update the thread's state.
- }
- if !<-t.proc.ready {
- // The monitor exited
- break
- }
- t.proc.debugEvents <- &ev
- break
- }
-}
-
-// setState sets this thread's state, starts a wait thread if
-// necessary, and invokes state transition handlers.
-//
-// Must be called from the monitor thread.
-func (t *thread) setState(newState threadState) {
- oldState := t.state
- t.state = newState
- t.logTrace("state %v -> %v", oldState, newState)
-
- if !oldState.isRunning() && (newState.isRunning() || newState.isZombie()) {
- // Start waiting on this thread
- go t.wait()
- }
-
- // Invoke state change handlers
- handlers := t.proc.transitionHandlers
- if handlers.Len() == 0 {
- return
- }
-
- t.proc.transitionHandlers = nil
- for _, h := range handlers {
- h := h.(*transitionHandler)
- h.handle(t, oldState, newState)
- }
-}
-
-// sendSigstop sends a SIGSTOP to this thread.
-func (t *thread) sendSigstop() os.Error {
- t.logTrace("sending SIGSTOP")
- err := syscall.Tgkill(t.proc.pid, t.tid, syscall.SIGSTOP)
- return os.NewSyscallError("tgkill", err)
-}
-
-// stopAsync sends SIGSTOP to all threads in state 'running'.
-//
-// Must be called from the monitor thread.
-func (p *process) stopAsync() os.Error {
- for _, t := range p.threads {
- if t.state == running {
- err := t.sendSigstop()
- if err != nil {
- return err
- }
- t.setState(stopping)
- }
- }
- return nil
-}
-
-// doTrap handles SIGTRAP debug events with a cause of 0. These can
-// be caused either by an installed breakpoint, a breakpoint in the
-// program text, or by single stepping.
-//
-// TODO(austin) I think we also get this on an execve syscall.
-func (ev *debugEvent) doTrap() (threadState, os.Error) {
- t := ev.t
-
- if t.state == singleStepping {
- return stopped, nil
- }
-
- // Hit a breakpoint. Linux leaves the program counter after
- // the breakpoint. If this is an installed breakpoint, we
- // need to back the PC up to the breakpoint PC.
- var regs syscall.PtraceRegs
- err := t.ptraceGetRegs(&regs)
- if err != nil {
- return stopped, err
- }
-
- b, ok := t.proc.breakpoints[uintptr(regs.PC())-uintptr(len(bpinst386))]
- if !ok {
- // We must have hit a breakpoint that was actually in
- // the program. Leave the IP where it is so we don't
- // re-execute the breakpoint instruction. Expose the
- // fact that we stopped with a SIGTRAP.
- return stoppedSignal, nil
- }
-
- t.breakpoint = b
- t.logTrace("at breakpoint %v, backing up PC from %#x", b, regs.PC())
-
- regs.SetPC(uint64(b.pc))
- err = t.ptraceSetRegs(&regs)
- if err != nil {
- return stopped, err
- }
- return stoppedBreakpoint, nil
-}
-
-// doPtraceClone handles SIGTRAP debug events with a PTRACE_EVENT_CLONE
-// cause. It initializes the new thread, adds it to the process, and
-// returns the appropriate thread state for the existing thread.
-func (ev *debugEvent) doPtraceClone() (threadState, os.Error) {
- t := ev.t
-
- // Get the TID of the new thread
- tid, err := t.ptraceGetEventMsg()
- if err != nil {
- return stopped, err
- }
-
- nt, err := t.proc.newThread(int(tid), syscall.SIGSTOP, true)
- if err != nil {
- return stopped, err
- }
-
- // Remember the thread
- t.newThread = nt
-
- return stoppedThreadCreate, nil
-}
-
-// doPtraceExit handles SIGTRAP debug events with a PTRACE_EVENT_EXIT
-// cause. It sets up the thread's state, but does not remove it from
-// the process. A later WIFEXITED debug event will remove it from the
-// process.
-func (ev *debugEvent) doPtraceExit() (threadState, os.Error) {
- t := ev.t
-
- // Get exit status
- exitStatus, err := t.ptraceGetEventMsg()
- if err != nil {
- return stopped, err
- }
- ws := syscall.WaitStatus(exitStatus)
- t.logTrace("exited with %v", ws)
- switch {
- case ws.Exited():
- t.exitStatus = ws.ExitStatus()
- case ws.Signaled():
- t.signal = ws.Signal()
- }
-
- // We still need to continue this thread and wait on this
- // thread's WIFEXITED event. We'll delete it then.
- return stoppedExiting, nil
-}
-
-// process handles a debug event. It modifies any thread or process
-// state as necessary, uninstalls breakpoints if necessary, and stops
-// any running threads.
-func (ev *debugEvent) process() os.Error {
- if ev.err != nil {
- return ev.err
- }
-
- t := ev.t
- t.exitStatus = -1
- t.signal = -1
-
- // Decode wait status.
- var state threadState
- switch {
- case ev.Stopped():
- state = stoppedSignal
- t.signal = ev.StopSignal()
- t.logTrace("stopped with %v", ev)
- if ev.StopSignal() == syscall.SIGTRAP {
- // What caused the debug trap?
- var err os.Error
- switch cause := ev.TrapCause(); cause {
- case 0:
- // Breakpoint or single stepping
- state, err = ev.doTrap()
-
- case syscall.PTRACE_EVENT_CLONE:
- state, err = ev.doPtraceClone()
-
- case syscall.PTRACE_EVENT_EXIT:
- state, err = ev.doPtraceExit()
-
- default:
- t.warn("Unknown trap cause %d", cause)
- }
-
- if err != nil {
- t.setState(stopped)
- t.warn("failed to handle trap %v: %v", ev, err)
- }
- }
-
- case ev.Exited():
- state = exited
- t.proc.threads[t.tid] = nil, false
- t.logTrace("exited %v", ev)
- // We should have gotten the exit status in
- // PTRACE_EVENT_EXIT, but just in case.
- t.exitStatus = ev.ExitStatus()
-
- case ev.Signaled():
- state = exited
- t.proc.threads[t.tid] = nil, false
- t.logTrace("signaled %v", ev)
- // Again, this should be redundant.
- t.signal = ev.Signal()
-
- default:
- panic(fmt.Sprintf("Unexpected wait status %v", ev.Waitmsg))
- }
-
- // If we sent a SIGSTOP to the thread (indicated by state
- // Stopping), we might have raced with a different type of
- // stop. If we didn't get the stop we expected, then the
- // SIGSTOP we sent is now queued up, so we should ignore the
- // next one we get.
- if t.state == stopping && ev.StopSignal() != syscall.SIGSTOP {
- t.ignoreNextSigstop = true
- }
-
- // TODO(austin) If we're in state stopping and get a SIGSTOP,
- // set state stopped instead of stoppedSignal.
-
- t.setState(state)
-
- if t.proc.someRunningThread() == nil {
- // Nothing is running, uninstall breakpoints
- return t.proc.uninstallBreakpoints()
- }
- // Stop any other running threads
- return t.proc.stopAsync()
-}
-
-// onStop adds a handler for state transitions from running to
-// non-running states. The handler will be called from the monitor
-// thread.
-//
-// Must be called from the monitor thread.
-func (t *thread) onStop(handle func(), onErr func(os.Error)) {
- // TODO(austin) This is rather inefficient for things like
- // stepping all threads during a continue. Maybe move
- // transitionHandlers to the thread, or have both per-thread
- // and per-process transition handlers.
- h := &transitionHandler{nil, onErr}
- h.handle = func(st *thread, old, new threadState) {
- if t == st && old.isRunning() && !new.isRunning() {
- handle()
- } else {
- t.proc.transitionHandlers.Push(h)
- }
- }
- t.proc.transitionHandlers.Push(h)
-}
-
-/*
- * Event monitor
- */
-
-// monitor handles debug events and debug requests for p, exiting when
-// there are no threads left in p.
-func (p *process) monitor() {
- var err os.Error
-
- // Linux requires that all ptrace calls come from the thread
- // that originally attached. Prevent the Go scheduler from
- // migrating us to other OS threads.
- runtime.LockOSThread()
- defer runtime.UnlockOSThread()
-
- hadThreads := false
- for err == nil {
- p.ready <- true
- select {
- case event := <-p.debugEvents:
- err = event.process()
-
- case req := <-p.debugReqs:
- req.res <- req.f()
-
- case err = <-p.stopReq:
- break
- }
-
- if len(p.threads) == 0 {
- if err == nil && hadThreads {
- p.logTrace("no more threads; monitor exiting")
- err = ProcessExited{}
- }
- } else {
- hadThreads = true
- }
- }
-
- // Abort waiting handlers
- // TODO(austin) How do I stop the wait threads?
- for _, h := range p.transitionHandlers {
- h := h.(*transitionHandler)
- h.onErr(err)
- }
-
- // Indicate that the monitor cannot receive any more messages
- p.err = err
- close(p.ready)
-}
-
-// do executes f in the monitor thread (and, thus, atomically with
-// respect to thread state changes). f must not block.
-//
-// Must NOT be called from the monitor thread.
-func (p *process) do(f func() os.Error) os.Error {
- if !<-p.ready {
- return p.err
- }
- req := &debugReq{f, make(chan os.Error)}
- p.debugReqs <- req
- return <-req.res
-}
-
-// stopMonitor stops the monitor with the given error. If the monitor
-// is already stopped, does nothing.
-func (p *process) stopMonitor(err os.Error) {
- if err == nil {
- panic("cannot stop the monitor with no error")
- }
- if <-p.ready {
- p.stopReq <- err
- }
-}
-
-/*
- * Public thread interface
- */
-
-func (t *thread) Regs() (Regs, os.Error) {
- var regs syscall.PtraceRegs
-
- err := t.proc.do(func() os.Error {
- if !t.state.isStopped() {
- return &badState{t, "cannot get registers", t.state}
- }
- return t.ptraceGetRegs(&regs)
- })
- if err != nil {
- return nil, err
- }
-
- setter := func(r *syscall.PtraceRegs) os.Error {
- return t.proc.do(func() os.Error {
- if !t.state.isStopped() {
- return &badState{t, "cannot get registers", t.state}
- }
- return t.ptraceSetRegs(r)
- })
- }
- return newRegs(&regs, setter), nil
-}
-
-func (t *thread) Peek(addr Word, out []byte) (int, os.Error) {
- var c int
-
- err := t.proc.do(func() os.Error {
- if !t.state.isStopped() {
- return &badState{t, "cannot peek text", t.state}
- }
-
- var err os.Error
- c, err = t.ptracePeekText(uintptr(addr), out)
- return err
- })
-
- return c, err
-}
-
-func (t *thread) Poke(addr Word, out []byte) (int, os.Error) {
- var c int
-
- err := t.proc.do(func() os.Error {
- if !t.state.isStopped() {
- return &badState{t, "cannot poke text", t.state}
- }
-
- var err os.Error
- c, err = t.ptracePokeText(uintptr(addr), out)
- return err
- })
-
- return c, err
-}
-
-// stepAsync starts this thread single stepping. When the single step
-// is complete, it will send nil on the given channel. If an error
-// occurs while setting up the single step, it returns that error. If
-// an error occurs while waiting for the single step to complete, it
-// sends that error on the channel.
-func (t *thread) stepAsync(ready chan os.Error) os.Error {
- if err := t.ptraceStep(); err != nil {
- return err
- }
- t.setState(singleStepping)
- t.onStop(func() { ready <- nil },
- func(err os.Error) { ready <- err })
- return nil
-}
-
-func (t *thread) Step() os.Error {
- t.logTrace("Step {")
- defer t.logTrace("}")
-
- ready := make(chan os.Error)
-
- err := t.proc.do(func() os.Error {
- if !t.state.isStopped() {
- return &badState{t, "cannot single step", t.state}
- }
- return t.stepAsync(ready)
- })
- if err != nil {
- return err
- }
-
- err = <-ready
- return err
-}
-
-// TODO(austin) We should probably get this via C's strsignal.
-var sigNames = [...]string{
- "SIGEXIT", "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL",
- "SIGTRAP", "SIGABRT", "SIGBUS", "SIGFPE", "SIGKILL",
- "SIGUSR1", "SIGSEGV", "SIGUSR2", "SIGPIPE", "SIGALRM",
- "SIGTERM", "SIGSTKFLT", "SIGCHLD", "SIGCONT", "SIGSTOP",
- "SIGTSTP", "SIGTTIN", "SIGTTOU", "SIGURG", "SIGXCPU",
- "SIGXFSZ", "SIGVTALRM", "SIGPROF", "SIGWINCH", "SIGPOLL",
- "SIGPWR", "SIGSYS",
-}
-
-// sigName returns the symbolic name for the given signal number. If
-// the signal number is invalid, returns "<invalid>".
-func sigName(signal int) string {
- if signal < 0 || signal >= len(sigNames) {
- return "<invalid>"
- }
- return sigNames[signal]
-}
-
-func (t *thread) Stopped() (Cause, os.Error) {
- var c Cause
- err := t.proc.do(func() os.Error {
- switch t.state {
- case stopped:
- c = Stopped{}
-
- case stoppedBreakpoint:
- c = Breakpoint(t.breakpoint.pc)
-
- case stoppedSignal:
- c = Signal(sigName(t.signal))
-
- case stoppedThreadCreate:
- c = &ThreadCreate{t.newThread}
-
- case stoppedExiting, exiting, exited:
- if t.signal == -1 {
- c = &ThreadExit{t.exitStatus, ""}
- } else {
- c = &ThreadExit{t.exitStatus, sigName(t.signal)}
- }
-
- default:
- return &badState{t, "cannot get stop cause", t.state}
- }
- return nil
- })
- if err != nil {
- return nil, err
- }
-
- return c, nil
-}
-
-func (p *process) Threads() []Thread {
- var res []Thread
-
- p.do(func() os.Error {
- res = make([]Thread, len(p.threads))
- i := 0
- for _, t := range p.threads {
- // Exclude zombie threads.
- st := t.state
- if st == exiting || st == exited || st == detached {
- continue
- }
-
- res[i] = t
- i++
- }
- res = res[0:i]
- return nil
- })
- return res
-}
-
-func (p *process) AddBreakpoint(pc Word) os.Error {
- return p.do(func() os.Error {
- if t := p.someRunningThread(); t != nil {
- return &badState{t, "cannot add breakpoint", t.state}
- }
- if _, ok := p.breakpoints[uintptr(pc)]; ok {
- return breakpointExistsError(pc)
- }
- p.breakpoints[uintptr(pc)] = &breakpoint{pc: uintptr(pc)}
- return nil
- })
-}
-
-func (p *process) RemoveBreakpoint(pc Word) os.Error {
- return p.do(func() os.Error {
- if t := p.someRunningThread(); t != nil {
- return &badState{t, "cannot remove breakpoint", t.state}
- }
- if _, ok := p.breakpoints[uintptr(pc)]; !ok {
- return noBreakpointError(pc)
- }
- p.breakpoints[uintptr(pc)] = nil, false
- return nil
- })
-}
-
-func (p *process) Continue() os.Error {
- // Single step any threads that are stopped at breakpoints so
- // we can reinstall breakpoints.
- var ready chan os.Error
- count := 0
-
- err := p.do(func() os.Error {
- // We make the ready channel big enough to hold all
- // ready message so we don't jam up the monitor if we
- // stop listening (e.g., if there's an error).
- ready = make(chan os.Error, len(p.threads))
-
- for _, t := range p.threads {
- if !t.state.isStopped() {
- continue
- }
-
- // We use the breakpoint map directly here
- // instead of checking the stop cause because
- // it could have been stopped at a breakpoint
- // for some other reason, or the breakpoint
- // could have been added since it was stopped.
- var regs syscall.PtraceRegs
- err := t.ptraceGetRegs(&regs)
- if err != nil {
- return err
- }
- if b, ok := p.breakpoints[uintptr(regs.PC())]; ok {
- t.logTrace("stepping over breakpoint %v", b)
- if err := t.stepAsync(ready); err != nil {
- return err
- }
- count++
- }
- }
- return nil
- })
- if err != nil {
- p.stopMonitor(err)
- return err
- }
-
- // Wait for single stepping threads
- for count > 0 {
- err = <-ready
- if err != nil {
- p.stopMonitor(err)
- return err
- }
- count--
- }
-
- // Continue all threads
- err = p.do(func() os.Error {
- if err := p.installBreakpoints(); err != nil {
- return err
- }
-
- for _, t := range p.threads {
- var err os.Error
- switch {
- case !t.state.isStopped():
- continue
-
- case t.state == stoppedSignal && t.signal != syscall.SIGSTOP && t.signal != syscall.SIGTRAP:
- t.logTrace("continuing with signal %d", t.signal)
- err = t.ptraceContWithSignal(t.signal)
-
- default:
- t.logTrace("continuing")
- err = t.ptraceCont()
- }
- if err != nil {
- return err
- }
- if t.state == stoppedExiting {
- t.setState(exiting)
- } else {
- t.setState(running)
- }
- }
- return nil
- })
- if err != nil {
- // TODO(austin) Do we need to stop the monitor with
- // this error atomically with the do-routine above?
- p.stopMonitor(err)
- return err
- }
-
- return nil
-}
-
-func (p *process) WaitStop() os.Error {
- // We need a non-blocking ready channel for the case where all
- // threads are already stopped.
- ready := make(chan os.Error, 1)
-
- err := p.do(func() os.Error {
- // Are all of the threads already stopped?
- if p.someRunningThread() == nil {
- ready <- nil
- return nil
- }
-
- // Monitor state transitions
- h := &transitionHandler{}
- h.handle = func(st *thread, old, new threadState) {
- if !new.isRunning() {
- if p.someRunningThread() == nil {
- ready <- nil
- return
- }
- }
- p.transitionHandlers.Push(h)
- }
- h.onErr = func(err os.Error) { ready <- err }
- p.transitionHandlers.Push(h)
- return nil
- })
- if err != nil {
- return err
- }
-
- return <-ready
-}
-
-func (p *process) Stop() os.Error {
- err := p.do(func() os.Error { return p.stopAsync() })
- if err != nil {
- return err
- }
-
- return p.WaitStop()
-}
-
-func (p *process) Detach() os.Error {
- if err := p.Stop(); err != nil {
- return err
- }
-
- err := p.do(func() os.Error {
- if err := p.uninstallBreakpoints(); err != nil {
- return err
- }
-
- for pid, t := range p.threads {
- if t.state.isStopped() {
- // We can't detach from zombies.
- if err := t.ptraceDetach(); err != nil {
- return err
- }
- }
- t.setState(detached)
- p.threads[pid] = nil, false
- }
- return nil
- })
- // TODO(austin) Wait for monitor thread to exit?
- return err
-}
-
-// newThread creates a new thread object and waits for its initial
-// signal. If cloned is true, this thread was cloned from a thread we
-// are already attached to.
-//
-// Must be run from the monitor thread.
-func (p *process) newThread(tid int, signal int, cloned bool) (*thread, os.Error) {
- t := &thread{tid: tid, proc: p, state: stopped}
-
- // Get the signal from the thread
- // TODO(austin) Thread might already be stopped if we're attaching.
- w, err := os.Wait(tid, syscall.WALL)
- if err != nil {
- return nil, err
- }
- if w.Pid != tid || w.StopSignal() != signal {
- return nil, &newThreadError{w, tid, signal}
- }
-
- if !cloned {
- err = t.ptraceSetOptions(syscall.PTRACE_O_TRACECLONE | syscall.PTRACE_O_TRACEEXIT)
- if err != nil {
- return nil, err
- }
- }
-
- p.threads[tid] = t
-
- return t, nil
-}
-
-// attachThread attaches a running thread to the process.
-//
-// Must NOT be run from the monitor thread.
-func (p *process) attachThread(tid int) (*thread, os.Error) {
- p.logTrace("attaching to thread %d", tid)
- var thr *thread
- err := p.do(func() os.Error {
- errno := syscall.PtraceAttach(tid)
- if errno != 0 {
- return os.NewSyscallError("ptrace(ATTACH)", errno)
- }
-
- var err os.Error
- thr, err = p.newThread(tid, syscall.SIGSTOP, false)
- return err
- })
- return thr, err
-}
-
-// attachAllThreads attaches to all threads in a process.
-func (p *process) attachAllThreads() os.Error {
- taskPath := "/proc/" + strconv.Itoa(p.pid) + "/task"
- taskDir, err := os.Open(taskPath)
- if err != nil {
- return err
- }
- defer taskDir.Close()
-
- // We stop threads as we attach to them; however, because new
- // threads can appear while we're looping over all of them, we
- // have to repeatly scan until we know we're attached to all
- // of them.
- for again := true; again; {
- again = false
-
- tids, err := taskDir.Readdirnames(-1)
- if err != nil {
- return err
- }
-
- for _, tidStr := range tids {
- tid, err := strconv.Atoi(tidStr)
- if err != nil {
- return err
- }
- if _, ok := p.threads[tid]; ok {
- continue
- }
-
- _, err = p.attachThread(tid)
- if err != nil {
- // There could have been a race, or
- // this process could be a zobmie.
- statFile, err2 := ioutil.ReadFile(taskPath + "/" + tidStr + "/stat")
- if err2 != nil {
- switch err2 := err2.(type) {
- case *os.PathError:
- if err2.Error == os.ENOENT {
- // Raced with thread exit
- p.logTrace("raced with thread %d exit", tid)
- continue
- }
- }
- // Return the original error
- return err
- }
-
- statParts := strings.Split(string(statFile), " ", 4)
- if len(statParts) > 2 && statParts[2] == "Z" {
- // tid is a zombie
- p.logTrace("thread %d is a zombie", tid)
- continue
- }
-
- // Return the original error
- return err
- }
- again = true
- }
- }
-
- return nil
-}
-
-// newProcess creates a new process object and starts its monitor thread.
-func newProcess(pid int) *process {
- p := &process{
- pid: pid,
- threads: make(map[int]*thread),
- breakpoints: make(map[uintptr]*breakpoint),
- ready: make(chan bool, 1),
- debugEvents: make(chan *debugEvent),
- debugReqs: make(chan *debugReq),
- stopReq: make(chan os.Error),
- }
-
- go p.monitor()
-
- return p
-}
-
-// Attach attaches to process pid and stops all of its threads.
-func Attach(pid int) (Process, os.Error) {
- p := newProcess(pid)
-
- // Attach to all threads
- err := p.attachAllThreads()
- if err != nil {
- p.Detach()
- // TODO(austin) Detach stopped the monitor already
- //p.stopMonitor(err);
- return nil, err
- }
-
- return p, nil
-}
-
-// StartProcess forks the current process and execs argv0, stopping the
-// new process after the exec syscall. See os.StartProcess for additional
-// details.
-func StartProcess(argv0 string, argv []string, attr *os.ProcAttr) (Process, os.Error) {
- sysattr := &syscall.ProcAttr{
- Dir: attr.Dir,
- Env: attr.Env,
- Ptrace: true,
- }
- p := newProcess(-1)
-
- // Create array of integer (system) fds.
- intfd := make([]int, len(attr.Files))
- for i, f := range attr.Files {
- if f == nil {
- intfd[i] = -1
- } else {
- intfd[i] = f.Fd()
- }
- }
- sysattr.Files = intfd
-
- // Fork from the monitor thread so we get the right tracer pid.
- err := p.do(func() os.Error {
- pid, _, errno := syscall.StartProcess(argv0, argv, sysattr)
- if errno != 0 {
- return &os.PathError{"fork/exec", argv0, os.Errno(errno)}
- }
- p.pid = pid
-
- // The process will raise SIGTRAP when it reaches execve.
- _, err := p.newThread(pid, syscall.SIGTRAP, false)
- return err
- })
- if err != nil {
- p.stopMonitor(err)
- return nil, err
- }
-
- return p, nil
-}
diff --git a/libgo/go/debug/proc/proc_windows.go b/libgo/go/debug/proc/proc_windows.go
deleted file mode 100644
index 661474b..0000000
--- a/libgo/go/debug/proc/proc_windows.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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.
-
-package proc
-
-import "os"
-
-// Process tracing is not supported on windows yet.
-
-func Attach(pid int) (Process, os.Error) {
- return nil, os.NewError("debug/proc not implemented on windows")
-}
-
-func StartProcess(argv0 string, argv []string, attr *os.ProcAttr) (Process, os.Error) {
- return Attach(0)
-}
diff --git a/libgo/go/debug/proc/regs_darwin_386.go b/libgo/go/debug/proc/regs_darwin_386.go
deleted file mode 100644
index 60c9ac7..0000000
--- a/libgo/go/debug/proc/regs_darwin_386.go
+++ /dev/null
@@ -1,5 +0,0 @@
-// 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.
-
-package proc
diff --git a/libgo/go/debug/proc/regs_darwin_amd64.go b/libgo/go/debug/proc/regs_darwin_amd64.go
deleted file mode 100644
index 60c9ac7..0000000
--- a/libgo/go/debug/proc/regs_darwin_amd64.go
+++ /dev/null
@@ -1,5 +0,0 @@
-// 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.
-
-package proc
diff --git a/libgo/go/debug/proc/regs_freebsd_386.go b/libgo/go/debug/proc/regs_freebsd_386.go
deleted file mode 100644
index 60c9ac7..0000000
--- a/libgo/go/debug/proc/regs_freebsd_386.go
+++ /dev/null
@@ -1,5 +0,0 @@
-// 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.
-
-package proc
diff --git a/libgo/go/debug/proc/regs_freebsd_amd64.go b/libgo/go/debug/proc/regs_freebsd_amd64.go
deleted file mode 100644
index 60c9ac7..0000000
--- a/libgo/go/debug/proc/regs_freebsd_amd64.go
+++ /dev/null
@@ -1,5 +0,0 @@
-// 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.
-
-package proc
diff --git a/libgo/go/debug/proc/regs_linux_386.go b/libgo/go/debug/proc/regs_linux_386.go
deleted file mode 100644
index b4a9769..0000000
--- a/libgo/go/debug/proc/regs_linux_386.go
+++ /dev/null
@@ -1,143 +0,0 @@
-// 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.
-
-package proc
-
-import (
- "os"
- "strconv"
- "syscall"
-)
-
-type _386Regs struct {
- syscall.PtraceRegs
- setter func(*syscall.PtraceRegs) os.Error
-}
-
-var names = []string{
- "eax",
- "ebx",
- "ecx",
- "edx",
- "esi",
- "edi",
- "ebp",
- "esp",
- "eip",
- "eflags",
- "cs",
- "ss",
- "ds",
- "es",
- "fs",
- "gs",
-}
-
-func (r *_386Regs) PC() Word { return Word(r.Eip) }
-
-func (r *_386Regs) SetPC(val Word) os.Error {
- r.Eip = int32(val)
- return r.setter(&r.PtraceRegs)
-}
-
-func (r *_386Regs) Link() Word {
- // TODO(austin)
- panic("No link register")
-}
-
-func (r *_386Regs) SetLink(val Word) os.Error { panic("No link register") }
-
-func (r *_386Regs) SP() Word { return Word(r.Esp) }
-
-func (r *_386Regs) SetSP(val Word) os.Error {
- r.Esp = int32(val)
- return r.setter(&r.PtraceRegs)
-}
-
-func (r *_386Regs) Names() []string { return names }
-
-func (r *_386Regs) Get(i int) Word {
- switch i {
- case 0:
- return Word(uint32(r.Eax))
- case 1:
- return Word(uint32(r.Ebx))
- case 2:
- return Word(uint32(r.Ecx))
- case 3:
- return Word(uint32(r.Edx))
- case 4:
- return Word(uint32(r.Esi))
- case 5:
- return Word(uint32(r.Edi))
- case 6:
- return Word(uint32(r.Ebp))
- case 7:
- return Word(uint32(r.Esp))
- case 8:
- return Word(uint32(r.Eip))
- case 9:
- return Word(uint32(r.Eflags))
- case 10:
- return Word(r.Xcs)
- case 11:
- return Word(r.Xss)
- case 12:
- return Word(r.Xds)
- case 13:
- return Word(r.Xes)
- case 14:
- return Word(r.Xfs)
- case 15:
- return Word(r.Xgs)
- }
- panic("invalid register index " + strconv.Itoa(i))
-}
-
-func (r *_386Regs) Set(i int, val Word) os.Error {
- switch i {
- case 0:
- r.Eax = int32(val)
- case 1:
- r.Ebx = int32(val)
- case 2:
- r.Ecx = int32(val)
- case 3:
- r.Edx = int32(val)
- case 4:
- r.Esi = int32(val)
- case 5:
- r.Edi = int32(val)
- case 6:
- r.Ebp = int32(val)
- case 7:
- r.Esp = int32(val)
- case 8:
- r.Eip = int32(val)
- case 9:
- r.Eflags = int32(val)
- case 10:
- r.Xcs = int32(val)
- case 11:
- r.Xss = int32(val)
- case 12:
- r.Xds = int32(val)
- case 13:
- r.Xes = int32(val)
- case 14:
- r.Xfs = int32(val)
- case 15:
- r.Xgs = int32(val)
- default:
- panic("invalid register index " + strconv.Itoa(i))
- }
- return r.setter(&r.PtraceRegs)
-}
-
-func newRegs(regs *syscall.PtraceRegs, setter func(*syscall.PtraceRegs) os.Error) Regs {
- res := _386Regs{}
- res.PtraceRegs = *regs
- res.setter = setter
- return &res
-}
diff --git a/libgo/go/debug/proc/regs_linux_amd64.go b/libgo/go/debug/proc/regs_linux_amd64.go
deleted file mode 100644
index 381be29..0000000
--- a/libgo/go/debug/proc/regs_linux_amd64.go
+++ /dev/null
@@ -1,191 +0,0 @@
-// 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.
-
-package proc
-
-import (
- "os"
- "strconv"
- "syscall"
-)
-
-type amd64Regs struct {
- syscall.PtraceRegs
- setter func(*syscall.PtraceRegs) os.Error
-}
-
-var names = [...]string{
- "rax",
- "rbx",
- "rcx",
- "rdx",
- "rsi",
- "rdi",
- "rbp",
- "rsp",
- "r8",
- "r9",
- "r10",
- "r11",
- "r12",
- "r13",
- "r14",
- "r15",
- "rip",
- "eflags",
- "cs",
- "ss",
- "ds",
- "es",
- "fs",
- "gs",
-
- // PtraceRegs contains these registers, but I don't think
- // they're actually meaningful.
- //"orig_rax",
- //"fs_base",
- //"gs_base",
-}
-
-func (r *amd64Regs) PC() Word { return Word(r.Rip) }
-
-func (r *amd64Regs) SetPC(val Word) os.Error {
- r.Rip = uint64(val)
- return r.setter(&r.PtraceRegs)
-}
-
-func (r *amd64Regs) Link() Word {
- // TODO(austin)
- panic("No link register")
-}
-
-func (r *amd64Regs) SetLink(val Word) os.Error {
- panic("No link register")
-}
-
-func (r *amd64Regs) SP() Word { return Word(r.Rsp) }
-
-func (r *amd64Regs) SetSP(val Word) os.Error {
- r.Rsp = uint64(val)
- return r.setter(&r.PtraceRegs)
-}
-
-func (r *amd64Regs) Names() []string { return names[0:] }
-
-func (r *amd64Regs) Get(i int) Word {
- switch i {
- case 0:
- return Word(r.Rax)
- case 1:
- return Word(r.Rbx)
- case 2:
- return Word(r.Rcx)
- case 3:
- return Word(r.Rdx)
- case 4:
- return Word(r.Rsi)
- case 5:
- return Word(r.Rdi)
- case 6:
- return Word(r.Rbp)
- case 7:
- return Word(r.Rsp)
- case 8:
- return Word(r.R8)
- case 9:
- return Word(r.R9)
- case 10:
- return Word(r.R10)
- case 11:
- return Word(r.R11)
- case 12:
- return Word(r.R12)
- case 13:
- return Word(r.R13)
- case 14:
- return Word(r.R14)
- case 15:
- return Word(r.R15)
- case 16:
- return Word(r.Rip)
- case 17:
- return Word(r.Eflags)
- case 18:
- return Word(r.Cs)
- case 19:
- return Word(r.Ss)
- case 20:
- return Word(r.Ds)
- case 21:
- return Word(r.Es)
- case 22:
- return Word(r.Fs)
- case 23:
- return Word(r.Gs)
- }
- panic("invalid register index " + strconv.Itoa(i))
-}
-
-func (r *amd64Regs) Set(i int, val Word) os.Error {
- switch i {
- case 0:
- r.Rax = uint64(val)
- case 1:
- r.Rbx = uint64(val)
- case 2:
- r.Rcx = uint64(val)
- case 3:
- r.Rdx = uint64(val)
- case 4:
- r.Rsi = uint64(val)
- case 5:
- r.Rdi = uint64(val)
- case 6:
- r.Rbp = uint64(val)
- case 7:
- r.Rsp = uint64(val)
- case 8:
- r.R8 = uint64(val)
- case 9:
- r.R9 = uint64(val)
- case 10:
- r.R10 = uint64(val)
- case 11:
- r.R11 = uint64(val)
- case 12:
- r.R12 = uint64(val)
- case 13:
- r.R13 = uint64(val)
- case 14:
- r.R14 = uint64(val)
- case 15:
- r.R15 = uint64(val)
- case 16:
- r.Rip = uint64(val)
- case 17:
- r.Eflags = uint64(val)
- case 18:
- r.Cs = uint64(val)
- case 19:
- r.Ss = uint64(val)
- case 20:
- r.Ds = uint64(val)
- case 21:
- r.Es = uint64(val)
- case 22:
- r.Fs = uint64(val)
- case 23:
- r.Gs = uint64(val)
- default:
- panic("invalid register index " + strconv.Itoa(i))
- }
- return r.setter(&r.PtraceRegs)
-}
-
-func newRegs(regs *syscall.PtraceRegs, setter func(*syscall.PtraceRegs) os.Error) Regs {
- res := amd64Regs{}
- res.PtraceRegs = *regs
- res.setter = setter
- return &res
-}
diff --git a/libgo/go/debug/proc/regs_linux_arm.go b/libgo/go/debug/proc/regs_linux_arm.go
deleted file mode 100644
index ec78cbc..0000000
--- a/libgo/go/debug/proc/regs_linux_arm.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// 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.
-
-package proc
-
-import (
- "os"
- "syscall"
-)
-
-// TODO(kaib): add support
-
-type armRegs struct{}
-
-func (r *armRegs) PC() Word { return Word(0) }
-
-func (r *armRegs) SetPC(val Word) os.Error { return nil }
-
-func (r *armRegs) Link() Word { return Word(0) }
-
-func (r *armRegs) SetLink(val Word) os.Error { return nil }
-
-func (r *armRegs) SP() Word { return Word(0) }
-
-func (r *armRegs) SetSP(val Word) os.Error { return nil }
-
-func (r *armRegs) Names() []string { return nil }
-
-func (r *armRegs) Get(i int) Word { return Word(0) }
-
-func (r *armRegs) Set(i int, val Word) os.Error {
- return nil
-}
-
-func newRegs(regs *syscall.PtraceRegs, setter func(*syscall.PtraceRegs) os.Error) Regs {
- res := armRegs{}
- return &res
-}
diff --git a/libgo/go/debug/proc/regs_windows_386.go b/libgo/go/debug/proc/regs_windows_386.go
deleted file mode 100644
index 60c9ac7..0000000
--- a/libgo/go/debug/proc/regs_windows_386.go
+++ /dev/null
@@ -1,5 +0,0 @@
-// 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.
-
-package proc
diff --git a/libgo/go/debug/proc/regs_windows_amd64.go b/libgo/go/debug/proc/regs_windows_amd64.go
deleted file mode 100644
index 60c9ac7..0000000
--- a/libgo/go/debug/proc/regs_windows_amd64.go
+++ /dev/null
@@ -1,5 +0,0 @@
-// 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.
-
-package proc