Introduction
Usage
Protocol
Encodings

sctl Manual

Introduction

sctl is a process control server that provides local and remote access to the state of one or more programs in execution. It is designed to present domains to Cinquecento programs, but does so through a protocol, documented in this manual, that could be spoken by other tools.

Process control operations served by sctl include:

sctl is the reconsidered name for the prctl service referenced in older Cinquecento documentation.

Usage

The L1 implementation of Cinquecento includes a library, called debug, that implements a client for sctl. Documentation and example programs for this library are included in the L1 distribution. This library implicitly invokes the sctl binary.

For other clients, the sctl command line usage is as follows:

sctl [options]

The options are:

	-c         start session on file descriptor 0
	-d         increase debug level
	-p port    listen for client on port
	-g         ignore debug information in target binaries

Protocol

This section describes the format and meaning of messages exchanged between sctl and its clients.

Messages are byte sequences exchanged over a bidirectional byte stream channel, such as a Unix socket pair or a TCP connection.

Messages are composed of encodings of integer and string values. The integer encodings are one-, four- or eight-byte little-endian byte sequences denoted name[1], name[4], or name[8], where name is a descriptive name for the field and the constant in brackets is the size in bytes of the encoding.

String encodings are denoted name[s] and begin with a length n[8] followed by n bytes comprising the string. Null bytes may appear anywhere in string data and have no special meaning.

Each message has the following format:

size[8] op[1] tag[4] operands

The size gives the length in bytes of the remaining portion of the message. The op is the message opcode identifying the type of message. Values of valid opcodes and other encodings are specified in the encodings section of this manual. The tag identifies the request/reply transaction associated with the message, as described below. The various operands associated with each message are described separately below.

Several message types have variable-length operands (besides strings). Since every message begins with its size, clients and servers can infer the aggregate size of such operands. The protocol exploits this property by omitting operand size fields in messages with exactly one variable-length operand; such operands are denoted field[].

There are three categories of messages:

Every request opcode is paired in a normal transaction with a corresponding reply opcode. For example, the normal reply to a Tlaunch request is an Rlaunch reply. However, if for any reason the server cannot complete a request, it sends an Rerror reply to conclude the transaction. (There is no Terror request.) The Rerror operand gives a textual reason for the error.

The tag field is an identifier, chosen by the client, that links each reply to its request. Clients must arrange for all outstanding requests to have distinct tags. For consistency, the Aevent message also has a tag field, but its value is undefined.

The formats of the ctl messages are:

size[8] Aevent[1] tag[4] bytes[]
size[8] Rerror[1] tag[4] err[]
size[8] Tversion[1] tag[4] version[]
size[8] Rversion[1] tag[4] version[]
size[8] Tping[1] tag[4] bytes[]
size[8] Rping[1] tag[4] cnt[8]
size[8] Tps[1] tag[4]
size[8] Rps[1] tag[4] bytes[]
size[8] Tlaunch[1] tag[4] bytes[]
size[8] Rlaunch[1] tag[4] id[8] ctx
size[8] Tattach[1] tag[4] pid[8]
size[8] Rattach[1] tag[4] ctlid[8] ctx
size[8] Tstat[1] tag[4] id[8]
size[8] Rstat[1] tag[4] bytes[]
size[8] Tcont[1] tag[4] id[8]
size[8] Rcont[1] tag[4]
size[8] Tstop[1] tag[4] id[8]
size[8] Rstop[1] tag[4] ctx
size[8] Tstep[1] tag[4] id[8]
size[8] Rstep[1] tag[4] ctx
size[8] Tsnap[1] tag[4] ctlid[8]
size[8] Rsnap[1] tag[4] spwnid[8] ctx[]
size[8] Tkill[1] tag[4] id[8]
size[8] Rkill[1] tag[4]
size[8] Tdetach[1] tag[4] id[8]
size[8] Rdetach[1] tag[4]
size[8] Ttrace[1] tag[4] id[8] bytes[]
size[8] Rtrace[1] tag[4]
size[8] Tsettrap[1] tag[4] id[8] bytes[]
size[8] Rsettrap[1] tag[4] tid[8]
size[8] Tclrtrap[1] tag[4] id[8] tid[8]
size[8] Rclrtrap[1] tag[4]
size[8] Tgetctx[1] tag[4] id[8]
size[8] Rgetctx[1] tag[4] ctx
size[8] Tsetctx[1] tag[4] id[8] ctx
size[8] Rsetctx[1] tag[4]
size[8] Tread[1] tag[4] id[8] fd[8] offset[8] cnt[8]
size[8] Rread[1] tag[4] bytes[]
size[8] Twrite[1] tag[4] id[8] fd[8] offset[8] bytes[]
size[8] Rwrite[1] tag[4] cnt[8]
size[8] Tnames[1] tag[4] path[s]
size[8] Rnames[1] tag[4] nsid[8]
size[8] Tlooksym[1] tag[4] nsid[8] name[s]
size[8] Rlooksym[1] tag[4] sym[]
size[8] Tenumsym[1] tag[4] nsid[8]
size[8] Renumsym[1] tag[4] syms[]
size[8] Tenumloc[1] tag[4] ctlid[8] addr[8]
size[8] Renumloc[1] tag[4] bytes[]
size[8] Tlooktype[1] tag[4] nsid[8] typename[]
size[8] Rlooktype[1] tag[4] typedef[]
size[8] Tenumtype[1] tag[4] nsid[8]
size[8] Renumtype[1] tag[4] typedefs[]
size[8] Tlookaddr[1] tag[4] nsid[8] addr[8]
size[8] Rlookaddr[1] tag[4] sym[]
size[8] Tunwind1[1] tag[4] nsid[8] addr[8]
size[8] Runwind1[1] tag[4] rules[]
size[8] Tlooksrc[1] tag[4] nsid[8] addr[8]
size[8] Rlooksrc[1] tag[4] file[s] line[4] col[4]
size[8] Tlookpc[1] tag[4] nsid[8] file[s] line[4]
size[8] Rlookpc[1] tag[4] addr[8]

