hwparcel

package
v0.0.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 3, 2026 License: CC0-1.0 Imports: 5 Imported by: 0

Documentation

Overview

Package hwparcel implements the HIDL HwParcel wire format for hwbinder transactions. Unlike AIDL parcels that use inline data, HIDL uses scatter-gather serialization with binder_buffer_object entries (BINDER_TYPE_PTR) that reference external data buffers.

The HIDL wire format is:

  • Interface token: null-terminated C string in the data buffer
  • Structured data: binder_buffer_object entries in the data buffer, each pointing to a separate buffer in process memory. The kernel copies these buffers to the target process.
  • hidl_string: 16-byte struct (8-byte pointer + 4-byte size + 4-byte pad) with string data as a child buffer
  • hidl_vec<T>: 16-byte struct (8-byte pointer + 4-byte size + 4-byte pad) with element data as a child buffer

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func KeepBuffersAlive

func KeepBuffersAlive(buffers [][]byte)

KeepBuffersAlive calls runtime.KeepAlive on all buffer slices. Must be called after the binder ioctl completes.

Types

type HwParcel

type HwParcel struct {
	// contains filtered or unexported fields
}

HwParcel builds a HIDL HwParcel for hwbinder transactions. It produces data and objects arrays compatible with the kernel binder scatter-gather protocol.

func New

func New() *HwParcel

New creates a new empty HwParcel.

func (*HwParcel) BufferCount

func (p *HwParcel) BufferCount() int

BufferCount returns the number of scatter-gather buffer objects.

func (*HwParcel) DataBytes

func (p *HwParcel) DataBytes() []byte

DataBytes returns the raw inline data bytes.

func (*HwParcel) DumpBufferObjects

func (p *HwParcel) DumpBufferObjects() []string

DumpBufferObjects returns a debug description of all buffer objects in the parcel (type, flags, length, parent, parent_offset).

func (*HwParcel) ObjectOffsets

func (p *HwParcel) ObjectOffsets() []uint64

ObjectOffsets returns the objects array (byte offsets of binder objects).

func (*HwParcel) ToParcel

func (p *HwParcel) ToParcel() (*parcel.Parcel, [][]byte)

ToParcel converts this HwParcel into a standard parcel.Parcel. It patches the buffer pointers in each binder_buffer_object to point to the actual buffer data in memory. The returned keepAlive slice must be kept alive (via runtime.KeepAlive) until the transaction completes.

func (*HwParcel) WriteBool

func (p *HwParcel) WriteBool(v bool)

WriteBool writes a boolean as a uint8 into the inline data buffer, padded to 4-byte alignment.

func (*HwParcel) WriteBuffer

func (p *HwParcel) WriteBuffer(buf []byte) int

WriteBuffer writes a top-level scatter-gather buffer object. Returns the handle (index) for parent references.

func (*HwParcel) WriteEmbeddedBuffer

func (p *HwParcel) WriteEmbeddedBuffer(
	buf []byte,
	parentHandle int,
	parentOffset uint64,
) int

WriteEmbeddedBuffer writes a child scatter-gather buffer embedded within a parent buffer. parentOffset is the byte offset within the parent buffer where the pointer to this child buffer lives (typically 0 for hidl_string and hidl_vec, since the pointer is the first field).

func (*HwParcel) WriteEmbeddedNativeHandle

func (p *HwParcel) WriteEmbeddedNativeHandle(
	fds []int32,
	ints []int32,
	parentHandle int,
	parentOffset uint64,
)

WriteEmbeddedNativeHandle writes a non-null native_handle_t as an embedded child buffer, plus a binder_fd_array_object so the kernel can translate the file descriptors.

Wire format:

uint64 native_handle_size (inline)
binder_buffer_object pointing to native_handle_t data (child of parent)
binder_fd_array_object referencing the FDs in the buffer

The native_handle_t buffer contains:

int32 version (= 12 = sizeof(native_handle_t))
int32 numFds
int32 numInts
int32[numFds] fds
int32[numInts] ints

func (*HwParcel) WriteFdArrayObject

func (p *HwParcel) WriteFdArrayObject(
	numFds int,
	bufferHandle int,
	parentOffset uint64,
)

WriteFdArrayObject writes a binder_fd_array_object into the data buffer and records its offset in the objects array. This tells the kernel that the buffer at bufferHandle contains file descriptors starting at parentOffset (typically offsetof(native_handle_t, data) = 12).

binder_fd_array_object layout (32 bytes):

[0:4]   uint32 type (BINDER_TYPE_FDA = 0x66646185)
[4:8]   uint32 pad
[8:16]  uint64 num_fds
[16:24] uint64 parent (buffer handle index)
[24:32] uint64 parent_offset (offset of FD array within parent buffer)

func (*HwParcel) WriteHidlString

func (p *HwParcel) WriteHidlString(s string)

