[syscalls][object] Expose Handle.GetInfo

Also, add support for PA_FD to Go startup.

Change-Id: Ia2ad5439694c92c2581eb1309f29ebc7843a70b7
diff --git a/src/syscall/syscall_fuchsia.go b/src/syscall/syscall_fuchsia.go
index 10c722fc..0bac6a1 100644
--- a/src/syscall/syscall_fuchsia.go
+++ b/src/syscall/syscall_fuchsia.go
@@ -372,13 +372,24 @@
 		switch zx.StdioHandleTypes[i] {
 		case 0:
 			return nil, EINVAL
-		case fdio.HandleTypeRemote:
-			obj := (*fidlIo.NodeInterface)(&fidl.ChannelProxy{Channel: zx.Channel(zx.StdioHandles[i])})
-			return &fdio.File{Node: fdio.Node{obj}}, nil
-		case fdio.HandleTypeSocket:
-			return fdio.NewPipe(zx.Socket(zx.StdioHandles[i])), nil
-		case fdio.HandleTypeLogger:
-			return fdio.NewLogger(zx.Log(zx.StdioHandles[i])), nil
+		case fdio.HandleTypeRemote, fdio.HandleTypeSocket, fdio.HandleTypeLogger, fdio.HandleTypeFileDescriptor:
+			info, err := zx.StdioHandles[i].GetInfoHandleBasic()
+			if err != nil {
+				println("syscall: GetInfoHandleBasic failed", err);
+				return nil, EINVAL
+			}
+			switch info.Type {
+			case zx.ObjectTypeChannel:
+				obj := (*fidlIo.NodeInterface)(&fidl.ChannelProxy{Channel: zx.Channel(zx.StdioHandles[i])})
+				return &fdio.File{Node: fdio.Node{obj}}, nil
+			case zx.ObjectTypeSocket:
+				return fdio.NewPipe(zx.Socket(zx.StdioHandles[i])), nil
+			case zx.ObjectTypeLog:
+				return fdio.NewLogger(zx.Log(zx.StdioHandles[i])), nil
+			default:
+				println("syscall: unknown object type for stdio: ", info.Type)
+				return nil, EINVAL
+			}
 		default:
 			println("syscall: unknown handle type for stdio: " + itoa(zx.StdioHandleTypes[i]))
 			return nil, EINVAL
@@ -391,7 +402,7 @@
 	}
 	stdout, err = initStdio(1)
 	if err != nil {
-		println("syscall: failed to create fdio stdiout: ", err.Error())
+		println("syscall: failed to create fdio stdout: ", err.Error())
 	}
 	stderr, err = initStdio(2)
 	if err != nil {
diff --git a/src/syscall/zx/fdio/fdio.go b/src/syscall/zx/fdio/fdio.go
index 3f9d53c..ce98f6b 100644
--- a/src/syscall/zx/fdio/fdio.go
+++ b/src/syscall/zx/fdio/fdio.go
@@ -74,7 +74,8 @@
 )
 
 const (
-	HandleTypeRemote = 0x32
-	HandleTypeLogger = 0x35
-	HandleTypeSocket = 0x36
+	HandleTypeFileDescriptor = 0x30
+	HandleTypeRemote         = 0x32
+	HandleTypeLogger         = 0x35
+	HandleTypeSocket         = 0x36
 )
diff --git a/src/syscall/zx/handle.go b/src/syscall/zx/handle.go
index a0aec84..5c88a5c 100644
--- a/src/syscall/zx/handle.go
+++ b/src/syscall/zx/handle.go
@@ -181,6 +181,27 @@
 	return cookie, nil
 }
 
+func (h *Handle) GetInfo(topic uint32, data []byte) (actual, avail uint, err error) {
+	dataBytes := uint(len(data))
+	var dataPtr unsafe.Pointer
+	if dataBytes > 0 {
+		dataPtr = unsafe.Pointer(&data[0])
+	}
+	if status := Sys_object_get_info(*h, topic, dataPtr, dataBytes, &actual, &avail); status != ErrOk {
+		err = Error{Status: status, Text: "zx.Handle.GetInfo"}
+	}
+	return
+}
+
+func (h *Handle) GetInfoHandleBasic() (info InfoHandleBasic, err error) {
+	dataBytes := uint(unsafe.Sizeof(info))
+	dataPtr := unsafe.Pointer(&info)
+	if status := Sys_object_get_info(*h, ObjectInfoHandleBasic, dataPtr, dataBytes, nil, nil); status != ErrOk {
+		err = Error{Status: status, Text: "zx.Handle.GetInfoHandleBasic"}
+	}
+	return
+}
+
 func (h *Handle) GetProperty(property uint32, data []byte) error {
 	var numBytes = uint(len(data))
 	var dataPtr unsafe.Pointer
diff --git a/src/syscall/zx/types.go b/src/syscall/zx/types.go
index 7d53577..ecb34af 100644
--- a/src/syscall/zx/types.go
+++ b/src/syscall/zx/types.go
@@ -8,15 +8,16 @@
 
 import "unsafe"
 
-type Status int32   // zx_status_t
-type Handle uint32  // zx_handle_t
-type Clock uint32   // zx_clock_t,
-type Time int64     // zx_time_t, nanoseconds
-type Duration int64 // zx_duration_t, nanoseconds
-type Signals uint32 // zx_signals_t
-type Rights uint32  // zx_rights_t
-type Paddr uintptr  // zx_paddr_t
-type Vaddr uintptr  // zx_vaddr_t
+type Status int32      // zx_status_t
+type Handle uint32     // zx_handle_t
+type Clock uint32      // zx_clock_t,
+type Time int64        // zx_time_t, nanoseconds
+type Duration int64    // zx_duration_t, nanoseconds
+type Signals uint32    // zx_signals_t
+type Rights uint32     // zx_rights_t
+type Paddr uintptr     // zx_paddr_t
+type Vaddr uintptr     // zx_vaddr_t
+type ObjectType uint32 //zx_obj_type_t
 
 type WaitItem struct {
 	Handle  Handle
@@ -52,6 +53,14 @@
 	ZX_RREC_SELF_ROOT    = 1
 )
 
+type InfoHandleBasic struct {
+	Koid        uint64
+	Rights      Rights
+	Type        ObjectType
+	RelatedKoid uint64
+	Props       uint32
+} // zx_info_handle_basic_t
+
 type RrecSelf struct {
 	Type        uint16 // ZX_RREC_SELF
 	Subtype     uint16
@@ -360,6 +369,38 @@
 	ObjectInfoVMAR
 )
 
+const (
+	ObjectTypeNone = ObjectType(iota)
+	ObjectTypeProcess
+	ObjectTypeThread
+	ObjectTypeVmo
+	ObjectTypeChannel
+	ObjectTypeEvent
+	ObjectTypePort
+	_ // 7
+	_ // 8
+	ObjectTypeInterrupt
+	_ // 10
+	ObjectTypePciDevice
+	ObjectTypeLog
+	_ // 13
+	ObjectTypeSocket
+	ObjectTypeResource
+	ObjectTypeEventPair
+	ObjectTypeJob
+	ObjectTypeVmar
+	ObjectTypeFifo
+	ObjectTypeGuest
+	ObjectTypeVcpu
+	ObjectTypeTimer
+	ObjectTypeIommu
+	ObjectTypeBti
+	ObjectTypeProfile
+	ObjectTypePmt
+	ObjectTypeSuspendToken
+	ObjectTypePager
+)
+
 // Options for socket_create
 const (
 	SocketStream     = iota            // 0