Many requests operate on a control target, a thread of execution. A control target is represented by an 8-byte unsigned integer identifier chosen by the server. Operands named ctlid in message formats and descriptions are control target identifiers.

All messages operate over a single set of control target identifiers. The set of currently valid target identifiers is determined by the following rules:

Every control target has an execution context that includes state such as the contents of processor registers and the set of pending exceptions. Several messages include a target context. Operands named ctx in the descriptions below are contexts. The size and format of a context operand is target-specific.

Every control target has an associated address space that comprises the byte-addressable memory of the target. Multiple control targets (e.g., in a threaded program) may be associated with the same address space. An address space may be read or written through operations on one of its associated control targets; there is no separate address space identifier.

A binary is a logical unit of executable code (e.g., a shared library or executable). Included in many binaries are data structures intended to support debuggers, such as symbol tables, type definitions, stack unwinding tables, and so on; the collection of such information for a given binary is called its name space. A name space is represented by a name space identifier. Operands named nsid in message formats and descriptions are name space identifiers.

Every address space consists of a set of non-overlapping mappings that each span a contiguous subrange of the valid addressable bytes in the address space. Some mappings may collectively form the image, possibly modified (e.g., by being relocated), of a binary that has been "mapped" into the address space at a particular base address. The same name space identifier may be used to reference a binary that has been mapped into multiple address spaces; to maintain mapping independence, the addresses reflected by any name space are always relative to a base address of zero.

Some mappings (e.g., "anonymous" mappings on Unix systems) may have no corresponding binary, but no mapping may be associated with more than one binary.

A variety of events may occur during the execution of a control target, including a system call, receipt of a signal, loading or unloading of a binary, spawning of a new thread or process, or death. Only those events that are currently being traced will be communicated to the sctl client. The set of traced events is local to each control target, and may be adjusted. The set of events is target specific. Targets derived from existing targets (e.g., via fork or clone) inherit the trace mode of their parent.

Several transactions involve information about the C programming language types used by target program. Two encodings are used to convey this type information: type names encode the names of C types; type definitions encode their definition.

