xref: /plan9/sys/doc/libmach.ms (revision f4cfa7261087fc6c730458a9637a27e8dcf71546)
1.HTML "Adding Application Support for a New Architecture in Plan 9
2.TL
3Adding Application Support for a New Architecture in Plan 9
4.AU
5Bob Flandrena
6bobf@plan9.bell-labs.com
7.SH
8Introduction
9.LP
10Plan 9 has five classes of architecture-dependent software:
11headers, kernels, compilers and loaders, the
12.CW libc
13system library, and a few application programs.  In general,
14architecture-dependent programs
15consist of a portable part shared by all architectures and a
16processor-specific portion for each supported architecture.
17The portable code is often compiled and stored in a library
18associated with
19each architecture.  A program is built by
20compiling the architecture-specific code and loading it with the
21library.  Support for a new architecture is provided
22by building a compiler for the architecture, using it to
23compile the portable code into libraries,
24writing the architecture-specific code, and
25then loading that code with
26the libraries.
27.LP
28This document describes the organization of the architecture-dependent
29code and headers on Plan 9.
30The first section briefly discusses the layout of
31the headers and the source code for the kernels, compilers, loaders, and the
32system library,
33.CW libc .
34The second section provides a detailed
35discussion of the structure of
36.CW libmach ,
37a library containing almost
38all architecture-dependent code
39used by application programs.
40The final section describes the steps required to add
41application program support for a new architecture.
42.SH
43Directory Structure
44.PP
45Architecture-dependent information for the new processor
46is stored in the directory tree rooted at \f(CW/\fP\fIm\fP
47where
48.I m
49is the name of the new architecture (e.g.,
50.CW mips ).
51The new directory should be initialized with several important
52subdirectories, notably
53.CW bin ,
54.CW include ,
55and
56.CW lib .
57The directory tree of an existing architecture
58serves as a good model for the new tree.
59The architecture-dependent
60.CW mkfile
61must be stored in the newly created root directory
62for the architecture.  It is easiest to copy the
63mkfile for an existing architecture and modify
64it for the new architecture.  When the mkfile
65is correct, change the
66.CW OS
67and
68.CW CPUS
69variables in the
70.CW /sys/src/mkfile.proto
71to reflect the addition of the new architecture.
72.SH
73Headers
74.LP
75Architecture-dependent headers are stored in directory
76.CW /\fIm\fP/include
77where
78.I m
79is the name of the architecture (e.g.,
80.CW mips ).
81Two header files are required:
82.CW u.h
83and
84.CW ureg.h .
85The first defines fundamental data types,
86bit settings for the floating point
87status and control registers, and
88.CW va_list
89processing which depends on the stack
90model for the architecture.  This file
91is best built by copying and modifying the
92.CW u.h
93file from an architecture
94with a similar stack model.
95The
96.CW ureg.h
97file
98contains a structure describing the layout
99of the saved register set for
100the architecture; it is defined by the kernel.
101.LP
102Header file
103.CW /sys/include/a.out.h
104contains the definitions of the magic
105numbers used to identify executables for
106each architecture.  When support for a new
107architecture is added, the magic number
108for the architecture must be added to this file.
109.LP
110The header format of a bootable executable is defined by
111each manufacturer.  Header file
112.CW /sys/include/bootexec.h
113contains structures describing the headers currently
114supported.  If the new architecture uses a common header
115such as COFF,
116the header format is probably already defined,
117but if the bootable header format is non-standard,
118a structure defining the format must be added to this file.
119.LP
120.SH
121Kernel
122.LP
123Although the kernel depends critically on the properties of the underlying
124hardware, most of the
125higher-level kernel functions, including process
126management, paging, pseudo-devices, and some
127networking code, are independent of processor
128architecture.  The portable kernel code
129is divided into two parts: that implementing kernel
130functions and that devoted to the boot process.
131Code in the first class is stored in directory
132.CW /sys/src/9/port
133and the portable boot code is stored in
134.CW /sys/src/9/boot .
135Architecture-dependent kernel code is stored in the
136subdirectories of
137.CW /sys/src/9
138named for each architecture.
139.LP
140The relationship between the kernel code and the boot code
141is convoluted and subtle.  The portable boot code
142is compiled into a library for each architecture.  An architecture-specific
143main program is loaded with the appropriate library and the resulting
144executable is compiled into the kernel where it is executed as
145a user process during the final stages of kernel initialization.  The boot process
146performs authentication, attaches the name space root to the appropriate
147file system and starts the
148.CW init
149process.
150.LP
151The organization of the portable kernel source code differs from that
152of most other architecture-specific code.
153Instead of storing the portable code in a library
154and loading it with the architecture-specific
155code, the portable code is compiled directly into
156the directory containing the architecture-specific code
157and linked with the object files built from the source in that directory.
158.LP
159.SH
160Compilers and Loaders
161.LP
162The compiler source code conforms to the usual
163organization: portable code is compiled into a library
164for each architecture
165and the architecture-dependent code is loaded with
166that library.
167The common compiler code is stored in
168.CW /sys/src/cmd/cc .
169The
170.CW mkfile
171in this directory compiles the portable source and
172archives the objects in a library for each architecture.
173The architecture-specific compiler source
174is stored in a subdirectory of
175.CW /sys/src/cmd
176with the same name as the compiler (e.g.,
177.CW /sys/src/cmd/vc ).
178.LP
179There is no portable code shared by the loaders.
180Each directory of loader source
181code is self-contained, except for
182a header file and an instruction name table
183included from the
184directory of the associated
185compiler.
186.LP
187.SH
188Libraries
189.LP
190Most C library modules are
191portable; the source code is stored in
192directories
193.CW /sys/src/libc/port
194and
195.CW /sys/src/libc/9sys .
196Architecture-dependent library code
197is stored in the subdirectory of
198.CW /sys/src/libc
199named the same as the target processor.
200Non-portable functions not only
201implement architecture-dependent operations
202but also supply assembly language implementations
203of functions where speed is critical.
204Directory
205.CW /sys/src/libc/9syscall
206is unusual because it
207contains architecture-dependent information
208for all architectures.
209It holds only a header file defining
210the names and numbers of system calls
211and a
212.CW mkfile .
213The
214.CW mkfile
215executes an
216.CW rc
217script that parses the header file, constructs
218assembler language functions implementing the system
219call for each architecture, assembles the code,
220and archives the object files in
221.CW libc .
222The assembler language syntax and the system interface
223differ for each architecture.
224The
225.CW rc
226script in this
227.CW mkfile
228must be modified to support a new architecture.
229.LP
230.SH
231Applications
232.LP
233Application programs process two forms of architecture-dependent
234information: executable images and intermediate object files.
235Almost all processing is on executable files.
236System library
237.CW libmach
238provides functions that convert
239architecture-specific data
240to a portable format so application programs
241can process this data independent of its
242underlying representation.
243Further, when a new architecture is implemented
244almost all code changes
245are confined to the library;
246most affected application programs need only be reloaded.
247The source code for the library is stored in
248.CW /sys/src/libmach .
249.LP
250An application program running on one type of
251processor must be able to interpret
252architecture-dependent information for all
253supported processors.
254For example, a debugger must be able to debug
255the executables of
256all architectures, not just the
257architecture on which it is executing, since
258.CW /proc
259may be imported from a different machine.
260.LP
261A small part of the application library
262provides functions to
263extract symbol references from object files.
264The remainder provides the following processing
265of executable files or memory images:
266.IP \(bu
267Header interpretation.
268.IP \(bu
269Symbol table interpretation.
270.IP \(bu
271Execution context interpretation, such as stack traces
272and stack frame location.
273.IP \(bu
274Instruction interpretation including disassembly and
275instruction size and follow-set calculations.
276.IP \(bu
277Exception and floating point number interpretation.
278.IP \(bu
279Architecture-independent read and write access through a
280relocation map.
281.LP
282Header file
283.CW /sys/include/mach.h
284defines the interfaces to the
285application library.  Manual pages
286.I mach (2),
287.I symbol (2),
288and
289.I object (2)
290describe the details of the
291library functions.
292.LP
293Two data structures, called
294.CW Mach
295and
296.CW Machdata ,
297contain architecture-dependent  parameters and
298a jump table of functions.
299Global variables
300.CW mach
301and
302.CW machdata
303point to the
304.CW Mach
305and
306.CW Machdata
307data structures associated with the target architecture.
308An application determines the target architecture of
309a file or executable image, sets the global pointers
310to the data structures associated with that architecture,
311and subsequently performs all references indirectly through the
312pointers.
313As a result, direct references to the tables for each
314architecture are avoided and the application code intrinsically
315supports all architectures (though only one at a time).
316.LP
317Object file processing is handled similarly: architecture-dependent
318functions identify and
319decode the intermediate files for the processor.
320The application indirectly
321invokes a classification function to identify
322the architecture of the object code and to select the
323appropriate decoding function.  Subsequent calls
324then use that function to decode each record.  Again,
325the layer of indirection allows the application code
326to support all architectures without modification.
327.LP
328Splitting the architecture-dependent information
329between the
330.CW Mach
331and
332.CW Machdata
333data structures
334allows applications to choose
335an appropriate level of service.  Even though an application
336does not directly reference the architecture-specific data structures,
337it must load the
338architecture-dependent tables and code
339for all architectures it supports.  The size of this data
340can be substantial and many applications do not require
341the full range of architecture-dependent functionality.
342For example, the
343.CW size
344command does not require the disassemblers for every architecture;
345it only needs to decode the header.
346The
347.CW Mach
348data structure contains a few architecture-specific parameters
349and a description of the processor register set.
350The size of the structure
351varies with the size of the register
352set but is generally small.
353The
354.CW Machdata
355data structure contains
356a jump table of architecture-dependent functions;
357the amount of code and data referenced by this table
358is usually large.
359.SH
360Libmach Source Code Organization
361.LP
362The
363.CW libmach
364library provides four classes of functionality:
365.LP
366.IP "Header and Symbol Table Decoding\ -\ "
367Files
368.CW executable.c
369and
370.CW sym.c
371contain code to interpret the header and
372symbol tables of
373an executable file or executing image.
374Function
375.CW crackhdr
376decodes the header,
377reformats the
378information into an
379.CW Fhdr
380data structure, and points
381global variable
382.CW mach
383to the
384.CW Mach
385data structure of the target architecture.
386The symbol table processing
387uses the data in the
388.CW Fhdr
389structure to decode the symbol table.
390A variety of symbol table access functions then support
391queries on the reformatted table.
392.IP "Debugger Support\ -\ "
393Files named
394.CW \fIm\fP.c ,
395where
396.I m
397is the code letter assigned to the architecture,
398contain the initialized
399.CW Mach
400data structure and the definition of the register
401set for each architecture.
402Architecture-specific debugger support functions and
403an initialized
404.CW Machdata
405structure are stored in
406files named
407.CW \fIm\fPdb.c .
408Files
409.CW machdata.c
410and
411.CW setmach.c
412contain debugger support functions shared
413by multiple architectures.
414.IP "Architecture-Independent Access\ -\ "
415Files
416.CW map.c ,
417.CW access.c ,
418and
419.CW swap.c
420provide accesses through a relocation map
421to data in an executable file or executing image.
422Byte-swapping is performed as needed.  Global variables
423.CW mach
424and
425.CW machdata
426must point to the
427.CW Mach
428and
429.CW Machdata
430data structures of the target architecture.
431.IP "Object File Interpretation\ -\ "
432These files contain functions to identify the
433target architecture of an
434intermediate object file
435and extract references to symbols.  File
436.CW obj.c
437contains code common to all architectures;
438file
439.CW \fIm\fPobj.c
440contains the architecture-specific source code
441for the machine with code character
442.I m .
443.LP
444The
445.CW Machdata
446data structure is primarily a jump
447table of architecture-dependent debugger support
448functions. Functions select the
449.CW Machdata
450structure for a target architecture based
451on the value of the
452.CW type
453code in the
454.CW Fhdr
455structure or the name of the architecture.
456The jump table provides functions to swap bytes, interpret
457machine instructions,
458perform stack
459traces, find stack frames, format floating point
460numbers, and decode machine exceptions.  Some functions, such as
461machine exception decoding, are idiosyncratic and must be
462supplied for each architecture.  Others depend
463on the compiler run-time model and several
464architectures may share code common to a model.  For
465example, many architectures share the code to
466process the fixed-frame stack model implemented by
467several of the compilers.
468Finally, some
469functions, such as byte-swapping, provide a general capability and
470the jump table need only select an implementation appropriate
471to the architecture.
472.LP
473.SH
474Adding Application Support for a New Architecture
475.LP
476This section describes the
477steps required to add application-level
478support for a new architecture.
479We assume
480the kernel, compilers, loaders and system libraries
481for the new architecture are already in place.  This
482implies that a code-character has been assigned and
483that the architecture-specific headers have been
484updated.
485With the exception of two programs,
486application-level changes are confined to header
487files and the source code in
488.CW /sys/src/libmach .
489.LP
490.IP 1.
491Begin by updating the application library
492header file in
493.CW /sys/include/mach.h .
494Add the following symbolic codes to the
495.CW enum
496statement near the beginning of the file:
497.RS
498.IP \(bu
499The processor type code, e.g.,
500.CW MSPARC .
501.IP \(bu
502The type of the executable.  There are usually
503two codes needed: one for a bootable
504executable (i.e., a kernel) and one for an
505application executable.
506.IP \(bu
507The disassembler type code.  Add one entry for
508each supported disassembler for the architecture.
509.IP \(bu
510A symbolic code for the object file.
511.RE
512.LP
513.IP 2.
514In a file name
515.CW /sys/src/libmach/\fIm\fP.c
516(where
517.I m
518is the identifier character assigned to the architecture),
519initialize
520.CW Reglist
521and
522.CW Mach
523data structures with values defining
524the register set and various system parameters.
525The source file for a similar architecture
526can serve as template.
527Most of the fields of the
528.CW Mach
529data structure are obvious
530but a few require further explanation.
531.RS
532.IP "\f(CWkbase\fP\ -\ "
533This field
534contains the address of the kernel
535.CW ublock .
536The debuggers
537assume the first entry of the kernel
538.CW ublock
539points to the
540.CW Proc
541structure for a kernel thread.
542.IP "\f(CWktmask\fP\ -\ "
543This field
544is a bit mask used to calculate the kernel text address from
545the kernel
546.CW ublock
547address.
548The first page of the
549kernel text segment is calculated by
550ANDing
551the negation of this mask with
552.CW kbase .
553.IP "\f(CWkspoff\fP\ -\ "
554This field
555contains the byte offset in the
556.CW Proc
557data structure to the saved kernel
558stack pointer for a suspended kernel thread.  This
559is the offset to the
560.CW sched.sp
561field of a
562.CW Proc
563table entry.
564.IP "\f(CWkpcoff\fP\ -\ "
565This field contains the byte offset into the
566.CW Proc
567data structure
568of
569the program counter of a suspended kernel thread.
570This is the offset to
571field
572.CW sched.pc
573in that structure.
574.IP "\f(CWkspdelta\fP and \f(CWkpcdelta\fP\ -\ "
575These fields
576contain corrections to be added to
577the stack pointer and program counter, respectively,
578to properly locate the stack and next
579instruction of a kernel thread.  These
580values bias the saved registers retrieved
581from the
582.CW Label
583structure named
584.CW sched
585in the
586.CW Proc
587data structure.
588Most architectures require no bias
589and these fields contain zeros.
590.IP "\f(CWscalloff\fP\ -\ "
591This field
592contains the byte offset of the
593.CW scallnr
594field in the
595.CW ublock
596data structure associated with a process.
597The
598.CW scallnr
599field contains the number of the
600last system call executed by the process.
601The location of the field varies depending on
602the size of the floating point register set
603which precedes it in the
604.CW ublock .
605.RE
606.LP
607.IP 3.
608Add an entry to the initialization of the
609.CW ExecTable
610data structure at the beginning of file
611.CW /sys/src/libmach/executable.c .
612Most architectures
613require two entries: one for
614a normal executable and
615one for a bootable
616image.  Each table entry contains:
617.RS
618.IP \(bu
619Magic Number\ \-\
620The big-endian magic number assigned to the architecture in
621.CW /sys/include/a.out.h .
622.IP \(bu
623Name\ \-\
624A string describing the executable.
625.IP \(bu
626Executable type code\ \-\
627The executable code assigned in
628.CW /sys/include/mach.h .
629.IP \(bu
630\f(CWMach\fP pointer\ \-\
631The address of the initialized
632.CW Mach
633data structure constructed in Step 2.
634You must also add the name of this table to the
635list of
636.CW Mach
637table definitions immediately preceding the
638.CW ExecTable
639initialization.
640.IP \(bu
641Header size\ \-\
642The number of bytes in the executable file header.
643The size of a normal executable header is always
644.CW sizeof(Exec) .
645The size of a bootable header is
646determined by the size of the structure
647for the architecture defined in
648.CW /sys/include/bootexec.h .
649.IP \(bu
650Byte-swapping function\ \-\
651The address of
652.CW beswal
653or
654.CW leswal
655for big-endian and little-endian
656architectures, respectively.
657.IP \(bu
658Decoder function\ -\
659The address of a function to decode the header.
660Function
661.CW adotout
662decodes the common header shared by all normal
663(i.e., non-bootable) executable files.
664The header format of bootable
665executable files is defined by the manufacturer and
666a custom function is almost always
667required to decode it.
668Header file
669.CW /sys/include/bootexec.h
670contains data structures defining the bootable
671headers for all architectures.  If the new architecture
672uses an existing format, the appropriate
673decoding function should already be in
674.CW executable.c .
675If the header format is unique, then
676a new function must be added to this file.
677Usually the decoding function for an existing
678architecture can be adopted with minor modifications.
679.RE
680.LP
681.IP 4.
682Write an object file parser and
683store it in file
684.CW /sys/src/libmach/\fIm\fPobj.c
685where
686.I m
687is the identifier character assigned to the architecture.
688Two functions are required: a predicate to identify an
689object file for the architecture and a function to extract
690symbol references from the object code.
691The object code format is obscure but
692it is often possible to adopt the
693code of an existing architecture
694with minor modifications.
695When these
696functions are in hand, insert their addresses
697in the jump table at the beginning of file
698.CW /sys/src/libmach/obj.c .
699.LP
700.IP 5.
701Implement the required debugger support functions and
702initialize the parameters and jump table of the
703.CW Machdata
704data structure for the architecture.
705This code is conventionally stored in
706a file named
707.CW /sys/src/libmach/\fIm\fPdb.c
708where
709.I m
710is the identifier character assigned to the architecture.
711The fields of the
712.CW Machdata
713structure are:
714.RS
715.IP "\f(CWbpinst\fP and \f(CWbpsize\fP\ -\ "
716These fields
717contain the breakpoint instruction and the size
718of the instruction, respectively.
719.IP "\f(CWswab\fP\ -\ "
720This field
721contains the address of a function to
722byte-swap a 16-bit value.  Choose
723.CW leswab
724or
725.CW beswab
726for little-endian or big-endian architectures, respectively.
727.IP "\f(CWswal\fP\ -\ "
728This field
729contains the address of a function to
730byte-swap a 32-bit value.  Choose
731.CW leswal
732or
733.CW beswal
734for little-endian or big-endian architectures, respectively.
735.IP "\f(CWctrace\fP\ -\ "
736This field
737contains the address of a function to perform a
738C-language stack trace.  Two general trace functions,
739.CW risctrace
740and
741.CW cisctrace ,
742traverse fixed-frame and relative-frame stacks,
743respectively.  If the compiler for the
744new architecture conforms to one of
745these models, select the appropriate function.  If the
746stack model is unique,
747supply a custom stack trace function.
748.IP "\f(CWfindframe\fP\ -\ "
749This field
750contains the address of a function to locate the stack
751frame associated with a text address.
752Generic functions
753.CW riscframe
754and
755.CW ciscframe
756process fixed-frame and relative-frame stack
757models.
758.IP "\f(CWufixup\fP\ -\ "
759This field
760contains the address of a function to adjust
761the base address of the register save area.
762Currently, only the
76368020 requires this bias
764to offset over the active
765exception frame.
766.IP "\f(CWexcep\fP\ -\ "
767This field
768contains the address of a function to produce a
769text
770string describing the
771current exception.
772Each architecture stores exception
773information uniquely, so this code must always be supplied.
774.IP "\f(CWbpfix\fP\ -\ "
775This field
776contains the address of a function to adjust an
777address prior to laying down a breakpoint.
778.IP "\f(CWsftos\fP\ -\ "
779This field
780contains the address of a function to convert a single
781precision floating point value
782to a string.  Choose
783.CW leieeesftos
784for little-endian
785or
786.CW beieeesftos
787for big-endian architectures.
788.IP "\f(CWdftos\fP\ -\ "
789This field
790contains the address of a function to convert a double
791precision floating point value
792to a string.  Choose
793.CW leieeedftos
794for little-endian
795or
796.CW beieeedftos
797for big-endian architectures.
798.IP "\f(CWfoll\fP, \f(CWdas\fP, \f(CWhexinst\fP, and \f(CWinstsize\fP\ -\ "
799These fields point to functions that interpret machine
800instructions.
801They rely on disassembly of the instruction
802and are unique to each architecture.
803.CW Foll
804calculates the follow set of an instruction.
805.CW Das
806disassembles a machine instruction to assembly language.
807.CW Hexinst
808formats a machine instruction as a text
809string of
810hexadecimal digits.
811.CW Instsize
812calculates the size in bytes, of an instruction.
813Once the disassembler is written, the other functions
814can usually be implemented as trivial extensions of it.
815.LP
816It is possible to provide support for a new architecture
817incrementally by filling the jump table entries
818of the
819.CW Machdata
820structure as code is written.  In general, if
821a jump table entry contains a zero, application
822programs requiring that function will issue an
823error message instead of attempting to
824call the function.  For example,
825the
826.CW foll ,
827.CW das ,
828.CW hexinst ,
829and
830.CW instsize
831jump table slots can be zeroed until a
832disassembler is written.
833Other capabilities, such as
834stack trace or variable inspection,
835can be supplied and will be available to
836the debuggers but attempts to use the
837disassembler will result in an error message.
838.RE
839.IP 6.
840Update the table named
841.CW machines
842near the beginning of
843.CW /sys/src/libmach/setmach.c .
844This table binds the
845file type code and machine name to the
846.CW Mach
847and
848.CW Machdata
849structures of an architecture.
850The names of the initialized
851.CW Mach
852and
853.CW Machdata
854structures built in steps 2 and 5
855must be added to the list of
856structure definitions immediately
857preceding the table initialization.
858If both Plan 9 and
859native disassembly are supported, add
860an entry for each disassembler to the table.  The
861entry for the default disassembler (usually
862Plan 9) must be first.
863.IP 7.
864Add an entry describing the architecture to
865the table named
866.CW trans
867near the end of
868.CW /sys/src/cmd/prof.c .
869.RE
870.IP 8.
871Add an entry describing the architecture to
872the table named
873.CW objtype
874near the start of
875.CW /sys/src/cmd/pcc.c .
876.RE
877.IP 9.
878Recompile and install
879all application programs that include header file
880.CW mach.h
881and load with
882.CW libmach.a .
883