henesyinit from p9f47575dc5 years agoHistory
183 lines · 8.4 KB · Text
RawDownload
  		Adding a new machine type to plan 9 applications Some commands contain machinbe-dependent code: db, file and size parsethe contents of an a.out header; nm and rl depend on the a.out fileheader and the machine-dependent encoding of object files.  A new processortype is added by adding entries to tables in a couple of files in thisdirectory and subdirectory "lib". Each architecture requires at least two pieces of code: a disassemblerand an object file parser.  Some code for each may be borrowed fromexisting processors but in general, this code is unique to each machine.Additionally, a new processor may require some special code for such thingsas parsing the bootable executable header (this is defined by the manufacturer),traversing the run-time stack frames (compiler-dependent), accessingspecial registers, etc.  Often these types of functions tend to fall intoone or two classes based on processor type (RISC or CISC), and it is usuallypossible to reuse code for an existing architecture. The disassembler must supply three entry points: print a disassembledinstruction; print the hexadecimal representation of an instruction;and calculate the follow set of an instruction.  All three functionstake a pc as an argument. The object code parser must supply two entry points: one to identifyan object file for the target architecture from the first 8 bytesof the file and one to extract symbol definition andsymbol reference information from the object file.  Usually the name,type, and address (if known) of a symbol is sufficient.  Once again,much of this code can be adapted from that of other architectures. Given these pieces, the following steps install support for anew architecture. General Processor-dependent Services Code to parse executable headers, symbol tables, and enforce byte-orderingconstraints is stored in directory /sys/src/cmd/db/lib.  It makes alibrary per executable type named libmach.<code>.a in that directory, where<code> is the code for the processor type.  All processor-dependentapplications link against these libraries.  Header files mach.h and obj.hdefine data structures used for cracking executables and object files,respectively. The Mach data structure contains general processor parameters; the Machdatadata structure contains debugger-specific information and a jump tableto functions providing several processor-dependent services used by the debugger. To add a new processor type, perform the following steps in the libsubdirectory: 	1. Add symbolic names for the new architecture in the enum at		the beginning of header mach.h.  Required symbols include		codes identifying the architecture, the a.out and bootable images,		and a type code for at least one disassembler.	2. Define the register set information for the processor then initialize a		Mach data structure.  By convention, this initialization is		stored in a C source file named after the processor code		(e.g., v.c for mips, k.c for sparc.c, 2.c for 68020.c,etc.).	3. Add two entries to table exectab in file executable.c describing the		decoding of the executable file header for the architecture.		One entry controls the decoding of application executable		images (a.out) and the other applies to bootable images.	4. If the processor has a unique bootable image format, add		the name of the typedef describing the image, found in		/sys/include/bootexec.h, to the union in structure		ExecHdr in file executable.c.	5. Add the names of the functions that identify and crack an object		file to the table named obj in file obj.c.  These functions		are conventionally stored in a file named after the code for		the architecture followed by "obj", e.g., vobj.c, kobj.c,		2obj.c.	6. Add the new files to the mkfile.  Do a "mk installall". Debugger Processor-dependent Services Add the new processor type to the debugger by performing the following stepsin directory /sys/src/cmd/db: 	1. Initialize a Machdata structure describing the debugger-specific		information and the jump table of machine specific services.		By convention, this table is initialized in a file named		<machine-name>db.c; e.g., 68020db.c for the 68020, mipsdb.c		for the mips, sparcdb.c for the sparc.  Any special code		needed to support the debugger is usually stored in this		file.  The disassembler associated with a machine type is		conventionally stored in a file named <machine-name>das.c;		e.g., 68020das.c, mipsdas.c. 	2. Add an entry to the tables named "machines" at the start of source		file machine.c.  This table relates a machine code or machine		name to the proper Mach and Machdata tables and also selects		the appropriate disassembler type for machines with multiple		disassembly formats. 	3. Add the names of the new files to the mkfile. 	4. Do a "mk installall". Other applications with processor-dependent code All other applications load processor-dependent code from the machine-dependentlibrary.  They only need to be reloaded. 	1. cd /sys/src/cmd; mk size.installall file.installall 	2. cd /sys/src/cmd/nm; mk installall Special helpful notes for initializing the data structures. 1. Processor-specific data initialization	Most of the fields of the Mach data structure are self-explanatory	or can be inferred from the initialization tables of currently	supported processors.  See files 2.c, 8.c, v.c, k.c or 6.c in	/sys/src/cmd/db/lib for examples. 2. The Machdata structure contains pointers to functions	providing machine-specific services.  Some functions are	unique for each architecture while others are shared.  Among the	latter are: 	A. The short and long byte order conversion functions always select	   functions beswab and beswal or leswab and leswal for big-endian	   and little-endian processors, respectively.	B. Function ctrace provides a C back trace appropriate for most CISC	   processors.  Functions mipsctrace or hobbitctrace are suitable	   for many RISC architectures.	C. Functions findframe and mipsfindframe locate stack frames	   for CISC and RISC architectures, respectively.	D. Functions rsnarf4 and rrest4 are usually suitable for	   retrieving and storing registers, respectively.	E. Functions beieeesfpout and beieeedfpout or leieeesfpout and	   leieeedfpout are usually suitable for printing single and	   double precision IEEE floating point numbers in big endian and	   little endian representation, respectively.  If your processor	   does not use IEEE representation, custom formatting functions	   are required. 	Services to print a single instruction, calculate the follow set,	print the floating point registers, and print an exception description	are almost always unique.  A linkage to an initialization function is	provided, but seldom needed. 2. The executable decoding table	This table is initialized in file executable.c and contains two entries for	each processor: one describing the header for an application	executable (an "a.out") and one describing the header for a bootable image.	Each entry contains: 	A. The magic number (always specified in big endian form).	B. A string describing the image.	C. The internal type code of the machine, from mach.h.	D. The address of the Mach structure for the architecture.	E. The size of the header.  For application executables this	   is always sizeof(Exec), where Exec is defined in a.out.h.	F. The address of a long-word byte swapping function: this is either	   beswal or leswal for bootable files for big endian or little	   endian architectures.  Application executable headers ("a.out") 	   are always big endian.	G. The address of a function to parse the header into an Fhdr structure.	   Function adotout is usually suitable for all executables, but the	   headers of bootable images are defined by the manufacturers, are	   mutually inconsistent, and must be custom parsed for each architecture. 3. The debugger decoding table 	This table is used to select a machine-dependent debugging environment,	either by name or by executable image type code.  The "machines" table,	stored in file /sys/src/cmd/db/machine.c, pulls together the information	required to construct the environment.  Each entry contains: 	A. A string describing the name of the processor. 	B. The type code of an a.out executable for the architecture. 	C. The type code of a bootable executable for the architecture. 	D. The assembler type code associated with the architecture. 	E. The address of the Mach data structure for the processor. 	F. The address of the Machdata data structure for the processor.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t