Type names come in nine variants:

  1. Base type names represent the names of base types of the C programming language. They are encoded as:

    Tbase[1] base[1]

    Base is a base type identifier:

    Base C type
    Vvoid void
    Vbool _Bool
    Vchar char
    Vshort short
    Vint int
    Vlong long
    Vvlong long long
    Vuchar unsigned char
    Vushort unsigned short
    Vuint unsigned int
    Vulong unsigned long
    Vuvlong unsigned long long
    Vfloat float
    Vdouble double
    Vlongdouble long double
    Vptr pointer

    Most of these base types correspond directly to C types. Vptr is a special base type name used to indicate the encoding of pointer values in the target program.

  2. Tagged type names represent the names of any of the three variants of tagged types in C. They are encoded as:

    Tstruct[1] tag[s]
    Tunion[1] tag[s]
    Tenum[1] tag[s]
  3. Typedef type names represent the names of types defined with typedef. They are encoded as:

    Ttypedef[1] tid[s]
  4. Pointer type names represent the type name of a pointer to some other type. They are encoded as:

    Tptr[1] tname[]

    Tname is the name of the pointed-to type.

  5. Array type names represent the type name of an array of some other type. They are encoded as:

    Tarr[1] nelem[8] tname[]

    Nelm is the number of elements in the array. Tname is the name of the element type.

  6. Function type names represent the type name of a function. They are encoded as:

    Tfun[1] tname[] np[8] np*param[]

    Tname is the name of the type returned by the function. Np is the number of parameters to the function. Each param is a description of a parameter, encoded as:

    attrs[] pname[s] tname[]

    Attrs is a set of attributes for the parameter. Pname is the name of the parameter. Tname is the name of its type.

  7. Bitfield type names describe the size and layout of a bitfield in a struct or union aggregate type. They are encoded as:

    Tbitfield[1] width[1] pos[1] tname[]

    Width is the number of bits comprising the bitfield. Pos is the number of bits from the beginning of field (i.e., its offset within the containing aggregate type) to the first bit of the bitfield. Tname is the name of the type used to represent values of the bitfield.

  8. The enumeration constant type name is a special name used to represent the type of enumeration constant values. The encoding is:

    Tconst[1] tname[]

    Tname is the name of the enumeration type.

  9. The undefined type name is a special name used to represent types that have not been defined. The encoding is:

    Tundef[1] tname[]

    Tname is the name of the undefined type.

Type definitions come in four variants:

  1. Base type definitions represent the definition of base types of the C programming language. They are encoded as:

    Tbase[1] base[1] rep[1]

    Base is any of the base type identifiers used for the encoding of base type names. Rep is a representation identifier:

    Identifier Representation
    Rundef undefined
    Ru08le 1 byte, unsigned, little-endian integer
    Ru16le 2 byte, unsigned, little-endian integer
    Ru32le 4 byte, unsigned, little-endian integer
    Ru64le 8 byte, unsigned, little-endian integer
    Rs08le 1 byte, signed, little-endian integer
    Rs16le 2 byte, signed, little-endian integer
    Rs32le 4 byte, signed, little-endian integer
    Rs64le 8 byte, signed, little-endian integer
    Ru08be 1 byte, unsigned, big-endian integer
    Ru16be 2 byte, unsigned, big-endian integer
    Ru32be 4 byte, unsigned, big-endian integer
    Ru64be 8 byte, unsigned, big-endian integer
    Rs08be 1 byte, signed, big-endian integer
    Rs16be 2 byte, signed, big-endian integer
    Rs32be 4 byte, signed, big-endian integer
    Rs64be 8 byte, signed, big-endian integer
    Rf32 4 byte floating point
    Rf64 8 byte floating point
    Rf96 12 byte floating point
    Rf128 16 byte floating point
    Rx64 8 byte complex floating point
    Rx128 16 byte complex floating point
    Rx192 24 byte complex floating point
  2. Aggregate type definitions are encoded as:

    Tstruct[1] tag[s] size[8] attrs[] nfield[8] nfield*field[]
    Tunion[1] tag[s] size[8] attrs[] nfield[8] nfield*field[]

    Tag is the tag of the aggregate. Size is the size in bytes of the aggregate. Attrs is a set of attributes for the aggregate. Nfield is the number of fields defined in the aggregate. Each field is a field specification, encoded as follows:

    off[8] attrs[] id[s] tname[]

    Off is the number of bytes from the beginning of the aggregate to the first byte of the field. Attrs is a set of attributes for the field. Id is the name of the field. Tname is the name of the type of the field.

  3. Enumeration type definitions are encoded as:

    Tenum[1] tag[s] rep[1] nconst[8] nconst*const[]

    Tag is the tag of the enumeration type. Rep is any of the representation identifiers used for the encoding of base type definitions; it indicates the representation of values of the enumeration type. Nconst is the number of enumeration constants defined in the type. Each constant definition const is encoded as:

    id[s] value[8]

    Id[s] is the name of the constant; Value[8] is its value encoded as an eight byte two's-complement integer.

  4. Typedef type definitions are encoded as:

    Ttypedef[1] tid[s] tname[]

    Tname is the name of the type aliased by the typedef. Tid is the alias.

Four of the above the encodings &mdash symbols, aggregates, fields, and parameters &mdash include a set of attributes. Attributes are key-value pairs. Each key or value may be one of three of types: string, symbol, or unsigned 8-byte integer. The encoding of a set of attributes attrs is:

na[8] na * (key[] val[])

Each key val and value val is a string, symbol, or unsigned integer value, encoded respectively as:

