aboutsummaryrefslogtreecommitdiff
path: root/libgo
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2017-10-24 22:10:47 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2017-10-24 22:10:47 +0000
commit6de8466358aad789d13f78a8c59127884afede60 (patch)
tree13d704048d21c52d88da1a7f830519800bb86399 /libgo
parente91ee0faa811b6cae44d146aa16c379797ad191e (diff)
parent6ab5a6f30f2a3a9db37604195ff4b802779f83bc (diff)
downloadgcc-6de8466358aad789d13f78a8c59127884afede60.zip
gcc-6de8466358aad789d13f78a8c59127884afede60.tar.gz
gcc-6de8466358aad789d13f78a8c59127884afede60.tar.bz2
Merge from trunk revision 254059.
From-SVN: r254062
Diffstat (limited to 'libgo')
-rw-r--r--libgo/Makefile.am20
-rw-r--r--libgo/Makefile.in18
-rw-r--r--libgo/go/cmd/cgo/gcc.go79
-rw-r--r--libgo/go/cmd/cgo/out.go21
-rw-r--r--libgo/go/cmd/go/internal/base/signal_unix.go2
-rw-r--r--libgo/go/cmd/go/internal/work/build.go18
-rw-r--r--libgo/go/debug/dwarf/entry.go4
-rw-r--r--libgo/go/debug/dwarf/entry_test.go60
-rw-r--r--libgo/go/debug/dwarf/open.go19
-rw-r--r--libgo/go/debug/dwarf/typeunit.go11
-rw-r--r--libgo/go/debug/dwarf/unit.go11
-rw-r--r--libgo/go/debug/elf/file.go42
-rw-r--r--libgo/go/debug/xcoff/file.go539
-rw-r--r--libgo/go/debug/xcoff/file_test.go150
-rw-r--r--libgo/go/debug/xcoff/testdata/gcc-ppc32-aix-dwarf2-execbin0 -> 54694 bytes
-rw-r--r--libgo/go/debug/xcoff/testdata/gcc-ppc32-aix-execbin0 -> 63312 bytes
-rw-r--r--libgo/go/debug/xcoff/testdata/gcc-ppc64-aix-dwarf2-execbin0 -> 57152 bytes
-rw-r--r--libgo/go/debug/xcoff/testdata/gcc-ppc64-aix-execbin0 -> 66618 bytes
-rw-r--r--libgo/go/debug/xcoff/testdata/hello.c7
-rw-r--r--libgo/go/debug/xcoff/testdata/xlc-ppc32-aix-execbin0 -> 6529 bytes
-rw-r--r--libgo/go/debug/xcoff/testdata/xlc-ppc64-aix-execbin0 -> 6112 bytes
-rw-r--r--libgo/go/debug/xcoff/xcoff.go262
-rw-r--r--libgo/go/go/build/deps_test.go3
-rw-r--r--libgo/go/go/internal/gccgoimporter/importer.go42
-rw-r--r--libgo/go/internal/poll/export_posix_test.go2
-rw-r--r--libgo/go/internal/poll/fd_poll_runtime.go2
-rw-r--r--libgo/go/internal/poll/fd_posix.go2
-rw-r--r--libgo/go/internal/poll/fd_posix_test.go2
-rw-r--r--libgo/go/internal/poll/fd_unix.go2
-rw-r--r--libgo/go/internal/poll/hook_unix.go2
-rw-r--r--libgo/go/internal/poll/sockopt.go2
-rw-r--r--libgo/go/internal/poll/sockoptip.go2
-rw-r--r--libgo/go/internal/poll/sys_cloexec.go2
-rw-r--r--libgo/go/net/error_posix.go2
-rw-r--r--libgo/go/net/sock_posix.go10
-rw-r--r--libgo/go/os/user/cgo_lookup_unix.go2
-rw-r--r--libgo/go/runtime/export_unix_test.go2
-rw-r--r--libgo/go/runtime/netpoll_aix.go15
-rw-r--r--libgo/go/syscall/dirent.go2
-rw-r--r--libgo/go/syscall/forkpipe_bsd.go2
-rw-r--r--libgo/go/syscall/libcall_aix.go130
-rw-r--r--libgo/go/syscall/socket_aix.go89
-rw-r--r--libgo/go/syscall/socket_bsd.go2
-rw-r--r--libgo/go/syscall/syscall_aix.go19
-rw-r--r--libgo/go/syscall/syscall_aix_ppc.go49
-rw-r--r--libgo/go/syscall/syscall_aix_ppc64.go49
-rwxr-xr-xlibgo/mkrsysinfo.sh1
-rwxr-xr-xlibgo/mksysinfo.sh2
-rw-r--r--libgo/runtime/go-caller.c2
-rw-r--r--libgo/runtime/proc.c2
50 files changed, 1642 insertions, 64 deletions
diff --git a/libgo/Makefile.am b/libgo/Makefile.am
index 2376130..bd0bbdd 100644
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -217,7 +217,8 @@ toolexeclibgodebug_DATA = \
debug/gosym.gox \
debug/macho.gox \
debug/pe.gox \
- debug/plan9obj.gox
+ debug/plan9obj.gox \
+ debug/xcoff.gox
toolexeclibgoencodingdir = $(toolexeclibgodir)/encoding
@@ -395,6 +396,13 @@ toolexeclibgounicode_DATA = \
unicode/utf16.gox \
unicode/utf8.gox
+# Some packages are only needed for tests, so unlike the other
+# internal packages nothing will explicitly depend on them.
+# Force them to be built.
+noinst_DATA = \
+ internal/testenv.gox \
+ net/internal/socktest.gox
+
if LIBGO_IS_RTEMS
rtems_task_variable_add_file = runtime/rtems-task-variable-add.c
else
@@ -573,7 +581,7 @@ s-runtime-inc: runtime.lo Makefile
rm -f runtime.inc.tmp2 runtime.inc.tmp3
$(STAMP) $@
-noinst_DATA = zstdpkglist.go zdefaultcc.go
+noinst_DATA += zstdpkglist.go zdefaultcc.go
# Generate the list of go std packages that were included in libgo
zstdpkglist.go: s-zstdpkglist; @true
@@ -715,6 +723,7 @@ PACKAGES = \
debug/macho \
debug/pe \
debug/plan9obj \
+ debug/xcoff \
encoding \
encoding/ascii85 \
encoding/asn1 \
@@ -924,6 +933,12 @@ libgotool_a_SOURCES =
libgotool_a_DEPENDENCIES = $(addsuffix .lo,$(GOTOOL_PACKAGES))
libgotool_a_LIBADD = $(addsuffix .o,$(GOTOOL_PACKAGES))
+define STATIC_template
+$(subst -,_,$(subst .,_,$(subst /,_,$(1))))_GOCFLAGS = -static
+endef
+
+$(foreach package,$(GOTOOL_PACKAGES),$(eval $(call STATIC_template,$(package).lo)))
+
# Make sure runtime.inc is built before compiling any .c file.
$(libgo_la_OBJECTS): runtime.inc
$(libgo_llgo_la_OBJECTS): runtime.inc
@@ -1280,6 +1295,7 @@ TEST_PACKAGES = \
debug/macho/check \
debug/pe/check \
debug/plan9obj/check \
+ debug/xcoff/check \
encoding/ascii85/check \
encoding/asn1/check \
encoding/base32/check \
diff --git a/libgo/Makefile.in b/libgo/Makefile.in
index 5f7adb2..064df58 100644
--- a/libgo/Makefile.in
+++ b/libgo/Makefile.in
@@ -612,7 +612,8 @@ toolexeclibgodebug_DATA = \
debug/gosym.gox \
debug/macho.gox \
debug/pe.gox \
- debug/plan9obj.gox
+ debug/plan9obj.gox \
+ debug/xcoff.gox
toolexeclibgoencodingdir = $(toolexeclibgodir)/encoding
toolexeclibgoencoding_DATA = \
@@ -765,6 +766,12 @@ toolexeclibgounicode_DATA = \
unicode/utf16.gox \
unicode/utf8.gox
+
+# Some packages are only needed for tests, so unlike the other
+# internal packages nothing will explicitly depend on them.
+# Force them to be built.
+noinst_DATA = internal/testenv.gox net/internal/socktest.gox \
+ zstdpkglist.go zdefaultcc.go
@LIBGO_IS_RTEMS_FALSE@rtems_task_variable_add_file =
@LIBGO_IS_RTEMS_TRUE@rtems_task_variable_add_file = runtime/rtems-task-variable-add.c
@LIBGO_IS_AIX_FALSE@@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@runtime_getncpu_file = runtime/getncpu-none.c
@@ -817,7 +824,6 @@ runtime_files = \
GCCGO_INSTALL_NAME := $(shell echo gccgo|sed '$(program_transform_name)')
GCC_INSTALL_NAME := $(shell echo gcc|sed '$(program_transform_name)')
GXX_INSTALL_NAME := $(shell echo g++|sed '$(program_transform_name)')
-noinst_DATA = zstdpkglist.go zdefaultcc.go
@LIBGO_IS_LINUX_FALSE@syscall_epoll_file =
@LIBGO_IS_LINUX_TRUE@syscall_epoll_file = epoll.go
SYSINFO_FLAGS = \
@@ -868,6 +874,7 @@ PACKAGES = \
debug/macho \
debug/pe \
debug/plan9obj \
+ debug/xcoff \
encoding \
encoding/ascii85 \
encoding/asn1 \
@@ -1293,6 +1300,7 @@ TEST_PACKAGES = \
debug/macho/check \
debug/pe/check \
debug/plan9obj/check \
+ debug/xcoff/check \
encoding/ascii85/check \
encoding/asn1/check \
encoding/base32/check \
@@ -3248,6 +3256,12 @@ s-epoll: Makefile
$(SHELL) $(srcdir)/mvifdiff.sh epoll.go.tmp epoll.go
$(STAMP) $@
+define STATIC_template
+$(subst -,_,$(subst .,_,$(subst /,_,$(1))))_GOCFLAGS = -static
+endef
+
+$(foreach package,$(GOTOOL_PACKAGES),$(eval $(call STATIC_template,$(package).lo)))
+
# Make sure runtime.inc is built before compiling any .c file.
$(libgo_la_OBJECTS): runtime.inc
$(libgo_llgo_la_OBJECTS): runtime.inc
diff --git a/libgo/go/cmd/cgo/gcc.go b/libgo/go/cmd/cgo/gcc.go
index 03239a0..5453d1c 100644
--- a/libgo/go/cmd/cgo/gcc.go
+++ b/libgo/go/cmd/cgo/gcc.go
@@ -13,6 +13,7 @@ import (
"debug/elf"
"debug/macho"
"debug/pe"
+ "debug/xcoff"
"encoding/binary"
"errors"
"flag"
@@ -1289,6 +1290,10 @@ func (p *Package) gccMachine() []string {
return []string{"-mabi=64"}
case "mips", "mipsle":
return []string{"-mabi=32"}
+ case "ppc64":
+ if goos == "aix" {
+ return []string{"-maix64"}
+ }
}
return nil
}
@@ -1616,7 +1621,79 @@ func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int6
return d, ints, floats, strs
}
- fatalf("cannot parse gcc output %s as ELF, Mach-O, PE object", gccTmp())
+ if f, err := xcoff.Open(gccTmp()); err == nil {
+ defer f.Close()
+ d, err := f.DWARF()
+ if err != nil {
+ fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
+ }
+ bo := binary.BigEndian
+ for _, s := range f.Symbols {
+ switch {
+ case isDebugInts(s.Name):
+ if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
+ sect := f.Sections[i]
+ if s.Value < sect.Size {
+ if sdat, err := sect.Data(); err == nil {
+ data := sdat[s.Value:]
+ ints = make([]int64, len(data)/8)
+ for i := range ints {
+ ints[i] = int64(bo.Uint64(data[i*8:]))
+ }
+ }
+ }
+ }
+ case isDebugFloats(s.Name):
+ if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
+ sect := f.Sections[i]
+ if s.Value < sect.Size {
+ if sdat, err := sect.Data(); err == nil {
+ data := sdat[s.Value:]
+ floats = make([]float64, len(data)/8)
+ for i := range floats {
+ floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
+ }
+ }
+ }
+ }
+ default:
+ if n := indexOfDebugStr(s.Name); n != -1 {
+ if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
+ sect := f.Sections[i]
+ if s.Value < sect.Size {
+ if sdat, err := sect.Data(); err == nil {
+ data := sdat[s.Value:]
+ strdata[n] = string(data)
+ }
+ }
+ }
+ break
+ }
+ if n := indexOfDebugStrlen(s.Name); n != -1 {
+ if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
+ sect := f.Sections[i]
+ if s.Value < sect.Size {
+ if sdat, err := sect.Data(); err == nil {
+ data := sdat[s.Value:]
+ strlen := bo.Uint64(data[:8])
+ if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
+ fatalf("string literal too big")
+ }
+ strlens[n] = int(strlen)
+ }
+ }
+ }
+ break
+ }
+ }
+ }
+
+ buildStrings()
+
+ return d, ints, floats, strs
+ }
+
+ fatalf("cannot parse gcc output %s as ELF, Mach-O, PE, XCOFF object", gccTmp())
panic("not reached")
}
diff --git a/libgo/go/cmd/cgo/out.go b/libgo/go/cmd/cgo/out.go
index c4ff07d..72dd884 100644
--- a/libgo/go/cmd/cgo/out.go
+++ b/libgo/go/cmd/cgo/out.go
@@ -9,6 +9,7 @@ import (
"debug/elf"
"debug/macho"
"debug/pe"
+ "debug/xcoff"
"fmt"
"go/ast"
"go/printer"
@@ -324,7 +325,25 @@ func dynimport(obj string) {
return
}
- fatalf("cannot parse %s as ELF, Mach-O or PE", obj)
+ if f, err := xcoff.Open(obj); err == nil {
+ sym, err := f.ImportedSymbols()
+ if err != nil {
+ fatalf("cannot load imported symbols from XCOFF file %s: %v", obj, err)
+ }
+ for _, s := range sym {
+ fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", s.Name, s.Name, s.Library)
+ }
+ lib, err := f.ImportedLibraries()
+ if err != nil {
+ fatalf("cannot load imported libraries from XCOFF file %s: %v", obj, err)
+ }
+ for _, l := range lib {
+ fmt.Fprintf(stdout, "//go:cgo_import_dynamic _ _ %q\n", l)
+ }
+ return
+ }
+
+ fatalf("cannot parse %s as ELF, Mach-O, PE or XCOFF", obj)
}
// Construct a gcc struct matching the gc argument frame.
diff --git a/libgo/go/cmd/go/internal/base/signal_unix.go b/libgo/go/cmd/go/internal/base/signal_unix.go
index 4ca3da9..b90f3a2 100644
--- a/libgo/go/cmd/go/internal/base/signal_unix.go
+++ b/libgo/go/cmd/go/internal/base/signal_unix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+// +build aix darwin dragonfly freebsd linux nacl netbsd openbsd solaris
package base
diff --git a/libgo/go/cmd/go/internal/work/build.go b/libgo/go/cmd/go/internal/work/build.go
index de8c493..562730b 100644
--- a/libgo/go/cmd/go/internal/work/build.go
+++ b/libgo/go/cmd/go/internal/work/build.go
@@ -9,6 +9,7 @@ import (
"bytes"
"container/heap"
"debug/elf"
+ "debug/xcoff"
"errors"
"flag"
"fmt"
@@ -745,9 +746,13 @@ func (b *Builder) Init() {
func readpkglist(shlibpath string) (pkgs []*load.Package) {
var stk load.ImportStack
if cfg.BuildToolchainName == "gccgo" {
- f, _ := elf.Open(shlibpath)
- sect := f.Section(".go_export")
- data, _ := sect.Data()
+ var data []byte
+ if f, err := elf.Open(shlibpath); err == nil {
+ sect := f.Section(".go_export")
+ data, _ = sect.Data()
+ } else if f, err := xcoff.Open(shlibpath); err == nil {
+ data = f.CSect(".go_export")
+ }
scanner := bufio.NewScanner(bytes.NewBuffer(data))
for scanner.Scan() {
t := scanner.Text()
@@ -1815,6 +1820,7 @@ func (b *Builder) cover(a *Action, dst, src string, perm os.FileMode, varName st
var objectMagic = [][]byte{
{'!', '<', 'a', 'r', 'c', 'h', '>', '\n'}, // Package archive
+ {'<', 'b', 'i', 'g', 'a', 'f', '>', '\n'}, // Package archive (AIX format)
{'\x7F', 'E', 'L', 'F'}, // ELF
{0xFE, 0xED, 0xFA, 0xCE}, // Mach-O big-endian 32-bit
{0xFE, 0xED, 0xFA, 0xCF}, // Mach-O big-endian 64-bit
@@ -1824,6 +1830,8 @@ var objectMagic = [][]byte{
{0x00, 0x00, 0x01, 0xEB}, // Plan 9 i386
{0x00, 0x00, 0x8a, 0x97}, // Plan 9 amd64
{0x00, 0x00, 0x06, 0x47}, // Plan 9 arm
+ {0x01, 0xDF}, // XCOFF32
+ {0x01, 0xF7}, // XCOFF64
}
func isObject(s string) bool {
@@ -3308,6 +3316,10 @@ func (b *Builder) gccArchArgs() []string {
return []string{"-mabi=64"}
case "mips", "mipsle":
return []string{"-mabi=32", "-march=mips32"}
+ case "ppc64":
+ if cfg.Goos == "aix" {
+ return []string{"-maix64"}
+ }
}
return nil
}
diff --git a/libgo/go/debug/dwarf/entry.go b/libgo/go/debug/dwarf/entry.go
index 80bf14c..ffa61c28 100644
--- a/libgo/go/debug/dwarf/entry.go
+++ b/libgo/go/debug/dwarf/entry.go
@@ -33,13 +33,13 @@ type abbrevTable map[uint32]abbrev
// ParseAbbrev returns the abbreviation table that starts at byte off
// in the .debug_abbrev section.
-func (d *Data) parseAbbrev(off uint32, vers int) (abbrevTable, error) {
+func (d *Data) parseAbbrev(off uint64, vers int) (abbrevTable, error) {
if m, ok := d.abbrevCache[off]; ok {
return m, nil
}
data := d.abbrev
- if off > uint32(len(data)) {
+ if off > uint64(len(data)) {
data = nil
} else {
data = data[off:]
diff --git a/libgo/go/debug/dwarf/entry_test.go b/libgo/go/debug/dwarf/entry_test.go
index 58a5d57..58f3023 100644
--- a/libgo/go/debug/dwarf/entry_test.go
+++ b/libgo/go/debug/dwarf/entry_test.go
@@ -135,3 +135,63 @@ func TestReaderRanges(t *testing.T) {
t.Errorf("saw only %d subprograms, expected %d", i, len(subprograms))
}
}
+
+func Test64Bit(t *testing.T) {
+ // I don't know how to generate a 64-bit DWARF debug
+ // compilation unit except by using XCOFF, so this is
+ // hand-written.
+ tests := []struct {
+ name string
+ info []byte
+ }{
+ {
+ "32-bit little",
+ []byte{0x30, 0, 0, 0, // comp unit length
+ 4, 0, // DWARF version 4
+ 0, 0, 0, 0, // abbrev offset
+ 8, // address size
+ 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ {
+ "64-bit little",
+ []byte{0xff, 0xff, 0xff, 0xff, // 64-bit DWARF
+ 0x30, 0, 0, 0, 0, 0, 0, 0, // comp unit length
+ 4, 0, // DWARF version 4
+ 0, 0, 0, 0, 0, 0, 0, 0, // abbrev offset
+ 8, // address size
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ {
+ "64-bit big",
+ []byte{0xff, 0xff, 0xff, 0xff, // 64-bit DWARF
+ 0, 0, 0, 0, 0, 0, 0, 0x30, // comp unit length
+ 0, 4, // DWARF version 4
+ 0, 0, 0, 0, 0, 0, 0, 0, // abbrev offset
+ 8, // address size
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ }
+
+ for _, test := range tests {
+ _, err := New(nil, nil, nil, test.info, nil, nil, nil, nil)
+ if err != nil {
+ t.Errorf("%s: %v", test.name, err)
+ }
+ }
+}
diff --git a/libgo/go/debug/dwarf/open.go b/libgo/go/debug/dwarf/open.go
index 0e9c01c..9381869 100644
--- a/libgo/go/debug/dwarf/open.go
+++ b/libgo/go/debug/dwarf/open.go
@@ -23,7 +23,7 @@ type Data struct {
str []byte
// parsed data
- abbrevCache map[uint32]abbrevTable
+ abbrevCache map[uint64]abbrevTable
order binary.ByteOrder
typeCache map[Offset]Type
typeSigs map[uint64]*typeUnit
@@ -33,7 +33,7 @@ type Data struct {
// New returns a new Data object initialized from the given parameters.
// Rather than calling this function directly, clients should typically use
// the DWARF method of the File type of the appropriate package debug/elf,
-// debug/macho, or debug/pe.
+// debug/macho, debug/pe, or debug/xcoff.
//
// The []byte arguments are the data from the corresponding debug section
// in the object file; for example, for an ELF object, abbrev is the contents of
@@ -48,17 +48,26 @@ func New(abbrev, aranges, frame, info, line, pubnames, ranges, str []byte) (*Dat
pubnames: pubnames,
ranges: ranges,
str: str,
- abbrevCache: make(map[uint32]abbrevTable),
+ abbrevCache: make(map[uint64]abbrevTable),
typeCache: make(map[Offset]Type),
typeSigs: make(map[uint64]*typeUnit),
}
// Sniff .debug_info to figure out byte order.
- // bytes 4:6 are the version, a tiny 16-bit number (1, 2, 3).
+ // 32-bit DWARF: 4 byte length, 2 byte version.
+ // 64-bit DWARf: 4 bytes of 0xff, 8 byte length, 2 byte version.
if len(d.info) < 6 {
return nil, DecodeError{"info", Offset(len(d.info)), "too short"}
}
- x, y := d.info[4], d.info[5]
+ offset := 4
+ if d.info[0] == 0xff && d.info[1] == 0xff && d.info[2] == 0xff && d.info[3] == 0xff {
+ if len(d.info) < 14 {
+ return nil, DecodeError{"info", Offset(len(d.info)), "too short"}
+ }
+ offset = 12
+ }
+ // Fetch the version, a tiny 16-bit number (1, 2, 3, 4, 5).
+ x, y := d.info[offset], d.info[offset+1]
switch {
case x == 0 && y == 0:
return nil, DecodeError{"info", 4, "unsupported version 0"}
diff --git a/libgo/go/debug/dwarf/typeunit.go b/libgo/go/debug/dwarf/typeunit.go
index 652e02d..76b357c 100644
--- a/libgo/go/debug/dwarf/typeunit.go
+++ b/libgo/go/debug/dwarf/typeunit.go
@@ -38,16 +38,11 @@ func (d *Data) parseTypes(name string, types []byte) error {
b.error("unsupported DWARF version " + strconv.Itoa(vers))
return b.err
}
- var ao uint32
+ var ao uint64
if !dwarf64 {
- ao = b.uint32()
+ ao = uint64(b.uint32())
} else {
- ao64 := b.uint64()
- if ao64 != uint64(uint32(ao64)) {
- b.error("type unit abbrev offset overflow")
- return b.err
- }
- ao = uint32(ao64)
+ ao = b.uint64()
}
atable, err := d.parseAbbrev(ao, vers)
if err != nil {
diff --git a/libgo/go/debug/dwarf/unit.go b/libgo/go/debug/dwarf/unit.go
index e45aed7..98024ca 100644
--- a/libgo/go/debug/dwarf/unit.go
+++ b/libgo/go/debug/dwarf/unit.go
@@ -61,13 +61,20 @@ func (d *Data) parseUnits() ([]unit, error) {
u.base = b.off
var n Offset
n, u.is64 = b.unitLength()
+ dataOff := b.off
vers := b.uint16()
if vers != 2 && vers != 3 && vers != 4 {
b.error("unsupported DWARF version " + strconv.Itoa(int(vers)))
break
}
u.vers = int(vers)
- atable, err := d.parseAbbrev(b.uint32(), u.vers)
+ var abbrevOff uint64
+ if u.is64 {
+ abbrevOff = b.uint64()
+ } else {
+ abbrevOff = uint64(b.uint32())
+ }
+ atable, err := d.parseAbbrev(abbrevOff, u.vers)
if err != nil {
if b.err == nil {
b.err = err
@@ -77,7 +84,7 @@ func (d *Data) parseUnits() ([]unit, error) {
u.atable = atable
u.asize = int(b.uint8())
u.off = b.off
- u.data = b.bytes(int(n - (2 + 4 + 1)))
+ u.data = b.bytes(int(n - (b.off - dataOff)))
}
if b.err != nil {
return nil, b.err
diff --git a/libgo/go/debug/elf/file.go b/libgo/go/debug/elf/file.go
index c493f2a..b415bb1 100644
--- a/libgo/go/debug/elf/file.go
+++ b/libgo/go/debug/elf/file.go
@@ -600,6 +600,8 @@ func (f *File) applyRelocations(dst []byte, rels []byte) error {
return f.applyRelocationsMIPS64(dst, rels)
case f.Class == ELFCLASS64 && f.Machine == EM_S390:
return f.applyRelocationss390x(dst, rels)
+ case f.Class == ELFCLASS32 && (f.Machine == EM_SPARC || f.Machine == EM_SPARC32PLUS):
+ return f.applyRelocationsSPARC(dst, rels)
case f.Class == ELFCLASS64 && f.Machine == EM_SPARCV9:
return f.applyRelocationsSPARC64(dst, rels)
case f.Class == ELFCLASS64 && f.Machine == EM_ALPHA:
@@ -1006,6 +1008,46 @@ func (f *File) applyRelocationss390x(dst []byte, rels []byte) error {
return nil
}
+func (f *File) applyRelocationsSPARC(dst []byte, rels []byte) error {
+ // 12 is the size of Rela32.
+ if len(rels)%12 != 0 {
+ return errors.New("length of relocation section is not a multiple of 12")
+ }
+
+ symbols, _, err := f.getSymbols(SHT_SYMTAB)
+ if err != nil {
+ return err
+ }
+
+ b := bytes.NewReader(rels)
+ var rela Rela32
+
+ for b.Len() > 0 {
+ binary.Read(b, f.ByteOrder, &rela)
+ symNo := rela.Info >> 32
+ t := R_SPARC(rela.Info & 0xff)
+
+ if symNo == 0 || symNo > uint32(len(symbols)) {
+ continue
+ }
+ sym := &symbols[symNo-1]
+ if SymType(sym.Info&0xf) != STT_SECTION {
+ // We don't handle non-section relocations for now.
+ continue
+ }
+
+ switch t {
+ case R_SPARC_32, R_SPARC_UA32:
+ if rela.Off+4 >= uint32(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
+ }
+ }
+
+ return nil
+}
+
func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error {
// 24 is the size of Rela64.
if len(rels)%24 != 0 {
diff --git a/libgo/go/debug/xcoff/file.go b/libgo/go/debug/xcoff/file.go
new file mode 100644
index 0000000..2958610
--- /dev/null
+++ b/libgo/go/debug/xcoff/file.go
@@ -0,0 +1,539 @@
+// Copyright 2017 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 xcoff implements access to XCOFF (Extended Common Object File Format) files.
+package xcoff
+
+import (
+ "debug/dwarf"
+ "encoding/binary"
+ "fmt"
+ "io"
+ "os"
+ "strings"
+)
+
+// Information we store about an XCOFF section header.
+type SectionHeader struct {
+ Name string
+ VirtualAddress uint64
+ Size uint64
+ Type uint32
+}
+type Section struct {
+ SectionHeader
+ io.ReaderAt
+ sr *io.SectionReader
+}
+
+// Information we store about an XCOFF symbol.
+type AuxiliaryCSect struct {
+ Length int64
+ StorageMappingClass int
+ SymbolType int
+}
+type Symbol struct {
+ Name string
+ Value uint64
+ SectionNumber int
+ StorageClass int
+ AuxCSect AuxiliaryCSect
+}
+
+// Information we store about an imported XCOFF symbol.
+type ImportedSymbol struct {
+ Name string
+ Library string
+}
+
+// A File represents an open XCOFF file.
+type FileHeader struct {
+ TargetMachine uint16
+}
+type File struct {
+ FileHeader
+ Sections []*Section
+ Symbols []*Symbol
+ StringTable []byte
+ LibraryPaths []string
+
+ closer io.Closer
+}
+
+// Open opens the named file using os.Open and prepares it for use as an XCOFF binary.
+func Open(name string) (*File, error) {
+ f, err := os.Open(name)
+ if err != nil {
+ return nil, err
+ }
+ ff, err := NewFile(f)
+ if err != nil {
+ f.Close()
+ return nil, err
+ }
+ ff.closer = f
+ return ff, nil
+}
+
+// Close closes the File.
+// If the File was created using NewFile directly instead of Open,
+// Close has no effect.
+func (f *File) Close() error {
+ var err error
+ if f.closer != nil {
+ err = f.closer.Close()
+ f.closer = nil
+ }
+ return err
+}
+
+// SectionByType returns the first section in f with the
+// given type, or nil if there is no such section.
+func (f *File) SectionByType(typ uint32) *Section {
+ for _, s := range f.Sections {
+ if s.Type == typ {
+ return s
+ }
+ }
+ return nil
+}
+
+// cstring converts ASCII byte sequence b to string.
+// It stops once it finds 0 or reaches end of b.
+func cstring(b []byte) string {
+ var i int
+ for i = 0; i < len(b) && b[i] != 0; i++ {
+ }
+ return string(b[:i])
+}
+
+// getString extracts a string from an XCOFF string table.
+func getString(st []byte, offset uint32) (string, bool) {
+ if offset < 4 || int(offset) >= len(st) {
+ return "", false
+ }
+ return cstring(st[offset:]), true
+}
+
+// NewFile creates a new File for accessing an XCOFF binary in an underlying reader.
+func NewFile(r io.ReaderAt) (*File, error) {
+ sr := io.NewSectionReader(r, 0, 1<<63-1)
+ // Read XCOFF target machine
+ var magic uint16
+ if err := binary.Read(sr, binary.BigEndian, &magic); err != nil {
+ return nil, err
+ }
+ if magic != U802TOCMAGIC && magic != U64_TOCMAGIC {
+ return nil, fmt.Errorf("unrecognised XCOFF magic", magic)
+ }
+
+ f := new(File)
+ f.TargetMachine = magic
+
+ // Read XCOFF file header
+ sr.Seek(0, io.SeekStart)
+ var nscns uint16
+ var symptr uint64
+ var nsyms int32
+ var opthdr uint16
+ var hdrsz int
+ switch f.TargetMachine {
+ case U802TOCMAGIC:
+ fhdr := new(FileHeader32)
+ if err := binary.Read(sr, binary.BigEndian, fhdr); err != nil {
+ return nil, err
+ }
+ nscns = fhdr.Fnscns
+ symptr = uint64(fhdr.Fsymptr)
+ nsyms = fhdr.Fnsyms
+ opthdr = fhdr.Fopthdr
+ hdrsz = FILHSZ_32
+ case U64_TOCMAGIC:
+ fhdr := new(FileHeader64)
+ if err := binary.Read(sr, binary.BigEndian, fhdr); err != nil {
+ return nil, err
+ }
+ nscns = fhdr.Fnscns
+ symptr = fhdr.Fsymptr
+ nsyms = fhdr.Fnsyms
+ opthdr = fhdr.Fopthdr
+ hdrsz = FILHSZ_64
+ }
+
+ if symptr == 0 || nsyms <= 0 {
+ return nil, fmt.Errorf("no symbol table")
+ }
+
+ // Read string table (located right after symbol table).
+ offset := symptr + uint64(nsyms)*SYMESZ
+ sr.Seek(int64(offset), io.SeekStart)
+ // The first 4 bytes contain the length (in bytes).
+ var l uint32
+ binary.Read(sr, binary.BigEndian, &l)
+ if l > 4 {
+ sr.Seek(int64(offset), io.SeekStart)
+ f.StringTable = make([]byte, l)
+ io.ReadFull(sr, f.StringTable)
+ }
+
+ // Read section headers
+ sr.Seek(int64(hdrsz)+int64(opthdr), io.SeekStart)
+ f.Sections = make([]*Section, nscns)
+ for i := 0; i < int(nscns); i++ {
+ var scnptr uint64
+ s := new(Section)
+ switch f.TargetMachine {
+ case U802TOCMAGIC:
+ shdr := new(SectionHeader32)
+ if err := binary.Read(sr, binary.BigEndian, shdr); err != nil {
+ return nil, err
+ }
+ s.Name = cstring(shdr.Sname[:])
+ s.VirtualAddress = uint64(shdr.Svaddr)
+ s.Size = uint64(shdr.Ssize)
+ scnptr = uint64(shdr.Sscnptr)
+ s.Type = shdr.Sflags
+ case U64_TOCMAGIC:
+ shdr := new(SectionHeader64)
+ if err := binary.Read(sr, binary.BigEndian, shdr); err != nil {
+ return nil, err
+ }
+ s.Name = cstring(shdr.Sname[:])
+ s.VirtualAddress = shdr.Svaddr
+ s.Size = shdr.Ssize
+ scnptr = shdr.Sscnptr
+ s.Type = shdr.Sflags
+ }
+ r2 := r
+ if scnptr == 0 { // .bss must have all 0s
+ r2 = zeroReaderAt{}
+ }
+ s.sr = io.NewSectionReader(r2, int64(scnptr), int64(s.Size))
+ s.ReaderAt = s.sr
+ f.Sections[i] = s
+ }
+
+ // Read symbol table
+ sr.Seek(int64(symptr), io.SeekStart)
+ f.Symbols = make([]*Symbol, 0)
+ for i := 0; i < int(nsyms); i++ {
+ var numaux int
+ var ok bool
+ sym := new(Symbol)
+ switch f.TargetMachine {
+ case U802TOCMAGIC:
+ se := new(SymEnt32)
+ if err := binary.Read(sr, binary.BigEndian, se); err != nil {
+ return nil, err
+ }
+ numaux = int(se.Nnumaux)
+ sym.SectionNumber = int(se.Nscnum)
+ sym.StorageClass = int(se.Nsclass)
+ sym.Value = uint64(se.Nvalue)
+ zeroes := binary.BigEndian.Uint32(se.Nname[:4])
+ if zeroes != 0 {
+ sym.Name = cstring(se.Nname[:])
+ } else {
+ offset := binary.BigEndian.Uint32(se.Nname[4:])
+ sym.Name, ok = getString(f.StringTable, offset)
+ if !ok {
+ goto skip
+ }
+ }
+ case U64_TOCMAGIC:
+ se := new(SymEnt64)
+ if err := binary.Read(sr, binary.BigEndian, se); err != nil {
+ return nil, err
+ }
+ numaux = int(se.Nnumaux)
+ sym.SectionNumber = int(se.Nscnum)
+ sym.StorageClass = int(se.Nsclass)
+ sym.Value = se.Nvalue
+ sym.Name, ok = getString(f.StringTable, se.Noffset)
+ if !ok {
+ goto skip
+ }
+ }
+ if sym.StorageClass != C_EXT && sym.StorageClass != C_WEAKEXT && sym.StorageClass != C_HIDEXT {
+ goto skip
+ }
+ // Must have at least one csect auxiliary entry.
+ if numaux < 1 || i+numaux >= int(nsyms) {
+ goto skip
+ }
+ if sym.SectionNumber < 1 || sym.SectionNumber > int(nscns) {
+ goto skip
+ }
+ sym.Value -= f.Sections[sym.SectionNumber-1].VirtualAddress
+
+ // Read csect auxiliary entry (by convention, it is the last).
+ sr.Seek(int64((numaux-1)*SYMESZ), io.SeekCurrent)
+ i += numaux
+ numaux = 0
+ switch f.TargetMachine {
+ case U802TOCMAGIC:
+ aux := new(AuxCSect32)
+ if err := binary.Read(sr, binary.BigEndian, aux); err != nil {
+ return nil, err
+ }
+ sym.AuxCSect.SymbolType = int(aux.Xsmtyp & 0x7)
+ sym.AuxCSect.StorageMappingClass = int(aux.Xsmclas)
+ sym.AuxCSect.Length = int64(aux.Xscnlen)
+ case U64_TOCMAGIC:
+ aux := new(AuxCSect64)
+ if err := binary.Read(sr, binary.BigEndian, aux); err != nil {
+ return nil, err
+ }
+ sym.AuxCSect.SymbolType = int(aux.Xsmtyp & 0x7)
+ sym.AuxCSect.StorageMappingClass = int(aux.Xsmclas)
+ sym.AuxCSect.Length = int64(aux.Xscnlenhi)<<32 | int64(aux.Xscnlenlo)
+ }
+
+ f.Symbols = append(f.Symbols, sym)
+ skip:
+ i += numaux // Skip auxiliary entries
+ sr.Seek(int64(numaux)*SYMESZ, io.SeekCurrent)
+ }
+
+ return f, nil
+}
+
+// zeroReaderAt is ReaderAt that reads 0s.
+type zeroReaderAt struct{}
+
+// ReadAt writes len(p) 0s into p.
+func (w zeroReaderAt) ReadAt(p []byte, off int64) (n int, err error) {
+ for i := range p {
+ p[i] = 0
+ }
+ return len(p), nil
+}
+
+// Data reads and returns the contents of the XCOFF section s.
+func (s *Section) Data() ([]byte, error) {
+ dat := make([]byte, s.sr.Size())
+ n, err := s.sr.ReadAt(dat, 0)
+ if n == len(dat) {
+ err = nil
+ }
+ return dat[0:n], err
+}
+
+// CSect reads and returns the contents of a csect.
+func (f *File) CSect(name string) []byte {
+ for _, sym := range f.Symbols {
+ if sym.Name == name && sym.AuxCSect.SymbolType == XTY_SD {
+ if i := sym.SectionNumber - 1; 0 <= i && i < len(f.Sections) {
+ s := f.Sections[i]
+ if sym.Value+uint64(sym.AuxCSect.Length) <= s.Size {
+ dat := make([]byte, sym.AuxCSect.Length)
+ _, err := s.sr.ReadAt(dat, int64(sym.Value))
+ if err != nil {
+ return nil
+ }
+ return dat
+ }
+ }
+ break
+ }
+ }
+ return nil
+}
+
+func (f *File) DWARF() (*dwarf.Data, error) {
+ // There are many other DWARF sections, but these
+ // are the ones the debug/dwarf package uses.
+ // Don't bother loading others.
+ var subtypes = [...]uint32{SSUBTYP_DWABREV, SSUBTYP_DWINFO, SSUBTYP_DWLINE, SSUBTYP_DWARNGE, SSUBTYP_DWSTR}
+ var dat [len(subtypes)][]byte
+ for i, subtype := range subtypes {
+ s := f.SectionByType(STYP_DWARF | subtype)
+ if s != nil {
+ b, err := s.Data()
+ if err != nil && uint64(len(b)) < s.Size {
+ return nil, err
+ }
+ dat[i] = b
+ }
+ }
+
+ abbrev, info, line, ranges, str := dat[0], dat[1], dat[2], dat[3], dat[4]
+ return dwarf.New(abbrev, nil, nil, info, line, nil, ranges, str)
+}
+
+// Read a loader section import file IDs.
+func (f *File) readImportIDs(s *Section) ([]string, error) {
+ // Read loader header
+ s.sr.Seek(0, io.SeekStart)
+ var istlen uint32
+ var nimpid int32
+ var impoff uint64
+ switch f.TargetMachine {
+ case U802TOCMAGIC:
+ lhdr := new(LoaderHeader32)
+ if err := binary.Read(s.sr, binary.BigEndian, lhdr); err != nil {
+ return nil, err
+ }
+ istlen = lhdr.Listlen
+ nimpid = lhdr.Lnimpid
+ impoff = uint64(lhdr.Limpoff)
+ case U64_TOCMAGIC:
+ lhdr := new(LoaderHeader64)
+ if err := binary.Read(s.sr, binary.BigEndian, lhdr); err != nil {
+ return nil, err
+ }
+ istlen = lhdr.Listlen
+ nimpid = lhdr.Lnimpid
+ impoff = lhdr.Limpoff
+ }
+
+ // Read loader import file ID table
+ s.sr.Seek(int64(impoff), io.SeekStart)
+ table := make([]byte, istlen)
+ io.ReadFull(s.sr, table)
+
+ offset := 0
+ // First import file ID is the default LIBPATH value
+ libpath := cstring(table[offset:])
+ f.LibraryPaths = strings.Split(libpath, ":")
+ offset += len(libpath) + 3 // 3 null bytes
+ all := make([]string, 0)
+ for i := 1; i < int(nimpid); i++ {
+ impidpath := cstring(table[offset:])
+ offset += len(impidpath) + 1
+ impidbase := cstring(table[offset:])
+ offset += len(impidbase) + 1
+ impidmem := cstring(table[offset:])
+ offset += len(impidmem) + 1
+ var path string
+ if len(impidpath) > 0 {
+ path = impidpath + "/" + impidbase
+ } else {
+ path = impidbase
+ }
+ all = append(all, path)
+ }
+
+ return all, nil
+}
+
+// ImportedSymbols returns the names of all symbols
+// referred to by the binary f that are expected to be
+// satisfied by other libraries at dynamic load time.
+// It does not return weak symbols.
+func (f *File) ImportedSymbols() ([]ImportedSymbol, error) {
+ s := f.SectionByType(STYP_LOADER)
+ if s == nil {
+ return nil, nil
+ }
+ // Read loader header
+ s.sr.Seek(0, io.SeekStart)
+ var stlen uint32
+ var stoff uint64
+ var nsyms int32
+ var symoff uint64
+ switch f.TargetMachine {
+ case U802TOCMAGIC:
+ lhdr := new(LoaderHeader32)
+ if err := binary.Read(s.sr, binary.BigEndian, lhdr); err != nil {
+ return nil, err
+ }
+ stlen = lhdr.Lstlen
+ stoff = uint64(lhdr.Lstoff)
+ nsyms = lhdr.Lnsyms
+ symoff = LDHDRSZ_32
+ case U64_TOCMAGIC:
+ lhdr := new(LoaderHeader64)
+ if err := binary.Read(s.sr, binary.BigEndian, lhdr); err != nil {
+ return nil, err
+ }
+ stlen = lhdr.Lstlen
+ stoff = lhdr.Lstoff
+ nsyms = lhdr.Lnsyms
+ symoff = lhdr.Lsymoff
+ }
+
+ // Read loader section string table
+ s.sr.Seek(int64(stoff), io.SeekStart)
+ st := make([]byte, stlen)
+ io.ReadFull(s.sr, st)
+
+ // Read imported libraries
+ libs, err := f.readImportIDs(s)
+ if err != nil {
+ return nil, err
+ }
+
+ // Read loader symbol table
+ s.sr.Seek(int64(symoff), io.SeekStart)
+ all := make([]ImportedSymbol, 0)
+ for i := 0; i < int(nsyms); i++ {
+ var name string
+ var ifile int32
+ var ok bool
+ switch f.TargetMachine {
+ case U802TOCMAGIC:
+ ldsym := new(LoaderSymbol32)
+ if err := binary.Read(s.sr, binary.BigEndian, ldsym); err != nil {
+ return nil, err
+ }
+ if ldsym.Lsmtype&0x40 == 0 {
+ continue // Imported symbols only
+ }
+ zeroes := binary.BigEndian.Uint32(ldsym.Lname[:4])
+ if zeroes != 0 {
+ name = cstring(ldsym.Lname[:])
+ } else {
+ offset := binary.BigEndian.Uint32(ldsym.Lname[4:])
+ name, ok = getString(st, offset)
+ if !ok {
+ continue
+ }
+ }
+ ifile = ldsym.Lifile
+ case U64_TOCMAGIC:
+ ldsym := new(LoaderSymbol64)
+ if err := binary.Read(s.sr, binary.BigEndian, ldsym); err != nil {
+ return nil, err
+ }
+ if ldsym.Lsmtype&0x40 == 0 {
+ continue // Imported symbols only
+ }
+ name, ok = getString(st, ldsym.Loffset)
+ if !ok {
+ continue
+ }
+ ifile = ldsym.Lifile
+ }
+ var sym ImportedSymbol
+ sym.Name = name
+ if ifile >= 1 && int(ifile) <= len(libs) {
+ sym.Library = libs[ifile-1]
+ }
+ all = append(all, sym)
+ }
+
+ return all, nil
+}
+
+// ImportedLibraries returns the names of all libraries
+// referred to by the binary f that are expected to be
+// linked with the binary at dynamic link time.
+func (f *File) ImportedLibraries() ([]string, error) {
+ s := f.SectionByType(STYP_LOADER)
+ if s == nil {
+ return nil, nil
+ }
+ all, err := f.readImportIDs(s)
+ return all, err
+}
+
+// FormatError is unused.
+// The type is retained for compatibility.
+type FormatError struct {
+}
+
+func (e *FormatError) Error() string {
+ return "unknown error"
+}
diff --git a/libgo/go/debug/xcoff/file_test.go b/libgo/go/debug/xcoff/file_test.go
new file mode 100644
index 0000000..115ce30
--- /dev/null
+++ b/libgo/go/debug/xcoff/file_test.go
@@ -0,0 +1,150 @@
+// Copyright 2014 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 xcoff
+
+import (
+ "reflect"
+ "testing"
+)
+
+type fileTest struct {
+ file string
+ hdr FileHeader
+ sections []*SectionHeader
+ needed []string
+}
+
+var fileTests = []fileTest{
+ {
+ "testdata/gcc-ppc32-aix-exec",
+ FileHeader{U802TOCMAGIC},
+ []*SectionHeader{
+ {".text", 0x10000150, 0x00000bbd, STYP_TEXT},
+ {".data", 0x20000d0d, 0x0000042b, STYP_DATA},
+ {".bss", 0x20001138, 0x00000218, STYP_BSS},
+ {".loader", 0x00000000, 0x000004b3, STYP_LOADER},
+ {".debug", 0x00000000, 0x0000751e, STYP_DEBUG},
+ },
+ []string{"libc.a"},
+ },
+ {
+ "testdata/gcc-ppc64-aix-exec",
+ FileHeader{U64_TOCMAGIC},
+ []*SectionHeader{
+ {".text", 0x10000240, 0x00000afd, STYP_TEXT},
+ {".data", 0x20000d3d, 0x000002e3, STYP_DATA},
+ {".bss", 0x20001020, 0x00000428, STYP_BSS},
+ {".loader", 0x00000000, 0x00000535, STYP_LOADER},
+ {".debug", 0x00000000, 0x00008238, STYP_DEBUG},
+ },
+ []string{"libc.a"},
+ },
+ {
+ "testdata/xlc-ppc32-aix-exec",
+ FileHeader{U802TOCMAGIC},
+ []*SectionHeader{
+ {".text", 0x10000150, 0x00000372, STYP_TEXT},
+ {".data", 0x200004c2, 0x0000032e, STYP_DATA},
+ {".bss", 0x200007f0, 0x00000004, STYP_BSS},
+ {".loader", 0x00000000, 0x0000029d, STYP_LOADER},
+ {".debug", 0x00000000, 0x0000008f, STYP_DEBUG},
+ },
+ []string{"libc.a"},
+ },
+ {
+ "testdata/xlc-ppc64-aix-exec",
+ FileHeader{U64_TOCMAGIC},
+ []*SectionHeader{
+ {".text", 0x100000240, 0x00000326, STYP_TEXT},
+ {".data", 0x110000566, 0x00000182, STYP_DATA},
+ {".bss", 0x1100006e8, 0x00000008, STYP_BSS},
+ {".loader", 0x00000000, 0x0000029b, STYP_LOADER},
+ {".debug", 0x00000000, 0x000000ea, STYP_DEBUG},
+ },
+ []string{"libc.a"},
+ },
+ {
+ "testdata/gcc-ppc32-aix-dwarf2-exec",
+ FileHeader{U802TOCMAGIC},
+ []*SectionHeader{
+ {".text", 0x10000290, 0x00000bbd, STYP_TEXT},
+ {".data", 0x20000e4d, 0x00000437, STYP_DATA},
+ {".bss", 0x20001284, 0x0000021c, STYP_BSS},
+ {".loader", 0x00000000, 0x000004b3, STYP_LOADER},
+ {".dwline", 0x00000000, 0x000000df, STYP_DWARF | SSUBTYP_DWLINE},
+ {".dwinfo", 0x00000000, 0x00000314, STYP_DWARF | SSUBTYP_DWINFO},
+ {".dwabrev", 0x00000000, 0x000000d6, STYP_DWARF | SSUBTYP_DWABREV},
+ {".dwarnge", 0x00000000, 0x00000020, STYP_DWARF | SSUBTYP_DWARNGE},
+ {".dwloc", 0x00000000, 0x00000074, STYP_DWARF | SSUBTYP_DWLOC},
+ {".debug", 0x00000000, 0x00005e4f, STYP_DEBUG},
+ },
+ []string{"libc.a"},
+ },
+ {
+ "testdata/gcc-ppc64-aix-dwarf2-exec",
+ FileHeader{U64_TOCMAGIC},
+ []*SectionHeader{
+ {".text", 0x10000480, 0x00000afd, STYP_TEXT},
+ {".data", 0x20000f7d, 0x000002f3, STYP_DATA},
+ {".bss", 0x20001270, 0x00000428, STYP_BSS},
+ {".loader", 0x00000000, 0x00000535, STYP_LOADER},
+ {".dwline", 0x00000000, 0x000000b4, STYP_DWARF | SSUBTYP_DWLINE},
+ {".dwinfo", 0x00000000, 0x0000036a, STYP_DWARF | SSUBTYP_DWINFO},
+ {".dwabrev", 0x00000000, 0x000000b5, STYP_DWARF | SSUBTYP_DWABREV},
+ {".dwarnge", 0x00000000, 0x00000040, STYP_DWARF | SSUBTYP_DWARNGE},
+ {".dwloc", 0x00000000, 0x00000062, STYP_DWARF | SSUBTYP_DWLOC},
+ {".debug", 0x00000000, 0x00006605, STYP_DEBUG},
+ },
+ []string{"libc.a"},
+ },
+}
+
+func TestOpen(t *testing.T) {
+ for i := range fileTests {
+ tt := &fileTests[i]
+
+ f, err := Open(tt.file)
+ if err != nil {
+ t.Error(err)
+ 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, sh := range f.Sections {
+ if i >= len(tt.sections) {
+ break
+ }
+ have := &sh.SectionHeader
+ want := tt.sections[i]
+ if !reflect.DeepEqual(have, want) {
+ t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
+ }
+ }
+ tn := len(tt.sections)
+ fn := len(f.Sections)
+ if tn != fn {
+ t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
+ }
+ tl := tt.needed
+ fl, err := f.ImportedLibraries()
+ if err != nil {
+ t.Error(err)
+ }
+ if !reflect.DeepEqual(tl, fl) {
+ t.Errorf("open %s: loader import = %v, want %v", tt.file, tl, fl)
+ }
+ }
+}
+
+func TestOpenFailure(t *testing.T) {
+ filename := "file.go" // not an XCOFF object file
+ _, err := Open(filename) // don't crash
+ if err == nil {
+ t.Errorf("open %s: succeeded unexpectedly", filename)
+ }
+}
diff --git a/libgo/go/debug/xcoff/testdata/gcc-ppc32-aix-dwarf2-exec b/libgo/go/debug/xcoff/testdata/gcc-ppc32-aix-dwarf2-exec
new file mode 100644
index 0000000..810e21a
--- /dev/null
+++ b/libgo/go/debug/xcoff/testdata/gcc-ppc32-aix-dwarf2-exec
Binary files differ
diff --git a/libgo/go/debug/xcoff/testdata/gcc-ppc32-aix-exec b/libgo/go/debug/xcoff/testdata/gcc-ppc32-aix-exec
new file mode 100644
index 0000000..6e44041
--- /dev/null
+++ b/libgo/go/debug/xcoff/testdata/gcc-ppc32-aix-exec
Binary files differ
diff --git a/libgo/go/debug/xcoff/testdata/gcc-ppc64-aix-dwarf2-exec b/libgo/go/debug/xcoff/testdata/gcc-ppc64-aix-dwarf2-exec
new file mode 100644
index 0000000..707d01e
--- /dev/null
+++ b/libgo/go/debug/xcoff/testdata/gcc-ppc64-aix-dwarf2-exec
Binary files differ
diff --git a/libgo/go/debug/xcoff/testdata/gcc-ppc64-aix-exec b/libgo/go/debug/xcoff/testdata/gcc-ppc64-aix-exec
new file mode 100644
index 0000000..82ffdaf
--- /dev/null
+++ b/libgo/go/debug/xcoff/testdata/gcc-ppc64-aix-exec
Binary files differ
diff --git a/libgo/go/debug/xcoff/testdata/hello.c b/libgo/go/debug/xcoff/testdata/hello.c
new file mode 100644
index 0000000..34d9ee7
--- /dev/null
+++ b/libgo/go/debug/xcoff/testdata/hello.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+void
+main(int argc, char *argv[])
+{
+ printf("hello, world\n");
+}
diff --git a/libgo/go/debug/xcoff/testdata/xlc-ppc32-aix-exec b/libgo/go/debug/xcoff/testdata/xlc-ppc32-aix-exec
new file mode 100644
index 0000000..e076f81
--- /dev/null
+++ b/libgo/go/debug/xcoff/testdata/xlc-ppc32-aix-exec
Binary files differ
diff --git a/libgo/go/debug/xcoff/testdata/xlc-ppc64-aix-exec b/libgo/go/debug/xcoff/testdata/xlc-ppc64-aix-exec
new file mode 100644
index 0000000..26041dc
--- /dev/null
+++ b/libgo/go/debug/xcoff/testdata/xlc-ppc64-aix-exec
Binary files differ
diff --git a/libgo/go/debug/xcoff/xcoff.go b/libgo/go/debug/xcoff/xcoff.go
new file mode 100644
index 0000000..8d76bf3
--- /dev/null
+++ b/libgo/go/debug/xcoff/xcoff.go
@@ -0,0 +1,262 @@
+// Copyright 2017 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 xcoff
+
+// File Header.
+type FileHeader32 struct {
+ Fmagic uint16 // Target machine
+ Fnscns uint16 // Number of sections
+ Ftimedat int32 // Time and date of file creation
+ Fsymptr uint32 // Byte offset to symbol table start
+ Fnsyms int32 // Number of entries in symbol table
+ Fopthdr uint16 // Number of bytes in optional header
+ Fflags uint16 // Flags
+}
+
+type FileHeader64 struct {
+ Fmagic uint16 // Target machine
+ Fnscns uint16 // Number of sections
+ Ftimedat int32 // Time and date of file creation
+ Fsymptr uint64 // Byte offset to symbol table start
+ Fopthdr uint16 // Number of bytes in optional header
+ Fflags uint16 // Flags
+ Fnsyms int32 // Number of entries in symbol table
+}
+
+const (
+ FILHSZ_32 = 20
+ FILHSZ_64 = 24
+)
+const (
+ U802TOCMAGIC = 0737 // AIX 32-bit XCOFF
+ U64_TOCMAGIC = 0767 // AIX 64-bit XCOFF
+)
+
+// Flags that describe the type of the object file.
+const (
+ F_RELFLG = 0x0001
+ F_EXEC = 0x0002
+ F_LNNO = 0x0004
+ F_FDPR_PROF = 0x0010
+ F_FDPR_OPTI = 0x0020
+ F_DSA = 0x0040
+ F_VARPG = 0x0100
+ F_DYNLOAD = 0x1000
+ F_SHROBJ = 0x2000
+ F_LOADONLY = 0x4000
+)
+
+// Section Header.
+type SectionHeader32 struct {
+ Sname [8]byte // Section name
+ Spaddr uint32 // Physical address
+ Svaddr uint32 // Virtual address
+ Ssize uint32 // Section size
+ Sscnptr uint32 // Offset in file to raw data for section
+ Srelptr uint32 // Offset in file to relocation entries for section
+ Slnnoptr uint32 // Offset in file to line number entries for section
+ Snreloc uint16 // Number of relocation entries
+ Snlnno uint16 // Number of line number entries
+ Sflags uint32 // Flags to define the section type
+}
+
+type SectionHeader64 struct {
+ Sname [8]byte // Section name
+ Spaddr uint64 // Physical address
+ Svaddr uint64 // Virtual address
+ Ssize uint64 // Section size
+ Sscnptr uint64 // Offset in file to raw data for section
+ Srelptr uint64 // Offset in file to relocation entries for section
+ Slnnoptr uint64 // Offset in file to line number entries for section
+ Snreloc uint32 // Number of relocation entries
+ Snlnno uint32 // Number of line number entries
+ Sflags uint32 // Flags to define the section type
+ Spad uint32 // Needs to be 72 bytes long
+}
+
+// Flags defining the section type.
+const (
+ STYP_DWARF = 0x0010
+ STYP_TEXT = 0x0020
+ STYP_DATA = 0x0040
+ STYP_BSS = 0x0080
+ STYP_EXCEPT = 0x0100
+ STYP_INFO = 0x0200
+ STYP_TDATA = 0x0400
+ STYP_TBSS = 0x0800
+ STYP_LOADER = 0x1000
+ STYP_DEBUG = 0x2000
+ STYP_TYPCHK = 0x4000
+ STYP_OVRFLO = 0x8000
+)
+const (
+ SSUBTYP_DWINFO = 0x10000 // DWARF info section
+ SSUBTYP_DWLINE = 0x20000 // DWARF line-number section
+ SSUBTYP_DWPBNMS = 0x30000 // DWARF public names section
+ SSUBTYP_DWPBTYP = 0x40000 // DWARF public types section
+ SSUBTYP_DWARNGE = 0x50000 // DWARF aranges section
+ SSUBTYP_DWABREV = 0x60000 // DWARF abbreviation section
+ SSUBTYP_DWSTR = 0x70000 // DWARF strings section
+ SSUBTYP_DWRNGES = 0x80000 // DWARF ranges section
+ SSUBTYP_DWLOC = 0x90000 // DWARF location lists section
+ SSUBTYP_DWFRAME = 0xA0000 // DWARF frames section
+ SSUBTYP_DWMAC = 0xB0000 // DWARF macros section
+)
+
+// Symbol Table Entry.
+type SymEnt32 struct {
+ Nname [8]byte // Symbol name
+ Nvalue uint32 // Symbol value
+ Nscnum int16 // Section number of symbol
+ Ntype uint16 // Basic and derived type specification
+ Nsclass int8 // Storage class of symbol
+ Nnumaux int8 // Number of auxiliary entries
+}
+
+type SymEnt64 struct {
+ Nvalue uint64 // Symbol value
+ Noffset uint32 // Offset of the name in string table or .debug section
+ Nscnum int16 // Section number of symbol
+ Ntype uint16 // Basic and derived type specification
+ Nsclass int8 // Storage class of symbol
+ Nnumaux int8 // Number of auxiliary entries
+}
+
+const SYMESZ = 18
+
+// Storage Class.
+const (
+ C_NULL = 0 // Symbol table entry marked for deletion
+ C_EXT = 2 // External symbol
+ C_STAT = 3 // Static symbol
+ C_BLOCK = 100 // Beginning or end of inner block
+ C_FCN = 101 // Beginning or end of function
+ C_FILE = 103 // Source file name and compiler information
+ C_HIDEXT = 107 // Unnamed external symbol
+ C_BINCL = 108 // Beginning of include file
+ C_EINCL = 109 // End of include file
+ C_WEAKEXT = 111 // Weak external symbol
+ C_DWARF = 112 // DWARF symbol
+ C_GSYM = 128 // Global variable
+ C_LSYM = 129 // Automatic variable allocated on stack
+ C_PSYM = 130 // Argument to subroutine allocated on stack
+ C_RSYM = 131 // Register variable
+ C_RPSYM = 132 // Argument to function or procedure stored in register
+ C_STSYM = 133 // Statically allocated symbol
+ C_BCOMM = 135 // Beginning of common block
+ C_ECOML = 136 // Local member of common block
+ C_ECOMM = 137 // End of common block
+ C_DECL = 140 // Declaration of object
+ C_ENTRY = 141 // Alternate entry
+ C_FUN = 142 // Function or procedure
+ C_BSTAT = 143 // Beginning of static block
+ C_ESTAT = 144 // End of static block
+ C_GTLS = 145 // Global thread-local variable
+ C_STTLS = 146 // Static thread-local variable
+)
+
+// csect Auxiliary Entry.
+type AuxCSect32 struct {
+ Xscnlen int32 // Length or symbol table index
+ Xparmhash uint32 // Offset of parameter type-check string
+ Xsnhash uint16 // .typchk section number
+ Xsmtyp uint8 // Symbol alignment and type
+ Xsmclas uint8 // Storage-mapping class
+ Xstab uint32 // Reserved
+ Xsnstab uint16 // Reserved
+}
+
+type AuxCSect64 struct {
+ Xscnlenlo uint32 // Lower 4 bytes of length or symbol table index
+ Xparmhash uint32 // Offset of parameter type-check string
+ Xsnhash uint16 // .typchk section number
+ Xsmtyp uint8 // Symbol alignment and type
+ Xsmclas uint8 // Storage-mapping class
+ Xscnlenhi int32 // Upper 4 bytes of length or symbol table index
+ Xpad uint8 // Unused
+ Xauxtype uint8 // Type of auxiliary entry
+}
+
+// Symbol type field.
+const (
+ XTY_ER = 0 // External reference
+ XTY_SD = 1 // Section definition
+ XTY_LD = 2 // Label definition
+ XTY_CM = 3 // Common csect definition
+)
+
+// Storage-mapping class.
+const (
+ XMC_PR = 0 // Program code
+ XMC_RO = 1 // Read-only constant
+ XMC_DB = 2 // Debug dictionary table
+ XMC_TC = 3 // TOC entry
+ XMC_UA = 4 // Unclassified
+ XMC_RW = 5 // Read/Write data
+ XMC_GL = 6 // Global linkage
+ XMC_XO = 7 // Extended operation
+ XMC_SV = 8 // 32-bit supervisor call descriptor
+ XMC_BS = 9 // BSS class
+ XMC_DS = 10 // Function descriptor
+ XMC_UC = 11 // Unnamed FORTRAN common
+ XMC_TC0 = 15 // TOC anchor
+ XMC_TD = 16 // Scalar data entry in the TOC
+ XMC_SV64 = 17 // 64-bit supervisor call descriptor
+ XMC_SV3264 = 18 // Supervisor call descriptor for both 32-bit and 64-bit
+ XMC_TL = 20 // Read/Write thread-local data
+ XMC_UL = 21 // Read/Write thread-local data (.tbss)
+ XMC_TE = 22 // TOC entry
+)
+
+// Loader Header.
+type LoaderHeader32 struct {
+ Lversion int32 // Loader section version number
+ Lnsyms int32 // Number of symbol table entries
+ Lnreloc int32 // Number of relocation table entries
+ Listlen uint32 // Length of import file ID string table
+ Lnimpid int32 // Number of import file IDs
+ Limpoff uint32 // Offset to start of import file IDs
+ Lstlen uint32 // Length of string table
+ Lstoff uint32 // Offset to start of string table
+}
+
+type LoaderHeader64 struct {
+ Lversion int32 // Loader section version number
+ Lnsyms int32 // Number of symbol table entries
+ Lnreloc int32 // Number of relocation table entries
+ Listlen uint32 // Length of import file ID string table
+ Lnimpid int32 // Number of import file IDs
+ Lstlen uint32 // Length of string table
+ Limpoff uint64 // Offset to start of import file IDs
+ Lstoff uint64 // Offset to start of string table
+ Lsymoff uint64 // Offset to start of symbol table
+ Lrldoff uint64 // Offset to start of relocation entries
+}
+
+const (
+ LDHDRSZ_32 = 32
+ LDHDRSZ_64 = 56
+)
+
+// Loader Symbol.
+type LoaderSymbol32 struct {
+ Lname [8]byte // Symbol name or byte offset into string table
+ Lvalue uint32 // Address field
+ Lscnum int16 // Section number containing symbol
+ Lsmtype int8 // Symbol type, export, import flags
+ Lsmclas int8 // Symbol storage class
+ Lifile int32 // Import file ID; ordinal of import file IDs
+ Lparm uint32 // Parameter type-check field
+}
+
+type LoaderSymbol64 struct {
+ Lvalue uint64 // Address field
+ Loffset uint32 // Byte offset into string table of symbol name
+ Lscnum int16 // Section number containing symbol
+ Lsmtype int8 // Symbol type, export, import flags
+ Lsmclas int8 // Symbol storage class
+ Lifile int32 // Import file ID; ordinal of import file IDs
+ Lparm uint32 // Parameter type-check field
+}
diff --git a/libgo/go/go/build/deps_test.go b/libgo/go/go/build/deps_test.go
index 87abfba..655c37c 100644
--- a/libgo/go/go/build/deps_test.go
+++ b/libgo/go/go/build/deps_test.go
@@ -221,7 +221,7 @@ var pkgDeps = map[string][]string{
"go/constant": {"L4", "go/token", "math/big"},
"go/importer": {"L4", "go/build", "go/internal/gccgoimporter", "go/internal/gcimporter", "go/internal/srcimporter", "go/token", "go/types"},
"go/internal/gcimporter": {"L4", "OS", "go/build", "go/constant", "go/token", "go/types", "text/scanner"},
- "go/internal/gccgoimporter": {"L4", "OS", "debug/elf", "go/constant", "go/token", "go/types", "text/scanner"},
+ "go/internal/gccgoimporter": {"L4", "OS", "debug/elf", "debug/xcoff", "go/constant", "go/token", "go/types", "text/scanner"},
"go/internal/srcimporter": {"L4", "fmt", "go/ast", "go/build", "go/parser", "go/token", "go/types", "path/filepath"},
"go/types": {"L4", "GOPARSER", "container/heap", "go/constant"},
@@ -243,6 +243,7 @@ var pkgDeps = map[string][]string{
"debug/macho": {"L4", "OS", "debug/dwarf"},
"debug/pe": {"L4", "OS", "debug/dwarf"},
"debug/plan9obj": {"L4", "OS"},
+ "debug/xcoff": {"L4", "OS", "debug/dwarf"},
"encoding": {"L4"},
"encoding/ascii85": {"L4"},
"encoding/asn1": {"L4", "math/big"},
diff --git a/libgo/go/go/internal/gccgoimporter/importer.go b/libgo/go/go/internal/gccgoimporter/importer.go
index a22d8fe..ee573ff 100644
--- a/libgo/go/go/internal/gccgoimporter/importer.go
+++ b/libgo/go/go/internal/gccgoimporter/importer.go
@@ -8,12 +8,14 @@ package gccgoimporter // import "go/internal/gccgoimporter"
import (
"bytes"
"debug/elf"
+ "debug/xcoff"
"fmt"
"go/types"
"io"
"os"
"os/exec"
"path/filepath"
+ "runtime"
"strings"
)
@@ -66,11 +68,12 @@ const (
gccgov2Magic = "v2;\n"
goimporterMagic = "\n$$ "
archiveMagic = "!<ar"
+ aixbigafMagic = "<big"
)
-// Opens the export data file at the given path. If this is an ELF file,
+// Opens the export data file at the given path. If this is an object file,
// searches for and opens the .go_export section. If this is an archive,
-// reads the export data from the first member, which is assumed to be an ELF file.
+// reads the export data from the first member, which is assumed to be an object file.
// This is intended to replicate the logic in gofrontend.
func openExportFile(fpath string) (reader io.ReadSeeker, closer io.Closer, err error) {
f, err := os.Open(fpath)
@@ -90,43 +93,58 @@ func openExportFile(fpath string) (reader io.ReadSeeker, closer io.Closer, err e
return
}
- var elfreader io.ReaderAt
+ var objreader io.ReaderAt
switch string(magic[:]) {
case gccgov1Magic, gccgov2Magic, goimporterMagic:
// Raw export data.
reader = f
return
- case archiveMagic:
+ case archiveMagic, aixbigafMagic:
// TODO(pcc): Read the archive directly instead of using "ar".
f.Close()
closer = nil
cmd := exec.Command("ar", "p", fpath)
+ if runtime.GOOS == "aix" && runtime.GOARCH == "ppc64" {
+ // AIX puts both 32-bit and 64-bit objects in the same archive.
+ // Tell the AIX "ar" command to only care about 64-bit objects.
+ cmd.Env = append(os.Environ(), "OBJECT_MODE=64")
+ }
var out []byte
out, err = cmd.Output()
if err != nil {
return
}
- elfreader = bytes.NewReader(out)
+ objreader = bytes.NewReader(out)
default:
- elfreader = f
+ objreader = f
}
- ef, err := elf.NewFile(elfreader)
- if err != nil {
+ ef, err := elf.NewFile(objreader)
+ if err == nil {
+ sec := ef.Section(".go_export")
+ if sec == nil {
+ err = fmt.Errorf("%s: .go_export section not found", fpath)
+ return
+ }
+ reader = sec.Open()
return
}
- sec := ef.Section(".go_export")
- if sec == nil {
- err = fmt.Errorf("%s: .go_export section not found", fpath)
+ xf, err := xcoff.NewFile(objreader)
+ if err == nil {
+ sdat := xf.CSect(".go_export")
+ if sdat == nil {
+ err = fmt.Errorf("%s: .go_export section not found", fpath)
+ return
+ }
+ reader = bytes.NewReader(sdat)
return
}
- reader = sec.Open()
return
}
diff --git a/libgo/go/internal/poll/export_posix_test.go b/libgo/go/internal/poll/export_posix_test.go
index 73b2c11..6b9bb8b 100644
--- a/libgo/go/internal/poll/export_posix_test.go
+++ b/libgo/go/internal/poll/export_posix_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
+// +build aix darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
// Export guts for testing on posix.
// Since testing imports os and os imports internal/poll,
diff --git a/libgo/go/internal/poll/fd_poll_runtime.go b/libgo/go/internal/poll/fd_poll_runtime.go
index bfbe3c7..9de8af1 100644
--- a/libgo/go/internal/poll/fd_poll_runtime.go
+++ b/libgo/go/internal/poll/fd_poll_runtime.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin dragonfly freebsd linux netbsd openbsd windows solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd windows solaris
package poll
diff --git a/libgo/go/internal/poll/fd_posix.go b/libgo/go/internal/poll/fd_posix.go
index e0e634c..4e6e355 100644
--- a/libgo/go/internal/poll/fd_posix.go
+++ b/libgo/go/internal/poll/fd_posix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
+// +build aix darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
package poll
diff --git a/libgo/go/internal/poll/fd_posix_test.go b/libgo/go/internal/poll/fd_posix_test.go
index cbe015e..246d498 100644
--- a/libgo/go/internal/poll/fd_posix_test.go
+++ b/libgo/go/internal/poll/fd_posix_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
+// +build aix darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
package poll_test
diff --git a/libgo/go/internal/poll/fd_unix.go b/libgo/go/internal/poll/fd_unix.go
index c40c701..0b43a19 100644
--- a/libgo/go/internal/poll/fd_unix.go
+++ b/libgo/go/internal/poll/fd_unix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+// +build aix darwin dragonfly freebsd linux nacl netbsd openbsd solaris
package poll
diff --git a/libgo/go/internal/poll/hook_unix.go b/libgo/go/internal/poll/hook_unix.go
index 85e102d..4cf36cc 100644
--- a/libgo/go/internal/poll/hook_unix.go
+++ b/libgo/go/internal/poll/hook_unix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+// +build aix darwin dragonfly freebsd linux nacl netbsd openbsd solaris
package poll
diff --git a/libgo/go/internal/poll/sockopt.go b/libgo/go/internal/poll/sockopt.go
index f86ce70..bb5ea02 100644
--- a/libgo/go/internal/poll/sockopt.go
+++ b/libgo/go/internal/poll/sockopt.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
package poll
diff --git a/libgo/go/internal/poll/sockoptip.go b/libgo/go/internal/poll/sockoptip.go
index 5d5dff6..ae59b0c 100644
--- a/libgo/go/internal/poll/sockoptip.go
+++ b/libgo/go/internal/poll/sockoptip.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin dragonfly freebsd linux netbsd openbsd windows
+// +build aix darwin dragonfly freebsd linux netbsd openbsd windows
package poll
diff --git a/libgo/go/internal/poll/sys_cloexec.go b/libgo/go/internal/poll/sys_cloexec.go
index 9ed35bd..fb5f2bc 100644
--- a/libgo/go/internal/poll/sys_cloexec.go
+++ b/libgo/go/internal/poll/sys_cloexec.go
@@ -5,7 +5,7 @@
// This file implements sysSocket and accept for platforms that do not
// provide a fast path for setting SetNonblock and CloseOnExec.
-// +build darwin nacl netbsd openbsd solaris
+// +build aix darwin nacl netbsd openbsd solaris
package poll
diff --git a/libgo/go/net/error_posix.go b/libgo/go/net/error_posix.go
index dd9754c..d0ffaae 100644
--- a/libgo/go/net/error_posix.go
+++ b/libgo/go/net/error_posix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
+// +build aix darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
package net
diff --git a/libgo/go/net/sock_posix.go b/libgo/go/net/sock_posix.go
index a30efe2..4733c42 100644
--- a/libgo/go/net/sock_posix.go
+++ b/libgo/go/net/sock_posix.go
@@ -182,7 +182,10 @@ func (fd *netFD) listenStream(laddr sockaddr, backlog int) error {
if err := fd.init(); err != nil {
return err
}
- lsa, _ := syscall.Getsockname(fd.pfd.Sysfd)
+ lsa, err := syscall.Getsockname(fd.pfd.Sysfd)
+ if err != nil {
+ return os.NewSyscallError("getsockname", err)
+ }
fd.setAddr(fd.addrFunc()(lsa), nil)
return nil
}
@@ -221,7 +224,10 @@ func (fd *netFD) listenDatagram(laddr sockaddr) error {
if err := fd.init(); err != nil {
return err
}
- lsa, _ := syscall.Getsockname(fd.pfd.Sysfd)
+ lsa, err := syscall.Getsockname(fd.pfd.Sysfd)
+ if err != nil {
+ return os.NewSyscallError("getsockname", err)
+ }
fd.setAddr(fd.addrFunc()(lsa), nil)
return nil
}
diff --git a/libgo/go/os/user/cgo_lookup_unix.go b/libgo/go/os/user/cgo_lookup_unix.go
index 8881366..9670ada 100644
--- a/libgo/go/os/user/cgo_lookup_unix.go
+++ b/libgo/go/os/user/cgo_lookup_unix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin dragonfly freebsd !android,linux netbsd openbsd solaris
+// +build aix darwin dragonfly freebsd !android,linux netbsd openbsd solaris
// +build cgo
package user
diff --git a/libgo/go/runtime/export_unix_test.go b/libgo/go/runtime/export_unix_test.go
index 54d5770..eecdfb7 100644
--- a/libgo/go/runtime/export_unix_test.go
+++ b/libgo/go/runtime/export_unix_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package runtime
diff --git a/libgo/go/runtime/netpoll_aix.go b/libgo/go/runtime/netpoll_aix.go
index 8c8e188..b4962cc 100644
--- a/libgo/go/runtime/netpoll_aix.go
+++ b/libgo/go/runtime/netpoll_aix.go
@@ -64,14 +64,14 @@ func netpollinit() {
var p [2]int32
if ps = pollset_create(-1); ps < 0 {
- throw("netpollinit: failed to create pollset")
+ throw("runtime: netpollinit failed to create pollset")
}
// It is not possible to add or remove descriptors from
// the pollset while pollset_poll is active.
// We use a pipe to wakeup pollset_poll when the pollset
// needs to be updated.
if err := libc_pipe(&p[0]); err < 0 {
- throw("netpollinit: failed to create pipe")
+ throw("runtime: netpollinit failed to create pipe")
}
rdwake = p[0]
wrwake = p[1]
@@ -90,12 +90,17 @@ func netpollinit() {
pctl.fd = rdwake
pctl.events = _POLLIN
if pollset_ctl(ps, &pctl, 1) != 0 {
- throw("netpollinit: failed to register pipe")
+ throw("runtime: netpollinit failed to register pipe")
}
mpfds = make(map[int32]*pollDesc)
}
+func netpolldescriptor() uintptr {
+ // ps is not a real file descriptor.
+ return ^uintptr(0)
+}
+
func netpollopen(fd uintptr, pd *pollDesc) int32 {
// pollset_ctl will block if pollset_poll is active
// so wakeup pollset_poll first.
@@ -144,7 +149,7 @@ func netpollclose(fd uintptr) int32 {
}
func netpollarm(pd *pollDesc, mode int) {
- throw("unused")
+ throw("runtime: unused")
}
func netpoll(block bool) *g {
@@ -168,7 +173,7 @@ retry:
if nfound < 0 {
e := errno()
if e != _EINTR {
- throw("pollset_poll failed")
+ throw("runtime: pollset_poll failed")
}
goto retry
}
diff --git a/libgo/go/syscall/dirent.go b/libgo/go/syscall/dirent.go
index 4db2d43..a09bf05 100644
--- a/libgo/go/syscall/dirent.go
+++ b/libgo/go/syscall/dirent.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+// +build aix darwin dragonfly freebsd linux nacl netbsd openbsd solaris
package syscall
diff --git a/libgo/go/syscall/forkpipe_bsd.go b/libgo/go/syscall/forkpipe_bsd.go
index 28897bf..d479284 100644
--- a/libgo/go/syscall/forkpipe_bsd.go
+++ b/libgo/go/syscall/forkpipe_bsd.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin dragonfly netbsd openbsd solaris
+// +build aix darwin dragonfly netbsd openbsd solaris
package syscall
diff --git a/libgo/go/syscall/libcall_aix.go b/libgo/go/syscall/libcall_aix.go
index 992eeb4..072f92a 100644
--- a/libgo/go/syscall/libcall_aix.go
+++ b/libgo/go/syscall/libcall_aix.go
@@ -6,6 +6,136 @@
package syscall
+import (
+ "unsafe"
+)
+
+//sys Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
+//open64at(dirfd _C_int, path *byte, flags _C_int, mode Mode_t) _C_int
+
+//sys ptrace(request int, id int, addr uintptr, data int, buff uintptr) (val int)
+//ptrace(request _C_int, id int, addr uintptr, data _C_int, buff *byte) _C_int
+
+//sys ptrace64(request int, id int64, addr int64, data int, buff uintptr) (err error)
+//ptrace64(request _C_int, id int64, addr int64, data _C_int, buff *byte) _C_int
+
func raw_ptrace(request int, pid int, addr *byte, data *byte) Errno {
+ if request == _PTRACE_TRACEME {
+ // Convert to AIX ptrace call.
+ err := ptrace64(_PT_TRACE_ME, 0, 0, 0, 0)
+ if err != nil {
+ return err.(Errno)
+ }
+ return 0
+ }
return ENOSYS
}
+
+func ptracePeek(pid int, addr uintptr, out []byte) (count int, err error) {
+ n := 0
+ for len(out) > 0 {
+ bsize := len(out)
+ if bsize > 1024 {
+ bsize = 1024
+ }
+ err = ptrace64(_PT_READ_BLOCK, int64(pid), int64(addr), bsize, uintptr(unsafe.Pointer(&out[0])))
+ if err != nil {
+ return 0, err
+ }
+ addr += uintptr(bsize)
+ n += bsize
+ out = out[n:]
+ }
+ return n, nil
+}
+
+func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
+ return ptracePeek(pid, addr, out)
+}
+
+func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
+ return ptracePeek(pid, addr, out)
+}
+
+func ptracePoke(pid int, addr uintptr, data []byte) (count int, err error) {
+ n := 0
+ for len(data) > 0 {
+ bsize := len(data)
+ if bsize > 1024 {
+ bsize = 1024
+ }
+ err = ptrace64(_PT_WRITE_BLOCK, int64(pid), int64(addr), bsize, uintptr(unsafe.Pointer(&data[0])))
+ if err != nil {
+ return 0, err
+ }
+ addr += uintptr(bsize)
+ n += bsize
+ data = data[n:]
+ }
+ return n, nil
+}
+
+func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
+ return ptracePoke(pid, addr, data)
+}
+
+func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
+ return ptracePoke(pid, addr, data)
+}
+
+func PtraceCont(pid int, signal int) (err error) {
+ return ptrace64(_PT_CONTINUE, int64(pid), 1, signal, 0)
+}
+
+func PtraceSingleStep(pid int) (err error) { return ptrace64(_PT_STEP, int64(pid), 1, 0, 0) }
+
+func PtraceAttach(pid int) (err error) { return ptrace64(_PT_ATTACH, int64(pid), 0, 0, 0) }
+
+func PtraceDetach(pid int) (err error) { return ptrace64(_PT_DETACH, int64(pid), 0, 0, 0) }
+
+//sys reboot(how int) (err error)
+//__linux_reboot(how _C_int) _C_int
+func Reboot(how int) (err error) {
+ return reboot(how)
+}
+
+//sys Acct(path string) (err error)
+//acct(path *byte) _C_int
+
+//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
+//faccessat(dirfd _C_int, pathname *byte, mode _C_int, flags _C_int) _C_int
+
+//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
+//fchmodat(dirfd _C_int, pathname *byte, mode Mode_t, flags _C_int) _C_int
+
+//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
+//fchownat(dirfd _C_int, path *byte, owner Uid_t, group Gid_t, flags _C_int) _C_int
+
+//sys Fstatfs(fd int, buf *Statfs_t) (err error)
+//fstatfs64(fd _C_int, buf *Statfs_t) _C_int
+
+//sys Mkdirat(dirfd int, path string, mode uint32) (err error)
+//mkdirat(dirfd _C_int, path *byte, mode Mode_t) _C_int
+
+//sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
+//mknodat(dirfd _C_int, path *byte, mode Mode_t, dev _dev_t) _C_int
+
+//sys getdirent(fd int, buf []byte) (n int, err error)
+//getdirent64(fd _C_int, buf *byte, nbyte Size_t) _C_int
+
+func ReadDirent(fd int, buf []byte) (n int, err error) {
+ return getdirent(fd, buf)
+}
+
+//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
+//renameat(olddirfd _C_int, oldpath *byte, newdirfd _C_int, newpath *byte) _C_int
+
+//sys Statfs(path string, buf *Statfs_t) (err error)
+//statfs64(path *byte, buf *Statfs_t) _C_int
+
+//sys unlinkat(dirfd int, path string, flags int) (err error)
+//unlinkat(dirfd _C_int, path *byte, flags _C_int) _C_int
+
+func Unlinkat(dirfd int, path string) (err error) {
+ return unlinkat(dirfd, path, 0)
+}
diff --git a/libgo/go/syscall/socket_aix.go b/libgo/go/syscall/socket_aix.go
new file mode 100644
index 0000000..40cf423
--- /dev/null
+++ b/libgo/go/syscall/socket_aix.go
@@ -0,0 +1,89 @@
+// socket_aix.go -- Socket handling specific to AIX.
+
+// Copyright 2017 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 syscall
+
+import "unsafe"
+
+const SizeofSockaddrInet4 = 16
+const SizeofSockaddrInet6 = 28
+const SizeofSockaddrUnix = 1025
+
+type RawSockaddrInet4 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Addr [4]byte /* in_addr */
+ Zero [8]uint8
+}
+
+func (sa *RawSockaddrInet4) setLen() Socklen_t {
+ sa.Len = SizeofSockaddrInet4
+ return SizeofSockaddrInet4
+}
+
+type RawSockaddrInet6 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+func (sa *RawSockaddrInet6) setLen() Socklen_t {
+ sa.Len = SizeofSockaddrInet6
+ return SizeofSockaddrInet6
+}
+
+type RawSockaddrUnix struct {
+ Len uint8
+ Family uint8
+ Path [1023]int8
+}
+
+func (sa *RawSockaddrUnix) setLen(n int) {
+ sa.Len = uint8(3 + n) // 2 for Family, Len; 1 for NUL.
+}
+
+func (sa *RawSockaddrUnix) getLen() (int, error) {
+ // Some versions of AIX have a bug in getsockname (see IV78655).
+ // We can't rely on sa.Len being set correctly.
+ n := SizeofSockaddrUnix - 3 // substract leading Family, Len, terminating NUL.
+ for i := 0; i < n; i++ {
+ if sa.Path[i] == 0 {
+ n = i
+ break
+ }
+ }
+ return n, nil
+}
+
+func (sa *RawSockaddrUnix) adjustAbstract(sl Socklen_t) Socklen_t {
+ return sl
+}
+
+type RawSockaddr struct {
+ Len uint8
+ Family uint8
+ Data [14]int8
+}
+
+// BindToDevice binds the socket associated with fd to device.
+func BindToDevice(fd int, device string) (err error) {
+ return ENOSYS
+}
+
+func anyToSockaddrOS(rsa *RawSockaddrAny) (Sockaddr, error) {
+ return nil, EAFNOSUPPORT
+}
+
+func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
+ var value IPv6MTUInfo
+ vallen := Socklen_t(SizeofIPv6MTUInfo)
+ err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+ return &value, err
+}
diff --git a/libgo/go/syscall/socket_bsd.go b/libgo/go/syscall/socket_bsd.go
index ecdab06..cf3fc4f 100644
--- a/libgo/go/syscall/socket_bsd.go
+++ b/libgo/go/syscall/socket_bsd.go
@@ -4,7 +4,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build aix darwin dragonfly freebsd openbsd netbsd
+// +build darwin dragonfly freebsd openbsd netbsd
package syscall
diff --git a/libgo/go/syscall/syscall_aix.go b/libgo/go/syscall/syscall_aix.go
new file mode 100644
index 0000000..c2554eb
--- /dev/null
+++ b/libgo/go/syscall/syscall_aix.go
@@ -0,0 +1,19 @@
+// Copyright 2017 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 syscall
+
+import "unsafe"
+
+func direntIno(buf []byte) (uint64, bool) {
+ return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
+}
+
+func direntReclen(buf []byte) (uint64, bool) {
+ return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
+}
+
+func direntNamlen(buf []byte) (uint64, bool) {
+ return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
+}
diff --git a/libgo/go/syscall/syscall_aix_ppc.go b/libgo/go/syscall/syscall_aix_ppc.go
new file mode 100644
index 0000000..83ed1e6
--- /dev/null
+++ b/libgo/go/syscall/syscall_aix_ppc.go
@@ -0,0 +1,49 @@
+// syscall_aix_ppc.go -- AIX 32-bit specific support
+
+// Copyright 2017 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 syscall
+
+import "unsafe"
+
+// AIX does not define a specific structure but instead uses separate
+// ptrace calls for the different registers.
+type PtraceRegs struct {
+ Gpr [32]uint32
+ Iar uint32
+ Msr uint32
+ Cr uint32
+ Lr uint32
+ Ctr uint32
+ Xer uint32
+}
+
+func (r *PtraceRegs) PC() uint64 { return uint64(r.Iar) }
+
+func (r *PtraceRegs) SetPC(pc uint64) { r.Iar = uint32(pc) }
+
+func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
+ ptrace(_PT_REGSET, pid, uintptr(unsafe.Pointer(&regsout.Gpr[0])), 0, 0)
+ regsout.Iar = uint32(ptrace(_PT_READ_GPR, pid, 128, 0, 0))
+ regsout.Msr = uint32(ptrace(_PT_READ_GPR, pid, 129, 0, 0))
+ regsout.Cr = uint32(ptrace(_PT_READ_GPR, pid, 130, 0, 0))
+ regsout.Lr = uint32(ptrace(_PT_READ_GPR, pid, 131, 0, 0))
+ regsout.Ctr = uint32(ptrace(_PT_READ_GPR, pid, 132, 0, 0))
+ regsout.Xer = uint32(ptrace(_PT_READ_GPR, pid, 133, 0, 0))
+ return nil
+}
+
+func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
+ for i := 0; i < len(regs.Gpr); i++ {
+ ptrace(_PT_WRITE_GPR, pid, uintptr(i), int(regs.Gpr[i]), 0)
+ }
+ ptrace(_PT_WRITE_GPR, pid, 128, int(regs.Iar), 0)
+ ptrace(_PT_WRITE_GPR, pid, 129, int(regs.Msr), 0)
+ ptrace(_PT_WRITE_GPR, pid, 130, int(regs.Cr), 0)
+ ptrace(_PT_WRITE_GPR, pid, 131, int(regs.Lr), 0)
+ ptrace(_PT_WRITE_GPR, pid, 132, int(regs.Ctr), 0)
+ ptrace(_PT_WRITE_GPR, pid, 133, int(regs.Xer), 0)
+ return nil
+}
diff --git a/libgo/go/syscall/syscall_aix_ppc64.go b/libgo/go/syscall/syscall_aix_ppc64.go
new file mode 100644
index 0000000..82388ca
--- /dev/null
+++ b/libgo/go/syscall/syscall_aix_ppc64.go
@@ -0,0 +1,49 @@
+// syscall_aix_ppc64.go -- AIX 64-bit specific support
+
+// Copyright 2017 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 syscall
+
+import "unsafe"
+
+// AIX does not define a specific structure but instead uses separate
+// ptrace calls for the different registers.
+type PtraceRegs struct {
+ Gpr [32]uint64
+ Iar uint64
+ Msr uint64
+ Cr uint64
+ Lr uint64
+ Ctr uint64
+ Xer uint64
+}
+
+func (r *PtraceRegs) PC() uint64 { return r.Iar }
+
+func (r *PtraceRegs) SetPC(pc uint64) { r.Iar = pc }
+
+func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
+ ptrace64(_PT_REGSET, int64(pid), int64(uintptr(unsafe.Pointer(&regsout.Gpr[0]))), 0, 0)
+ ptrace64(_PT_READ_GPR, int64(pid), 128, 0, uintptr(unsafe.Pointer(&regsout.Iar)))
+ ptrace64(_PT_READ_GPR, int64(pid), 129, 0, uintptr(unsafe.Pointer(&regsout.Msr)))
+ ptrace64(_PT_READ_GPR, int64(pid), 130, 0, uintptr(unsafe.Pointer(&regsout.Cr)))
+ ptrace64(_PT_READ_GPR, int64(pid), 131, 0, uintptr(unsafe.Pointer(&regsout.Lr)))
+ ptrace64(_PT_READ_GPR, int64(pid), 132, 0, uintptr(unsafe.Pointer(&regsout.Ctr)))
+ ptrace64(_PT_READ_GPR, int64(pid), 133, 0, uintptr(unsafe.Pointer(&regsout.Xer)))
+ return nil
+}
+
+func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
+ for i := 0; i < len(regs.Gpr); i++ {
+ ptrace64(_PT_WRITE_GPR, int64(pid), int64(i), 0, uintptr(unsafe.Pointer(&regs.Gpr[i])))
+ }
+ ptrace64(_PT_WRITE_GPR, int64(pid), 128, 0, uintptr(unsafe.Pointer(&regs.Iar)))
+ ptrace64(_PT_WRITE_GPR, int64(pid), 129, 0, uintptr(unsafe.Pointer(&regs.Msr)))
+ ptrace64(_PT_WRITE_GPR, int64(pid), 130, 0, uintptr(unsafe.Pointer(&regs.Cr)))
+ ptrace64(_PT_WRITE_GPR, int64(pid), 131, 0, uintptr(unsafe.Pointer(&regs.Lr)))
+ ptrace64(_PT_WRITE_GPR, int64(pid), 132, 0, uintptr(unsafe.Pointer(&regs.Ctr)))
+ ptrace64(_PT_WRITE_GPR, int64(pid), 133, 0, uintptr(unsafe.Pointer(&regs.Xer)))
+ return nil
+}
diff --git a/libgo/mkrsysinfo.sh b/libgo/mkrsysinfo.sh
index 44a3a6b..aee0163 100755
--- a/libgo/mkrsysinfo.sh
+++ b/libgo/mkrsysinfo.sh
@@ -23,6 +23,7 @@ grep -v '^// ' gen-sysinfo.go | \
grep -v '^type _timespec_t ' | \
grep -v '^type _timespec ' | \
grep -v '^type _epoll_' | \
+ grep -v '^type _*locale[_ ]' | \
grep -v 'in6_addr' | \
grep -v 'sockaddr_in6' | \
sed -e 's/\([^a-zA-Z0-9_]\)_timeval\([^a-zA-Z0-9_]\)/\1timeval\2/g' \
diff --git a/libgo/mksysinfo.sh b/libgo/mksysinfo.sh
index 54978b9..cbe5b97 100755
--- a/libgo/mksysinfo.sh
+++ b/libgo/mksysinfo.sh
@@ -34,6 +34,7 @@ grep -v '^// ' gen-sysinfo.go | \
grep -v '^type _timespec ' | \
grep -v '^type _timestruc_t ' | \
grep -v '^type _epoll_' | \
+ grep -v '^type _*locale[_ ]' | \
grep -v 'in6_addr' | \
grep -v 'sockaddr_in6' | \
sed -e 's/\([^a-zA-Z0-9_]\)_timeval\([^a-zA-Z0-9_]\)/\1Timeval\2/g' \
@@ -485,6 +486,7 @@ fi | sed -e 's/type _dirent64/type Dirent/' \
-e 's/d_name/Name/' \
-e 's/]int8/]byte/' \
-e 's/d_ino/Ino/' \
+ -e 's/d_namlen/Namlen/' \
-e 's/d_off/Off/' \
-e 's/d_reclen/Reclen/' \
-e 's/d_type/Type/' \
diff --git a/libgo/runtime/go-caller.c b/libgo/runtime/go-caller.c
index 360bae6..ee8abdc 100644
--- a/libgo/runtime/go-caller.c
+++ b/libgo/runtime/go-caller.c
@@ -159,7 +159,7 @@ syminfo_callback (void *data, uintptr_t pc __attribute__ ((unused)),
/* Set *VAL to the value of the symbol for PC. */
static _Bool
-__go_symbol_value (uintptr_t pc, uintptr_t *val)
+__go_symbol_value (uintptr pc, uintptr *val)
{
*val = 0;
backtrace_syminfo (__go_get_backtrace_state (), pc, syminfo_callback,
diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c
index e591824..d6e42e6 100644
--- a/libgo/runtime/proc.c
+++ b/libgo/runtime/proc.c
@@ -179,7 +179,7 @@ fixcontext(ucontext_t* c)
// So we make the field larger in runtime2.go and pick an appropriate
// offset within the field here.
static ucontext_t*
-ucontext_arg(uintptr* go_ucontext)
+ucontext_arg(uintptr_t* go_ucontext)
{
uintptr_t p = (uintptr_t)go_ucontext;
size_t align = __alignof__(ucontext_t);