MACH-MAP(3)

NAME
allocmap, addseg, findseg, addrtoseg, addrtosegafter, removeseg, freemap, get1, get2, get4, get8, put1, put2, put4, put8, rget1, rget2, rget4, rget8, rput1, rput2, rput4, rput8, locaddr, locconst, locreg, locindir, loccmp, loceval, locfmt, locredir, lget1, lget2, lget4, lget8, lput1, lput2, lput4, lput8 - machine-independent access to address spaces and register sets

SYNOPSIS
#include <u.h>
#include <libc.h>
#include <mach.h>

typedef struct Map Map;
typedef struct Seg Seg;

struct Seg
{
	char	*name;
	char	*file;
	int	fd;
	ulong	base;
	ulong	size;
	ulong	offset;
	int	(*rw)(Map*, Seg*, ulong, void*, uint, int);
};

struct Map
{
	Seg	*seg;
	int	nseg;
	...
};

Map	*allocmap(void)
int	addseg(Map *map, Seg seg)
int	findseg(Map *map, char *name, char *file)
int	addrtoseg(Map *map, ulong addr, Seg *seg)
int	addrtosegafter(Map *map, ulong addr, Seg *seg)
void	removeseg(Map *map, int i)
void	freemap(Map *map)

int	get1(Map *map, ulong addr, uchar *a, uint n)
int	get2(Map *map, ulong addr, u16int *u)
int	get4(Map *map, ulong addr, u32int *u)
int	get8(Map *map, ulong addr, u64int *u)

int	put1(Map *map, ulong addr, uchar *a, uint n)
int	put2(Map *map, ulong addr, u16int u)
int	put4(Map *map, ulong addr, u32int u)
int	put8(Map *map, ulong addr, u64int u)

int	rget1(Map *map, char *reg, u8int *u)
int	rget2(Map *map, char *reg, u16int *u)
int	rget4(Map *map, char *reg, u32int *u)
int	rget8(Map *map, char *reg, u64int *u)
int	fpformat(Map *map, char *reg, char *a, uint n, char code);

int	rput1(Map *map, char *reg, u8int u)
int	rput2(Map *map, char *reg, u16int u)
int	rput4(Map *map, char *reg, u32int u)
int	rput8(Map *map, char *reg, u64int u)

Loc	locaddr(ulong addr)
Loc	locconst(ulong con)
Loc	locreg(char *reg)
Loc	locindir(char *reg, long offset)

int	loccmp(Loc *a, Loc *b)
int	loceval(Map *map, Loc loc, ulong *addr)
int	locfmt(Fmt *fmt)
int	locredir(Map *map, Loc *regs, Loc loc, Loc *newloc)

int	lget1(Map *map, Loc loc, uchar *a, uint n)
int	lget2(Map *map, Loc loc, u16int *u)
int	lget4(Map *map, Loc loc, u32int *u)
int	lget8(Map *map, Loc loc, u64int *u)

int	lput1(Map *map, Loc loc, uchar *a, uint n)
int	lput2(Map *map, Loc loc, u16int u)
int	lput4(Map *map, Loc loc, u32int u)
int	lput8(Map *map, Loc loc, u64int u)

DESCRIPTION
These functions provide a processor-independent interface for accessing executable files, core files, and running processes via maps, data structures that provides access to an address space and register set. The functions described in mach-file(3) are typically used to construct these maps. Related library functions described in mach-symbol(3) provide similar access to symbol tables.

Each map comprises an optional register set and one or more segments, each associating a non-overlapping range of memory addresses with a logical section of an executable file or of a running process's address space. Other library functions then use a map and the architecture-specific data structures to provide a generic interface to the processor-dependent data.

Each segment has a name (e.g., text or data) and may be associated with a particular file. A segment represents a range of accessible address space. Segments may be backed an arbitary access function (if the rw pointer is non-nil), or by the contents of an open file (using the fd file descriptor). Each range has a starting address in the space (base) and an extent (size). In segments mapped by files, the range begins at byte offset in the file. The rw function is most commonly used to provide access to executing processes via ptrace(2) and to zeroed segments.

Allocmap creates an empty map; freemap frees a map.

Addseg adds the given segment to the map, resizing the map's seg array if necessary. A negative return value indicates an allocation error.

Findseg returns the index of the segment with the given name (and, if file is non-nil, the given file), or -1 if no such segment is found.

Addrtoseg returns the index of the segment containing for the given address, or -1 if that address is not mapped. Segments may have overlapping address ranges: addseg appends segments to the end of the seg array in the map, and addrtoseg searches the map backwards from the end, so the most recently mapped segment wins.

Addrtosegafter returns the index of the segment containing the lowest mapped address greater than addr.

Removeseg removes the segment at the given index.

Get1, get2, get4, and get8 retrieve the data stored at address addr in the address space associated with map. Get1 retrieves n bytes of data beginning at addr into buf. Get2, get4 and get8 retrieve 16-bit, 32-bit and 64-bit values respectively, into the location pointed to by u. The value is byte-swapped if the source byte order differs from that of the current architecture. This implies that the value returned by get2, get4, and get8 may not be the same as the byte sequences returned by get1 when n is two, four or eight; the former may be byte-swapped, the latter reflects the byte order of the target architecture. These functions return the number of bytes read or a -1 when there is an error.

Put1, put2, put4, and put8 write to the address space associated with map. The address is translated using the map parameters and multi-byte quantities are byte-swapped, if necessary, before they are written. Put1 transfers n bytes stored at buf; put2, put4, and put8 write the 16-bit, 32-bit or 64-bit quantity contained in val, respectively. The number of bytes transferred is returned. A -1 return value indicates an error.

When representing core files or running programs, maps also provide access to the register set. Rget1, rget2, rget4, rget8, rput1, rput2, rput4, and rput8 read or write the 1-, 2-, 4-, or 8-byte register named by reg. If the register is not the requested size, the behavior is undefined.

Fpformat converts the contents of a floating-point register to a string. Buf is the address of a buffer of n bytes to hold the resulting string. Code must be either or selecting double or single precision, respectively. If code is the contents of the specified register and the following register are interpreted as a double-precision floating-point number; this is meaningful only for architectures that implement double-precision floats by combining adjacent single-precision registers.

A location represents a place in an executing image capable of storing a value. Note that locations are typically passed by value rather than by reference.

Locnone returns an unreadable, unwritable location. Locaddr returns a location representing the memory address addr. Locreg returns a location representing the register reg. Locindir returns an location representing the memory address at offset added to the value of reg. Locconst returns an imaginary unwritable location holding the constant con; such locations are useful for passing specific constants to functions expect locations, such as unwind (see mach-stack(3)).

Loccmp compares two locations, returning negative, zero, or positive values if *a is less than, equal to, or greater than *b, respectively. Register locations are ordered before memory addresses, which are ordered before indirections.

Locfmt is a print(3)-verb that formats a Loc structure (not a pointer to one).

Indirection locations are needed in some contexts (e.g., when using findlsym (see mach-symbol(3))), but bothersome in most. Locsimplify rewrites indirections as absolute memory addresses, by evaluating the register using the given map and adding the offset.

The functions lget1, lget2, lget4, lget8, lput1, lput2, lput4, and lput8 read and write the given locations, using the get, put, rget, and rput function families as necessary.

SOURCE
/usr/local/plan9/src/libmach

SEE ALSO
mach(3), mach-file(3)

DIAGNOSTICS
These routines set errstr.