Astr[1] s[s]
Acid[1] s[s]
Auint[1] v[8]

The remainder of this section describes the format and meaning of the transactions.

version – negotiate protocol version

Every ctl session begins with a version transaction to negotiate the procotol version (but see ping):

size[8] Tversion[1] tag[4] version[]
size[8] Rversion[1] tag[4] version[]

The version operand of both request and reply is a string of the form

ctl-version:sys-version,...

ctl-version names a base protocol version. The base protocol version described in this manual is sctl-2012.

The one or more following sys-versions name a set of system-specific dialects. Supported system dialects include:

x86-linux-2012 – i386 and x86_64 Linux targets
x86-win-2012 – i386 Windows targets

Tversion announce to the server the base protocol version and the set of system dialects that the client speaks.

The Rversion reply must specify the same base version and a non-empty subset of the sys-versions. This transaction establishes that the client and server will speak the mutually named base protocol, and only those system dialects named in the server's reply.

If the server does not support the base version or any of the named system dialects, it returns Rerror.

A subsequent version transaction on the same connection is an error.

ping – exchange a ping

The ping request has no effect and is used mainly for debugging. Servers should respond immediately to pings.

size[8] Tping[1] tag[4] bytes[]
size[8] Rping[1] tag[4] cnt[8]

The bytes operand of the request contains zero or more bytes of arbitrary data. The reply's cnt operand must be the length of the request's bytes operand.

ps – list targets

The ps request returns a list of targets that the server can control.
size[8] Tps[1] tag[4]
size[8] Rps[1] tag[4] bytes[]

The format of the reply is system dependent.

On x86-linux-2012, the bytes operand of the reply has the format:

ntarg[8] ntarg * (pid[8] len[8] cmd[len] ntid[8] ntid * tid[8])

Ntarg is the number of targets reported in the reply. For each target, pid is the system process id, cmd is the name of the command, and ntid is the number of threads associated with the process. Each tid is an identifier for a thread associated with the process.

On x86-win-2012, the ps request is unsupported.

error – failed request

size[8] Rerror[1] tag[4] err[]

The error reply indicates that a previous request could not be completed. Err is an ASCII string (not nul-terminated) that describes the reason.

launch – start a process

size[8] Tlaunch[1] tag[4] spec[]
size[8] Rlaunch[1] tag[4] id[8] ctx

The launch request starts a new process running under sctl control, stopped just prior to the execution of its first instruction. The spec operand of the request specifies the parameters of the new execution in a system-dependent format described below. The id operand of the reply is the identifier for the new target process.

On x86-linux-2012, the format of spec is:

flags[8] narg[8] narg*arg[s]
Flags is a set of undefined flags. Narg is the number of command arguments, including the executable name. The actual arguments follow as the subsequent arg[s] strings.

On x86-win-2012, the format of spec is the same as that for x86-linux-2012.

attach – assume control of a process

The attach request assumes control of an already running target. The target process is stopped.

size[8] Tattach[1] tag[4] pid[8]
size[8] Rattach[1] tag[4] ctlid[8] ctx

The pid operand of the request is the system process id of the target.

The ctlid field of the reply is the identifer for the new target.

stat – target status

size[8] Tstat[1] tag[4] id[8]
size[8] Rstat[1] tag[4] stat[]

The stat request returns information about the current state of the target in a system-dependent format.

On x86-linux-2012, stat consists of a sequence of records of the form:

pid[8] nr[8] nr*region nb[8] nb*bin

Pid is the process id of the target.

Nr is the number of regions of mapped memory in the target address space. Each mapping is described by a region of the form:

file[s] addr[8] len[8] flags[8]

File is an ASCII name for the mapping, addr is the start address of the mapping, len is the size in bytes of the mapping, and flags is a bitmask of protection flags:

		PROT_READ	= 0x1,	/* Page can be read.  */
		PROT_WRITE	= 0x2,	/* Page can be written.  */
		PROT_EXEC	= 0x4,	/* Page can be executed.  */

Nb is the number of loaded binaries (shared libraries or executables) in the target address space. Each binary is described by a bin of the form:

nsid[8] base[8] isexe[1] path[s]

Nsid is the namespace identifier for the binary, base is the load address of the binary, isexe is a boolean indicating whether the binary is an executable, and path is an ASCII path to the binary in the target file system.

On x86-win-2012, the format of stat is undocumented.

stop – stop execution

size[8] Tstop[1] tag[4] ctlid[8]
size[8] Rstop[1] tag[4] ctx[]

The stop request stops execution of the control target. The ctx operand of the reply is the context of the target at the instant of the stop.

step – step execution

size[8] Tstep[1] tag[4] ctlid[8]
size[8] Rstep[1] tag[4] ctx[]

The step request steps the execution of the control target. The target must be stopped, and remains stopped following the transaction. If the target trace set includes Estepctx, then the ctx operand of the reply is the context of the target following the step; otherwise the ctx operand is omitted (zero-sized).

cont – resume execution

size[8] Tcont[1] tag[4] id[8]
size[8] Rcont[1] tag[4]

The cont request resumes execution of the control target, if stopped.

snap – take snapshot

size[8] Tsnap[1] tag[4] ctlid[8]
size[8] Rsnap[1] tag[4] spwnid[8] ctx[]

The snap request takes a snapshot of the control target, creating a new stopped control target. The spwnid field of the reply is the identifier for the new control target.

kill – terminate target

size[8] Tkill[1] tag[4] ctlid[8]
size[8] Rkill[1] tag[4]

The kill request terminates the control target ctlid.

detach – release target

size[8] Tdetach[1] tag[4] ctlid[8]
size[8] Rdetach[1] tag[4]

The detach request detaches sctl from the control target ctlid.

trace – register for events

size[8] Ttrace[1] tag[4] ctlid[8] bytes[]
size[8] Rtrace[1] tag[4]

The trace request updates the set of events occurring in the control target ctlid that are to be reported through Aevent messages.

Details are encoded in the system-specific bytes operand.

On x86-linux-2012, the format of bytes is a bitfield:

flags[8]

The bits of the flags field are:

		0  mode      - set=1, clear=0
		1  Esyscall  - entry or exit to system call
		2  Eexec     - successful return from exec
		3  Efork     - successful return from fork
		4  Eclone    - successful return from clone
		5  Esignal   - pending signal
		6  Eexit     - target exit
		7  Etrap     - arrival at a trap point
		8  Esnap     - arrival at a snap point
		9  Estepctx  - return context on step (no corresponding event)
	       10  Eload     - successful new binary load
	       11  Eunload   - successful binary unload

If the mode bit is set, the specified events are added the current set of traced events; if cleared, they are removed.

Control targets created by launch and attach requests have the following default trace set:

		Eexit|Eclone|Efork|Eexec|Estepctx|Eload|Eunload|Esignal

On x86-win-2012, the format of bytes is a bitfield:

flags[8]

The bits of the flags field are:

		0  mode      - set=1, clear=0
		3  Efork     - successful return from fork
		4  Eclone    - successful return from clone
		5  Esignal   - pending signal
		6  Eexit     - target exit
		7  Etrap     - arrival at a trap point
		8  Esnap     - arrival at a snap point
		9  Estepctx  - return context on step (no corresponding event)
	       10  Eload     - successful new binary load
	       11  Eunload   - successful binary unload

If the mode bit is set, the specified events are added the current set of traced events; if cleared, they are removed.

Control targets created by launch and attach requests have the following default trace set:

		Etrap|Eclone|Efork|Eexit|Eload|Eunload|Esignal

settrap – set a trap

size[8] Tsettrap[1] tag[4] ctlid[8] bytes[]
size[8] Rsettrap[1] tag[4] tid[8]

The settrap sets a breakpoint trap. Details are encoded in the system-specific bytes operand.

The tid operand of the reply is a server-chosen identifier for the trap. This identifier is used in subsequent Aevent messages to identify the trap. The trap identifier name space is local to each control target. Targets derived from existing targets (e.g., via fork or clone) inherit the trace mode of their parent.

On x86-linux-2012, the format of the bytes operand is:

mode[8] addr[8]

The addr field is the address of the trap.

The mode field is a bitmask with the following bits:

		0  action      - snap=1, stop=0

Action specifies the action performed when the trap occurs. When set to stop, the target is stopped and an Aevent reporting the trap is sent to the client. When set to snap, the target is momentarily stopped for a snapshot, then it is resumed and an Aevent reporting the trap is sent to the client.

On x86-win-2012, the format of the bytes operand is identical to that of x86-linux-2012, but the snap action is not yet implemented.

clrtrap – clear a trap

size[8] Tclrtrap[1] tag[4] id[8] tid[8]
size[8] Rclrtrap[1] tag[4]

The clrtrap request clears the previously set trap tid from control target ctlid.

event – notify client of event

size[8] Aevent[1] tag[4] bytes[]

The event message is sent from servers to clients to notify the client that a traced event has occurred in one of its targets.

The tag operand is undefined: the event message is an asynchronous notification, not a reply to a previous request.