WriteHidlString writes a hidl_string value. Creates two buffer objects:

  1. The hidl_string struct (16 bytes)
  2. The string data (child of #1, linked at the pointer field offset 0)

func (*HwParcel) WriteHidlVecBytes

func (p *HwParcel) WriteHidlVecBytes(data []byte)

WriteHidlVecBytes writes a hidl_vec<uint8_t>. Creates two buffer objects:

  1. The hidl_vec header (16 bytes)
  2. The byte array data (child of #1)

func (*HwParcel) WriteHidlVecUint32

func (p *HwParcel) WriteHidlVecUint32(values []uint32)

WriteHidlVecUint32 writes a hidl_vec<uint32_t>. Creates two buffer objects:

  1. The hidl_vec header (16 bytes)
  2. The uint32 array data (child of #1)

func (*HwParcel) WriteInt32

func (p *HwParcel) WriteInt32(v int32)

WriteInt32 writes an int32 directly into the inline data buffer.

func (*HwParcel) WriteInterfaceToken

func (p *HwParcel) WriteInterfaceToken(descriptor string)

WriteInterfaceToken writes the HIDL interface descriptor as a null-terminated C string in the data buffer.

func (*HwParcel) WriteLocalBinder

func (p *HwParcel) WriteLocalBinder(
	binderPtr uintptr,
	cookie uintptr,
)

WriteLocalBinder writes a local HIDL binder reference (BINDER_TYPE_BINDER) into the inline data with a real binder/cookie pair. The kernel will create a binder_node for this object and translate it to a BINDER_TYPE_HANDLE in the receiving process.

Unlike AIDL, HIDL does NOT write a stability level after the flat_binder_object. The offset IS recorded in the objects array so the kernel processes it.

func (*HwParcel) WriteNullBinder

func (p *HwParcel) WriteNullBinder()

WriteNullBinder writes a null HIDL binder reference into the inline data. HIDL null binders use flat_binder_object with BINDER_TYPE_BINDER and binder=0, cookie=0. Unlike AIDL, HIDL does NOT append a stability level. The offset is NOT recorded in the objects array (matching AOSP behavior where null binder objects are inert data).

func (*HwParcel) WriteNullNativeHandle

func (p *HwParcel) WriteNullNativeHandle()

WriteNullNativeHandle writes the HIDL serialization for a null native_handle (hidl_handle with mHandle == nullptr).

Wire format: uint64(0) inline.

func (*HwParcel) WriteUint32

func (p *HwParcel) WriteUint32(v uint32)

WriteUint32 writes a uint32 directly into the inline data buffer (not as a scatter-gather buffer object). Used for simple scalar arguments that follow buffer objects.

func (*HwParcel) WriteUint64

func (p *HwParcel) WriteUint64(v uint64)

WriteUint64 writes a uint64 directly into the inline data buffer.

type ResponseParcel

type ResponseParcel struct {
	// contains filtered or unexported fields
}

ResponseParcel wraps a reply parcel.Parcel from a HIDL transaction and provides methods to read HIDL-formatted response data. HIDL replies don't use scatter-gather -- the kernel copies all buffer data into the target's mmap region, and the driver copies it into the reply parcel data buffer inline.

func NewResponseParcel

func NewResponseParcel(p *parcel.Parcel) *ResponseParcel

NewResponseParcel wraps a standard parcel for HIDL response reading.

func (*ResponseParcel) DataLen

func (r *ResponseParcel) DataLen() int

DataLen returns the total data length.

func (*ResponseParcel) Position

func (r *ResponseParcel) Position() int

Position returns the current read position.

func (*ResponseParcel) ReadInt32

func (r *ResponseParcel) ReadInt32() (int32, error)

ReadInt32 reads an int32 from the response.

func (*ResponseParcel) ReadNativeHandle

func (r *ResponseParcel) ReadNativeHandle() (fds []int32, ints []int32, err error)

ReadNativeHandle reads a native_handle_t from the HIDL response. Wire format: int32 numFds, int32 numInts, then flat_binder_object entries for each FD, then int32 entries for each int.

func (*ResponseParcel) ReadRawBytes

func (r *ResponseParcel) ReadRawBytes(n int) ([]byte, error)

ReadRawBytes reads n raw bytes.

func (*ResponseParcel) ReadStrongBinder

func (r *ResponseParcel) ReadStrongBinder() (uint32, error)

ReadStrongBinder reads a binder handle from the HIDL response. HIDL does NOT write a stability level after the flat_binder_object (unlike AIDL).

func (*ResponseParcel) ReadUint32

func (r *ResponseParcel) ReadUint32() (uint32, error)

ReadUint32 reads a uint32 from the response.

func (*ResponseParcel) Remaining

func (r *ResponseParcel) Remaining() int

Remaining returns the number of unread bytes.

func (*ResponseParcel) SkipBytes

func (r *ResponseParcel) SkipBytes(n int) error

SkipBytes advances the read position by n bytes (4-byte aligned).

func (*ResponseParcel) Underlying

func (r *ResponseParcel) Underlying() *parcel.Parcel

Underlying returns the wrapped parcel for low-level access.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL