MACH(2)                                                   MACH(2)

          crackhdr, machbytype, machbyname, newmap, setmap, findseg,
          unusemap, loadmap, attachproc, get1, get2, get4, get8, geta,
          put1, put2, put4, put8, puta beswab, beswal, beswav, leswab,
          leswal, leswav - machine-independent access to executable

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

          int crackhdr(int fd, Fhdr *fp)

          void machbytype(int type)

          int machbyname(char *name)

          Map *newmap(Map *map, int n)

          int setmap(Map *map, int fd, uvlong base, uvlong end,

                      vlong foffset, char *name)

          int findseg(Map *map, char *name)

          void unusemap(Map *map, int seg)

          Map *loadmap(Map *map, int fd, Fhdr *fp)

          Map *attachproc(int pid, int kflag, int corefd, Fhdr *fp)

          int get1(Map *map, uvlong addr, uchar *buf, int n)

          int get2(Map *map, uvlong addr, ushort *val)

          int get4(Map *map, uvlong addr, ulong *val)

          int get8(Map *map, uvlong addr, uvlong *val)

          int geta(Map *map, uvlong addr, uvlong *val)

          int put1(Map *map, uvlong addr, uchar *buf, int n)

          int put2(Map *map, uvlong addr, ushort val)

          int put4(Map *map, uvlong addr, ulong val)

          int put8(Map *map, uvlong addr, uvlong val)

     Page 1                       Plan 9             (printed 7/22/24)

     MACH(2)                                                   MACH(2)

          int puta(Map *map, uvlong addr, uvlong val)

          ushort beswab(ushort val)

          ulong beswal(ulong val)

          uvlong beswav(uvlong val)

          ushort leswab(ushort val)

          ulong leswal(ulong val)

          uvlong leswav(uvlong val)

          extern Mach mach;

          extern Machdata machdata;

          These functions provide a processor-independent interface
          for accessing the executable files or executing images of
          all architectures.  Related library functions described in
          symbol(2) and object(2) provide similar access to symbol
          tables and object files.

          An executable is a file containing an executable program or
          the text file of the /proc file system associated with an
          executing process as described in proc(3). After opening an
          executable, an application invokes a library function which
          parses the file header, determines the target architecture
          and initializes data structures with parameters and pointers
          to functions appropriate for that architecture.  Next, the
          application invokes functions to construct one or more maps,
          data structures that translate references in the address
          space of the executable to offsets in the file.  Each map
          comprises one or more segments, each associating a non-
          overlapping range of memory addresses with a logical section
          of the executable.  Other library functions then use a map
          and the architecture-specific data structures to provide a
          generic interface to the processor-dependent data.

          Crackhdr interprets the header of the executable associated
          with the open file descriptor fd. It loads the data struc-
          ture fp with a machine-independent description of the header
          information and points global variable mach to the Mach data
          structure containing processor-dependent parameters of the
          target architecture.

          Machbytype selects architecture-specific data structures and
          parameter values based on the code stored in the field named
          type in the Fhdr data structure.  Machbyname performs the
          same selection based on the name of a processor class; see

     Page 2                       Plan 9             (printed 7/22/24)

     MACH(2)                                                   MACH(2)

          2c(1) for a list of valid names.  Both functions point glo-
          bal variables mach and machdata to the Mach and Machdata
          data structures appropriate for the target architecture and
          load global variable asstype with the proper disassembler
          type code.

          Newmap creates an empty map with n segments.  If map is
          zero, the new map is dynamically allocated, otherwise it is
          assumed to point to an existing dynamically allocated map
          whose size is adjusted, as necessary.  A zero return value
          indicates an allocation error.

          Setmap loads the first unused segment in map with the seg-
          ment mapping parameters.  Fd is an open file descriptor
          associated with an executable.  Base and end contain the
          lowest and highest virtual addresses mapped by the segment.
          Foffset is the offset to the start of the segment in the
          file.  Name is a name to be attached to the segment.

          Findseg returns the index of the segment named name in map.
          A return of -1 indicates that no segment matches name.

          Unusemap marks segment number seg in map map unused.  Other
          segments in the map remain unaffected.

          Loadmap initializes a default map containing segments named
          `text' and `data' that map the instruction and data segments
          of the executable described in the Fhdr structure pointed to
          by fp. Usually that structure was loaded by crackhdr and can
          be passed to this function without modification.  If map is
          non-zero, that map, which must have been dynamically allo-
          cated, is resized to contain two segments; otherwise a new
          map is allocated.  This function returns zero if allocation
          fails.  Loadmap is usually used to build a map for accessing
          a static executable, for example, an executable program

          Attachproc constructs a map for accessing a running process.
          It returns the address of a Map containing segments mapping
          the address space of the running process whose process ID is
          pid.  If kflag is non-zero, the process is assumed to be a
          kernel process.  Corefd is an file descriptor opened to
          /proc/pid/mem.  Fp points to the Fhdr structure describing
          the header of the executable.  For most architectures the
          resulting Map contains four segments named `text', `data',
          `regs' and `fpregs'.  The latter two provide access to the
          general and floating point registers, respectively.  If the
          executable is a kernel process (indicated by a non-zero
          kflag argument), the data segment extends to the maximum
          supported address, currently 0xffffffff, and the register
          sets are read-only.  In user-level programs, the data seg-
          ment extends to the top of the stack or 0x7fffffff if the

     Page 3                       Plan 9             (printed 7/22/24)

     MACH(2)                                                   MACH(2)

          stack top cannot be found, and the register sets are read-
          able and writable.  Attachproc returns zero if it is unable
          to build the map for the specified process.

          Get1, get2, get4, and get8 retrieve the data stored at
          address addr in the executable 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 val. 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.  If the file
          descriptor associated with the applicable segment in map is
          negative, the address itself is placed in the return loca-
          tion.  These functions return the number of bytes read or a
          -1 when there is an error.

          Put1, put2, put4, and put8 write to the executable associ-
          ated 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 num-
          ber of bytes transferred is returned.  A -1 return value
          indicates an error.

          Beswab, beswal, and beswav return the ushort, long, and
          vlong big-endian representation of val, respectively.
          Leswab, leswal, and leswav return the little-endian repre-
          sentation of the ushort, long, and vlong contained in val.


          2c(1), symbol(2), object(2), errstr(2), proc(3), a.out(6)

          These routines set errstr.

     Page 4                       Plan 9             (printed 7/22/24)