Bytes contains a system- and event-dependent description of the event.

On x86-linux-2012, the bytes operand begins with two fields:

ctlid[8] flags[8]

Ctlid is the target in which the event occurred. Flags is a bitmask indicating which event occurred. The flags of the bitmask are the same as those used in the flags of the settrace request. Only one event is reported per event message.

The format of the rest of bytes depends on the event:

Esyscall

The format is:

ctx[]
The target is stopped with context ctx.

Etrap

The format is:

tid[8] ctx[]
Tid is a trap identifier returned by settrap. The target is stopped with context ctx.

Esnap

The format is:

tid[8] spwnid[8] ctx[]
Tid is a trap identifier returned by settrap. Spwnid is a control target identifier for the snapshot. Ctx is the context of the target at the instant of the snapshot. The original target is resumed.

Efork, Eclone

The format is:

spwnid[8] ctx[] spwnctx[]
Spwnid is the identifier for the new control target snapshot. Ctx is the context of the target at the instant of the fork or clone; spwnctx is the context of the new target. The original target and the new target are both stopped.

Eexec

The format is:

ctx[]
The target is stopped, with context ctx, just before execution of the first instruction of the new program image. All traps in the target are cleared. The set of traced events is unchanged.

Eexit

The format is:

status[8] ctx[]
The target has finished executing, exiting with status status. The target is stopped, with context ctx. No futher execution can occur.

Esignal

The format is:

ctx[]
The target is stopped, with context ctx, just before delivery of the signal.

Eload, Eunload

The format is:

nl[8] nl * (path[s] base[8]) ctx[]
The target is stopped with context ctx. Nl binaries have been loaded (unloaded). Each pair path, base specifies the name and base address of one of the libraries.

On x86-win-2012, the bytes operand has the same format and semantics as on x86-linux-2012, except for the following differences:

getctx – get target context

size[8] Tgetctx[1] tag[4] ctlid[8]
size[8] Rgetctx[1] tag[4] ctx[]

The getctx request retrieves the current context of the control target ctlid, which must be stopped.

setctx – set target context

size[8] Tsetctx[1] tag[4] id[8] ctx[]
size[8] Rsetctx[1] tag[4]

The setctx request replaces the context of the control target ctlid with ctx. The target must be stopped.

read – read target resource

size[8] Tread[1] tag[4] ctlid[8] fd[8] offset[8] cnt[8]
size[8] Rread[1] tag[4] bytes[]

The read request retrieves a sequence of bytes from a resource associated with the control target ctlid.

The fd operand identifies the resource. The only currently defined fd value is (uint64)-1, which references the address space of the target.

The offset operand specifies the starting offset in bytes of the access.

The cnt operand specifies the number of bytes to be read, which are returned in the bytes operands of the reply. Fewer bytes than requested may be returned.

write – write target resource

size[8] Twrite[1] tag[4] id[8] fd[8] offset[8] bytes[]
size[8] Rwrite[1] tag[4] cnt[8]

The write request writes a sequence of bytes to a resource associated with the control target ctlid.

The fd operand identifies the resource. The only currently defined fd value is (uint64)-1, which references the address space of the target.

The offset operand specifies the starting offset in bytes of the access.

The bytes operand contains the bytes to be written. The cnt operand of the reply indicates the number of bytes successfully written.

names – bind name space

size[8] Tnames[1] tag[4] path[s]
size[8] Rnames[1] tag[4] nsid[8]

The names request establishes a binding for the name space associated with the binary named path. The nsid operand of the reply is the resulting name space identifier.

looksym – look-up symbol

size[8] Tlooksym[1] tag[4] nsid[8] name[s]
size[8] Rlooksym[1] tag[4] sym[]

The looksym request returns the definition of the symbol name in name space nsid. The format of the symbol definition sym is:

name[s] flags[1] val[8] attrs[] size[8] tname[]

Name is the name of the symbol. Flags is a bitmask indicating properties of the symbol:

		1  Sundef    - symbol is undefined
		2  Sdata     - symbol is data
		3  Stext     - symbol is text
		4  Sro       - symbol is read-only
		5  Senum     - symbol is an enumeration constant
		6  Sinline   - symbol is declared inline

Val is the value of the symbol: for enumeration constants, the value of the constant; for all other symbols, the location of the object named by the symbol.

Size is the size in bytes of the object named by the symbol (for enumeration constants, this operand is present but not meaningful).

Tname is the name of the type of the symbol.

enumsym – enumerate symbols

size[8] Tenumsym[1] tag[4] nsid[8]
size[8] Renumsym[1] tag[4] syms[]

The enumsym request returns the definitions of all symbols in name space nsid. The format of the syms operand of the response is:

ns[8] ns*sym[]

Ns is the number of symbols defined, and each sym is a symbol definition in the format returned by looksym.

enumloc – enumerate locals

size[8] Tenumloc[1] tag[4] nsid[8] addr[8]
size[8] Renumloc[1] tag[4] bytes[]

The enumloc request returns descriptions of the local variables, including any parameters to the currently active function, defined at the program counter addr in the name space. The bytes of the response have the format:

nl[8] nl*loc[]

Nl is the number of local variables. Each local variable description loc has the following format:

id[s] tname[] kind[1] lexpr[]

Id is the name of the local variable. Tname is the name of its type. Vkind specifies whether the local is a local variable (0) or parameter (1).

Lexpr is an expression that evaluates to a specification of the location of the variable, as follows (yes, this specification is confusing):

Lreg[1] no[1]

Specifies that the value is stored in register no. Register numbering is target-dependent.

Lderef[1] lexpr[]

Specifies that the value of the local expression lexpr is the address of the value.

Ladd[1] lexpr1[] lexpr2[]
Lsub[1] lexpr1[] lexpr2[]

Specifies that value is the sum (Ladd) or difference (Lsub) of the local expressions lexpr1 and lexpr2.

Lulit[1] v[8]
Lslit[1] v[8]

Specifies that the value is the literal v interpreted as either an unsigned (Lulit) or signed (Lslit) integer.

looktype – look-up type

size[8] Tlooktype[1] tag[4] nsid[8] tname[]
size[8] Rlooktype[1] tag[4] tdef[]

The looktype request returns the definition of the type named tname in the name space nsid. Servers are expected to provide definitions only for base type names (Tbase), tagged type names (Tstruct, Tunion, Tenum), and typedef type names (Ttypedef). Clients should resolve pointer, array, and function types by stripping these type modifiers and asking for the underlying type name.

The tdef operand of the response is the type definition.

enumtype – enumerate types

size[8] Tenumtype[1] tag[4] nsid[8]
size[8] Renumtype[1] tag[4] tdefs[]

The enumsym request returns the definitions of all symbols in name space nsid. The format of the tdefs operand of the response is:

nt[8] nt*tdef[]

Nt is the number of types defined, and each tdef is a type definition.

lookaddr – look-up address

size[8] Tlookaddr[1] tag[4] nsid[8] addr[8]
size[8] Rlookaddr[1] tag[4] sym[]

The lookaddr request returns a symbol associated with the address addr in the name space nsid.

The response is the symbol sym in nsid, in the format of the looksym response, whose address is the greatest address equal to or less than addr. If more than one such symbol is defined, an arbitrary one is returned. In any case, only a symbol corrresponding to a location (not an enumeration constant) is returned.

unwind1 – unwind one stack frame

size[8] Tunwind1[1] tag[4] nsid[8] addr[8]
size[8] Runwind1[1] tag[4] rules[]

The unwind1 request returns a set of unwind rules specifying how to unwind the call frame at the program counter addr in an execution of the binary nsid.

The rules specify the construction of a new context representing the previous frame. Evaluation of the rules may depend on values of the input context as well as other values in the address space of the target. The unwind1 form allow the client to control the access to these values during evaluation of the unwind rules.

The format of rules is based on the encoding of unwind rules specified by DWARF:

nr[8] nr*(kind[1] reg[8] no[8])

Each rule comprises a triple of integer values, including a rule instruction kind, and two operands, reg and no. These correspond to a commonly employed subset of the unwind rule instructions and operands defined by DWARF (see section 6.4 of the DWARF version 3 specification). We anticipate that the representation and interpretation of the rules will change; users wishing to understand the current format should examine the source code for an existing client.

looksrc – look-up source information

size[8] Tlooksrc[1] tag[4] nsid[8] addr[8]
size[8] Rlooksrc[1] tag[4] file[s] line[4] col[4]

The looksrc request returns source coordinates for the program counter addr in an execution of the binary nsid.

File is the name of the source file, line is the line number within the file, and col is the column number within the line.

lookpc – look-up program counter

size[8] Tlookpc[1] tag[4] nsid[8] file[s] line[4]
size[8] Rlookpc[1] tag[4] addr[8]

The lookpc request returns a program counter value corresponding to the source coordinates file and line in an execution of the binary nsid.

Addr is the program counter value.

Encodings

This section gives the encodings for all named constants in the sctl protocol.

enum Mkind {
	Rerror = 1,
	Aevent = 3,
	Tversion = 4,
	Rversion = 5,
	Tping = 6,
	Rping = 7,
	Tps = 8,
	Rps = 9,
	Tlaunch = 10,
	Rlaunch = 11,
	Tattach = 12,
	Rattach = 13,
	Tstat = 14,
	Rstat = 15,
	Tcont = 16,
	Rcont = 17,
	Tstop = 18,
	Rstop = 19,
	Tstep = 20,
	Rstep = 21,
	Tsnap = 22,
	Rsnap = 23,
	Tkill = 24,
	Rkill = 25,
	Tdetach = 26,
	Rdetach = 27,
	Ttrace = 28,
	Rtrace = 29,
	Tsettrap = 30,
	Rsettrap = 31,
	Tclrtrap = 32,
	Rclrtrap = 33,
	Tgetctx = 34,
	Rgetctx = 35,
	Tsetctx = 36,
	Rsetctx = 37,
	Tread = 38,
	Rread = 39,
	Twrite = 40,
	Rwrite = 41,
	Tlooksym = 42,
	Rlooksym = 43,
	Tenumsym = 44,
	Renumsym = 45,
	Tlooktype = 46,
	Rlooktype = 47,
	Tenumtype = 48,
	Renumtype = 49,
	Tlookaddr = 50,
	Rlookaddr = 51,
	Tenumloc = 52,
	Renumloc = 53,
	Tunwind = 54,
	Runwind = 55,
	Tenumseg = 56,
	Renumseg = 57,
	Tnames = 58,
	Rnames = 59,
	Tunwind1 = 60,
	Runwind1 = 61,
	Tlooksrc = 62,
	Rlooksrc = 63,
	Tlookpc = 64,
	Rlookpc = 65,
};

enum Evkind {
	Eclear = 0,
	Eset = 1,
	Esyscall = 2,
	Eexec = 4,
	Efork = 8,
	Eclone = 16,
	Esignal = 32,
	Eexit = 64,
	Etrap = 128,
	Esnap = 256,
	Estepctx = 512,
	Eload = 1024,
	Eunload = 2048,
};

enum Tkind {
	Tvoid = 0,
	Tbase = 1,
	Tstruct = 2,
	Tunion = 3,
	Tenum = 4,
	Tptr = 5,
	Tarr = 6,
	Tfun = 7,
	Ttypedef = 8,
	Tbitfield = 9,
	Tconst = 10,
	Txaccess = 11,
	Tundef = 12,
};

enum Cbase {
	Vundef = 0,
	Vlo = 1,
	Vbool = 1,
	Vchar = 2,
	Vshort = 3,
	Vint = 4,
	Vlong = 5,
	Vvlong = 6,
	Vuchar = 7,
	Vushort = 8,
	Vuint = 9,
	Vulong = 10,
	Vuvlong = 11,
	Vfloat = 12,
	Vdouble = 13,
	Vlongdouble = 14,
	Vcomplex = 15,
	Vdoublex = 16,
	Vlongdoublex = 17,
	Vnbase = 18,
	Vptr = 18,
	Vvoid = 19,
	Vnallbase = 20,
};

enum Rkind {
	Rundef = 0,
	Ru08le = 1,
	Ru16le = 2,
	Ru32le = 3,
	Ru64le = 4,
	Rs08le = 5,
	Rs16le = 6,
	Rs32le = 7,
	Rs64le = 8,
	Ru08be = 9,
	Ru16be = 10,
	Ru32be = 11,
	Ru64be = 12,
	Rs08be = 13,
	Rs16be = 14,
	Rs32be = 15,
	Rs64be = 16,
	Rf32 = 17,
	Rf64 = 18,
	Rf96 = 19,
	Rf128 = 20,
	Rx64 = 21,
	Rx128 = 22,
	Rx192 = 23,
	Rnrep = 24,
};

enum Stype {
	Sundef = 1,
	Sdata = 2,
	Stext = 4,
	Sro = 8,
	Senum = 16,
	Sinline = 32,
};

enum Lkind {
	Lreg = 0,
	Lderef = 1,
	Ladd = 2,
	Lsub = 3,
	Lulit = 4,
	Lslit = 5,
};

enum Vkind {
	Vlocal = 0,
	Vparam = 1,
};

enum Rulekind {
	Rnone = 0,
	Rcfaro = 1,
	Rcfae = 2,
	Rsame = 3,
	Roff = 4,
	Rvoff = 5,
	Rreg = 6,
	Rexp = 7,
	Rvexp = 8,
};

enum Attrval {
	Astr = 0,
	Acid = 1,
	Auint = 2,
};