--- /dev/null
+.TH KDB 8 "September 21, 2005"
+.hy 0
+.SH NAME
+Built-in Kernel Debugger for Linux - v4.4
+.SH "Overview"
+This document describes the built-in kernel debugger available
+for linux. This debugger allows the programmer to interactively
+examine kernel memory, disassemble kernel functions, set breakpoints
+in the kernel code and display and modify register contents.
+.P
+A symbol table is included in the kernel image and in modules which
+enables all non-stack symbols (including static symbols) to be used as
+arguments to the kernel debugger commands.
+.SH "Getting Started"
+To include the kernel debugger in a linux kernel, use a
+configuration mechanism (e.g. xconfig, menuconfig, et. al.)
+to enable the \fBCONFIG_KDB\fP option. Additionally, for accurate
+stack tracebacks, it is recommended that the \fBCONFIG_FRAME_POINTER\fP
+option be enabled (if present). \fBCONFIG_FRAME_POINTER\fP changes the compiler
+flags so that the frame pointer register will be used as a frame
+pointer rather than a general purpose register.
+.P
+After linux has been configured to include the kernel debugger,
+make a new kernel with the new configuration file (a make clean
+is recommended before making the kernel), and install the kernel
+as normal.
+.P
+You can compile a kernel with kdb support but have kdb off by default,
+select \fBCONFIG_KDB_OFF\fR. Then the user has to explicitly activate
+kdb by booting with the 'kdb=on' flag or, after /proc is mounted, by
+.nf
+ echo "1" > /proc/sys/kernel/kdb
+.fi
+You can also do the reverse, compile a kernel with kdb on and
+deactivate kdb with the boot flag 'kdb=off' or, after /proc is mounted,
+by
+.nf
+ echo "0" > /proc/sys/kernel/kdb
+.fi
+.P
+When booting the new kernel, the 'kdb=early' flag
+may be added after the image name on the boot line to
+force the kernel to stop in the kernel debugger early in the
+kernel initialization process. 'kdb=early' implies 'kdb=on'.
+If the 'kdb=early' flag isn't provided, then kdb will automatically be
+invoked upon system panic or when the \fBPAUSE\fP key is used from the
+keyboard, assuming that kdb is on. Older versions of kdb used just a
+boot flag of 'kdb' to activate kdb early, this is no longer supported.
+.P
+KDB can also be used via the serial port. Set up the system to
+have a serial console (see \fIDocumentation/serial-console.txt\fP), you
+must also have a user space program such as agetty set up to read from
+the serial console.
+The control sequence \fB<esc>KDB\fP on the serial port will cause the
+kernel debugger to be entered, assuming that kdb is on, that some
+program is reading from the serial console, at least one cpu is
+accepting interrupts and the serial console driver is still usable.
+.P
+\fBNote:\fR\ When the serial console sequence consists of multiple
+characters such as <esc>KDB then all but the last character are passed
+through to the application that is reading from the serial console.
+After exiting from kdb, you should use backspace to delete the rest of
+the control sequence.
+.P
+You can boot with kdb activated but without the ability to enter kdb
+via any keyboard sequence.
+In this mode, kdb will only be entered after a system failure.
+Booting with kdb=on-nokey will activate kdb but ignore keyboard
+sequences that would normally drop you into kdb.
+kdb=on-nokey is mainly useful when you are using a PC keyboard and your
+application needs to use the Pause key.
+You can also activate this mode by
+.nf
+ echo "2" > /proc/sys/kernel/kdb
+.fi
+.P
+If the console is sitting on the login prompt when you enter kdb, then
+the login command may switch into upper case mode.
+This is not a kdb bug, it is a "feature" of login - if the userid is
+all upper case then login assumes that you using a TeleType (circa
+1960) which does not have lower case characters.
+Wait 60 seconds for login to timeout and it will switch back to lower
+case mode.
+.P
+\fBNote:\fR\ Your distributor may have chosen a different kdb
+activation sequence for the serial console.
+Consult your distribution documentation.
+.P
+If you have both a keyboard+video and a serial console, you can use
+either for kdb.
+Define both video and serial consoles with boot parameters
+.P
+.nf
+ console=tty0 console=ttyS0,38400
+.fi
+.P
+Any kdb data entered on the keyboard or the serial console will be echoed
+to both.
+.P
+If you are using a USB keyboard then kdb commands cannot be entered
+until the kernel has initialised the USB subsystem and recognised the
+keyboard.
+Using kdb=early with a USB keyboard will not work, the USB subsystem is
+initialised too late.
+.P
+While kdb is active, the keyboard (not serial console) indicators may strobe.
+The caps lock and scroll lock lights will turn on and off, num lock is not used
+because it can confuse laptop keyboards where the numeric keypad is mapped over
+the normal keys.
+On exit from kdb the keyboard indicators will probably be wrong, they will not match the kernel state.
+Pressing caps lock twice should get the indicators back in sync with
+the kernel.
+.SH "Basic Commands"
+There are several categories of commands available to the
+kernel debugger user including commands providing memory
+display and modification, register display and modification,
+instruction disassemble, breakpoints and stack tracebacks.
+Any command can be prefixed with '-' which will cause kdb to ignore any
+errors on that command, this is useful when packaging commands using
+defcmd.
+A line whose first non-space character is '#' is printed and ignored.
+.P
+The following table shows the currently implemented standard commands,
+these are always available. Other commands can be added by extra
+debugging modules, type '?' at the kdb prompt to get a list of all
+available commands.
+.DS
+.TS
+box, center;
+l | l
+l | l.
+Command Description
+_
+bc Clear Breakpoint
+bd Disable Breakpoint
+be Enable Breakpoint
+bl Display breakpoints
+bp Set or Display breakpoint
+bph Set or Display hardware breakpoint
+bpa Set or Display breakpoint globally
+bpha Set or Display hardware breakpoint globally
+bt Stack backtrace for current process
+btp Stack backtrace for specific process
+bta Stack backtrace for all processes
+btc Cycle over all live cpus and backtrace each one
+cpu Display or switch cpus
+dmesg Display system messages
+defcmd Define a command as a set of other commands
+ef Print exception frame
+env Show environment
+go Restart execution
+handlers Control the display of IA64 MCA/INIT handlers
+help Display help message
+id Disassemble Instructions
+kill Send a signal to a process
+ll Follow Linked Lists
+lsmod List loaded modules
+md Display memory contents
+mdWcN Display memory contents with width W and count N.
+mdp Display memory based on a physical address
+mdr Display raw memory contents
+mds Display memory contents symbolically
+mm Modify memory contents, words
+mmW Modify memory contents, bytes
+per_cpu Display per_cpu variables
+pid Change the default process context
+ps Display process status
+reboot Reboot the machine
+rd Display register contents
+rm Modify register contents
+rq Display runqueue for one cpu
+rqa Display runqueue for all cpus
+set Add/change environment variable
+sr Invoke SysReq commands
+ss Single step a cpu
+ssb Single step a cpu until a branch instruction
+stackdepth Print the stack depth for selected processes
+summary Summarize the system
+.TE
+.DE
+.P
+Some commands can be abbreviated, such commands are indicated by a
+non-zero \fIminlen\fP parameter to \fBkdb_register\fP; the value of
+\fIminlen\fP being the minimum length to which the command can be
+abbreviated (for example, the \fBgo\fP command can be abbreviated
+legally to \fBg\fP).
+.P
+If an input string does not match a command in the command table,
+it is treated as an address expression and the corresponding address
+value and nearest symbol are shown.
+.P
+Some of the commands are described here.
+Information on the more complicated commands can be found in the
+appropriate manual pages.
+.TP 8
+cpu
+With no parameters, it lists the available cpus.
+\&'*' after a cpu number indicates a cpu that did not respond to the kdb
+stop signal.
+\&'+' after a cpu number indicates a cpu for which kdb has some data, but
+that cpu is no longer responding to kdb, so you cannot switch to it.
+This could be a cpu that has failed after entering kdb, or the cpu may
+have saved its state for debugging then entered the prom, this is
+normal for an IA64 MCA event.
+\&'I' after a cpu number means that the cpu was idle before it entered
+kdb, it is unlikely to contain any useful data.
+\&'F' after a cpu number means that the cpu is offline.
+There is currenly no way to distinguish between cpus that used to be
+online but are now offline and cpus that were never online, the kernel
+does not maintain the information required to separate those two cases.
+.I cpu
+followed by a number will switch to that cpu, you cannot switch to
+a cpu marked '*', '+' or 'F'.
+This command is only available if the kernel was configured for SMP.
+.TP 8
+dmesg [lines] [adjust]
+Displays the system messages from the kernel buffer.
+If kdb logging is on, it is disabled by dmesg and is left as disabled.
+With no parameters or a zero value for 'lines', dmesg dumps the entire
+kernel buffer.
+If lines is specified and is positive, dmesg dumps the last 'lines'
+from the buffer.
+If lines is specified and is negative, dmesg dumps the first 'lines'
+from the buffer.
+If adjust is specified, adjust the starting point for the lines that
+are printed.
+When 'lines' is positive, move the starting point back by 'adjust'
+lines, when 'lines' is negative, move the starting point forward by
+\&'adjust' lines.
+.I dmesg -100
+will dump 100 lines, from the start of the buffer.
+.I dmesg 100
+will dump 100 lines, starting 100 lines from the end of the buffer,
+.I dmesg 100 100
+will dump 100 lines, starting 200 lines from the end of the buffer.
+.I dmesg -100 100
+will dump 100 lines, starting 100 lines from the start of the buffer.
+.TP 8
+defcmd
+Defines a new command as a set of other commands, all input until
+.I endefcmd
+is saved and executed as a package.
+.I defcmd
+takes three parameters, the command name to be defined and used to
+invoke the package, a quoted string containing the usage text and a
+quoted string containing the help text for the command.
+When using defcmd, it is a good idea to prefix commands that might fail
+with '-', this ignores errors so the following commands are still
+executed.
+For example,
+.P
+.nf
+ defcmd diag "" "Standard diagnostics"
+ set LINES 2000
+ set BTAPROMPT 0
+ -id %eip-0x40
+ -cpu
+ -ps
+ -dmesg 80
+ -bt
+ -bta
+ endefcmd
+.fi
+.P
+When used with no parameters, defcmd prints all the defined commands.
+.TP 8
+go
+Continue normal execution.
+Active breakpoints are reestablished and the processor(s) allowed to
+run normally.
+To continue at a specific address, use
+.I rm
+to change the instruction pointer then go.
+.TP 8
+handlers
+Control the display of IA64 MCA/INIT handlers.
+The IA64 MCA/INIT handlers run on separate tasks.
+During an MCA/INIT event, the active tasks are typically the handlers,
+rather than the original tasks, which is not very useful for debugging.
+By default, KDB hides the MCA/INIT handlers so commands such as ps and
+btc will display the original task.
+You can change this behaviour by using
+.I handlers show
+to display the MCA/INIT handlers instead of the original tasks or use
+.I handlers hide
+(the default) to hide the MCA/INIT handlers and display the original
+tasks.
+.I handlers status
+will list the address of the handler task and the original task for
+each cpu.
+\fBNote:\fR\ If the original task was running in user space or it
+failed any of the MCA/INIT verification tests then there is no original
+task to display.
+In this case, the handler will be displayed even if
+.I handlers hide
+is set and
+.I handlers status
+will not show an original task.
+.TP 8
+id
+Disassemble instructions starting at an address.
+Environment variable IDCOUNT controls how many lines of disassembly
+output the command produces.
+.TP 8
+kill
+Internal command to send a signal (like kill(1)) to a process.
+kill -signal pid.
+.TP 8
+lsmod
+Internal command to list modules.
+This does not use any kernel nor user space services so can be used at any time.
+.TP 8
+per_cpu <variable_name> [<length>] [<cpu>]
+Display the values of a per_cpu variable, the variable_name is
+specified without the \fIper_cpu__\fR prefix.
+Length is the length of the variable, 1-8, if omitted or 0 it defaults
+to the size of the machine's register.
+To display the variable on a specific cpu, the third parameter is the
+cpu number.
+When the third parameter is omitted, the variable's value is printed
+from all cpus, except that zero values are suppressed.
+For each cpu, per_cpu prints the cpu number, the address of the
+variable and its value.
+.TP 8
+pid <number>
+Change the current process context, with no parameters it displays the
+current process.
+The current process is used to display registers, both kernel and user
+space.
+It is also used when dumping user pages.
+.I pid R
+resets to the original process that was running when kdb was entered.
+This command is useful if you have been looking at other processes and/or
+cpus and you want to get back to the original process.
+It does not switch cpus, it only resets the context to the original process.
+.TP 8
+reboot
+Reboot the system, with no attempt to do a clean close down.
+.TP 8
+rq <cpu>
+Display the runqueues for the specified cpu.
+.TP 8
+rqa
+Display the runqueues for all cpus.
+.TP 8
+stackdepth <percentage>
+Print the stack usage for processes using more than the specified
+percentage of their stack.
+If percentage is not supplied, it defaults to 60.
+This command is only implemented on i386 and ia64 architectures,
+patches for other architectures will be gratefully accepted.
+.TP 8
+summary
+Print a summary of the system, including the time (no timezone is
+applied), uname information and various critical system counters.
+.SH INITIAL KDB COMMANDS
+kdb/kdb_cmds is a plain text file where you can define kdb commands
+which are to be issued during kdb_init(). One command per line, blank
+lines are ignored, lines starting with '#' are ignored. kdb_cmds is
+intended for per user customization of kdb, you can use it to set
+environment variables to suit your hardware or to set standard
+breakpoints for the problem you are debugging. This file is converted
+to a small C object, compiled and linked into the kernel. You must
+rebuild and reinstall the kernel after changing kdb_cmds. This file
+will never be shipped with any useful data so you can always override
+it with your local copy. Sample kdb_cmds:
+.P
+.nf
+# Initial commands for kdb, alter to suit your needs.
+# These commands are executed in kdb_init() context, no SMP, no
+# processes. Commands that require process data (including stack or
+# registers) are not reliable this early. set and bp commands should
+# be safe. Global breakpoint commands affect each cpu as it is booted.
+
+set LINES=50
+set MDCOUNT=25
+set RECURSE=1
+bp sys_init_module
+.fi
+.SH INTERRUPTS AND KDB
+When a kdb event occurs, one cpu (the initial cpu) enters kdb state.
+It uses a cross system interrupt to interrupt the
+other cpus and bring them all into kdb state. All cpus run with
+interrupts disabled while they are inside kdb, this prevents most
+external events from disturbing the kernel while kdb is running.
+.B Note:
+Disabled interrupts means that any I/O that relies on interrupts cannot
+proceed while kdb is in control, devices can time out. The clock tick
+is also disabled, machines will lose track of time while they are
+inside kdb.
+.P
+Even with interrupts disabled, some non-maskable interrupt events will
+still occur, these can disturb the kernel while you are debugging it.
+The initial cpu will still accept NMI events, assuming that kdb was not
+entered for an NMI event. Any cpu where you use the SS or SSB commands
+will accept NMI events, even after the instruction has finished and the
+cpu is back in kdb. This is an unavoidable side effect of the fact that
+doing SS[B] requires the cpu to drop all the way out of kdb, including
+exiting from the event that brought the cpu into kdb. Under normal
+circumstances the only NMI event is for the NMI oopser and that is kdb
+aware so it does not disturb the kernel while kdb is running.
+.P
+Sometimes doing SS or SSB on ix86 will allow one interrupt to proceed,
+even though the cpu is disabled for interrupts. I have not been able
+to track this one down but I suspect that the interrupt was pending
+when kdb was entered and it runs when kdb exits through IRET even
+though the popped flags are marked as cli(). If any ix86 hardware
+expert can shed some light on this problem, please notify the kdb
+maintainer.
+.SH RECOVERING FROM KDB ERRORS
+If a kdb command breaks and kdb has enough of a recovery environment
+then kdb will abort the command and drop back into mainline kdb code.
+This means that user written kdb commands can follow bad pointers
+without killing kdb. Ideally all code should verify that data areas
+are valid (using kdb_getarea) before accessing it but lots of calls to
+kdb_getarea can be clumsy.
+.P
+The sparc64 port does not currently provide this error recovery.
+If someone would volunteer to write the necessary longjmp/setjmp
+code, their efforts would be greatly appreciated. In the
+meantime, it is possible for kdb to trigger a panic by accessing
+a bad address.
+.SH DEBUGGING THE DEBUGGER
+kdb has limited support for debugging problems within kdb. If you
+suspect that kdb is failing, you can set environment variable KDBDEBUG
+to a bit pattern which will activate kdb_printf statements within kdb.
+See include/linux/kdb.h, KDB_DEBUG_FLAG_xxx defines. For example
+.nf
+ set KDBDEBUG=0x60
+.fi
+activates the event callbacks into kdb plus state tracing in sections
+of kdb.
+.nf
+ set KDBDEBUG=0x18
+.fi
+gives lots of tracing as kdb tries to decode the process stack.
+.P
+You can also perform one level of recursion in kdb. If environment
+variable RECURSE is not set or is 0 then kdb will either recover from
+an error (if the recovery environment is satisfactory) or kdb will
+allow the error to percolate, usually resulting in a dead system. When
+RECURSE is 1 then kdb will recover from an error or, if there is no
+satisfactory recovery environment, it will drop into kdb state to let
+you diagnose the problem. When RECURSE is 2 then all errors drop into
+kdb state, kdb does not attempt recovery first. Errors while in
+recursive state all drop through, kdb does not even attempt to recover
+from recursive errors.
+.SH KEYBOARD EDITING
+kdb supports a command history, which can be accessed via keyboard
+sequences.
+It supports the special keys on PC keyboards, control characters and
+vt100 sequences on a serial console or a PC keyboard.
+.P
+.DS
+.TS
+box, center;
+l | l | l l | l
+l | l | l l | l.
+PC Special keys Control VT100 key Codes Action
+_
+Backspace ctrl-H Backspace 0x7f Delete character to the left of the cursor
+Delete ctrl-D Delete \\e[3~ Delete character to the right of the cursor
+Home ctrl-A Home \\e[1~ Go to start of line
+End ctrl-E End \\e[4~ Go to end of line
+Up arrow ctrl-P Up arrow \\e[A Up one command in history
+Down arrow ctrl-N Down arrow \\e[B Down one command in history
+Left arrow ctrl-B Left arrow \\e[D Left one character in current command
+Right arrow ctrl-F Right arrow \\e[C Right one character in current command
+.TE
+.DE
+.P
+There is no toggle for insert/replace mode, kdb editing is always in
+insert mode.
+Use delete and backspace to delete characters.
+.P
+kdb also supports tab completion for kernel symbols
+Type the start of a kernel symbol and press tab (ctrl-I) to complete
+the name
+If there is more than one possible match, kdb will append any common
+characters and wait for more input, pressing tab a second time will
+display the possible matches
+The number of matches is limited by environment variable DTABCOUNT,
+with a default of 30 if that variable is not set.
+.SH AUTHORS
+Scott Lurndal, Richard Bass, Scott Foehner, Srinivasa Thirumalachar,
+Masahiro Adegawa, Marc Esipovich, Ted Kline, Steve Lord, Andi Kleen,
+Sonic Zhang.
+.br
+Keith Owens <kaos@sgi.com> - kdb maintainer.
+.SH SEE ALSO
+.P
+linux/Documentation/kdb/kdb_{bp,bt,env,ll,md,ps,rd,sr,ss}.man
--- /dev/null
+.TH BD 1 "July 12, 2004"
+.SH NAME
+bp, bpa, bph, bpha, bd, bc, be, bl \- breakpoint commands
+.SH SYNOPSIS
+bp \fIaddress-expression\fP
+.LP
+bpa \fIaddress-expression\fP
+.LP
+bph \fIaddress-expression\fP [\f(CWDATAR|DATAW|DATAA|IO\fP [\fIlength\fP]]
+.LP
+bpha \fIaddress-expression\fP [\f(CWDATAR|DATAW|DATAA|IO\fP [\fIlength\fP]]
+.LP
+bd \fIbreakpoint-number\fP
+.LP
+bc \fIbreakpoint-number\fP
+.LP
+be \fIbreakpoint-number\fP
+.LP
+bl
+.SH DESCRIPTION
+.hy 0
+The
+.B bp
+family of commands are used to establish a breakpoint.
+The \fIaddress-expression\fP may be a numeric value (decimal or
+hexidecimal), a symbol name, a register name preceeded by a
+percent symbol '%', or a simple expression consisting of a
+symbol name, an addition or subtraction character and a numeric
+value (decimal or hexidecimal).
+.P
+\fBbph\fP and \fBbpha\fP will force the use of a hardware register, provided
+the processor architecture supports them.
+.P
+The \fIaddress-expression\fP may also consist of a single
+asterisk '*' symbol which indicates that the command should
+operate on all existing breakpoints (valid only for \fBbc\fP,
+\fBbd\fP and \fBbe\fP).
+.P
+Four different types of
+breakpoints may be set:
+
+.TP 8
+Instruction
+Causes the kernel debugger to be invoked from the debug exception
+path when an instruction is fetched from the specified address. This
+is the default if no other type of breakpoint is requested or when
+the \fBbp\fP command is used.
+
+.TP 8
+DATAR
+Causes the kernel debugger to be entered when data of length
+\fIlength\fP is read from or written to the specified address.
+This type of breakpoint must use a processor debug register which
+places an architecture dependent limit on the number of data and I/O
+breakpoints that may be established. On arm mode XScale platform
+(thumb mode is not supported yet),
+debugger is triggered by reading from the specified address.
+The \fBbph\fP or \fBbpha\fP commands must be used.
+
+.TP 8
+DATAW
+Enters the kernel debugger when data of length \fIlength\fP
+is written to the specified address. \fIlength\fP defaults
+to four bytes if it is not explicitly specified.
+Note that the processor may have already overwritten the prior data at
+the breakpoint location before the kernel debugger is invoked.
+The prior data should be saved before establishing the breakpoint, if
+required. On arm mode XScale platform, the debugger is triggered
+after having overwritten the specified address.
+The \fBbph\fP or \fBbpha\fP commands must be used.
+
+.TP 8
+IO
+Enters the kernel debugger when an \fBin\fP or \fBout\fP instruction
+targets the specified I/O address. The \fBbph\fP or \fBbpha\fP
+commands must be used. This type of breakpoint is not valid in
+arm mode XScale platform. This option is not valid in arm
+mode XScale platform.
+
+.TP 8
+DATAA
+Enters the kernel debugger after the data in specified address has
+been accessed (read or write), this option is only used in arm
+mode XScale platform.
+
+.P
+The
+.B bpha
+command will establish a breakpoint on all processors in an
+SMP system. This command is not available in an uniprocessor
+kernel.
+.P
+The
+.B bd
+command will disable a breakpoint without removing it from the kernel
+debugger's breakpoint table.
+This can be used to keep breakpoints in the table without exceeding the
+architecture limit on breakpoint registers.
+A breakpoint-number of \fI*\fR will disable all break points.
+.P
+The
+.B be
+command will re-enable a disabled breakpoint.
+A breakpoint-number of \fI*\fR will enable all break points.
+.P
+The
+.B bc
+command will clear a breakpoint from the breakpoint table.
+A breakpoint-number of \fI*\fR will clear all break points.
+.P
+The
+.B bl
+command will list the existing set of breakpoints.
+.SH LIMITATIONS
+There is a compile time limit of sixteen entries in the
+breakpoint table at any one time.
+.P
+There are architecture dependent limits on the number of hardware
+breakpoints that can be set.
+.IP ix86 8
+Four.
+.PD 0
+.IP xscale 8
+Two for insruction breakpoints and another two for data breakpoint.
+.PD 0
+.IP ia64 8
+?
+.PD 0
+.IP sparc64 8
+None.
+.PD 1
+When issuing the "go" command after entering the debugger due to
+a breakpoint, kdb will silently perform a single step in order to
+reapply the breakpoint. The sparc64 port has some limitations on
+single stepping, which may limit where a breakpoint may be safely
+set. Please read the man page for \fBss\fP for more information.
+.SH ENVIRONMENT
+The breakpoint subsystem does not currently use any environment
+variables.
+.SH SMP CONSIDERATIONS
+Using
+.B bc
+is risky on SMP systems.
+If you clear a breakpoint when another cpu has hit that breakpoint but
+has not been processed then it may not be recognised as a kdb
+breakpoint, usually resulting in incorrect program counters and kernel
+panics.
+It is safer to disable the breakpoint with
+.BR bd ,
+then
+.B go
+to let any other processors that are waiting on the breakpoint to
+clear.
+After all processors are clear of the disabled breakpoint then it is
+safe to clear it using
+.BR bc .
+.P
+Breakpoints which use the processor breakpoint registers
+are only established on the processor which is
+currently active. If you wish breakpoints to be universal
+use the
+.B bpa
+or
+.B bpha
+commands.
+.SH EXAMPLES
+.TP 8
+bp schedule
+Sets an instruction breakpoint at the begining of the
+function \fBschedule\fP.
+
+.TP 8
+bp schedule+0x12e
+Sets an instruction breakpoint at the instruction located
+at \fBschedule\fP+\fI0x12e\fP.
+
+.TP 8
+bph ttybuffer+0x24 dataw
+Sets a data write breakpoint at the location referenced by
+\fBttybuffer\fP+\fI0x24\fP for a length of four bytes.
+
+.TP 8
+bph 0xc0254010 datar 1
+Establishes a data reference breakpoint at address \fB0xc0254010\fP
+for a length of one byte.
+
+.TP 8
+bp
+List current breakpoint table.
+
+.TP 8
+bd 0
+Disable breakpoint #0.
+
+.TP 8
+bc *
+Clear all breakpoints
--- /dev/null
+.TH BT 1 "August 25, 2006"
+.SH NAME
+bt \- Stack Traceback command
+.SH SYNOPSIS
+bt [ <stack-frame-address> ]
+.LP
+btp <pid>
+.LP
+btt <struct-task-address>
+.LP
+bta [ DRSTZUIMA ]
+.LP
+btc [<cpu>]
+.SH DESCRIPTION
+.hy 0
+The
+.B bt
+command is used to print a stack traceback. It uses the
+current registers (see \fBrd\fP command) to determine
+the starting context and attempts to provide a complete
+stack traceback for the active thread. If \fIstack-frame-address\fP
+is supplied, it is assumed to point to the start of a valid
+stack frame and the stack will be traced back from that
+point (e.g. on i386 architecture, \fIstack-frame-address\fP
+should be the stack address of a saved \fB%eip\fP value from a \fBcall\fP
+instruction. on sparc64 architecture, it should be a pointer to a
+saved register window, as is found in the \fB%fp\fP register).
+.P
+If present, a kernel configuration option \fBCONFIG_FRAME_POINTER\fP
+should be enabled so that the compiler will utilize the frame pointer
+register properly to maintain a stack which can be correctly
+analyzed. Some architectures (e.g. sparc64) always use
+\fBCONFIG_FRAME_POINTER\fP, and so the option is not present.
+.P
+The \fBbt\fP command will attempt to analyze the stack without
+frame pointers if the \fBCONFIG_FRAME_POINTER\fP option is not
+enabled, but the analysis is difficult and may not produce
+accurate nor complete results.
+.P
+The \fBbtp\fP command will analyze the stack for the given
+process identification (see the \fBps\fP command).
+\fBbtp\fP sets the current process for any following register display or update
+commands.
+.P
+The \fBbtt\fP command will analyze the stack for the given task
+structure.
+It is exactly equivalent to \fBbtp\fR on the pid extracted from the
+task structure.
+\fBbtt\fP sets the current process for any following register display or update
+commands.
+.P
+The \fBbta\fP command lists the stack for all processes in the desired
+state.
+Without any parameters, \fBbta\fP gives a backtrace for all useful processes.
+If a parameter is specified, it is a single string consisting of the
+letters D, R, S, T, Z, U, I, M and A in any order.
+See the kdb \fBps\fR man page for more details.
+\fBbta\fP does not change the current process.
+.P
+The \fBbtc\fP command will analyze the stack for the current process on
+a specified cpu or, if no cpu number is supplied, for the current
+process on all cpus.
+It does not switch to the other cpus, instead it uses the task
+structures to identify and issue \fBbtt\fR against the current task on
+the desired cpus.
+\fBbtc\fP with no arguments does not change the current process.
+\fBbtc\fP with a cpu number sets the current process for any following register
+display or update commands.
+.P
+For each function, the stack trace prints at least two lines.
+The first line contains four or five fields\ :-
+.IP * 3
+The pointer to the previous stack frame, blank if there is no valid
+frame pointer.
+.PD 0
+.IP * 3
+The current address within this frame.
+.IP * 3
+The address converted to a function name (actually the first non-local
+label which is <= the address).
+.IP * 3
+The offset of the address within the function.
+.IP * 3
+Any parameters to the function.
+.PD 1
+.PP
+If environment variable NOSECT is set to 0 then the next line contains
+five fields which are designed to make it easier to match the trace
+against the kernel code\ :-
+.IP * 3
+The module name that contains the address, "kernel" if it is in the
+base kernel.
+.PD 0
+.IP * 3
+The section name that contains the address (not available on 2.6 kernels).
+.IP * 3
+The start address of the section (not available on 2.6 kernels).
+.IP * 3
+The start address of the function.
+.IP * 3
+The end address of the function (the first non-local label which is >
+the address).
+.PD 1
+.PP
+If arguments are being converted to symbols, any argument which
+converts to a kernel or module address is printed as\ :-
+.IP * 3
+Argument address.
+.PD 0
+.IP * 3
+The module name that contains the address, "kernel" if it is in the
+base kernel.
+.IP * 3
+The symbol name the argument maps to.
+.IP * 3
+The offset of the argument from the symbol, suppressed if 0.
+.PD 1
+.P
+On architectures that use nested stacks, the backtrace will indicate a
+switch to a new stack by printing a line of equal signs and the type of
+stack.
+.SH MATCHING TRACE TO KERNEL CODE
+The command "objdump\ -S" will disassemble an object and, if the code
+was compiled with debugging (gcc flag -g), objdump will interleave the
+C source lines with the generated object.
+.PP
+A complete objdump of the kernel or a module is too big, normally you
+only want specific functions.
+By default objdump will only print the .text section but Linux uses
+other section names for executable code.
+When objdump prints relocatable objects (modules) it uses an offset of
+0 which is awkward to relate to the stack trace.
+The five fields which are printed for each function are designed to
+make it easier to match the stack trace against the kernel code using
+"objdump\ -S".
+.PP
+If the function is in the kernel then you need the section name, the
+start and end address of the function. The command is
+.PP
+.nf
+ objdump -S -j <section_name> \\
+ --start-address=<start-address> \\
+ --stop-address=<end-address> \\
+ /usr/src/linux/vmlinux
+.fi
+.PP
+If the function is in a module then you need the section name, the
+start address of the section, the start and end address of the
+function, the module name. The command is
+.PP
+.nf
+ objdump -S -j <section_name> \\
+ --adjust-vma=<section-start> \\
+ --start-address=<start-address> \\
+ --stop-address=<end-address> \\
+ /path/to/module/<module-name>.o
+.fi
+.PP
+Unfortunately the 2.6 kernel does not provide the information required
+to locate the start of the section, which makes it very difficult to
+perform a reliable objdump on a module.
+.PP
+All addresses to objdump must be preceded by '0x' if they are in hex,
+objdump does not assume hex.
+The stack trace values are printed with leading '0x' to make it easy to
+run objdump.
+.SH LIMITATIONS
+If the kernel is compiled without frame pointers, stack tracebacks
+may be incomplete. The \fBmds %esp\fP (i386) or \fBmds %fp\fP (sparc64)
+command may be useful in attemping to determine the actual stack
+traceback manually.
+.P
+A stack trace can be misleading if any code in a function exit has been
+executed, the stack is partially unwound at that stage.
+.P
+The \fBbt\fP command may print more arguments for a function
+than that function accepts; For sparc64, this will always happen
+as the debugger cannot determine the correct number. For i386, this happens
+when the C compiler doesn't immediately pop the arguments off the stack upon
+return from a called function. When this is this case, these extra
+stack words will be considered additional arguments by the \fBbt\fP
+command.
+.SH ENVIRONMENT
+The \fBBTARGS\fP environment variable governs the maximum number
+of arguments that are printed for any single function.
+On IA64 hardware, there is no difference between input and local registers, the
+first \fBBTARGS\fP registers are printed, up to the total limit of input plus
+local registers.
+Use a large value for \fBBTARGS\fP if you want to see the local registers on
+IA64.
+.PP
+If the \fBBTSP\fP environment variable is non-zero then each backtrace frame
+may print an extra line giving information about the stack pointers, this is
+architecture specific.
+.PP
+If the \fBBTSYMARG\fP environment variable is non-zero then any
+arguments that fall within the kernel are converted to symbols.
+.PP
+If the \fBNOSECT\fP environment variable is non-zero then the
+section information is suppressed.
+The default is NOSECT=1 so section data is suppressed; use set\ NOSECT=0
+to see section information.
+.PP
+The \fBBTAPROMPT\fP environment variable controls the prompt after each
+process is listed by the \fBbta\fP command. If \fBBTAPROMPT\fP is not
+set or is non-zero then \fBbta\fP issues a prompt after each process is
+listed. If \fBBTAPROMPT\fP is set to zero then no prompt is issued and
+all processes are listed without human intervention.
+.PP
+\fBbt\fR with no parameters uses the \fBPS\fR environment variable, see
+the kdb \fBps\fR man page.
+.SH SMP CONSIDERATIONS
+None.
+.SH EXAMPLES
+.nf
+.na
+.ft CW
+Entering kdb (0xc3cb4000) due to Breakpoint @ 0xc011725d
+Instruction(i) breakpoint #0 at 0xc011725c
+qm_modules+0xd1: movl %ebp,%esp
+kdb> bt
+ EBP EIP Function(args)
+0xc3cb5f98 0xc011725d qm_modules+0xd1 (0x80721c0, 0x100, 0xbfff5000)
+ kernel .text 0xc0100000 0xc011718c 0xc0117264
+0xc3cb5fbc 0xc0117875 sys_query_module+0x1b1 (0x0, 0x1, 0x80721c0, 0x100, 0xbfff5000)
+ kernel .text 0xc0100000 0xc01176c4 0xc01178e8
+ 0xc01095f8 system_call+0x34
+ kernel .text 0xc0100000 0xc01095c4 0xc01095fc
--- /dev/null
+.TH ENV 1 "24 September 2000"
+.SH NAME
+env, set \- Environment manipulation commands
+.SH SYNOPSIS
+env
+.LP
+set \fIenvironment-variable\fP=\fIvalue\fP
+.SH DESCRIPTION
+The kernel debugger contains an environment which contains a series
+of name-value pairs. Some environment variables are known to the
+various kernel debugger commands and have specific meaning to the
+command; such are enumerated on the respective reference material.
+.P
+Arbitrary environment variables may be created and used with
+many commands (those which require an \fIaddress-expression\fP).
+.P
+The
+.B env
+command is used to display the current environment.
+.P
+The
+.B set
+command is used to alter an existing environment variable or
+establish a new environment variable.
+.SH LIMITATIONS
+There is a compile-time limit of 33 environment variables.
+.P
+There is a compile-time limit of 512 bytes (\fBKDB_ENVBUFSIZE\fP)
+of heap space available for new environment variables and for
+environment variables changed from their compile-time values.
+.SH ENVIRONMENT
+These commands explicitly manipulate the environment.
+.SH SMP CONSIDERATIONS
+None.
+.SH USER SETTINGS
+You can include "set" commands in kdb/kdb_cmds (see kdb.mm) to define
+your environment variables at kernel startup.
+.SH EXAMPLES
+.TP 8
+env
+Display current environment settings.
+
+.TP 8
+set IDCOUNT=100
+Set the number of lines to display for the \fBid\fP command
+to the value \fI100\fP.
--- /dev/null
+.TH LL 1 "19 April 1999"
+.SH NAME
+ll \- Linked List examination
+.SH SYNOPSIS
+ll <addr> <link-offset> <cmd>
+.SH DESCRIPTION
+The
+.B ll
+command is used to execute a single command repetitively for
+each element of a linked list.
+.P
+The command specified by <cmd> will be executed with a single
+argument, the address of the current element.
+.SH LIMITATIONS
+Be careful if using this command recursively.
+.SH ENVIRONMENT
+None.
+.SH SMP CONSIDERATIONS
+None.
+.SH EXAMPLES
+.nf
+.na
+.ft CW
+# cd modules
+# insmod kdbm_vm.o
+# Entering kdb on processor 0 due to PAUSE
+kdb> ps
+Task Addr Pid Parent cpu lcpu Tss Command
+0xc03de000 0000000001 0000000000 0000 0000 0xc03de2d4 init
+0xc0090000 0000000002 0000000001 0000 0000 0xc00902d4 kflushd
+0xc000e000 0000000003 0000000001 0000 0000 0xc000e2d4 kpiod
+0xc000c000 0000000004 0000000001 0000 0000 0xc000c2d4 kswapd
+0xc7de2000 0000000056 0000000001 0000 0000 0xc7de22d4 kerneld
+0xc7d3a000 0000000179 0000000001 0000 0000 0xc7d3a2d4 syslogd
+0xc7a7e000 0000000188 0000000001 0000 0000 0xc7a7e2d4 klogd
+0xc7a04000 0000000199 0000000001 0000 0000 0xc7a042d4 atd
+0xc7b84000 0000000210 0000000001 0000 0000 0xc7b842d4 crond
+0xc79d6000 0000000221 0000000001 0000 0000 0xc79d62d4 portmap
+0xc798e000 0000000232 0000000001 0000 0000 0xc798e2d4 snmpd
+0xc7904000 0000000244 0000000001 0000 0000 0xc79042d4 inetd
+0xc78fc000 0000000255 0000000001 0000 0000 0xc78fc2d4 lpd
+0xc77ec000 0000000270 0000000001 0000 0000 0xc77ec2d4 sendmail
+0xc77b8000 0000000282 0000000001 0000 0000 0xc77b82d4 gpm
+0xc7716000 0000000300 0000000001 0000 0000 0xc77162d4 smbd
+0xc7ee2000 0000000322 0000000001 0000 0000 0xc7ee22d4 mingetty
+0xc7d6e000 0000000323 0000000001 0000 0000 0xc7d6e2d4 login
+0xc778c000 0000000324 0000000001 0000 0000 0xc778c2d4 mingetty
+0xc78b6000 0000000325 0000000001 0000 0000 0xc78b62d4 mingetty
+0xc77e8000 0000000326 0000000001 0000 0000 0xc77e82d4 mingetty
+0xc7708000 0000000327 0000000001 0000 0000 0xc77082d4 mingetty
+0xc770e000 0000000328 0000000001 0000 0000 0xc770e2d4 mingetty
+0xc76b0000 0000000330 0000000001 0000 0000 0xc76b02d4 update
+0xc7592000 0000000331 0000000323 0000 0000 0xc75922d4 ksh
+0xc7546000 0000000338 0000000331 0000 0000 0xc75462d4 su
+0xc74dc000 0000000339 0000000338 0000 0000 0xc74dc2d4 ksh
+kdb> md 0xc74dc2d4
+c74dc2d4: 00000000 c74de000 00000018 00000000 .....`MG........
+c74dc2e4: 00000000 00000000 00000000 074de000 .............`M.
+c74dc2f4: c01123ff 00000000 00000000 00000000 #.@............
+c74dc304: 00000000 00000000 c74dded0 00000000 ........P^MG....
+[omitted]
+c74dc474: 00000000 00000000 00000000 00000000 ................
+c74dc484: 00000000 c7c15d00 c77b0900 c026fbe0 .....]AG..{G`{&@
+c74dc494: 00000000 c76c2000 00000000 00000000 ..... lG........
+c74dc4a4: 00000000 00000000 00000000 c74dc4ac ............,DMG
+kdb> md 0xc026fbe0
+c026fbe0: c0262b60 00000000 c7594940 c74de000 @HYG....@IYG.`MG
+[omitted]
+kdb> md 0xc0262b60
+c0262b60: c0266660 08048000 0804c000 c7bec360 `f&@.....@..`C>G
+kdb> ll c0262b60 12 md
+c0262b60: c0266660 08048000 0804c000 c7bec360 `f&@.....@..`C>G
+c7bec360: c0266660 0804c000 0804d000 c7becb20 `f&@.@...P.. K>G
+c7becb20: c0266660 0804d000 08050000 c7bec3a0 `f&@.P...... C>G
+c7bec3a0: c0266660 40000000 40009000 c7bec420 `f&@...@...@ D>G
+c7bec420: c0266660 40009000 4000b000 c7bec4a0 `f&@...@.0.@ D>G
+c7bec4a0: c0266660 4000b000 40010000 c7bec8e0 `f&@.0.@...@`H>G
+c7bec8e0: c0266660 40010000 400a1000 c7becbe0 `f&@...@...@`K>G
+c7becbe0: c0266660 400a1000 400a8000 c7becc60 `f&@...@...@`L>G
+c7becc60: c0266660 400a8000 400b4000 c7952300 `f&@...@.@.@.#.G
+c7952300: c0266660 400b5000 400bc000 c79521c0 `f&@.P.@.@.@@!.G
+c79521c0: c0266660 400bc000 400bd000 c7bec6e0 `f&@.@.@.P.@`F>G
+c7bec6e0: c0266660 bffff000 c0000000 00000000 `f&@.p?...@....
+kdb>
+kdb> ll c0262b60 12 vm
+struct vm_area_struct at 0xc0262b60 for 56 bytes
+vm_start = 0x8048000 vm_end = 0x804c000
+page_prot = 0x25 avl_height = 2244 vm_offset = 0x0
+flags: READ EXEC MAYREAD MAYWRITE MAYEXEC DENYWRITE EXECUTABLE
+struct vm_area_struct at 0xc7bec360 for 56 bytes
+vm_start = 0x804c000 vm_end = 0x804d000
+page_prot = 0x25 avl_height = -31808 vm_offset = 0x3000
+flags: READ WRITE MAYREAD MAYWRITE MAYEXEC DENYWRITE EXECUTABLE
+struct vm_area_struct at 0xc7becb20 for 56 bytes
+vm_start = 0x804d000 vm_end = 0x8050000
+page_prot = 0x25 avl_height = -28664 vm_offset = 0x0
+flags: READ WRITE EXEC MAYREAD MAYWRITE MAYEXEC
+struct vm_area_struct at 0xc7bec3a0 for 56 bytes
+vm_start = 0x40000000 vm_end = 0x40009000
+page_prot = 0x25 avl_height = 30126 vm_offset = 0x0
+flags: READ EXEC MAYREAD MAYWRITE MAYEXEC DENYWRITE
+struct vm_area_struct at 0xc7bec420 for 56 bytes
+vm_start = 0x40009000 vm_end = 0x4000b000
+page_prot = 0x25 avl_height = 30126 vm_offset = 0x8000
+flags: READ WRITE MAYREAD MAYWRITE MAYEXEC DENYWRITE
+struct vm_area_struct at 0xc7bec4a0 for 56 bytes
+vm_start = 0x4000b000 vm_end = 0x40010000
+page_prot = 0x25 avl_height = 26853 vm_offset = 0x0
+flags: READ MAYREAD MAYWRITE MAYEXEC
+struct vm_area_struct at 0xc7bec8e0 for 56 bytes
+vm_start = 0x40010000 vm_end = 0x400a1000
+page_prot = 0x25 avl_height = 2244 vm_offset = 0x0
+flags: READ EXEC MAYREAD MAYWRITE MAYEXEC
+struct vm_area_struct at 0xc7becbe0 for 56 bytes
+vm_start = 0x400a1000 vm_end = 0x400a8000
+page_prot = 0x25 avl_height = 30126 vm_offset = 0x90000
+flags: READ WRITE MAYREAD MAYWRITE MAYEXEC
+struct vm_area_struct at 0xc7becc60 for 56 bytes
+vm_start = 0x400a8000 vm_end = 0x400b4000
+page_prot = 0x25 avl_height = 2244 vm_offset = 0x0
+flags: READ WRITE MAYREAD MAYWRITE MAYEXEC
+struct vm_area_struct at 0xc7952300 for 56 bytes
+vm_start = 0x400b5000 vm_end = 0x400bc000
+page_prot = 0x25 avl_height = 30126 vm_offset = 0x0
+flags: READ EXEC MAYREAD MAYWRITE MAYEXEC
+struct vm_area_struct at 0xc79521c0 for 56 bytes
+vm_start = 0x400bc000 vm_end = 0x400bd000
+page_prot = 0x25 avl_height = -16344 vm_offset = 0x6000
+flags: READ WRITE MAYREAD MAYWRITE MAYEXEC
+struct vm_area_struct at 0xc7bec6e0 for 56 bytes
+vm_start = 0xbffff000 vm_end = 0xc0000000
+page_prot = 0x25 avl_height = 2244 vm_offset = 0x0
+flags: READ WRITE EXEC MAYREAD MAYWRITE MAYEXEC GROWSDOWN
+kdb>
--- /dev/null
+.TH MD 1 "August 4, 2004"
+.SH NAME
+md, mdWcN, mdr, mds, mm, mmW\- Memory manipulation commands
+.SH SYNOPSIS
+md [ \fIaddress-expression\fP [ \fIline-count\fP [\fIoutput-radix\fP ] ] ]
+.LP
+md\fIW\fRc\fIn\fR [ \fIaddress-expression\fP [ \fIline-count\fP [\fIoutput-radix\fP ] ] ]
+.LP
+mdp \fIphysical-address-expression\fP,\fIbytes\fP
+.LP
+mdr \fIaddress-expression\fP,\fIbytes\fP
+.LP
+mds [ \fIaddress-expression\fP [ \fIline-count\fP [\fIoutput-radix\fP ] ] ]
+.LP
+mm \fIaddress-expression\fP \fInew-contents\fP
+.LP
+mm\fIW\fR \fIaddress-expression\fP \fInew-contents\fP
+.SH DESCRIPTION
+The
+.B md
+command is used to display the contents of memory.
+The \fIaddress-expression\fP may be a numeric value (decimal or
+hexidecimal), a symbol name, a register name preceeded by one or more
+percent symbols '%', an environment variable name preceeded by
+a currency symbol '$', or a simple expression consisting of a
+symbol name, an addition or subtraction character and a numeric
+value (decimal or hexidecimal).
+.P
+If an address is specified and the \fIline-count\fP or \fIradix\fP arguments
+are omitted, they default to the values of the \fBMDCOUNT\fP and \fBRADIX\fP
+environment variables respectively. If the \fBMDCOUNT\fP or \fBRADIX\fP
+environment variables are unset, the appropriate defaults will be used [see
+\fBENVIRONMENT\fP below]. If no address is specified then md resumes
+after the last address printed, using the previous values of count and
+radix. The start address is rounded down to a multiple of the
+BYTESPERWORD (md) or width (md\fIW\fR).
+.P
+md uses the current value of environment variable \fBBYTESPERWORD\fP to
+read the data. When reading hardware registers that require special
+widths, it is more convenient to use md\fIW\fRc\fIn\fR where \fIW\fR is
+the width for this command and \fRc\fIn\fR is the number of entries to
+read. For example, md1c20 reads 20 bytes, 1 at a time. To continue
+printing just type md, the width and count apply to following md
+commands with no parameters. \fBNote:\fR The count is the number of
+repeats of the width, unlike MDCOUNT which gives the number of md lines
+to print.
+.P
+The
+.B mdp
+command displays the contents of physical memory, starting at the
+specified physical address for the specified number of bytes.
+The address is preceded by 'phys'.
+.P
+The
+.B mdr
+command displays the raw contents of memory, starting at the specified
+address for the specified number of bytes.
+The data is printed in one line without a leading address and no
+trailing character conversion.
+.B mdr
+is intended for interfacing with external debuggers, it is of little
+use to humans.
+.P
+The
+.B mds
+command displays the contents of memory one word per line and
+attempts to correlate the contents of each word with a symbol
+in the symbol table. If no symbol is found, the ascii representation
+of the word is printed, otherwise the symbol name and offset from
+symbol value are printed.
+By default the section data is printed for kernel symbols.
+.P
+The
+.B mm
+and
+\fBmm\fIW\fR
+commands allow modification of memory. The bytes at the address
+represented by \fIaddress-expression\fP are changed to
+\fInew-contents\fP. \fInew-contents\fP is allowed to be an
+\fIaddress-expression\fP.
+.B mm
+changes a machine word, \fBmm\fIW\fR changes \fIW\fR bytes at that
+address.
+.SH LIMITATIONS
+None.
+.SH ENVIRONMENT
+.TP 8
+MDCOUNT
+This environment variable (default=8) defines the number of lines
+that will be displayed by each invocation of the \fBmd\fP command.
+
+.TP 8
+RADIX
+This environment variable (default=16) defines the radix used to
+print the memory contents.
+
+.TP 8
+BYTESPERWORD
+This environment variable (default=4) selects the width of output
+data when printing memory contents. Select the value two to get
+16-bit word output, select the value one to get byte output.
+
+.TP 8
+LINES
+This environment variable governs the number of lines of output
+that will be presented before the kernel debugger built-in pager
+pauses the output. This variable only affects the functioning
+of the \fBmd\fP and \fBmds\fP if the \fBMDCOUNT\fP variable
+is set to a value greater than the \fBLINES\fP variable.
+
+.TP 8
+NOSECT
+If the \fBNOSECT\fP environment variable is non-zero then the
+section information is suppressed.
+The default is NOSECT=1 so section data is suppressed; use set\ NOSECT=0
+to see section information.
+.SH SMP CONSIDERATIONS
+None.
+.SH EXAMPLES
+.TP 8
+md %edx
+Display memory starting at the address contained in register \fB%edx\fP.
+
+.TP 8
+mds %esp
+Display stack contents symbolically. This command is quite useful
+in manual stack traceback.
+
+.TP 8
+mm 0xc0252110 0x25
+Change the memory location at 0xc0252110 to the value 0x25.
+
+.TP 8
+md chrdev_table 15
+Display 15 lines (at 16 bytes per line) starting at address
+represented by the symbol \fIchrdev_table\fP.
--- /dev/null
+.TH PS 1 "September 14, 2004"
+.SH NAME
+ps \- Display processes
+.SH SYNOPSIS
+ps [ DRSTCZEUIMA ]
+.SH DESCRIPTION
+The
+.B ps
+command displays the status of all processes in the desired state.
+This command does not take any locks (all cpus should be frozen while
+kdb is running) so it can safely be used to debug lock problems with
+the process table.
+.P
+Without any parameters, \fBps\fP displays all the interesting
+processes, excluding idle tasks and sleeping system daemons.
+If a parameter is specified, it is a single string consisting of the
+letters D, R, S, T, C, Z, E, U, I and M, in any order.
+Each letter selects processes in a specific state, when multiple
+letters are specified, a process will be displayed if it is in any of
+the specified states.
+The states are\ :-
+.P
+.DS
+.TS
+box, center;
+l | l
+l | l.
+D Uninterruptible sleep
+R Running
+S Interruptible sleep
+T Stopped
+C Traced
+Z Zombie
+E Dead
+U Unrunnable
+I Idle task
+M Sleeping system daemon
+A All
+.TE
+.DE
+.P
+For state R (running), the process may not be on a cpu at the moment,
+but it is ready to run.
+The header line above the backtrace contains '1' in the fourth field if
+the process is actually on a cpu.
+.P
+The idle task is run on each cpu when there is no work for that cpu to do.
+Unless the idle task is servicing an interrupt, there is no point in
+printing the idle task.
+An idle task that is not servicing a interrupt is marked as state I,
+while servicing an interrupt it is in state R.
+By default, idle tasks are not printed, use \fBps\ I\fR to print them.
+If the idle tasks are not being printed, the start of the \fBps\R
+output contains a list of which cpus are idle.
+.P
+Each cpu has one or more system daemons to handle per cpu work such as
+soft irqs.
+A system daemon (idenified by a NULL mm pointer) that is sleeping is
+marked as state M.
+These processes rarely have any useful data and generate a lot of
+output on large machines, so sleeping system daemons are not printed by
+default.
+Use \fBps\ M\fR to print them.
+.P
+At the start of the \fBps\fR output is a line giving the cpu status,
+see the kdb \fBcpu\fR command.
+.SH LIMITATIONS
+None.
+.SH ENVIRONMENT
+.TP 8
+PS
+This environment variable (default=DRSTCZEU) is used when \fBps\fR
+is issued with no parameters.
+
+.SH SMP CONSIDERATIONS
+None.
+.SH EXAMPLES
+.TP 8
+\fBps\fR
+displays the useful tasks, suppressing idle tasks and sleeping
+system daemons.
+
+.TP 8
+\fBps\ RD\fR
+displays only tasks that are running or are in an uninterruptible
+sleep.
+
+.TP 8
+\fBps\ DRSTCZEUIM\fR
+displays all tasks.
+
+.TP 8
+\fBps\ A\fR
+displays all tasks.
+This is easier than remembering DRSTCZEUIM.
+
--- /dev/null
+.TH RD 1 "September 20, 2005"
+.SH NAME
+rd, rm\- Register manipulation commands
+.SH SYNOPSIS
+rd [[c [n]]|d|u]
+.LP
+rm \fIregister-name\fP \fInew-contents\fP
+.LP
+ef <address>
+.SH DESCRIPTION
+The
+.B rd
+command is used to display the contents of processor and coprocessor registers.
+Without any arguments, the rd command displays the contents of the general
+register set at the point at which the kernel debugger was entered.
+If the bt* or pid commands have been used to change the current process then
+.B rd
+and
+.B rm
+may not be able to display any registers.
+'n' argument is only used for XScale platform to identify the desired
+coprocessor number, while 'd' option is not valid for XScale platform.
+.P
+On IA32 and IA64, with the 'c' argument, the processor control registers
+%cr0, %cr1, %cr2 and %cr4 are displayed, while with the 'd' argument
+the processor debug registers are displayed. If the 'u' argument
+is supplied, the registers for the current task as of the last
+time the current task entered the kernel are displayed.
+.P
+On XScale, 'c' argument is used to display the
+all coprocessor control registers or specified coprocessor registers by
+argumnet 'n'. Argument 'u' is used to display the
+registers for the current task as of the last time the current task
+entered the kernel. Argument 'd' is not supported.
+.P
+On ix86, the
+.B rm
+command allows modification of a register. The following
+register names are valid: \fB%eax\fP, \fB%ebx\fP, \fB%ecx\fP,
+\fB%edx\fP, \fB%esi\fP, \fB%edi\fP, \fB%esp\fP, \fB%eip\fP,
+and \fB%ebp\fP. Note that if two '%' symbols are used
+consecutively, the register set displayed by the 'u' argument
+to the \fBrd\fP command is modified.
+.P
+The debug registers, \fBdr0\fP through \fBdr3\fP and both
+\fBdr6\fP and \fBdr7\fP can also be modified with the \fBrm\fP
+command.
+.P
+On sparc64, the valid registers are named \fB%g0\fP through
+\fB%g7\fP, \fB%l0\fP through \fB%l7\fP, \fB%o0\fP through
+\fB%o7\fP, and \fB%i0\fP through \fB%i7\fP, with the exceptions
+that \fB%o6\fP is called \fB%sp\fP and that \fB%i6\fP is called
+\fB%fp\fP. The registers \fB%tstate\fP, \fB%tpc\fP, \fB%tnpc\fP,
+\fB%y\fP, and \fB%fprs\fP provide state information at the time
+the system entered kdb. Additionally, when viewing registers, two
+convenience names are provided: \fB%®s\fP shows the
+address on the stack of the current registers, and \fB%csp\fP
+shows the current stack pointer within kdb itself.
+.P
+While on XScale, both the cpu registers and most coprocessor
+registers can be be modified. \fIregister-name\fP can be followings like
+r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14,
+r15, cpsr to address cpu registers. For the coprocessor registers in XSacle,
+either alias name or \fICpcc[CRndd[CRmbb[Opaa]]]\fP can be used to address
+the register in coprocessor cc with CRn=dd, CRm=bb and opcode2=aa. All aa, bb, cc, dd can be
+1 or 2 decimal digitals, the default value is 0 when any of them is omitted. Name
+acc0_h and acc0_l are used to identify the high byte and
+low word of accumulator in coprocessor 0.
+.P
+On IA64, the parameter to
+.B rd
+can be d (debug registers), u (user registers at most recent entry to kernel),
+i (interrupt registers), %isr (current interrupt status), s (stacked
+registers), k (kernel registers). You can also specify these individual
+registers -
+psr,
+ifs,
+ip,
+unat,
+pfs,
+rsc,
+rnat,
+bsps,
+pr,
+ldrs,
+ccv,
+fpsr,
+b0,
+b6,
+b7,
+r1,
+r2,
+r3,
+r8,
+r9,
+r10,
+r11,
+r12,
+r13,
+r14,
+r15,
+r16,
+r17,
+r18,
+r19,
+r20,
+r21,
+r22,
+r23,
+r24,
+r25,
+r26,
+r27,
+r28,
+r29,
+r30,
+r31.
+.B rm
+can change any of the individual registers or the stacked registers.
+.P
+The
+.B ef
+command displays an exception frame at the specified address.
+.SH LIMITATIONS
+Currently the \fBrm\fP command will not allow modification of the
+control registers.
+.P
+Currently neither the \fBrd\fP command nor the \fBrm\fP command will
+display or modify the model specific registers on the Pentium
+and Pentium Pro families.
+.SH ENVIRONMENT
+None.
+.SH SMP CONSIDERATIONS
+None.
+.SH EXAMPLES
+.TP 8
+rd
+Display general register set from kdb's current task.
+
+.TP 8
+rd c 0
+Display coprocessor 0 registers.
+
+.TP 8
+rm %eax 0
+Set the contents of \fB%eax\fP to zero. This will be the
+value of %eax when kdb returns from the condition which
+invoked it.
+
+.TP 8
+rm %%eax 0
+Set the value of the \fB%eax\fP register to zero. This will
+be the value the user-mode application will see upon returning
+from the kernel.
+
+.TP 8
+rm %acc0_h 0
+Set the contents of high byte of accumulator to zero.
+
+.TP 8
+rm dr0 0xc1287220
+Set the value of the \fBdr0\fB register to \f(CW0xc1287220\fP.
+
+.TP 8
+rm %InVLD_BTB 0
+Write 0 to coprocessor 15 register with CRn=7, CRm=5, opcode2=6.
+
+.TP 8
+rm %CP15CRn7CRm5Op6 0
+Same with above.
--- /dev/null
+.TH SR 1 "7 October 2002"
+.SH NAME
+sr \- invoke sysrq commands from kdb
+.SH SYNOPSIS
+sr \fIx\fP
+.SH DESCRIPTION
+.hy 0
+The
+.B sr
+command invokes the existing sysrq handler code in the kernel.
+This command takes a single character which is passed to sysrq
+processing, as if you had entered the sysrq key sequence followed by
+that character.
+.P
+.B Caveats:
+.P
+kdb will always call the sysrq code but sysrq may be disabled.
+If you expect to use sysrq functions during debugging then
+.IP ""
+echo "1" > /proc/sys/kernel/sysrq
+.P
+before starting the debug session.
+Alternatively issue
+.IP ""
+mm4 sysrq_enabled 1
+.P
+during debugging.
+.P
+The sysrq code prints a heading using console loglevel 7 then reverts
+to the original loglevel for the rest of the sysrq processing.
+If the rest of the sysrq output is printed at a level below your
+current loglevel then you will not see the output on the kdb console,
+the output will only appear in the printk buffer.
+It is the user's responsibility to set the loglevel correctly if they
+want to see the sysrq output on the console.
+Issue
+.IP ""
+sr 7
+.P
+before any other
+.B sr
+commands if you want to see the output on the console.
+You may even have to adjust the default message loglevel in order to
+see any output from
+.BR sr .
+See Documentation/sysctl/kernel.txt for details on setting console
+loglevels via /proc.
+You can also adjust the loglevel variables via kdb
+.BR mm ;
+on older kernels there are variables such as default_message_level, on
+newer kernels all the loglevel variables are in array console_printk,
+see kernel/printk.c for your kernel.
+.P
+Operations that require interrupt driven I/O can be invoked from kdb
+.BR sr ,
+but they will not do anything until you type 'go' to exit from kdb
+(interrupts are disabled while in kdb).
+There is no guarantee that these operations will work, if the machine
+entered kdb because of an error then interrupt driven I/O may already
+be dead.
+Do not assume that
+.B sr\ s
+does anything useful.
+.P
+The sysrq handler uses locks and calls printk which also uses locks.
+If the sysrq handler or any of the sysrq functions have to wait for a
+lock then they will never return and kdb will appear to hang.
+Invoking sysrq code from kdb is inherently unsafe.
--- /dev/null
+.TH SS 1 "17 January 2002"
+.SH NAME
+ss, ssb \- Single Step
+.SH SYNOPSIS
+ss
+.LP
+ssb
+.SH DESCRIPTION
+The
+.B ss
+command is used to execute a single instruction and return
+to the kernel debugger.
+.P
+Both the instruction that was single-stepped and the next
+instruction to execute are printed.
+.P
+The \fBssb\fP command will execute instructions from the
+current value of the instruction pointer. Each instruction
+may be printed as it is executed, depending upon architecture;
+execution will stop at any instruction which would cause the flow
+of control to change (e.g. branch, call, interrupt instruction,
+return, etc.)
+.SH LIMITATIONS
+On sparc64, there are some circumstances where single-stepping
+can be dangerous. Do not single-step across an instruction which
+changes the interrupt-enable bit in %tstate. Do not single step
+through code which is invoked when entering or leaving the
+kernel, particularly any kernel entry code before %tl is set to
+0, or any kernel exit code after %tl is set to 1.
+.SH ENVIRONMENT
+None.
+.SH SMP CONSIDERATIONS
+Other processors are held in the kernel debugger when the instruction
+is traced. Single stepping though code that requires a lock which is
+in use by another processor is an exercise in futility, it will never
+succeed.
+.SH INTERRUPT CONSIDERATIONS
+When a kdb event occurs, one cpu (the initial cpu) enters kdb state.
+It uses a cross system interrupt to interrupt the
+other cpus and bring them all into kdb state. All cpus run with
+interrupts disabled while they are inside kdb, this prevents most
+external events from disturbing the kernel while kdb is running.
+.B Note:
+Disabled interrupts means that any I/O that relies on interrupts cannot
+proceed while kdb is in control, devices can time out. The clock tick
+is also disabled, machines will lose track of time while they are
+inside kdb.
+.P
+Even with interrupts disabled, some non-maskable interrupt events
+will still occur, these can disturb the kernel while you are
+debugging it. The initial cpu will still accept NMI events,
+assuming that kdb was not entered for an NMI event. Any cpu
+where you use the SS or SSB commands will accept NMI events, even
+after the instruction has finished and the cpu is back in kdb.
+This is an unavoidable side effect of the fact that doing SS[B]
+requires the cpu to drop all the way out of kdb, including
+exiting from the NMI event that brought the cpu into kdb. Under
+normal circumstances the only NMI event is for the NMI oopser and
+that is kdb aware so it does not disturb the kernel while kdb is
+running.
+.P
+Sometimes doing SS or SSB on ix86 will allow one interrupt to proceed,
+even though the cpu is disabled for interrupts. I have not been able
+to track this one down but I suspect that the interrupt was pending
+when kdb was entered and it runs when kdb exits through IRET even
+though the popped flags are marked as cli(). If any ix86 hardware
+expert can shed some light on this problem, please notify the kdb
+maintainer.
+.SH EXAMPLES
+.nf
+.na
+.ft CW
+kdb> bp gendisk_head datar 4
+Data Access Breakpoint #0 at 0xc024ddf4 (gendisk_head) in dr0 is enabled on cpu 0
+for 4 bytes
+kdb> go
+...
+[root@host /root]# cat /proc/partitions
+Entering kdb on processor 0 due to Debug Exception @ 0xc01845e3
+Read/Write breakpoint #0 at 0xc024ddf4
+[0]kdb> ssb
+sd_finish+0x7b: movzbl 0xc02565d4,%edx
+sd_finish+0x82: leal 0xf(%edx),%eax
+sd_finish+0x85: sarl $0x4,%eax
+sd_finish+0x88: movl 0xc0256654,%ecx
+sd_finish+0x8e: leal (%eax,%eax,4),%edx
+sd_finish+0x91: leal (%eax,%edx,2),%edx
+sd_finish+0x94: movl 0xc0251108,%eax
+sd_finish+0x99: movl %eax,0xffffffc(%ecx,%edx,4)
+sd_finish+0x9d: movl %ecx,0xc0251108
+sd_finish+0xa3: xorl %ebx,%ebx
+sd_finish+0xa5: cmpb $0x0,0xc02565d4
+[0]kdb> go
+[root@host /root]#
+
+[0]kdb> ss
+sys_read: pushl %ebp
+SS trap at 0xc01274c1
+sys_read+0x1: movl %esp,%ebp
+[0]kdb> ss
+sys_read+0x1: movl %esp,%ebp
+SS trap at 0xc01274c3
+sys_read+0x3: subl $0xc,%esp
+[0]kdb> ss
+sys_read+0x3: subl $0xc,%esp
+SS trap at 0xc01274c6
+sys_read+0x6: pushl %edi
+[0]kdb>
+
--- /dev/null
+#! /opt/cpg/bin/do-mgp
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%deffont "standard" tfont "comic.ttf"
+%deffont "thick" tfont "arialb.ttf"
+%deffont "typewriter" xfont "courier new-bold-r"
+%deffont "type2writer" xfont "arial narrow-bold-r"
+%%
+%% Default settings per each line numbers.
+%%
+#%default 1 leftfill, size 2, fore "black", back "LemonChiffon2", font "thick"
+%default 1 leftfill, size 2, fore "black", back "white", font "thick"
+%default 2 size 10, vgap 10, prefix " ", center
+%default 3 size 2, bar "gray70", vgap 10
+%default 4 size 6, fore "black", vgap 30, prefix " ", font "standard", left
+%%
+%% Default settings that are applied to TAB-indented lines.
+%%
+%tab 1 size 4, vgap 35, prefix " ", icon arc "red" 40
+%tab 2 size 4, vgap 20, prefix " ", icon delta3 "blue" 40
+%tab 3 size 4, vgap 20, prefix " ", icon delta3 "green" 40
+%%
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+KDB - Kernel Debugger
+
+
+
+%size 7,center, font "thick"
+Introduction
+
+And
+
+Demonstration
+
+
+%size 3
+
+February 5, 2002 IBM Linux Technology Center Paul Dorwin
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+IBM Legal
+
+
+ IBM Legal requires this information:
+
+%size 3
+
+ THE INFORMATION IN THE FOLLOWING PRESENTATION IS PREPARED
+ SOLELY FOR THE INFORMATION OF THE READER, AND COMES "AS IS"
+ AND WITHOUT WARRANTY OR REPRESENATION OF ANY KIND.
+
+ ANY PARTY USING THE MATERIALS IN THIS PRESENTATION DOES SO
+ AT ITS OWN RISK LIABILITY AND THE PROVIDER OF THE MATERIALS
+ ACCEPTS NO RISK OR LIABILITY FOR SUCH USE OR RESULTING FROM
+ DISSEMINATION TO OR USE BY ANY OTHER PARTY
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Agenda
+
+%size 5
+
+ Installing and Configuring KDB
+
+ KDB Commands
+
+ Scull Demo
+
+ Setting Breakpoints
+
+ Displaying Data Structures
+
+ Kernel Data structures
+
+ Take a walk through an IO operation
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Installing Configuring KDB
+
+
+ Install KDB patch.
+ Start with a clean source tree
+ Apply architecture specific patches
+ Obtain patch for your kernel version
+ see http://oss.sgi.com/projects/kdb/
+ Apply the kdb patch
+ patch -p 1 -N -u -i /path/to/patch
+ Apply any other patches
+ Build and reboot on your kdb enabled kernel
+ Man pages can be found at Documentation/kdb
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Configuring KDB
+
+
+ Config kernel with the following options:
+ These are documented in Documentation/Configure.help
+
+ CONFIG_KDB=y
+ Enable compilation of KDB in the kernel..
+ Setting this also sets CONFIG_KALLSYMS=y.
+ CONFIG_KDB_MODULES=n
+ KDB may be extended, compiling kdb/modules.
+ CONFIG_KDB_OFF=n
+ y = KDB is disabled by default.
+ boot with kdb=on to enable at boot.
+ /proc/sys/kernel/kdb to enable/disable when system is up.
+ CONFIG_KALLSYMS=y
+ This causes all symbols to be exported.
+ CONFIG_FRAME_POINTER=y
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Invoking KDB
+
+
+ KDB can be invoked in the following ways:
+
+ Early init with "kdb=early" lilo flag
+ Hits breakpoint prior to fork_init() (init/main.c)
+
+ Serial console with CNTRL-A
+
+ Console with PAUSE key
+
+ When a pre-set breakpoint is hit
+
+ On panic
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+KDB Commands
+
+
+ KDB environment
+ env Show environment variables
+ set Set environment variables
+ help Display Help Message
+ ? Display Help Message
+
+ System related
+ sections List kernel and module sections
+ lsmod List loaded kernel modules
+ reboot Reboot the machine immediately
+ cpu <cpunum> Switch to new cpu
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+KDB Commands
+
+
+ Memory Manipulation
+ md <vaddr> Display Memory Contents
+ mdr <vaddr> <bytes> Display Raw Memory
+ mds <vaddr> Display Symbolically
+ mm <vaddr> <value> Modify Memory Contents
+ id <vaddr> Display Instructions
+
+ Register Manipulation
+ rd Display Registers
+ rm <reg> <value> Modify Registers
+ ef <vaddr> Display exception frame
+
+ Stack
+ bt [<vaddr>] Stack traceback
+ btp <pid> Display stack for <pid>
+ bta Display all stacks
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+KDB Commands
+
+
+ Breakpoint
+ bc <bpnum> Clear Breakpoint
+ bd <bpnum> Disable Breakpoint
+ be <bpnum> Enable Breakpoint
+ bl [<vaddr>] Display breakpoints
+ bp [<vaddr>] Set/Display breakpoints
+ bpa [<vaddr>] Set/Display global breakpoints
+ bph [<vaddr>] Set hardware breakpoint
+ bpha [<vaddr>] Set global hardware breakpoint
+ bp* modifiers:
+ instruction - break on instruction fetch (default)
+ datar - break on read at vaddr
+ dataw - break on write at vaddr
+ IO - break on in or out op at vaddress
+
+ Execution control
+ go [<vaddr>] Continue Execution
+ ss [<#steps>] Single Step
+ ssb Single step to branch/call
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+KDB Commands
+
+
+ Kernel structures
+ ll <vaddr> <offset> <command> Traverse list and execute command
+ ps Display active task list
+ vm <vaddr> Display vm_area_struct
+ dentry <dentry> Display interesting dentry stuff
+ filp <filp> Display interesting filp stuff
+ sh <vaddr> Show scsi_host
+ sd <vaddr> Show scsi_device
+ sc <vaddr> Show scsi_cmnd
+ kiobuf <vaddr> Display kiobuf
+ page <vaddr> Display page
+ inode <vaddr> Display inode
+ bh <vaddr> Display buffer head
+ inode_pages <inode *> Display pages in an inode
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Scull Demo
+
+
+ Objective
+ Find and display the data associated with a scull device
+
+ The sequence of events
+ Populate the scull device with data
+ Identify the breakpoints
+ Set breakpoint in the device read function
+ Identify the data structure elements
+ Identify device structures used to track data
+ Display data structures containing the data
+ Show the usage of the filp command
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Scull Demo: Populate Device
+
+
+ Obtain the code
+ Surf to http://examples.oreilly.com/linuxdrive2/
+ Download the tarball
+ Untar it to /usr/src
+
+ Build and install the module
+ cd /usr/src/ldd2-samples-1.0.1/scull
+ make
+ ./scull.init start
+
+ Populate the scull device
+ cat main.c > /dev/scull0
+ cat /dev/scull0
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Scull Demo: Driver Details
+
+
+ cat /dev/scull0
+ fd =
+%fore "blue", cont
+open
+%fore "black", cont
+("/dev/scull0", O_RDONLY);
+ Kernel finds the file_operations structure
+ Kernel then invokes the open function
+%fore "blue"
+ read
+%fore "black", cont
+(fd, buf, size);
+ Kernel finds the file_operations structure
+ Kernel then invokes the read function
+
+ Scull device file operations structure
+
+%font "typewriter", size 3
+ struct file_operations scull_fops = {
+ llseek: scull_llseek,
+%fore "blue"
+ read: scull_read,
+%fore "black"
+ write: scull_write,
+ ioctl: scull_ioctl,
+%fore "blue"
+ open: scull_open,
+%fore "black"
+ release: scull_release,
+ };
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Scull Demo: Driver Details
+
+%font "typewriter", size 3
+ scull_open code
+%font "typewriter", size 3
+ int
+%fore "blue", cont
+scull_open
+%fore "black", cont
+(struct inode *inode, struct file *filp)
+ {
+ Scull_Dev *dev; /* device information */
+ int num = NUM(inode->i_rdev);
+
+ <snip>
+
+ dev = (Scull_Dev *)filp->private_data;
+ if (!dev) {
+ if (num >= scull_nr_devs) return -ENODEV;
+%fore "blue"
+ dev = &scull_devices[num];
+ filp->private_data = dev;
+%fore "black"
+ }
+
+ <snip>
+
+ }
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Scull Demo: Driver Details
+
+%font "typewriter", size 3
+ scull_read code
+%font "typewriter", size 3
+ ssize_t
+%fore "blue", cont
+scull_read
+%fore "black", cont
+(struct file *filp, char *buf, size_t count,
+ loff_t *f_pos)
+ {
+
+%fore "blue", cont
+ Scull_Dev *dev = filp->private_data;
+%fore "black", cont
+ /* the first listitem */
+%fore "blue"
+ Scull_Dev *dptr;
+%fore "black"
+ int quantum = dev->quantum;
+ int qset = dev->qset;
+ int itemsize = quantum * qset;
+ if (down_interruptible(&dev->sem))
+ return -ERESTARTSYS;
+ if (*f_pos + count > dev->size)
+ count = dev->size - *f_pos;
+
+ /* find listitem, qset index, and offset in the quantum */
+ item = (long)*f_pos / itemsize;
+ rest = (long)*f_pos % itemsize;
+ s_pos = rest / quantum; q_pos = rest % quantum;
+
+ /* follow the list up to the right position */
+%fore "blue"
+ dptr = scull_follow(dev, item);
+%fore "black"
+
+ <snip>
+
+ }
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Scull Demo: Breakpoints
+
+
+%font "typewriter", size 3
+ Determine where to set breakpoint
+%font "typewriter", size 3
+%fore "blue"
+ dptr = scull_follow(dev, item);
+%fore "black"
+
+%font "typewriter", size 3
+ Disassemble scull_read
+%font "typewriter", size 3
+ [0]kdb>
+%fore "blue", cont
+id scull_read
+%fore "black"
+ 0xf8c083b4 scull_read: push %ebp
+ 0xf8c083b5 scull_read+0x1:mov %esp,%ebp
+ 0xf8c083b7 scull_read+0x3:push %edi
+ <snip>
+ 0xf8c08465 scull_read+0xb1:sub $0x8,%esp
+%fore "blue"
+ 0xf8c08468 scull_read+0xb4:push %ecx
+ 0xf8c08469 scull_read+0xb5:push %esi
+ 0xf8c0846a scull_read+0xb6:call 0xf8c08364 scull_follow:
+%fore "black"
+ 0xf8c0846f scull_read+0xbb:mov %eax,
+%fore "blue", cont
+ %edx
+%fore "black"
+ 0xf8c08471
+%fore "blue", cont
+scull_read+0xbd
+%fore "black", cont
+:add $0x10,%esp
+ <snip>
+
+ Set breakpoint in driver read
+%font "typewriter", size 3
+ [0]kdb>
+%fore "blue",cont
+bp scull_read+0xbd
+%fore "black"
+ Instruction(i) BP #0 at 0xf8c08471 ([scull]scull_read+0xbd)
+ is enabled globally adjust 1
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Scull Demo: Breakpoints
+
+
+%font "typewriter", size 3
+ Restart the system
+%font "typewriter", size 3
+ [0]kdb>
+%fore "blue", cont
+go
+%fore "black"
+
+ Hit the Breakpoint
+%font "typewriter", size 3
+ [root@elm3b77 root]#
+%fore "blue", cont
+cat /dev/scull0
+%fore "black"
+ Instruction(i) breakpoint #0 at 0xf8c08471 (adjusted)
+ 0xf8c08471 scull_read+0xbd:int3
+ Entering kdb (current=0xf73ec000, pid 1249) on processor 2
+ due to Breakpoint @ 0xf8c08471
+
+ Display the registers
+%font "typewriter", size 3
+ [2]kdb>
+%fore "blue", cont
+rd
+%fore "black"
+ eax = 0xf77d7b60 ebx = 0x00000000 ecx = 0x00000000 edx =
+%fore "blue", cont
+0xf77d7b60
+%fore "black"
+ esi =
+%fore "blue", cont
+0xf77d7b60
+%fore "black", cont
+ edi = 0x00001000 esp = 0xf7415f40 eip = 0xf8c08471
+ ebp = 0xf7415f78 xss = 0x00000018 xcs = 0x00000010 eflags = 0x00000246
+ xds = 0xf7590018 xes = 0x00000018 origeax = 0xffffffff ®s = 0xf7415f0c
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Scull Demo: Data Structures
+
+%font "typewriter", size 3
+ Display the Scull_Dev structure
+%font "typewriter", size 3
+ [2]kdb>
+%fore "blue", cont
+md 0xf77d7b60 2
+%fore "black"
+ 0xf77d7b60
+%fore "blue", cont
+f7400000
+%fore "black", cont
+ 00000000 00000fa0 000003e8 ..@w.... ...h...
+ 0xf77d7b70 0000534e 00000000 00000000 00000000 NS..............
+
+ Scull Device Structure
+%font "typewriter", size 3
+ typedef struct Scull_Dev {
+%fore "blue"
+ void **data;
+%fore "black"
+ struct Scull_Dev *next; /* next listitem */
+ int quantum; /* the current quantum size */
+ int qset; /* the current array size */
+ unsigned long size;
+ devfs_handle_t handle; /* only used if devfs is there */
+ unsigned int access_key; /* used by sculluid and scullpriv */
+ struct semaphore sem; /* mutual exclusion semaphore */
+ } Scull_Dev;
+%size 6
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Scull Demo: Data Structures
+
+
+%font "typewriter", size 3
+ Display the quantum set (dev->data)
+%font "typewriter", size 3
+ [2]kdb>
+%fore "blue", cont
+md f7400000 2
+%fore "black"
+ 0xf7400000
+%fore "blue", cont
+f73ea000
+%fore "black", cont
+ f73f1000 f740c000 f7ab4000 . >w..?w.@@w.@+w
+ 0xf7400010 f73ef000 f755b000 00000000 00000000 .p>w.0Uw........
+
+ Display the first quantum (dev->data[0])
+%font "typewriter", size 3
+ [2]kdb>
+%fore "blue", cont
+md f73ea000
+%fore "black"
+ 0xf73ea000 200a2a2f 616d202a 632e6e69 202d2d20 /*. * main.c --
+ 0xf73ea010 20656874 65726162 75637320 63206c6c the bare scull c
+ 0xf73ea020 20726168 75646f6d 200a656c 2a200a2a har module. *. *
+ 0xf73ea030 706f4320 67697279 28207468 32202943 Copyright (C) 2
+ 0xf73ea040 20313030 73656c41 646e6173 52206f72 001 Alessandro R
+ 0xf73ea050 6e696275 6e612069 6f4a2064 6874616e ubini and Jonath
+ 0xf73ea060 43206e61 6562726f 2a200a74 706f4320 an Corbet. * Cop
+ 0xf73ea070 67697279 28207468 32202943 20313030 yright (C) 2001
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Scull Demo: filp command
+
+
+%font "typewriter", size 3
+ Show filp usage - here is the scull_read prototype
+%font "typewriter", size 3
+ ssize_t scull_read(
+%fore "blue", cont
+struct file *filp
+%fore "black", cont
+, char *buf,
+ size_t count, loff_t *f_pos);
+ Show the stack trace:
+%font "typewriter", size 3
+[2]kdb>
+%fore "blue", cont
+bt
+%fore "black"
+ EBP EIP Function(args)
+ 0xee9dbf78 0xf8c08471 [scull]scull_read+0xbd (
+%fore "blue", cont
+0xeaf6c0c0
+%fore "black", cont
+, 0x804e128,
+ 0x1000, 0xeaf6c0e0, 0x804f000)
+ scull .text 0xf8c08060 0xf8c083b4 0xf8c084dc
+ 0xee9dbfbc 0xc0136278 sys_read+0x98 (0x3, 0x804e128, 0x1000, ...
+ kernel .text 0xc0100000 0xc01361e0 0xc01362b0
+ 0xc010702b system_call+0x33
+ kernel .text 0xc0100000 0xc0106ff8 0xc0107030
+ And show the filp output
+%font "typewriter", size 3
+ [2]kdb>
+%fore "blue", cont
+filp 0xeaf6c0c0
+%fore "black"
+ name.name 0xe93889fc name.len 6
+ File Pointer at 0xeaf6c0c0
+ f_list.nxt = 0xe42deca0 f_list.prv = 0xf7e69070
+%fore "blue"
+ f_dentry = 0xe93889a0
+%fore "black", cont
+ f_op = 0xf8c0a200
+ f_count = 2 f_flags = 0x8000 f_mode = 0x1
+ f_pos = 0 f_reada = 0 f_ramax = 0
+ f_raend = 0 f_ralen = 0 f_rawin = 0
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Scull Demo: filp command
+
+
+%font "typewriter", size 3
+ filp output - continued
+%font "typewriter", size 3
+%fore "blue"
+ Directory Entry at 0xe93889a0
+%fore "black"
+ d_name.len = 6
+%fore "orange", cont
+d_name.name = 0xe93889fc
+%fore "black", cont
+>
+ d_count = 1 d_flags = 0x0
+%fore "blue", cont
+d_inode = 0xe827b680
+%fore "black"
+ d_hash.nxt = 0xc215aec8 d_hash.prv = 0xc215aec8
+ d_lru.nxt = 0xe93889b8 d_lru.prv = 0xe93889b8
+ d_child.nxt = 0xe89e1e80 d_child.prv = 0xe9388940
+ d_subdirs.nxt = 0xe93889c8 d_subdirs.prv = 0xe93889c8
+ d_alias.nxt = 0xe827b690 d_alias.prv = 0xe827b690
+ d_op = 0x00000000 d_sb = 0xf7e69000
+
+%fore "blue"
+ Inode Entry at 0xe827b680
+%fore "black"
+ i_mode = 0x21a4 i_nlink = 1 i_rdev = 0xfe00
+ i_ino = 37182 i_count = 1 i_dev = 0x821
+ i_hash.nxt = 0xc20e6be8 i_hash.prv = 0xc20e6be8
+ i_list.nxt = 0xe827b2c8 i_list.prv = 0xe827b868
+ i_dentry.nxt = 0xe93889d0 i_dentry.prv = 0xe93889d0
+
+ Check the filename (display d_name.name)
+%font "typewriter", size 3
+ [2]kdb>
+%fore "orange", cont
+md 0xe93889fc 1
+%fore "black"
+ 0xe93889fc 6c756373 0000306c 00000000 00000000 scull0..........
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Kernel Structures
+
+
+ Objective
+ Show output from various kernel related kdb commands
+
+ Sequence of events
+ Simple Program
+ Write a simple program which allocates memory and hangs
+ Show usage of the ps, vm, and ll commands
+ Walk an IO operation
+ Hit a breakpoint in qlogic driver (isp1020_queuecommand)
+ Show usage of scsi related commands (sc, sh, and sd)
+ Show usage of vm related commands (bh, page, inode, inode_pages)
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Simple program
+
+%font "typewriter", size 3
+ simple.c - simple program which allocates memory
+%font "typewriter", size 3
+%fore "blue"
+ int foo_global[8192];
+%fore "black"
+ main()
+ {
+ int *
+%fore "blue", cont
+foo_malloc;
+%fore "black"
+ int i;
+ foo_malloc = (int *)malloc(0x8192);
+ for(i = 0; i < 0x100; i++) {
+ foo_global[i] = 0xdead0000 | i;
+ foo_malloc[i] = 0xbeef0000 | i;
+ }
+ printf("foo_global at %x\n", (int)foo_global);
+ printf("foo_malloc at %x\n", (int)foo_malloc);
+ printf("sleep forever\n");
+ sleep(2000000);
+ }
+
+ simple output
+%font "typewriter", size 3
+ [root@elm3b77 scull]# cc -o simple simple.c
+ [root@elm3b77 scull]# ./simple
+ foo_global at
+%fore "blue", cont
+8049780
+%fore "black"
+ foo_malloc at
+%fore "blue", cont
+8051788
+%fore "black"
+ sleep forever
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Simple Program
+
+%font "typewriter", size 3
+ Show the output of the ps command
+%font "typewriter", size 3
+ Entering kdb (current=0xc2010000, pid 0) on processor 3 due to
+ Keyboard Entry
+ [3]kdb>
+%fore "blue", cont
+ps
+%fore "black"
+ Task Addr Pid Parent [*] cpu State Thread Command
+ 0xf7efe000 00000001 00000000 0 003 stop 0xf7efe370 init
+ 0xf7ef0000 00000002 00000001 0 001 stop 0xf7ef0370 keventd
+ 0xf7eec000 00000003 00000000 0 000 stop 0xf7eec370 ksoftirqd_CPU0
+ 0xf7eea000 00000004 00000000 0 001 stop 0xf7eea370 ksoftirqd_CPU1
+ 0xf7ee8000 00000005 00000000 0 002 stop 0xf7ee8370 ksoftirqd_CPU2
+ 0xf7ee6000 00000006 00000000 0 003 stop 0xf7ee6370 ksoftirqd_CPU3
+
+ <snip>
+
+ 0xf7b46000 00001006 00000737 0 003 stop 0xf7b46370 sshd
+ 0xf7ace000 00001007 00001006 0 000 stop 0xf7ace370 bash
+ 0xef06a000 00001066 00001007 0 003 stop 0xef06a370 su
+ 0xeef88000 00001067 00001066 0 000 stop 0xeef88370 bash
+ 0xeef64000 00001119 00000770 0 001 stop 0xeef64370 in.ftpd
+%fore "blue"
+ 0xeeeac000
+%fore "black", cont
+ 00001138 00001067 0 001 stop 0xeeeac370
+%fore "blue", cont
+simple
+%fore "black"
+ [3]kdb>
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Simple Program
+
+%font "typewriter", size 3
+ Display the task struct
+%font "typewriter", size 3
+ [3]kdb>
+%fore "blue", cont
+md 0xeeeac000
+%fore "black"
+ 0xeeeac000 00000001 00000000 00000000 c0000000 ................
+ 0xeeeac010 c0339880 00000000 00000000 ffffffff ................
+ 0xeeeac020 0000000a 00000000 00000000
+%fore "blue", cont
+f7e10f00
+%fore "black", cont
+ ..............aw
+ 0xeeeac030 00000001 ffffffff ffffffff 00000000 ................
+
+%font "typewriter", size 3
+ Determine offset of mm_struct ptr in task_struct
+%font "typewriter", size 3
+ struct task_struct {
+ [0] volatile long state;
+ [4] unsigned long flags;
+ [8] int sigpending;
+ [c] mm_segment_t addr_limit;
+ [10] struct exec_domain *exec_domain;
+ [14] volatile long need_resched;
+ [18] unsigned long ptrace;
+ [1c] int lock_depth;
+ [20] long counter;
+ [24] long nice;
+ [28] unsigned long policy;
+%fore "blue"
+ [2c] struct mm_struct *mm;
+%fore "black"
+ [30] int processor;
+ [34] unsigned long cpus_runnable, cpus_allowed;
+ <snip>
+ };
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Simple Program
+
+
+%font "typewriter", size 3
+ Display the mm_struct associated with simple process
+%font "typewriter", size 3
+ [3]kdb>
+%fore "blue", cont
+md f7e10f00
+%fore "black"
+ 0xf7e10f00
+%fore "blue", cont
+e8357a80
+%fore "black", cont
+ e8357978 f7ac77e0 eb15eac0 .z5hxy5h`w,w@j.k
+ 0xf7e10f10 00000001 00000002 0000000b 00000000 ................
+ 0xf7e10f20 00000001 f7e10f24 f7e10f24 00000001 ................
+ 0xf7e10f30 f7e35e70 eea7e8f0 08048000 0804862b ................
+ 0xf7e10f40 0804962c 08049744 08051780 0805a000 ................
+ 0xf7e10f50 bffffd10 bffffe00 bffffe09 bffffe09 ................
+ 0xf7e10f60 bffffff3 0000005a 00000168 00000000 ................
+ 0xf7e10f70 00000000 00000002 00000000 00000001 ................
+
+%font "typewriter", size 3
+ Determine offset of the first vma in the process
+%font "typewriter", size 3
+ struct mm_struct {
+%fore "blue"
+ struct vm_area_struct * mmap;
+%fore "black"
+ rb_root_t mm_rb;
+ struct vm_area_struct * mmap_cache;
+ <snip>
+ };
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Simple Program
+
+%font "typewriter", size 3
+ Display the first vma using md
+%font "typewriter", size 3
+ [3]kdb>
+%fore "blue", cont
+md e8357a80
+%fore "black"
+ 0xe8357a80 f7e10f00 08048000 08049000
+%fore "blue", cont
+e8727e00
+%fore "black",cont
+ ..aw.........~rh
+ 0xe8357a90 00000025 00001875 e8727e18 00000001 %...u....~rh....
+
+ Display the first vma using vma
+%font "typewriter", size 3
+ [3]kdb>
+%fore "blue", cont
+vma e8357a80
+%fore "black"
+ struct vm_area_struct at 0xe8357a80 for 68 bytes
+ vm_start = 0x8048000 vm_end = 0x8049000
+ page_prot = 0x25
+ flags: READ EXEC MAYREAD MAYWRITE MAYEXEC DENYWRITE EXECUTABLE
+%font "typewriter", size 3
+
+ Determine the offset to the vma list
+%font "typewriter", size 3
+ struct vm_area_struct {
+ [0] struct mm_struct * vm_mm;
+ [4] unsigned long vm_start;
+ [8] unsigned long vm_end;
+%fore "blue"
+ [c] struct vm_area_struct *vm_next;
+%fore "black"
+ <snip>
+ };
+ Display the next vma
+%font "typewriter", size 3
+ [3]kdb> vma e8727e00
+ struct vm_area_struct at 0xe8727e00 for 68 bytes
+ vm_start = 0x8049000 vm_end = 0x804a000
+ page_prot = 0x25
+ flags: READ WRITE MAYREAD MAYWRITE MAYEXEC DENYWRITE EXECUTABLE
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Simple Program
+
+%font "typewriter", size 3
+ Use the ll command to display the list of vma's
+%font "typewriter", size 3
+ [3]kdb> ll e8357a80 0xc vma
+.
+ struct vm_area_struct at 0xe8357a80 for 68 bytes
+ vm_start = 0x8048000 vm_end = 0x8049000
+ page_prot = 0x25
+ flags: READ EXEC MAYREAD MAYWRITE MAYEXEC DENYWRITE EXECUTABLE
+.
+ struct vm_area_struct at 0xe8727e00 for 68 bytes
+ vm_start =
+%fore "orange", cont
+0x8049000
+%fore "black", cont
+ vm_end =
+%fore "orange", cont
+0x804a000
+%fore "black"
+ page_prot = 0x25
+ flags: READ WRITE MAYREAD MAYWRITE MAYEXEC DENYWRITE EXECUTABLE
+.
+ struct vm_area_struct at 0xe8727c80 for 68 bytes
+ vm_start =
+%fore "blue", cont
+0x804a000
+%fore "black", cont
+ vm_end =
+%fore "blue", cont
+0x805a000
+%fore "black"
+ page_prot = 0x25
+ flags: READ WRITE EXEC MAYREAD MAYWRITE MAYEXEC
+ <snip>
+ struct vm_area_struct at 0xe8357900 for 68 bytes
+ vm_start = 0xbfffe000 vm_end = 0xc0000000
+ page_prot = 0x25
+ flags: READ WRITE EXEC MAYREAD MAYWRITE MAYEXEC GROWSDOWN
+
+ Match the vma to the displayed addresses
+%font "typewriter", size 3
+ foo_global at
+%fore "orange", cont
+8049780
+%fore "black"
+ foo_malloc at
+%fore "blue", cont
+8051788
+%fore "black"
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Walking IO structures
+
+
+ Objective
+ Show usage of various scsi and vm related kdb commands
+
+ Sequence:
+ Set a breakpoint in the scsi driver
+ Stops when queueing a command to the controller
+ Cause IO on an idle disk
+ Show various IO stack traces
+ Display the IO data structures
+ Display vm information about the data
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Walking IO structures
+
+
+%font "typewriter", size 3
+ Set the breakpoint
+
+%font "typewriter", size 3
+ [3]kdb>
+%fore "blue", cont
+bp isp1020_queuecommand
+%fore "black"
+ Instruction(i) BP #0 at 0xc01ecfe0 (isp1020_queuecommand)
+ is enabled globally adjust 1
+
+%font "typewriter", size 3
+ Create some activity on a previously unused disk
+
+%font "typewriter", size 3
+ [3]kdb>
+%fore "blue", cont
+go
+%fore "black"
+ [root@elm3b77 root]#
+%fore "blue", cont
+ls /rh62
+%fore "black"
+
+ Instruction(i) breakpoint #0 at 0xc01ecfe0 (adjusted)
+ 0xc01ecfe0 isp1020_queuecommand:int3
+
+ Entering kdb (current=0xf75ba000, pid 1181) on processor 3 due to
+ Breakpoint @ 0xc01ecfe0
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Walking IO structures
+
+
+%font "typewriter", size 3
+ Show the stack.
+ This is a read of the /rh62 directory
+
+%font "typewriter", size 3
+ [1]kdb>
+%fore "blue", cont
+bt
+%fore "black"
+ EBP EIP Function(args)
+ 0xf75bbdf4 0xc01ecfe0 isp1020_queuecommand
+ 0xc01e2c77 scsi_dispatch_cmd+0x1f7
+ 0xf75bbe24 0xc01e99b1 scsi_request_fn+0x2f1
+ 0xf75bbe34 0xc01c84fd generic_unplug_device+0x2d
+ 0xf75bbe50 0xc011b3af __run_task_queue+0x5f
+ 0xf75bbe6c 0xc013a63c block_sync_page+0x1c
+ 0xf75bbe98 0xc0128127 __lock_page+0x77
+ 0xf75bbea4 0xc0128178 lock_page+0x18
+ 0xf75bbec8 0xc012a4b3 read_cache_page+0xc3
+ 0xf75bbef4 0xc0168e23 ext2_get_page+0x23
+ 0xf75bbf48 0xc0168fdd ext2_readdir+0xfd
+ 0xf75bbf68 0xc0143d2e vfs_readdir+0x7e
+ 0xf75bbfbc 0xc01442ed
+%fore "blue", cont
+sys_getdents64+0x4d
+%fore "black"
+ 0xc010702b system_call+0x33
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Walking IO structures
+
+
+%font "typewriter", size 3
+ Allow the operation to complete
+
+%font "typewriter", size 3
+ [3]kdb>
+%fore "blue", cont
+go
+%fore "black"
+ bench build etc lib mnt oldsys rh72 spv usr
+ bin data h linux mnt1 opt root test var
+ boot dev home lost+found mnt2 proc sbin tmp
+
+%font "typewriter", size 3
+ Force some more activity
+
+%font "typewriter", size 3
+ [root@elm3b77 root]#
+%fore "blue", cont
+cd /rh62/tmp
+%fore "black"
+ Instruction(i) breakpoint #0 at 0xc01ecfe0 (adjusted)
+ 0xc01ecfe0 isp1020_queuecommand:int3
+
+ Entering kdb (current=0xf768a000, pid 981) on processor 3 due to
+ Breakpoint @ 0xc01ecfe0
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Walking IO structures
+
+
+%font "typewriter", size 3
+ Show the stack.
+ This is an inode read for /rh62/tmp
+
+%font "typewriter", size 3
+ [3]kdb>
+%fore "blue", cont
+bt
+%fore "black"
+ EBP EIP Function(args)
+ 0xf768bd68 0xc01ecfe0 isp1020_queuecommand
+ 0xc01e2c77 scsi_dispatch_cmd+0x1f7
+ 0xf768bd98 0xc01e99b1 scsi_request_fn+0x2f1
+ 0xf768bda8 0xc01c84fd generic_unplug_device+0x2d
+ 0xf768bdc4 0xc011b3af __run_task_queue+0x5f
+ 0xf768bdfc 0xc0137216 __wait_on_buffer+0x56
+ 0xf768be1c 0xc0138600 bread+0x50
+ 0xf768be5c 0xc016b684 ext2_read_inode+0x114
+ 0xf768bf0c 0xc013fbec real_lookup+0x7c
+ 0xf768bf78 0xc014035d link_path_walk+0x5ad
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Walking IO structures
+
+
+%font "typewriter", size 3
+ Create a new file, causing yet more disk activity
+
+%font "typewriter", size 3
+ [3]kdb>
+%fore "blue", cont
+go
+%fore "black"
+
+ [root@elm3b77 tmp]#
+%fore "blue", cont
+echo "Hello linux reading group" > j1;sync
+%fore "black"
+
+ Instruction(i) breakpoint #0 at 0xc01ecfe0 (adjusted)
+ 0xc01ecfe0 isp1020_queuecommand:int3
+
+ Entering kdb (current=0xf768a000, pid 981) on processor 3 due to
+ Breakpoint @ 0xc01ecfe0
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Walking IO structures
+
+
+%font "typewriter", size 3
+ Show the stack
+ This is an inode read in response to the open
+%font "typewriter", size 3
+ [3]kdb>
+%fore "blue", cont
+bt
+%fore "black"
+ EBP EIP Function(args)
+ 0xf768bd78 0xc01ecfe0 isp1020_queuecommand
+ 0xc01e2c77 scsi_dispatch_cmd+0x1f7
+ 0xf768bda8 0xc01e99b1 scsi_request_fn+0x2f1
+ 0xf768bdb8 0xc01c84fd generic_unplug_device+0x2d
+ 0xf768bdd4 0xc011b3af __run_task_queue+0x5f
+ 0xf768bdf0 0xc013a63c block_sync_page+0x1c
+ 0xf768be1c 0xc0128127 __lock_page+0x77
+ 0xf768be28 0xc0128178 lock_page+0x18
+ 0xf768be4c 0xc012a4b3 read_cache_page+0xc3
+ 0xf768be78 0xc0168e23 ext2_get_page+0x23
+ 0xf768beb8 0xc01691ed ext2_find_entry+0x8d
+ 0xf768bed4 0xc016933a ext2_inode_by_name+0x1a
+ 0xf768befc 0xc016c077 ext2_lookup+0x27
+ 0xf768bf1c 0xc014094a lookup_hash+0x9a
+ 0xf768bf64 0xc0140c4d open_namei+0xfd
+ 0xf768bfa0 0xc0135907 filp_open+0x37
+ 0xf768bfbc 0xc0135c64 sys_open+0x34
+ 0xc010702b system_call+0x33
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Walking IO structures
+
+
+%font "typewriter", size 3
+ Let the operation continue
+%font "typewriter", size 3
+ [3]kdb>
+%fore "blue", cont
+go
+%fore "black"
+ Instruction(i) breakpoint #0 at 0xc01ecfe0 (adjusted)
+ 0xc01ecfe0 isp1020_queuecommand: int3
+ Entering kdb (current=0xc0352000, pid 0) on processor 0 due to
+ Breakpoint @ 0xc01ecfe0
+ Show the stack
+ This is an io completion queuing the next request
+%font "typewriter", size 3
+ [0]kdb>
+%fore "blue", cont
+bt
+%fore "black"
+ EBP EIP Function(args)
+ 0xc0353df4 0xc01ecfe0 isp1020_queuecommand(
+%fore "blue", cont
+0xf7e63a00
+%fore "black", cont
+,0xc01e7fc0...
+ 0xc01e2c77 scsi_dispatch_cmd+0x1f7
+ 0xc0353e24 0xc01e99b1 scsi_request_fn+0x2f1
+ 0xc0353e40 0xc01e8f6a
+%fore "blue", cont
+scsi_queue_next_request+0x4a
+%fore "black"
+ 0xc0353e5c 0xc01e9166 __scsi_end_request+0x116
+ 0xc0353ea8 0xc01e93e0
+%fore "blue", cont
+scsi_io_completion+0x170
+%fore "black"
+ 0xc0353ecc 0xc01f658e rw_intr+0x14e
+ 0xc0353ef8 0xc01e8668 scsi_old_done+0x6a8
+ 0xc0353fd4 0xc01052c2 cpu_idle+0x52
+ Function prototype
+%font "typewriter", size 3
+ int isp1020_queuecommand(
+%fore "blue", cont
+Scsi_Cmnd *Cmnd,
+%fore "black"
+ void (*done)(Scsi_Cmnd *))
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Walking IO structures
+
+
+%font "typewriter", size 3
+ Show the command being queued
+%font "typewriter", size 3
+ [0]kdb>
+%fore "blue", cont
+sc 0xf7e63a00
+%fore "black"
+ scsi_cmnd at 0xf7e63a00
+%fore "blue"
+ host = 0xf7e91400
+%fore "black", cont
+ state = 4099 owner = 258
+%fore "blue", cont
+device = 0xf7ed5d80
+%fore "black"
+ bnext = 0x00000000 reset_chain = 0x00000000 eh_state = 0
+ done = 0xc01f6440
+ serial_number = 3402 serial_num_at_to = 0 retries = 0 timeout = 0
+ id/lun/cmnd = [0/0/0] cmd_len = 10 old_cmd_len = 10
+ cmnd = [2a/00/00/28/00/3f/00/00/10/00/ef/f7]
+ data_cmnd = [2a/00/00/28/00/3f/00/00/10/00/ef/f7]
+ request_buffer = 0xc03fd000 bh_next = 0x00000000
+ request_bufflen = 8192
+ use_sg = 2 old_use_sg = 2 sglist_len = 512 abore_reason = 0
+ bufflen = 8192 buffer = 0xc03fd000 underflow = 8192
+ transfersize = 512
+ tag = 0 pid = 3401
+ request struct
+ rq_status = RQ_ACTIVE rq_dev = [8/1] errors = 1 cmd = 0
+ sector = 2621440 nr_sectors = 16 current_nr_sectors = 8
+ buffer = 0xf7599000
+%fore "blue", cont
+bh = 0xf75ca300
+%fore "black", cont
+ bhtail = 0xf75ca3c0
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Walking IO structures
+
+
+%font "typewriter", size 3
+ Display the host adapter
+%font "typewriter", size 3
+ [0]kdb>
+%fore "blue", cont
+sh 0xf7e91400
+%fore "black"
+ Scsi_Host at 0xf7e91400
+ next = 0x00000000
+%fore "blue", cont
+host_queue = 0xf7ed5d80
+%fore "black"
+ ehandler = 0x00000000 eh_wait = 0x00000000 en_notify = 0x00000000
+ eh_action = 0x00000000
+ h_active = 0x0 host_wait = 0xc0353ac4 hostt = 0xc034bce0
+ host_busy = 1
+ host_failed = 0 extra_bytes = 524 host_no = 0 resetting = 0
+ max id/lun/channel = [16/8/0] this_id = 7
+ can_queue = 64 cmd_per_lun = 1 sg_tablesize = 427 u_isa_dma = 0
+ host_blocked = 0 reverse_ordering = 0
+
+%font "typewriter", size 3
+ Display the scsi device
+%font "typewriter", size 3
+ [0]kdb>
+%fore "blue", cont
+sd 0xf7ed5d80
+%fore "black"
+ scsi_device at 0xf7ed5d80
+ next = 0xf7ed5c80 prev = 0x00000000 host = 0xf7e91400
+ device_busy = 1
+%fore "blue", cont
+device_queue 0xf7e63a00
+%fore "black"
+ id/lun/chan = [0/0/0] single_lun = 0 device_blocked = 0
+ queue_depth = 1 current_tag = 0 scsi_level = 4
+ IBM DGHS18X 0360
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Walking IO structures
+
+
+%font "typewriter", size 3
+ Display the Buffer header associated with the command
+%font "typewriter", size 3
+ [0]kdb>
+%fore "blue", cont
+bh 0xf75ca300
+%fore "black"
+ buffer_head at 0xf75ca300
+ next 0x00000000 bno 327680 rsec 2621440 size 4096
+ dev 0x801 rdev 0x801
+ count 2 state 0x1d [Uptodate Lock Req Mapped] ftime 0x7695e
+ b_list 1 b_reqnext 0xf75ca3c0 b_data 0xf7599000
+%fore "blue"
+ b_page 0xc1dd6640
+%fore "black", cont
+ b_this_page 0xf75ca300 b_private 0x00000000
+
+ Display the associated page structure
+%font "typewriter", size 3
+ [0]kdb>
+%fore "blue", cont
+page 0xc1dd6640
+%fore "black"
+ struct page at 0xc1dd6640
+ next 0xc1dd7300 prev 0xc1dd6240
+%fore "blue", cont
+addr space 0xf7af04d0
+%fore "black"
+ index 327680 (offset 0x50000000)
+ count 2 flags PG_referenced PG_lru virtual 0xf7599000
+ buffers 0xf75ca300
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Walking IO structures
+
+
+%font "typewriter", size 3
+ Display the Address space associated with the page
+%font "typewriter", size 3
+ [0]kdb>
+%fore "blue", cont
+md 0xf7af04d0
+%fore "black"
+ 0xf7af04d0 c1dd6240 c1dea740 f7af04d8 f7af04d8 @b]A@'^AX./wX./w
+ 0xf7af04e0 f7af04e0 f7af04e0 00000007 c033b700 `./w`./w.....73@
+ 0xf7af04f0
+%fore "blue", cont
+f7af0420
+%fore "black", cont
+ 00000000 00000000 00000001 ./w............
+ 0xf7af0500 000001d0 00000000 00000000 f7af050c P............./w
+ 0xf7af0510 f7af050c 00000000 f7a8afa0 00000000 ../w.... /(w....
+
+ The structure looks like:
+%size 3
+ struct address_space {
+ struct list_head clean_pages; /* list of clean pages */
+ struct list_head dirty_pages; /* list of dirty pages */
+ struct list_head locked_pages;/* list of locked pages */
+ unsigned long nrpages; /* number of total pages */
+ spinlock_t page_lock; /* spinlock protecting them*/
+ struct address_space_operations *a_ops; /* methods */
+%fore "blue"
+ struct inode *host; /* owner: inode, block_dev */
+%fore "black"
+ <snip>
+ };
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Walking IO structures
+
+
+%font "typewriter", size 3
+ Display the inode associated with the address space
+ I think htis is the inode for the block device.
+
+%font "typewriter", size 3
+ [1]kdb>
+%fore "blue", cont
+inode f7af0420
+%fore "black"
+ struct inode at 0xf7af0420
+ i_ino = 289 i_count = 1 i_dev = 0x801 i_size 4301789184
+ i_mode = 0x8000 i_nlink = 1 i_rdev = 0x801
+ i_hash.nxt = 0xf7af0420 i_hash.prv = 0xf7af0420
+ i_list.nxt = 0xf7af0608 i_list.prv = 0xf7af0068
+ i_dentry.nxt = 0xf7af0430 i_dentry.prv = 0xf7af0430
+ i_dirty_buffers.nxt = 0xf7af0438 i_dirty_buffers.prv = 0xf7af0438
+ i_sb = 0xc201f200 i_op = 0xc03cfdc0 i_data = 0xf7af04d0 nrpages = 6
+ i_mapping = 0xf7af04d0
+ i_flags 0x0 i_state 0x0 [] fs specific info @ 0xf7af0540
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%page
+
+Walking IO structures
+
+
+%font "typewriter", size 3
+ Display the page list associated with the inode
+%font "typewriter", size 3
+ [0]kdb>
+%fore "blue", cont
+inode_pages f7af0420
+%fore "black"
+CLEAN page_struct index cnt flags
+ 0xc1dd6240 327735 2 0x44 bh 0xf75caae0 bno 327735
+ [Lock Req Mapped]
+%fore "blue"
+ 0xc1dd6640 327680 2 0x44 bh 0xf75ca300 bno 327680
+ [Uptodate Lock Req Mapped]
+%fore "black"
+ 0xc1dd7300 327681 2 0x44 bh 0xf75ca3c0 bno 327681
+ [Uptodate Lock Req Mapped]
+ 0xc1dd6e00 327684 2 0x44 bh 0xf75ca420 bno 327684
+ [Uptodate Req Mapped]
+ 0xc1de8fc0 4 2 0xc0 bh 0xf7b5ade0 bno 4
+ [Uptodate Req Mapped]
+ 0xc1dea700 1 2 0x44 bh 0xf7e02740 bno 1
+ [Uptodate Req Mapped]
+ 0xc1dea740 0 2 0x44 bh 0xf7e028c0 bno 0
+ [Uptodate Req Mapped]
+DIRTY page_struct index cnt flags
+LOCKED page_struct index cnt flags
ifeq ($(KBUILD_EXTMOD),)
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
+core-$(CONFIG_KDB) += kdb/
vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
$(core-y) $(core-m) $(drivers-y) $(drivers-m) \
option saves about 4k and might cause you much additional grey
hair.
+config KDB
+ bool "Built-in Kernel Debugger support"
+ depends on DEBUG_KERNEL
+ select KALLSYMS
+ select KALLSYMS_ALL
+ help
+ This option provides a built-in kernel debugger. The built-in
+ kernel debugger contains commands which allow memory to be examined,
+ instructions to be disassembled and breakpoints to be set. For details,
+ see Documentation/kdb/kdb.mm and the manual pages kdb_bt, kdb_ss, etc.
+ Kdb can also be used via the serial port. Set up the system to
+ have a serial console (see Documentation/serial-console.txt).
+ The key sequence <escape>KDB on the serial port will cause the
+ kernel debugger to be entered with input from the serial port and
+ output to the serial console. If unsure, say N.
+
+config KDB_MODULES
+ tristate "KDB modules"
+ depends on KDB
+ help
+ KDB can be extended by adding your own modules, in directory
+ kdb/modules. This option selects the way that these modules should
+ be compiled, as free standing modules (select M) or built into the
+ kernel (select Y). If unsure say M.
+
+config KDB_OFF
+ bool "KDB off by default"
+ depends on KDB
+ help
+ Normally kdb is activated by default, as long as CONFIG_KDB is set.
+ If you want to ship a kernel with kdb support but only have kdb
+ turned on when the user requests it then select this option. When
+ compiled with CONFIG_KDB_OFF, kdb ignores all events unless you boot
+ with kdb=on or you echo "1" > /proc/sys/kernel/kdb. This option also
+ works in reverse, if kdb is normally activated, you can boot with
+ kdb=off or echo "0" > /proc/sys/kernel/kdb to deactivate kdb. If
+ unsure, say N.
+
+config KDB_CONTINUE_CATASTROPHIC
+ int "KDB continues after catastrophic errors"
+ depends on KDB
+ default "0"
+ help
+ This integer controls the behaviour of kdb when the kernel gets a
+ catastrophic error, i.e. for a panic, oops, NMI or other watchdog
+ tripping. CONFIG_KDB_CONTINUE_CATASTROPHIC interacts with
+ /proc/sys/kernel/kdb and CONFIG_LKCD_DUMP (if your kernel has the
+ LKCD patch).
+ When KDB is active (/proc/sys/kernel/kdb == 1) and a catastrophic
+ error occurs, nothing extra happens until you type 'go'.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 0 (default). The first time
+ you type 'go', kdb warns you. The second time you type 'go', KDB
+ tries to continue - no guarantees that the kernel is still usable.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 1. KDB tries to continue - no
+ guarantees that the kernel is still usable.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 2. If your kernel has the LKCD
+ patch and LKCD is configured to take a dump then KDB forces a dump.
+ Whether or not a dump is taken, KDB forces a reboot.
+ When KDB is not active (/proc/sys/kernel/kdb == 0) and a catastrophic
+ error occurs, the following steps are automatic, no human
+ intervention is required.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 0 (default) or 1. KDB attempts
+ to continue - no guarantees that the kernel is still usable.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 2. If your kernel has the LKCD
+ patch and LKCD is configured to take a dump then KDB automatically
+ forces a dump. Whether or not a dump is taken, KDB forces a
+ reboot.
+ If you are not sure, say 0.
+
+config KDB_USB
+ bool "Support for USB Keyboard in KDB (OHCI only)"
+ depends on KDB && USB_OHCI_HCD
+ help
+ If you want to use kdb from a OHCI USB keyboard then say Y here. If you
+ say N then kdb can only be used from a PC (AT) keyboard or a serial
+ console.
+
endmenu
# must be linked after kernel/
drivers-$(CONFIG_OPROFILE) += arch/i386/oprofile/
drivers-$(CONFIG_PM) += arch/i386/power/
+drivers-$(CONFIG_KDB) += arch/i386/kdb/
CFLAGS += $(mflags-y)
AFLAGS += $(mflags-y)
--- /dev/null
+2006-09-20 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-i386-1.
+
+2006-09-15 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc7-i386-1.
+
+2006-08-30 Keith Owens <kaos@sgi.com>
+
+ * Add warning for problems when following alternate stacks.
+ * kdb v4.4-2.6.18-rc5-i386-3.
+
+2006-08-29 Keith Owens <kaos@sgi.com>
+
+ * Rewrite all backtrace code.
+ * kdb v4.4-2.6.18-rc5-i386-2.
+
+2006-08-28 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc5-i386-1.
+
+2006-08-08 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc4-i386-1.
+
+2006-08-04 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc3-i386-1.
+
+2006-07-18 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc2-i386-1.
+
+2006-07-12 Keith Owens <kaos@sgi.com>
+
+ * Remove dead KDB_REASON codes.
+ * sparse cleanups.
+ * kdb v4.4-2.6.18-rc1-i386-2.
+
+2006-07-07 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc1-i386-1.
+
+2006-07-04 Keith Owens <kaos@sgi.com>
+
+ * Make KDB rendezvous on i386 a two stage approach.
+ * Clean up generation of KDB interrupt code.
+ * Move smp_kdb_stop() and smp_kdb_interrupt() to kdbasupport.c.
+ * Move setting of interrupt traps to kdbasupport.c.
+ * Remove KDB hooks from arch/i386/kernel smp.c, smpboot.c, i8259.c,
+ io_apic.c.
+ * Add KDB_REASON_CPU_UP support.
+ * Move per cpu setup to kdba_cpu_up().
+ * Rework support for 4K stacks to make backtrace more accurate.
+ * Add BTSP option to get the full backtrace, including kdb routines.
+ * Delete kdba_enable_mce, architectures now do their own setup.
+ * Delete kdba_enable_lbr, kdba_disable_lbr, kdba_print_lbr,
+ page_fault_mca. Only ever implemented on x86, difficult to maintain
+ and rarely used in the field.
+ * Replace #ifdef KDB_HAVE_LONGJMP with #ifdef kdba_setjmp.
+ * kdb v4.4-2.6.17-i386-2.
+
+2006-06-19 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-i386-1.
+
+2006-05-25 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-rc5-i386-1.
+
+2006-05-15 Keith Owens <kaos@sgi.com>
+
+ * Refresh bfd related files from binutils 2.16.91.0.2.
+ * kdb v4.4-2.6.17-rc4-i386-2.
+
+2006-05-12 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-rc4-i386-1.
+
+2006-04-28 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-rc3-i386-1.
+
+2006-04-22 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-rc2-i386-1.
+
+2006-04-11 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-rc1-i386-1.
+
+2006-03-30 Keith Owens <kaos@sgi.com>
+
+ * Change CONFIG_LKCD to CONFIG_LKCD_DUMP.
+ * kdb v4.4-2.6.16-i386-3.
+
+2006-03-24 Keith Owens <kaos@sgi.com>
+
+ * Define a dummy kdba_wait_for_cpus().
+ * kdb v4.4-2.6.16-i386-2.
+
+2006-03-21 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.16-i386-1.
+
+2006-03-14 Nathan Scott <nathans@sgi.com>
+
+ * kdb v4.4-2.6.16-rc6-i386-1.
+
+2006-02-28 Nathan Scott <nathans@sgi.com>
+
+ * kdb v4.4-2.6.16-rc5-i386-1.
+
+2006-02-20 Nathan Scott <nathans@sgi.com>
+
+ * kdb v4.4-2.6.16-rc4-i386-1.
+
+2006-02-06 Keith Owens <kaos@sgi.com>
+
+ * Change CONFIG_CRASH_DUMP to CONFIG_LKCD.
+ * kdb v4.4-2.6.16-rc2-i386-2.
+
+2006-02-06 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.16-rc2-i386-1.
+
+2006-01-18 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.16-rc1-i386-1.
+
+2006-01-08 Keith Owens <kaos@sgi.com>
+
+ * Add DIE_KDEBUG_ENTER and DIE_KDEBUG_LEAVE to notify_die.
+ * kdb v4.4-2.6.15-i386-2.
+
+2006-01-04 Keith Owens <kaos@sgi.com>
+
+ * Remove some inlines and the last vestige of CONFIG_NUMA_REPLICATE.
+ * Read the keyboard acknowledgment after sending a character. SuSE
+ Bugzilla 60240.
+ * kdb v4.4-2.6.15-i386-1.
+
+2005-12-25 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.15-rc7-i386-1.
+
+2005-12-20 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.15-rc6-i386-1.
+
+2005-12-05 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.15-rc5-i386-1.
+
+2005-12-02 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.15-rc4-i386-1.
+
+2005-11-30 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.15-rc3-i386-1.
+
+2005-11-21 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.15-rc2-i386-1.
+
+2005-11-15 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.15-rc1-i386-1.
+
+2005-10-28 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.14-i386-1.
+
+2005-10-21 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.14-rc5-i386-1.
+
+2005-10-11 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.14-rc4-i386-1.
+
+2005-10-04 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.14-rc3-i386-1.
+
+2005-09-21 Keith Owens <kaos@sgi.com>
+
+ * Support kdb_current_task in register display and modify commands.
+ * kdb v4.4-2.6.14-rc2-i386-1.
+
+2005-09-20 Keith Owens <kaos@sgi.com>
+
+ * Remove use of __STDC_VERSION__ in ansidecl.h.
+ * kdb v4.4-2.6.14-rc1-i386-1.
+
+2005-08-29 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.13-i386-1.
+
+2005-08-24 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.13-rc7-i386-1.
+
+2005-08-08 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.13-rc6-i386-1.
+
+2005-08-02 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.13-rc5-i386-1.
+
+2005-07-30 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.13-rc4-i386-1.
+
+2005-07-22 Keith Owens <kaos@sgi.com>
+
+ * Compile fix for kprobes.
+ * kdb v4.4-2.6.13-rc3-i386-2.
+
+2005-07-19 Keith Owens <kaos@sgi.com>
+
+ * Add support for USB keyboard (OHCI only). Aaron Young, SGI.
+ * kdb v4.4-2.6.13-rc3-i386-1.
+
+2005-07-08 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.13-rc2-i386-1.
+
+2005-07-01 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.13-rc1-i386-1.
+
+2005-06-19 Keith Owens <kaos@sgi.com>
+
+ * gcc 4 compile fix, remove extern kdb_hardbreaks. Steve Lord.
+ * kdb v4.4-2.6.12-i386-2.
+
+2005-06-18 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.12-i386-1.
+
+2005-06-08 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.12-rc6-i386-1.
+
+2005-05-25 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.12-rc5-i386-1.
+
+2005-05-08 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.12-rc4-i386-1.
+
+2005-04-21 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.12-rc3-i386-1.
+
+2005-04-06 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.12-rc2-i386-1.
+
+2005-03-29 Keith Owens <kaos@sgi.com>
+
+ * Replace __copy_to_user with __copy_to_user_inatomic.
+ * kdb v4.4-2.6.12-rc1-i386-1.
+
+2005-03-08 Keith Owens <kaos@sgi.com>
+
+ * Coexistence patches for lkcd.
+ * kdb v4.4-2.6.11-i386-2.
+
+2005-03-03 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.11-i386-1.
+
+2005-02-14 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.11-rc4-i386-1.
+
+2005-02-08 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.11-rc3-bk4-i386-1.
+
+2005-02-03 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.11-rc3-i386-1.
+
+2005-01-27 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.11-rc2-i386-1.
+
+2005-01-12 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.11-rc1-i386-1.
+
+2004-12-25 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.10-i386-1.
+
+2004-12-07 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.10-rc3-i386-1.
+
+2004-11-23 Keith Owens <kaos@sgi.com>
+
+ * Coexist with asmlinkage/fastcall changes.
+ * kdb v4.4-2.6.10-rc2-i386-1.
+
+2004-10-29 Keith Owens <kaos@sgi.com>
+
+ * Handle change defintions for hard and soft irq context.
+ * Make stack switch in kdb backtrace look more like the oops output.
+ * kdb v4.4-2.6.10-rc1-i386-1.
+
+2004-10-19 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.9-i386-1.
+
+2004-10-12 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.9-rc4-i386-1.
+
+2004-10-01 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.9-rc3-i386-1.
+
+2004-09-30 Keith Owens <kaos@sgi.com>
+
+ * Add stackdepth command.
+ * Handle backtrace with separate soft and hard irq stacks
+ (CONFIG_4KSTACKS).
+ * Work around RESTORE_ALL macro, which can only be used once.
+ * Export kdba_dumpregs. Bryan Cardillo, UPenn.
+ * kdb v4.4-2.6.9-rc2-i386-2.
+
+2004-09-14 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.9-rc2-i386-1.
+
+2004-08-27 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.9-rc1-i386-1.
+
+2004-08-14 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.8-i386-1.
+
+2004-08-12 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.8-rc4-i386-1.
+
+2004-08-04 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.8-rc3-i386-1.
+
+2004-07-18 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.8-rc2-i386-1.
+
+2004-07-12 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.8-rc1-i386-1.
+
+2004-06-16 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.7-i386-1.
+
+2004-06-10 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.7-rc3-i386-1.
+
+2004-06-09 Keith Owens <kaos@sgi.com>
+
+ * Namespace clean up. Mark code/variables as static when it is only
+ used in one file, delete dead code/variables.
+ * kdb v4.4-2.6.7-rc2-i386-3.
+
+2004-06-08 Keith Owens <kaos@sgi.com>
+
+ * Whitespace clean up, no code changes.
+ * kdb v4.4-2.6.7-rc2-i386-2.
+
+2004-06-07 Keith Owens <kaos@sgi.com>
+
+ * Force KALLSYMS and KALLSYMS_ALL for CONFIG_KDB.
+ * kdb v4.4-2.6.7-rc2-i386-1.
+
+2004-06-06 Keith Owens <kaos@sgi.com>
+
+ * Correct Kconfig help text.
+ * Coexist with CONFIG_REGPARM.
+ * Add standard archkdb commands.
+ * Move kdb_{get,put}userarea_size definitions to linux/kdb.h.
+ * kdb v4.4-2.6.6-i386-2.
+
+2004-05-23 Keith Owens <kaos@sgi.com>
+
+ * Move bfd.h and ansidecl.h from arch/$(ARCH)/kdb to include/asm-$(ARCH).
+ * Update copyright notices.
+ * kdb v4.4-2.6.6-i386-1.
+
+2004-05-10 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.6.6-i386-1.
+
+2004-05-06 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.6.6-rc3-i386-1.
+
+2004-05-06 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.6.6-rc2-i386-1.
+
+2004-04-30 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.6.6-rc1-i386-1.
+
+2004-04-05 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.6-5-i386-1.
+
+2004-02-29 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.6-4-rc1-i386-1.
+
+2004-02-18 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.6-3-i386-1.
+
+2004-02-17 Keith Owens <kaos@sgi.com>
+
+ * Pick up changes from Jim Houston for 2.6.
+ * Sync with kdb v4.3-2.4.25-rc1-i386-1.
+ * Adjust for LDT changes in i386 mainline.
+ * Convert longjmp buffers from static to dynamic allocation, for large
+ cpu counts.
+ * Do not use USB keyboard if it has not been probed.
+ * Do not print section data, 2.6 kallsyms does not support sections :(.
+ * kdb v4.3-2.6-3-rc3-i386-1.
+
+2003-08-29 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.4.22-i386-1.
+
+2003-08-05 Keith Owens <kaos@sgi.com>
+
+ * Remove duplicate setting of trap for machine_check.
+ * Only reset keyboard when CONFIG_VT_CONSOLE is defined.
+
+2003-07-27 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.4.22-pre8-i386-5.
+
+2003-07-20 Keith Owens <kaos@sgi.com>
+
+ * Remove compile warning on x86 commands.
+ * kdb v4.3-2.4.21-i386-5.
+
+2003-07-08 Keith Owens <kaos@sgi.com>
+
+ * Add new x86 commands - rdv, gdt, idt, ldt, ldtp, ptex.
+ Vamsi Krishna S., IBM.
+ * kdb v4.3-2.4.21-i386-4.
+
+2003-07-01 Keith Owens <kaos@sgi.com>
+
+ * Convert kdba_find_return() to two passes to reduce false positives.
+ * Correct jmp disp8 offset calculation for out of line lock code.
+ * Use NMI for kdb IPI in clustered APIC mode. Sachin Sant, IBM.
+ * kdb v4.3-2.4.21-i386-3.
+
+2003-06-23 Keith Owens <kaos@sgi.com>
+
+ * Sync with XFS 2.4.21 tree.
+ * kdb v4.3-2.4.21-i386-2.
+
+2003-06-20 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.4.21-i386-1.
+
+2003-06-20 Keith Owens <kaos@sgi.com>
+
+ * Add CONFIG_KDB_CONTINUE_CATASTROPHIC.
+ * Correct KDB_ENTER() definition.
+ * kdb v4.3-2.4.20-i386-1.
+
+2003-05-02 Keith Owens <kaos@sgi.com>
+
+ * Add kdba_fp_value().
+ * Limit backtrace size to catch loops.
+ * Add read/write access to user pages. Vamsi Krishna S., IBM
+ * Clean up USB keyboard support. Steven Dake.
+ * kdb v4.2-2.4.20-i386-1.
+
+2003-04-04 Keith Owens <kaos@sgi.com>
+
+ * Workarounds for scheduler bugs.
+ * kdb v4.1-2.4.20-i386-1.
+
+2003-03-16 Keith Owens <kaos@sgi.com>
+
+ * Each cpu saves its state as it enters kdb or before it enters code
+ which cannot call kdb, converting kdb from a pull to a push model.
+ * Clean up kdb interaction with CONFIG_SERIAL_CONSOLE.
+ * Removal of special cases for i386 backtrace from common code
+ simplifies the architecture code.
+ * Add command to dump i386 struct pt_regs.
+ * kdb v4.0-2.4.20-i386-1.
+
+2003-02-03 Keith Owens <kaos@sgi.com>
+
+ * Register kdb commands early.
+ * Handle KDB_ENTER() when kdb=off.
+ * Optimize __kdba_getarea_size when width is a constant.
+ * Decode oops via kallsyms if it is available.
+ * Update copyright notices to 2003.
+ * Handle call *disp32(%reg) in backtrace.
+ * Correct keyboard freeze. Ashish Kalra.
+ * Add command history and editing. Sonic Zhang.
+ * kdb_toggleled is conditional on KDB_BLINK_LED. Bernhard Fischer.
+ * Allow tab on serial line for symbol completion.
+ * Ignore KDB_ENTER() when kdb is already running.
+ * kdb v3.0-2.4.20-i386-1.
+
+2002-11-29 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.20.
+ * kdb v2.5-2.4.20-i386-1.
+
+2002-11-14 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.20-rc1.
+ * kdb v2.5-2.4.20-rc1-i386-1.
+
+2002-11-14 Keith Owens <kaos@sgi.com>
+
+ * General clean up of handling for breakpoints and single stepping over
+ software breakpoints.
+ * Accept ff 1x as well as ff dx for call *(%reg) in backtrace.
+ * kdb v2.5-2.4.19-i386-1.
+
+2002-11-01 Keith Owens <kaos@sgi.com>
+
+ * Prevent SMP IRQ overwriting KDB_ENTER().
+ * kdb v2.4-2.4.19-i386-2.
+
+2002-10-31 Keith Owens <kaos@sgi.com>
+
+ * Avoid KDB_VECTOR conflict with DUMP_VECTOR.
+ * Remove kdb_eframe_t.
+ * Sanity check if we have pt_regs.
+ * Remove kdba_getcurrentframe().
+ * Reinstate missing nmi_watchdog/kdb hook.
+ * kdb v2.4-2.4.19-i386-1.
+
+2002-10-17 Keith Owens <kaos@sgi.com>
+
+ * Correct compile with CONFIG_VT_CONSOLE=n.
+ * kdb v2.3-2.4.19-i386-5.
+
+2002-10-04 Keith Owens <kaos@sgi.com>
+
+ * Add USB keyboard option.
+ * Minimize differences between patches for 2.4 and 2.5 kernels.
+ * kdb v2.3-2.4.19-i386-4.
+
+2002-08-10 Keith Owens <kaos@sgi.com>
+
+ * Replace kdb_port with kdb_serial to support memory mapped I/O.
+ Note: This needs kdb v2.3-2.4.19-common-2 or later.
+ * kdb v2.3-2.4.19-i386-3.
+
+2002-08-09 Keith Owens <kaos@sgi.com>
+
+ * Use -fno-optimize-sibling-calls for kdb if gcc supports it.
+ * .text.lock does not consume an activation frame.
+ * kdb v2.3-2.4.19-i386-2.
+
+2002-08-07 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.19.
+ * Remove individual SGI copyrights, the general SGI copyright applies.
+ * New .text.lock name. Hugh Dickins.
+ * Set KERNEL_CS in kdba_getcurrentframe. Hugh Dickins.
+ * Clean up disassembly layout. Hugh Dickins, Keith Owens.
+ * Replace hard coded stack size with THREAD_SIZE. Hugh Dickins.
+ * Better stack layout on bt with no frame pointers. Hugh Dickins.
+ * Make i386 IO breakpoints (bpha <address> IO) work again.
+ Martin Wilck, Keith Owens.
+ * Remove fixed KDB_MAX_COMMANDS size.
+ * Add set_fs() around __copy_to_user on kernel addresses.
+ Randolph Chung.
+ * Position i386 for CONFIG_NUMA_REPLICATE.
+ * kdb v2.3-2.4.19-i386-1.
+
+2002-07-09 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.19-rc1.
+
+2002-06-14 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.19-pre10.
+ * kdb v2.1-2.4.19-pre10-i386-1.
+
+2002-04-09 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.19-pre6.
+ * kdb v2.1-2.4.19-pre6-i386-1.
+
+2002-02-26 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.18.
+ * kdb v2.1-2.4.18-i386-1.
+
+2002-01-18 Keith Owens <kaos@sgi.com>
+
+ * Use new kdb_get/put functions.
+ * Define kdba_{get,put}area_size functions for i386.
+ * Remove over-engineered dblist callback functions.
+ * Correctly handle failing call disp32 in backtrace.
+ * Remove bp_instvalid flag, redundant code.
+ * Remove dead code.
+ * kdb v2.1-2.4.17-i386-1.
+
+2002-01-04 Keith Owens <kaos@sgi.com>
+
+ * Sync xfs <-> kdb i386 code.
+
+2001-12-22 Keith Owens <kaos@sgi.com>
+
+ * Split kdb for i386 as kdb v2.0-2.4.17-i386-1.
--- /dev/null
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+#
+
+obj-$(CONFIG_KDB) := kdba_bt.o kdba_bp.o kdba_id.o kdba_io.o kdbasupport.o i386-dis.o
+
+override CFLAGS := $(CFLAGS:%-pg=% )
--- /dev/null
+/* Print i386 instructions for GDB, the GNU debugger.
+ Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use.
+ * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as
+ * required.
+ * Keith Owens <kaos@sgi.com> 15 May 2006
+ */
+
+/* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
+ July 1988
+ modified by John Hassey (hassey@dg-rtp.dg.com)
+ x86-64 support added by Jan Hubicka (jh@suse.cz)
+ VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
+
+/* The main tables describing the instructions is essentially a copy
+ of the "Opcode Map" chapter (Appendix A) of the Intel 80386
+ Programmers Manual. Usually, there is a capital letter, followed
+ by a small letter. The capital letter tell the addressing mode,
+ and the small letter tells about the operand size. Refer to
+ the Intel manual for details. */
+
+#ifdef __KERNEL__
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/dis-asm.h>
+#include <linux/kdb.h>
+#define abort() BUG()
+#else /* __KERNEL__ */
+#include "dis-asm.h"
+#include "sysdep.h"
+#include "opintl.h"
+#endif /* __KERNEL__ */
+
+#define MAXLEN 20
+
+#ifndef __KERNEL__
+#include <setjmp.h>
+#endif /* __KERNEL__ */
+
+#ifndef UNIXWARE_COMPAT
+/* Set non-zero for broken, compatible instructions. Set to zero for
+ non-broken opcodes. */
+#define UNIXWARE_COMPAT 1
+#endif
+
+static int fetch_data (struct disassemble_info *, bfd_byte *);
+static void ckprefix (void);
+static const char *prefix_name (int, int);
+static int print_insn (bfd_vma, disassemble_info *);
+static void dofloat (int);
+static void OP_ST (int, int);
+static void OP_STi (int, int);
+static int putop (const char *, int);
+static void oappend (const char *);
+static void append_seg (void);
+static void OP_indirE (int, int);
+static void print_operand_value (char *, int, bfd_vma);
+static void OP_E (int, int);
+static void OP_G (int, int);
+static bfd_vma get64 (void);
+static bfd_signed_vma get32 (void);
+static bfd_signed_vma get32s (void);
+static int get16 (void);
+static void set_op (bfd_vma, int);
+static void OP_REG (int, int);
+static void OP_IMREG (int, int);
+static void OP_I (int, int);
+static void OP_I64 (int, int);
+static void OP_sI (int, int);
+static void OP_J (int, int);
+static void OP_SEG (int, int);
+static void OP_DIR (int, int);
+static void OP_OFF (int, int);
+static void OP_OFF64 (int, int);
+static void ptr_reg (int, int);
+static void OP_ESreg (int, int);
+static void OP_DSreg (int, int);
+static void OP_C (int, int);
+static void OP_D (int, int);
+static void OP_T (int, int);
+static void OP_Rd (int, int);
+static void OP_MMX (int, int);
+static void OP_XMM (int, int);
+static void OP_EM (int, int);
+static void OP_EX (int, int);
+static void OP_MS (int, int);
+static void OP_XS (int, int);
+static void OP_M (int, int);
+static void OP_VMX (int, int);
+static void OP_0fae (int, int);
+static void OP_0f07 (int, int);
+static void NOP_Fixup (int, int);
+static void OP_3DNowSuffix (int, int);
+static void OP_SIMD_Suffix (int, int);
+static void SIMD_Fixup (int, int);
+static void PNI_Fixup (int, int);
+static void SVME_Fixup (int, int);
+static void INVLPG_Fixup (int, int);
+static void BadOp (void);
+static void SEG_Fixup (int, int);
+static void VMX_Fixup (int, int);
+
+struct dis_private {
+ /* Points to first byte not fetched. */
+ bfd_byte *max_fetched;
+ bfd_byte the_buffer[MAXLEN];
+ bfd_vma insn_start;
+ int orig_sizeflag;
+#ifndef __KERNEL__
+ jmp_buf bailout;
+#endif /* __KERNEL__ */
+};
+
+/* The opcode for the fwait instruction, which we treat as a prefix
+ when we can. */
+#define FWAIT_OPCODE (0x9b)
+
+/* Set to 1 for 64bit mode disassembly. */
+static int mode_64bit;
+
+/* Flags for the prefixes for the current instruction. See below. */
+static int prefixes;
+
+/* REX prefix the current instruction. See below. */
+static int rex;
+/* Bits of REX we've already used. */
+static int rex_used;
+#define REX_MODE64 8
+#define REX_EXTX 4
+#define REX_EXTY 2
+#define REX_EXTZ 1
+/* Mark parts used in the REX prefix. When we are testing for
+ empty prefix (for 8bit register REX extension), just mask it
+ out. Otherwise test for REX bit is excuse for existence of REX
+ only in case value is nonzero. */
+#define USED_REX(value) \
+ { \
+ if (value) \
+ rex_used |= (rex & value) ? (value) | 0x40 : 0; \
+ else \
+ rex_used |= 0x40; \
+ }
+
+/* Flags for prefixes which we somehow handled when printing the
+ current instruction. */
+static int used_prefixes;
+
+/* Flags stored in PREFIXES. */
+#define PREFIX_REPZ 1
+#define PREFIX_REPNZ 2
+#define PREFIX_LOCK 4
+#define PREFIX_CS 8
+#define PREFIX_SS 0x10
+#define PREFIX_DS 0x20
+#define PREFIX_ES 0x40
+#define PREFIX_FS 0x80
+#define PREFIX_GS 0x100
+#define PREFIX_DATA 0x200
+#define PREFIX_ADDR 0x400
+#define PREFIX_FWAIT 0x800
+
+/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
+ to ADDR (exclusive) are valid. Returns 1 for success, longjmps
+ on error. */
+#define FETCH_DATA(info, addr) \
+ ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
+ ? 1 : fetch_data ((info), (addr)))
+
+static int
+fetch_data (struct disassemble_info *info, bfd_byte *addr)
+{
+ int status;
+ struct dis_private *priv = (struct dis_private *) info->private_data;
+ bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
+
+ status = (*info->read_memory_func) (start,
+ priv->max_fetched,
+ addr - priv->max_fetched,
+ info);
+ if (status != 0)
+ {
+ /* If we did manage to read at least one byte, then
+ print_insn_i386 will do something sensible. Otherwise, print
+ an error. We do that here because this is where we know
+ STATUS. */
+ if (priv->max_fetched == priv->the_buffer)
+ (*info->memory_error_func) (status, start, info);
+#ifndef __KERNEL__
+ longjmp (priv->bailout, 1);
+#else /* __KERNEL__ */
+ /* XXX - what to do? */
+ kdb_printf("Hmm. longjmp.\n");
+#endif /* __KERNEL__ */
+ }
+ else
+ priv->max_fetched = addr;
+ return 1;
+}
+
+#define XX NULL, 0
+
+#define Eb OP_E, b_mode
+#define Ev OP_E, v_mode
+#define Ed OP_E, d_mode
+#define Eq OP_E, q_mode
+#define Edq OP_E, dq_mode
+#define Edqw OP_E, dqw_mode
+#define indirEv OP_indirE, branch_v_mode
+#define indirEp OP_indirE, f_mode
+#define Em OP_E, m_mode
+#define Ew OP_E, w_mode
+#define Ma OP_E, v_mode
+#define M OP_M, 0 /* lea, lgdt, etc. */
+#define Mp OP_M, f_mode /* 32 or 48 bit memory operand for LDS, LES etc */
+#define Gb OP_G, b_mode
+#define Gv OP_G, v_mode
+#define Gd OP_G, d_mode
+#define Gdq OP_G, dq_mode
+#define Gm OP_G, m_mode
+#define Gw OP_G, w_mode
+#define Rd OP_Rd, d_mode
+#define Rm OP_Rd, m_mode
+#define Ib OP_I, b_mode
+#define sIb OP_sI, b_mode /* sign extened byte */
+#define Iv OP_I, v_mode
+#define Iq OP_I, q_mode
+#define Iv64 OP_I64, v_mode
+#define Iw OP_I, w_mode
+#define I1 OP_I, const_1_mode
+#define Jb OP_J, b_mode
+#define Jv OP_J, v_mode
+#define Cm OP_C, m_mode
+#define Dm OP_D, m_mode
+#define Td OP_T, d_mode
+#define Sv SEG_Fixup, v_mode
+
+#define RMeAX OP_REG, eAX_reg
+#define RMeBX OP_REG, eBX_reg
+#define RMeCX OP_REG, eCX_reg
+#define RMeDX OP_REG, eDX_reg
+#define RMeSP OP_REG, eSP_reg
+#define RMeBP OP_REG, eBP_reg
+#define RMeSI OP_REG, eSI_reg
+#define RMeDI OP_REG, eDI_reg
+#define RMrAX OP_REG, rAX_reg
+#define RMrBX OP_REG, rBX_reg
+#define RMrCX OP_REG, rCX_reg
+#define RMrDX OP_REG, rDX_reg
+#define RMrSP OP_REG, rSP_reg
+#define RMrBP OP_REG, rBP_reg
+#define RMrSI OP_REG, rSI_reg
+#define RMrDI OP_REG, rDI_reg
+#define RMAL OP_REG, al_reg
+#define RMAL OP_REG, al_reg
+#define RMCL OP_REG, cl_reg
+#define RMDL OP_REG, dl_reg
+#define RMBL OP_REG, bl_reg
+#define RMAH OP_REG, ah_reg
+#define RMCH OP_REG, ch_reg
+#define RMDH OP_REG, dh_reg
+#define RMBH OP_REG, bh_reg
+#define RMAX OP_REG, ax_reg
+#define RMDX OP_REG, dx_reg
+
+#define eAX OP_IMREG, eAX_reg
+#define eBX OP_IMREG, eBX_reg
+#define eCX OP_IMREG, eCX_reg
+#define eDX OP_IMREG, eDX_reg
+#define eSP OP_IMREG, eSP_reg
+#define eBP OP_IMREG, eBP_reg
+#define eSI OP_IMREG, eSI_reg
+#define eDI OP_IMREG, eDI_reg
+#define AL OP_IMREG, al_reg
+#define AL OP_IMREG, al_reg
+#define CL OP_IMREG, cl_reg
+#define DL OP_IMREG, dl_reg
+#define BL OP_IMREG, bl_reg
+#define AH OP_IMREG, ah_reg
+#define CH OP_IMREG, ch_reg
+#define DH OP_IMREG, dh_reg
+#define BH OP_IMREG, bh_reg
+#define AX OP_IMREG, ax_reg
+#define DX OP_IMREG, dx_reg
+#define indirDX OP_IMREG, indir_dx_reg
+
+#define Sw OP_SEG, w_mode
+#define Ap OP_DIR, 0
+#define Ob OP_OFF, b_mode
+#define Ob64 OP_OFF64, b_mode
+#define Ov OP_OFF, v_mode
+#define Ov64 OP_OFF64, v_mode
+#define Xb OP_DSreg, eSI_reg
+#define Xv OP_DSreg, eSI_reg
+#define Yb OP_ESreg, eDI_reg
+#define Yv OP_ESreg, eDI_reg
+#define DSBX OP_DSreg, eBX_reg
+
+#define es OP_REG, es_reg
+#define ss OP_REG, ss_reg
+#define cs OP_REG, cs_reg
+#define ds OP_REG, ds_reg
+#define fs OP_REG, fs_reg
+#define gs OP_REG, gs_reg
+
+#define MX OP_MMX, 0
+#define XM OP_XMM, 0
+#define EM OP_EM, v_mode
+#define EX OP_EX, v_mode
+#define MS OP_MS, v_mode
+#define XS OP_XS, v_mode
+#define VM OP_VMX, q_mode
+#define OPSUF OP_3DNowSuffix, 0
+#define OPSIMD OP_SIMD_Suffix, 0
+
+#define cond_jump_flag NULL, cond_jump_mode
+#define loop_jcxz_flag NULL, loop_jcxz_mode
+
+/* bits in sizeflag */
+#define SUFFIX_ALWAYS 4
+#define AFLAG 2
+#define DFLAG 1
+
+#define b_mode 1 /* byte operand */
+#define v_mode 2 /* operand size depends on prefixes */
+#define w_mode 3 /* word operand */
+#define d_mode 4 /* double word operand */
+#define q_mode 5 /* quad word operand */
+#define t_mode 6 /* ten-byte operand */
+#define x_mode 7 /* 16-byte XMM operand */
+#define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
+#define cond_jump_mode 9
+#define loop_jcxz_mode 10
+#define dq_mode 11 /* operand size depends on REX prefixes. */
+#define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
+#define f_mode 13 /* 4- or 6-byte pointer operand */
+#define const_1_mode 14
+#define branch_v_mode 15 /* v_mode for branch. */
+
+#define es_reg 100
+#define cs_reg 101
+#define ss_reg 102
+#define ds_reg 103
+#define fs_reg 104
+#define gs_reg 105
+
+#define eAX_reg 108
+#define eCX_reg 109
+#define eDX_reg 110
+#define eBX_reg 111
+#define eSP_reg 112
+#define eBP_reg 113
+#define eSI_reg 114
+#define eDI_reg 115
+
+#define al_reg 116
+#define cl_reg 117
+#define dl_reg 118
+#define bl_reg 119
+#define ah_reg 120
+#define ch_reg 121
+#define dh_reg 122
+#define bh_reg 123
+
+#define ax_reg 124
+#define cx_reg 125
+#define dx_reg 126
+#define bx_reg 127
+#define sp_reg 128
+#define bp_reg 129
+#define si_reg 130
+#define di_reg 131
+
+#define rAX_reg 132
+#define rCX_reg 133
+#define rDX_reg 134
+#define rBX_reg 135
+#define rSP_reg 136
+#define rBP_reg 137
+#define rSI_reg 138
+#define rDI_reg 139
+
+#define indir_dx_reg 150
+
+#define FLOATCODE 1
+#define USE_GROUPS 2
+#define USE_PREFIX_USER_TABLE 3
+#define X86_64_SPECIAL 4
+
+#define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
+
+#define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0
+#define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0
+#define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0
+#define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0
+#define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0
+#define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0
+#define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0
+#define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0
+#define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0
+#define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0
+#define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
+#define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
+#define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
+#define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
+#define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
+#define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
+#define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
+#define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
+#define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
+#define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
+#define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
+#define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
+#define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
+#define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0
+#define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0
+
+#define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0
+#define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0
+#define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0
+#define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0
+#define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0
+#define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0
+#define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0
+#define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0
+#define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0
+#define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0
+#define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
+#define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
+#define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
+#define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
+#define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
+#define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
+#define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
+#define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
+#define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
+#define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
+#define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
+#define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
+#define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
+#define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
+#define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
+#define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
+#define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
+#define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0
+#define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0
+#define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0
+#define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0
+#define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0
+#define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0
+
+#define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
+
+typedef void (*op_rtn) (int bytemode, int sizeflag);
+
+struct dis386 {
+ const char *name;
+ op_rtn op1;
+ int bytemode1;
+ op_rtn op2;
+ int bytemode2;
+ op_rtn op3;
+ int bytemode3;
+};
+
+/* Upper case letters in the instruction names here are macros.
+ 'A' => print 'b' if no register operands or suffix_always is true
+ 'B' => print 'b' if suffix_always is true
+ 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
+ . size prefix
+ 'E' => print 'e' if 32-bit form of jcxz
+ 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
+ 'H' => print ",pt" or ",pn" branch hint
+ 'I' => honor following macro letter even in Intel mode (implemented only
+ . for some of the macro letters)
+ 'J' => print 'l'
+ 'L' => print 'l' if suffix_always is true
+ 'N' => print 'n' if instruction has no wait "prefix"
+ 'O' => print 'd', or 'o'
+ 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
+ . or suffix_always is true. print 'q' if rex prefix is present.
+ 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
+ . is true
+ 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
+ 'S' => print 'w', 'l' or 'q' if suffix_always is true
+ 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
+ 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
+ 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
+ 'X' => print 's', 'd' depending on data16 prefix (for XMM)
+ 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
+
+ Many of the above letters print nothing in Intel mode. See "putop"
+ for the details.
+
+ Braces '{' and '}', and vertical bars '|', indicate alternative
+ mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
+ modes. In cases where there are only two alternatives, the X86_64
+ instruction is reserved, and "(bad)" is printed.
+*/
+
+static const struct dis386 dis386[] = {
+ /* 00 */
+ { "addB", Eb, Gb, XX },
+ { "addS", Ev, Gv, XX },
+ { "addB", Gb, Eb, XX },
+ { "addS", Gv, Ev, XX },
+ { "addB", AL, Ib, XX },
+ { "addS", eAX, Iv, XX },
+ { "push{T|}", es, XX, XX },
+ { "pop{T|}", es, XX, XX },
+ /* 08 */
+ { "orB", Eb, Gb, XX },
+ { "orS", Ev, Gv, XX },
+ { "orB", Gb, Eb, XX },
+ { "orS", Gv, Ev, XX },
+ { "orB", AL, Ib, XX },
+ { "orS", eAX, Iv, XX },
+ { "push{T|}", cs, XX, XX },
+ { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */
+ /* 10 */
+ { "adcB", Eb, Gb, XX },
+ { "adcS", Ev, Gv, XX },
+ { "adcB", Gb, Eb, XX },
+ { "adcS", Gv, Ev, XX },
+ { "adcB", AL, Ib, XX },
+ { "adcS", eAX, Iv, XX },
+ { "push{T|}", ss, XX, XX },
+ { "popT|}", ss, XX, XX },
+ /* 18 */
+ { "sbbB", Eb, Gb, XX },
+ { "sbbS", Ev, Gv, XX },
+ { "sbbB", Gb, Eb, XX },
+ { "sbbS", Gv, Ev, XX },
+ { "sbbB", AL, Ib, XX },
+ { "sbbS", eAX, Iv, XX },
+ { "push{T|}", ds, XX, XX },
+ { "pop{T|}", ds, XX, XX },
+ /* 20 */
+ { "andB", Eb, Gb, XX },
+ { "andS", Ev, Gv, XX },
+ { "andB", Gb, Eb, XX },
+ { "andS", Gv, Ev, XX },
+ { "andB", AL, Ib, XX },
+ { "andS", eAX, Iv, XX },
+ { "(bad)", XX, XX, XX }, /* SEG ES prefix */
+ { "daa{|}", XX, XX, XX },
+ /* 28 */
+ { "subB", Eb, Gb, XX },
+ { "subS", Ev, Gv, XX },
+ { "subB", Gb, Eb, XX },
+ { "subS", Gv, Ev, XX },
+ { "subB", AL, Ib, XX },
+ { "subS", eAX, Iv, XX },
+ { "(bad)", XX, XX, XX }, /* SEG CS prefix */
+ { "das{|}", XX, XX, XX },
+ /* 30 */
+ { "xorB", Eb, Gb, XX },
+ { "xorS", Ev, Gv, XX },
+ { "xorB", Gb, Eb, XX },
+ { "xorS", Gv, Ev, XX },
+ { "xorB", AL, Ib, XX },
+ { "xorS", eAX, Iv, XX },
+ { "(bad)", XX, XX, XX }, /* SEG SS prefix */
+ { "aaa{|}", XX, XX, XX },
+ /* 38 */
+ { "cmpB", Eb, Gb, XX },
+ { "cmpS", Ev, Gv, XX },
+ { "cmpB", Gb, Eb, XX },
+ { "cmpS", Gv, Ev, XX },
+ { "cmpB", AL, Ib, XX },
+ { "cmpS", eAX, Iv, XX },
+ { "(bad)", XX, XX, XX }, /* SEG DS prefix */
+ { "aas{|}", XX, XX, XX },
+ /* 40 */
+ { "inc{S|}", RMeAX, XX, XX },
+ { "inc{S|}", RMeCX, XX, XX },
+ { "inc{S|}", RMeDX, XX, XX },
+ { "inc{S|}", RMeBX, XX, XX },
+ { "inc{S|}", RMeSP, XX, XX },
+ { "inc{S|}", RMeBP, XX, XX },
+ { "inc{S|}", RMeSI, XX, XX },
+ { "inc{S|}", RMeDI, XX, XX },
+ /* 48 */
+ { "dec{S|}", RMeAX, XX, XX },
+ { "dec{S|}", RMeCX, XX, XX },
+ { "dec{S|}", RMeDX, XX, XX },
+ { "dec{S|}", RMeBX, XX, XX },
+ { "dec{S|}", RMeSP, XX, XX },
+ { "dec{S|}", RMeBP, XX, XX },
+ { "dec{S|}", RMeSI, XX, XX },
+ { "dec{S|}", RMeDI, XX, XX },
+ /* 50 */
+ { "pushS", RMrAX, XX, XX },
+ { "pushS", RMrCX, XX, XX },
+ { "pushS", RMrDX, XX, XX },
+ { "pushS", RMrBX, XX, XX },
+ { "pushS", RMrSP, XX, XX },
+ { "pushS", RMrBP, XX, XX },
+ { "pushS", RMrSI, XX, XX },
+ { "pushS", RMrDI, XX, XX },
+ /* 58 */
+ { "popS", RMrAX, XX, XX },
+ { "popS", RMrCX, XX, XX },
+ { "popS", RMrDX, XX, XX },
+ { "popS", RMrBX, XX, XX },
+ { "popS", RMrSP, XX, XX },
+ { "popS", RMrBP, XX, XX },
+ { "popS", RMrSI, XX, XX },
+ { "popS", RMrDI, XX, XX },
+ /* 60 */
+ { "pusha{P|}", XX, XX, XX },
+ { "popa{P|}", XX, XX, XX },
+ { "bound{S|}", Gv, Ma, XX },
+ { X86_64_0 },
+ { "(bad)", XX, XX, XX }, /* seg fs */
+ { "(bad)", XX, XX, XX }, /* seg gs */
+ { "(bad)", XX, XX, XX }, /* op size prefix */
+ { "(bad)", XX, XX, XX }, /* adr size prefix */
+ /* 68 */
+ { "pushT", Iq, XX, XX },
+ { "imulS", Gv, Ev, Iv },
+ { "pushT", sIb, XX, XX },
+ { "imulS", Gv, Ev, sIb },
+ { "ins{b||b|}", Yb, indirDX, XX },
+ { "ins{R||R|}", Yv, indirDX, XX },
+ { "outs{b||b|}", indirDX, Xb, XX },
+ { "outs{R||R|}", indirDX, Xv, XX },
+ /* 70 */
+ { "joH", Jb, XX, cond_jump_flag },
+ { "jnoH", Jb, XX, cond_jump_flag },
+ { "jbH", Jb, XX, cond_jump_flag },
+ { "jaeH", Jb, XX, cond_jump_flag },
+ { "jeH", Jb, XX, cond_jump_flag },
+ { "jneH", Jb, XX, cond_jump_flag },
+ { "jbeH", Jb, XX, cond_jump_flag },
+ { "jaH", Jb, XX, cond_jump_flag },
+ /* 78 */
+ { "jsH", Jb, XX, cond_jump_flag },
+ { "jnsH", Jb, XX, cond_jump_flag },
+ { "jpH", Jb, XX, cond_jump_flag },
+ { "jnpH", Jb, XX, cond_jump_flag },
+ { "jlH", Jb, XX, cond_jump_flag },
+ { "jgeH", Jb, XX, cond_jump_flag },
+ { "jleH", Jb, XX, cond_jump_flag },
+ { "jgH", Jb, XX, cond_jump_flag },
+ /* 80 */
+ { GRP1b },
+ { GRP1S },
+ { "(bad)", XX, XX, XX },
+ { GRP1Ss },
+ { "testB", Eb, Gb, XX },
+ { "testS", Ev, Gv, XX },
+ { "xchgB", Eb, Gb, XX },
+ { "xchgS", Ev, Gv, XX },
+ /* 88 */
+ { "movB", Eb, Gb, XX },
+ { "movS", Ev, Gv, XX },
+ { "movB", Gb, Eb, XX },
+ { "movS", Gv, Ev, XX },
+ { "movQ", Sv, Sw, XX },
+ { "leaS", Gv, M, XX },
+ { "movQ", Sw, Sv, XX },
+ { "popU", Ev, XX, XX },
+ /* 90 */
+ { "nop", NOP_Fixup, 0, XX, XX },
+ { "xchgS", RMeCX, eAX, XX },
+ { "xchgS", RMeDX, eAX, XX },
+ { "xchgS", RMeBX, eAX, XX },
+ { "xchgS", RMeSP, eAX, XX },
+ { "xchgS", RMeBP, eAX, XX },
+ { "xchgS", RMeSI, eAX, XX },
+ { "xchgS", RMeDI, eAX, XX },
+ /* 98 */
+ { "cW{tR||tR|}", XX, XX, XX },
+ { "cR{tO||tO|}", XX, XX, XX },
+ { "Jcall{T|}", Ap, XX, XX },
+ { "(bad)", XX, XX, XX }, /* fwait */
+ { "pushfT", XX, XX, XX },
+ { "popfT", XX, XX, XX },
+ { "sahf{|}", XX, XX, XX },
+ { "lahf{|}", XX, XX, XX },
+ /* a0 */
+ { "movB", AL, Ob64, XX },
+ { "movS", eAX, Ov64, XX },
+ { "movB", Ob64, AL, XX },
+ { "movS", Ov64, eAX, XX },
+ { "movs{b||b|}", Yb, Xb, XX },
+ { "movs{R||R|}", Yv, Xv, XX },
+ { "cmps{b||b|}", Xb, Yb, XX },
+ { "cmps{R||R|}", Xv, Yv, XX },
+ /* a8 */
+ { "testB", AL, Ib, XX },
+ { "testS", eAX, Iv, XX },
+ { "stosB", Yb, AL, XX },
+ { "stosS", Yv, eAX, XX },
+ { "lodsB", AL, Xb, XX },
+ { "lodsS", eAX, Xv, XX },
+ { "scasB", AL, Yb, XX },
+ { "scasS", eAX, Yv, XX },
+ /* b0 */
+ { "movB", RMAL, Ib, XX },
+ { "movB", RMCL, Ib, XX },
+ { "movB", RMDL, Ib, XX },
+ { "movB", RMBL, Ib, XX },
+ { "movB", RMAH, Ib, XX },
+ { "movB", RMCH, Ib, XX },
+ { "movB", RMDH, Ib, XX },
+ { "movB", RMBH, Ib, XX },
+ /* b8 */
+ { "movS", RMeAX, Iv64, XX },
+ { "movS", RMeCX, Iv64, XX },
+ { "movS", RMeDX, Iv64, XX },
+ { "movS", RMeBX, Iv64, XX },
+ { "movS", RMeSP, Iv64, XX },
+ { "movS", RMeBP, Iv64, XX },
+ { "movS", RMeSI, Iv64, XX },
+ { "movS", RMeDI, Iv64, XX },
+ /* c0 */
+ { GRP2b },
+ { GRP2S },
+ { "retT", Iw, XX, XX },
+ { "retT", XX, XX, XX },
+ { "les{S|}", Gv, Mp, XX },
+ { "ldsS", Gv, Mp, XX },
+ { "movA", Eb, Ib, XX },
+ { "movQ", Ev, Iv, XX },
+ /* c8 */
+ { "enterT", Iw, Ib, XX },
+ { "leaveT", XX, XX, XX },
+ { "lretP", Iw, XX, XX },
+ { "lretP", XX, XX, XX },
+ { "int3", XX, XX, XX },
+ { "int", Ib, XX, XX },
+ { "into{|}", XX, XX, XX },
+ { "iretP", XX, XX, XX },
+ /* d0 */
+ { GRP2b_one },
+ { GRP2S_one },
+ { GRP2b_cl },
+ { GRP2S_cl },
+ { "aam{|}", sIb, XX, XX },
+ { "aad{|}", sIb, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "xlat", DSBX, XX, XX },
+ /* d8 */
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ /* e0 */
+ { "loopneFH", Jb, XX, loop_jcxz_flag },
+ { "loopeFH", Jb, XX, loop_jcxz_flag },
+ { "loopFH", Jb, XX, loop_jcxz_flag },
+ { "jEcxzH", Jb, XX, loop_jcxz_flag },
+ { "inB", AL, Ib, XX },
+ { "inS", eAX, Ib, XX },
+ { "outB", Ib, AL, XX },
+ { "outS", Ib, eAX, XX },
+ /* e8 */
+ { "callT", Jv, XX, XX },
+ { "jmpT", Jv, XX, XX },
+ { "Jjmp{T|}", Ap, XX, XX },
+ { "jmp", Jb, XX, XX },
+ { "inB", AL, indirDX, XX },
+ { "inS", eAX, indirDX, XX },
+ { "outB", indirDX, AL, XX },
+ { "outS", indirDX, eAX, XX },
+ /* f0 */
+ { "(bad)", XX, XX, XX }, /* lock prefix */
+ { "icebp", XX, XX, XX },
+ { "(bad)", XX, XX, XX }, /* repne */
+ { "(bad)", XX, XX, XX }, /* repz */
+ { "hlt", XX, XX, XX },
+ { "cmc", XX, XX, XX },
+ { GRP3b },
+ { GRP3S },
+ /* f8 */
+ { "clc", XX, XX, XX },
+ { "stc", XX, XX, XX },
+ { "cli", XX, XX, XX },
+ { "sti", XX, XX, XX },
+ { "cld", XX, XX, XX },
+ { "std", XX, XX, XX },
+ { GRP4 },
+ { GRP5 },
+};
+
+static const struct dis386 dis386_twobyte[] = {
+ /* 00 */
+ { GRP6 },
+ { GRP7 },
+ { "larS", Gv, Ew, XX },
+ { "lslS", Gv, Ew, XX },
+ { "(bad)", XX, XX, XX },
+ { "syscall", XX, XX, XX },
+ { "clts", XX, XX, XX },
+ { "sysretP", XX, XX, XX },
+ /* 08 */
+ { "invd", XX, XX, XX },
+ { "wbinvd", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "ud2a", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { GRPAMD },
+ { "femms", XX, XX, XX },
+ { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix. */
+ /* 10 */
+ { PREGRP8 },
+ { PREGRP9 },
+ { PREGRP30 },
+ { "movlpX", EX, XM, SIMD_Fixup, 'h' },
+ { "unpcklpX", XM, EX, XX },
+ { "unpckhpX", XM, EX, XX },
+ { PREGRP31 },
+ { "movhpX", EX, XM, SIMD_Fixup, 'l' },
+ /* 18 */
+ { GRP14 },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ /* 20 */
+ { "movL", Rm, Cm, XX },
+ { "movL", Rm, Dm, XX },
+ { "movL", Cm, Rm, XX },
+ { "movL", Dm, Rm, XX },
+ { "movL", Rd, Td, XX },
+ { "(bad)", XX, XX, XX },
+ { "movL", Td, Rd, XX },
+ { "(bad)", XX, XX, XX },
+ /* 28 */
+ { "movapX", XM, EX, XX },
+ { "movapX", EX, XM, XX },
+ { PREGRP2 },
+ { "movntpX", Ev, XM, XX },
+ { PREGRP4 },
+ { PREGRP3 },
+ { "ucomisX", XM,EX, XX },
+ { "comisX", XM,EX, XX },
+ /* 30 */
+ { "wrmsr", XX, XX, XX },
+ { "rdtsc", XX, XX, XX },
+ { "rdmsr", XX, XX, XX },
+ { "rdpmc", XX, XX, XX },
+ { "sysenter", XX, XX, XX },
+ { "sysexit", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ /* 38 */
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ /* 40 */
+ { "cmovo", Gv, Ev, XX },
+ { "cmovno", Gv, Ev, XX },
+ { "cmovb", Gv, Ev, XX },
+ { "cmovae", Gv, Ev, XX },
+ { "cmove", Gv, Ev, XX },
+ { "cmovne", Gv, Ev, XX },
+ { "cmovbe", Gv, Ev, XX },
+ { "cmova", Gv, Ev, XX },
+ /* 48 */
+ { "cmovs", Gv, Ev, XX },
+ { "cmovns", Gv, Ev, XX },
+ { "cmovp", Gv, Ev, XX },
+ { "cmovnp", Gv, Ev, XX },
+ { "cmovl", Gv, Ev, XX },
+ { "cmovge", Gv, Ev, XX },
+ { "cmovle", Gv, Ev, XX },
+ { "cmovg", Gv, Ev, XX },
+ /* 50 */
+ { "movmskpX", Gdq, XS, XX },
+ { PREGRP13 },
+ { PREGRP12 },
+ { PREGRP11 },
+ { "andpX", XM, EX, XX },
+ { "andnpX", XM, EX, XX },
+ { "orpX", XM, EX, XX },
+ { "xorpX", XM, EX, XX },
+ /* 58 */
+ { PREGRP0 },
+ { PREGRP10 },
+ { PREGRP17 },
+ { PREGRP16 },
+ { PREGRP14 },
+ { PREGRP7 },
+ { PREGRP5 },
+ { PREGRP6 },
+ /* 60 */
+ { "punpcklbw", MX, EM, XX },
+ { "punpcklwd", MX, EM, XX },
+ { "punpckldq", MX, EM, XX },
+ { "packsswb", MX, EM, XX },
+ { "pcmpgtb", MX, EM, XX },
+ { "pcmpgtw", MX, EM, XX },
+ { "pcmpgtd", MX, EM, XX },
+ { "packuswb", MX, EM, XX },
+ /* 68 */
+ { "punpckhbw", MX, EM, XX },
+ { "punpckhwd", MX, EM, XX },
+ { "punpckhdq", MX, EM, XX },
+ { "packssdw", MX, EM, XX },
+ { PREGRP26 },
+ { PREGRP24 },
+ { "movd", MX, Edq, XX },
+ { PREGRP19 },
+ /* 70 */
+ { PREGRP22 },
+ { GRP10 },
+ { GRP11 },
+ { GRP12 },
+ { "pcmpeqb", MX, EM, XX },
+ { "pcmpeqw", MX, EM, XX },
+ { "pcmpeqd", MX, EM, XX },
+ { "emms", XX, XX, XX },
+ /* 78 */
+ { "vmread", Em, Gm, XX },
+ { "vmwrite", Gm, Em, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { PREGRP28 },
+ { PREGRP29 },
+ { PREGRP23 },
+ { PREGRP20 },
+ /* 80 */
+ { "joH", Jv, XX, cond_jump_flag },
+ { "jnoH", Jv, XX, cond_jump_flag },
+ { "jbH", Jv, XX, cond_jump_flag },
+ { "jaeH", Jv, XX, cond_jump_flag },
+ { "jeH", Jv, XX, cond_jump_flag },
+ { "jneH", Jv, XX, cond_jump_flag },
+ { "jbeH", Jv, XX, cond_jump_flag },
+ { "jaH", Jv, XX, cond_jump_flag },
+ /* 88 */
+ { "jsH", Jv, XX, cond_jump_flag },
+ { "jnsH", Jv, XX, cond_jump_flag },
+ { "jpH", Jv, XX, cond_jump_flag },
+ { "jnpH", Jv, XX, cond_jump_flag },
+ { "jlH", Jv, XX, cond_jump_flag },
+ { "jgeH", Jv, XX, cond_jump_flag },
+ { "jleH", Jv, XX, cond_jump_flag },
+ { "jgH", Jv, XX, cond_jump_flag },
+ /* 90 */
+ { "seto", Eb, XX, XX },
+ { "setno", Eb, XX, XX },
+ { "setb", Eb, XX, XX },
+ { "setae", Eb, XX, XX },
+ { "sete", Eb, XX, XX },
+ { "setne", Eb, XX, XX },
+ { "setbe", Eb, XX, XX },
+ { "seta", Eb, XX, XX },
+ /* 98 */
+ { "sets", Eb, XX, XX },
+ { "setns", Eb, XX, XX },
+ { "setp", Eb, XX, XX },
+ { "setnp", Eb, XX, XX },
+ { "setl", Eb, XX, XX },
+ { "setge", Eb, XX, XX },
+ { "setle", Eb, XX, XX },
+ { "setg", Eb, XX, XX },
+ /* a0 */
+ { "pushT", fs, XX, XX },
+ { "popT", fs, XX, XX },
+ { "cpuid", XX, XX, XX },
+ { "btS", Ev, Gv, XX },
+ { "shldS", Ev, Gv, Ib },
+ { "shldS", Ev, Gv, CL },
+ { GRPPADLCK2 },
+ { GRPPADLCK1 },
+ /* a8 */
+ { "pushT", gs, XX, XX },
+ { "popT", gs, XX, XX },
+ { "rsm", XX, XX, XX },
+ { "btsS", Ev, Gv, XX },
+ { "shrdS", Ev, Gv, Ib },
+ { "shrdS", Ev, Gv, CL },
+ { GRP13 },
+ { "imulS", Gv, Ev, XX },
+ /* b0 */
+ { "cmpxchgB", Eb, Gb, XX },
+ { "cmpxchgS", Ev, Gv, XX },
+ { "lssS", Gv, Mp, XX },
+ { "btrS", Ev, Gv, XX },
+ { "lfsS", Gv, Mp, XX },
+ { "lgsS", Gv, Mp, XX },
+ { "movz{bR|x|bR|x}", Gv, Eb, XX },
+ { "movz{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movzww ! */
+ /* b8 */
+ { "(bad)", XX, XX, XX },
+ { "ud2b", XX, XX, XX },
+ { GRP8 },
+ { "btcS", Ev, Gv, XX },
+ { "bsfS", Gv, Ev, XX },
+ { "bsrS", Gv, Ev, XX },
+ { "movs{bR|x|bR|x}", Gv, Eb, XX },
+ { "movs{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movsww ! */
+ /* c0 */
+ { "xaddB", Eb, Gb, XX },
+ { "xaddS", Ev, Gv, XX },
+ { PREGRP1 },
+ { "movntiS", Ev, Gv, XX },
+ { "pinsrw", MX, Edqw, Ib },
+ { "pextrw", Gdq, MS, Ib },
+ { "shufpX", XM, EX, Ib },
+ { GRP9 },
+ /* c8 */
+ { "bswap", RMeAX, XX, XX },
+ { "bswap", RMeCX, XX, XX },
+ { "bswap", RMeDX, XX, XX },
+ { "bswap", RMeBX, XX, XX },
+ { "bswap", RMeSP, XX, XX },
+ { "bswap", RMeBP, XX, XX },
+ { "bswap", RMeSI, XX, XX },
+ { "bswap", RMeDI, XX, XX },
+ /* d0 */
+ { PREGRP27 },
+ { "psrlw", MX, EM, XX },
+ { "psrld", MX, EM, XX },
+ { "psrlq", MX, EM, XX },
+ { "paddq", MX, EM, XX },
+ { "pmullw", MX, EM, XX },
+ { PREGRP21 },
+ { "pmovmskb", Gdq, MS, XX },
+ /* d8 */
+ { "psubusb", MX, EM, XX },
+ { "psubusw", MX, EM, XX },
+ { "pminub", MX, EM, XX },
+ { "pand", MX, EM, XX },
+ { "paddusb", MX, EM, XX },
+ { "paddusw", MX, EM, XX },
+ { "pmaxub", MX, EM, XX },
+ { "pandn", MX, EM, XX },
+ /* e0 */
+ { "pavgb", MX, EM, XX },
+ { "psraw", MX, EM, XX },
+ { "psrad", MX, EM, XX },
+ { "pavgw", MX, EM, XX },
+ { "pmulhuw", MX, EM, XX },
+ { "pmulhw", MX, EM, XX },
+ { PREGRP15 },
+ { PREGRP25 },
+ /* e8 */
+ { "psubsb", MX, EM, XX },
+ { "psubsw", MX, EM, XX },
+ { "pminsw", MX, EM, XX },
+ { "por", MX, EM, XX },
+ { "paddsb", MX, EM, XX },
+ { "paddsw", MX, EM, XX },
+ { "pmaxsw", MX, EM, XX },
+ { "pxor", MX, EM, XX },
+ /* f0 */
+ { PREGRP32 },
+ { "psllw", MX, EM, XX },
+ { "pslld", MX, EM, XX },
+ { "psllq", MX, EM, XX },
+ { "pmuludq", MX, EM, XX },
+ { "pmaddwd", MX, EM, XX },
+ { "psadbw", MX, EM, XX },
+ { PREGRP18 },
+ /* f8 */
+ { "psubb", MX, EM, XX },
+ { "psubw", MX, EM, XX },
+ { "psubd", MX, EM, XX },
+ { "psubq", MX, EM, XX },
+ { "paddb", MX, EM, XX },
+ { "paddw", MX, EM, XX },
+ { "paddd", MX, EM, XX },
+ { "(bad)", XX, XX, XX }
+};
+
+static const unsigned char onebyte_has_modrm[256] = {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* ------------------------------- */
+ /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
+ /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
+ /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
+ /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
+ /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
+ /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
+ /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
+ /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
+ /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
+ /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
+ /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
+ /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
+ /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
+ /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
+ /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
+ /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
+ /* ------------------------------- */
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+};
+
+static const unsigned char twobyte_has_modrm[256] = {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* ------------------------------- */
+ /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
+ /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
+ /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
+ /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
+ /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
+ /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
+ /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
+ /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
+ /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
+ /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
+ /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
+ /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
+ /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
+ /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
+ /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
+ /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
+ /* ------------------------------- */
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+};
+
+static const unsigned char twobyte_uses_SSE_prefix[256] = {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* ------------------------------- */
+ /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
+ /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
+ /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
+ /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
+ /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
+ /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
+ /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
+ /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, /* 7f */
+ /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
+ /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
+ /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
+ /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
+ /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
+ /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
+ /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
+ /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
+ /* ------------------------------- */
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+};
+
+static char obuf[100];
+static char *obufp;
+static char scratchbuf[100];
+static unsigned char *start_codep;
+static unsigned char *insn_codep;
+static unsigned char *codep;
+static disassemble_info *the_info;
+static int mod;
+static int rm;
+static int reg;
+static unsigned char need_modrm;
+
+/* If we are accessing mod/rm/reg without need_modrm set, then the
+ values are stale. Hitting this abort likely indicates that you
+ need to update onebyte_has_modrm or twobyte_has_modrm. */
+#define MODRM_CHECK if (!need_modrm) abort ()
+
+static const char **names64;
+static const char **names32;
+static const char **names16;
+static const char **names8;
+static const char **names8rex;
+static const char **names_seg;
+static const char **index16;
+
+static const char *intel_names64[] = {
+ "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
+};
+static const char *intel_names32[] = {
+ "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
+ "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
+};
+static const char *intel_names16[] = {
+ "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
+ "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
+};
+static const char *intel_names8[] = {
+ "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
+};
+static const char *intel_names8rex[] = {
+ "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
+ "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
+};
+static const char *intel_names_seg[] = {
+ "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
+};
+static const char *intel_index16[] = {
+ "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
+};
+
+static const char *att_names64[] = {
+ "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
+ "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
+};
+static const char *att_names32[] = {
+ "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
+ "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
+};
+static const char *att_names16[] = {
+ "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
+ "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
+};
+static const char *att_names8[] = {
+ "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
+};
+static const char *att_names8rex[] = {
+ "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
+ "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
+};
+static const char *att_names_seg[] = {
+ "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
+};
+static const char *att_index16[] = {
+ "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
+};
+
+static const struct dis386 grps[][8] = {
+ /* GRP1b */
+ {
+ { "addA", Eb, Ib, XX },
+ { "orA", Eb, Ib, XX },
+ { "adcA", Eb, Ib, XX },
+ { "sbbA", Eb, Ib, XX },
+ { "andA", Eb, Ib, XX },
+ { "subA", Eb, Ib, XX },
+ { "xorA", Eb, Ib, XX },
+ { "cmpA", Eb, Ib, XX }
+ },
+ /* GRP1S */
+ {
+ { "addQ", Ev, Iv, XX },
+ { "orQ", Ev, Iv, XX },
+ { "adcQ", Ev, Iv, XX },
+ { "sbbQ", Ev, Iv, XX },
+ { "andQ", Ev, Iv, XX },
+ { "subQ", Ev, Iv, XX },
+ { "xorQ", Ev, Iv, XX },
+ { "cmpQ", Ev, Iv, XX }
+ },
+ /* GRP1Ss */
+ {
+ { "addQ", Ev, sIb, XX },
+ { "orQ", Ev, sIb, XX },
+ { "adcQ", Ev, sIb, XX },
+ { "sbbQ", Ev, sIb, XX },
+ { "andQ", Ev, sIb, XX },
+ { "subQ", Ev, sIb, XX },
+ { "xorQ", Ev, sIb, XX },
+ { "cmpQ", Ev, sIb, XX }
+ },
+ /* GRP2b */
+ {
+ { "rolA", Eb, Ib, XX },
+ { "rorA", Eb, Ib, XX },
+ { "rclA", Eb, Ib, XX },
+ { "rcrA", Eb, Ib, XX },
+ { "shlA", Eb, Ib, XX },
+ { "shrA", Eb, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "sarA", Eb, Ib, XX },
+ },
+ /* GRP2S */
+ {
+ { "rolQ", Ev, Ib, XX },
+ { "rorQ", Ev, Ib, XX },
+ { "rclQ", Ev, Ib, XX },
+ { "rcrQ", Ev, Ib, XX },
+ { "shlQ", Ev, Ib, XX },
+ { "shrQ", Ev, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "sarQ", Ev, Ib, XX },
+ },
+ /* GRP2b_one */
+ {
+ { "rolA", Eb, I1, XX },
+ { "rorA", Eb, I1, XX },
+ { "rclA", Eb, I1, XX },
+ { "rcrA", Eb, I1, XX },
+ { "shlA", Eb, I1, XX },
+ { "shrA", Eb, I1, XX },
+ { "(bad)", XX, XX, XX },
+ { "sarA", Eb, I1, XX },
+ },
+ /* GRP2S_one */
+ {
+ { "rolQ", Ev, I1, XX },
+ { "rorQ", Ev, I1, XX },
+ { "rclQ", Ev, I1, XX },
+ { "rcrQ", Ev, I1, XX },
+ { "shlQ", Ev, I1, XX },
+ { "shrQ", Ev, I1, XX },
+ { "(bad)", XX, XX, XX},
+ { "sarQ", Ev, I1, XX },
+ },
+ /* GRP2b_cl */
+ {
+ { "rolA", Eb, CL, XX },
+ { "rorA", Eb, CL, XX },
+ { "rclA", Eb, CL, XX },
+ { "rcrA", Eb, CL, XX },
+ { "shlA", Eb, CL, XX },
+ { "shrA", Eb, CL, XX },
+ { "(bad)", XX, XX, XX },
+ { "sarA", Eb, CL, XX },
+ },
+ /* GRP2S_cl */
+ {
+ { "rolQ", Ev, CL, XX },
+ { "rorQ", Ev, CL, XX },
+ { "rclQ", Ev, CL, XX },
+ { "rcrQ", Ev, CL, XX },
+ { "shlQ", Ev, CL, XX },
+ { "shrQ", Ev, CL, XX },
+ { "(bad)", XX, XX, XX },
+ { "sarQ", Ev, CL, XX }
+ },
+ /* GRP3b */
+ {
+ { "testA", Eb, Ib, XX },
+ { "(bad)", Eb, XX, XX },
+ { "notA", Eb, XX, XX },
+ { "negA", Eb, XX, XX },
+ { "mulA", Eb, XX, XX }, /* Don't print the implicit %al register, */
+ { "imulA", Eb, XX, XX }, /* to distinguish these opcodes from other */
+ { "divA", Eb, XX, XX }, /* mul/imul opcodes. Do the same for div */
+ { "idivA", Eb, XX, XX } /* and idiv for consistency. */
+ },
+ /* GRP3S */
+ {
+ { "testQ", Ev, Iv, XX },
+ { "(bad)", XX, XX, XX },
+ { "notQ", Ev, XX, XX },
+ { "negQ", Ev, XX, XX },
+ { "mulQ", Ev, XX, XX }, /* Don't print the implicit register. */
+ { "imulQ", Ev, XX, XX },
+ { "divQ", Ev, XX, XX },
+ { "idivQ", Ev, XX, XX },
+ },
+ /* GRP4 */
+ {
+ { "incA", Eb, XX, XX },
+ { "decA", Eb, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ },
+ /* GRP5 */
+ {
+ { "incQ", Ev, XX, XX },
+ { "decQ", Ev, XX, XX },
+ { "callT", indirEv, XX, XX },
+ { "JcallT", indirEp, XX, XX },
+ { "jmpT", indirEv, XX, XX },
+ { "JjmpT", indirEp, XX, XX },
+ { "pushU", Ev, XX, XX },
+ { "(bad)", XX, XX, XX },
+ },
+ /* GRP6 */
+ {
+ { "sldtQ", Ev, XX, XX },
+ { "strQ", Ev, XX, XX },
+ { "lldt", Ew, XX, XX },
+ { "ltr", Ew, XX, XX },
+ { "verr", Ew, XX, XX },
+ { "verw", Ew, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX }
+ },
+ /* GRP7 */
+ {
+ { "sgdtIQ", VMX_Fixup, 0, XX, XX },
+ { "sidtIQ", PNI_Fixup, 0, XX, XX },
+ { "lgdt{Q|Q||}", M, XX, XX },
+ { "lidt{Q|Q||}", SVME_Fixup, 0, XX, XX },
+ { "smswQ", Ev, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "lmsw", Ew, XX, XX },
+ { "invlpg", INVLPG_Fixup, w_mode, XX, XX },
+ },
+ /* GRP8 */
+ {
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "btQ", Ev, Ib, XX },
+ { "btsQ", Ev, Ib, XX },
+ { "btrQ", Ev, Ib, XX },
+ { "btcQ", Ev, Ib, XX },
+ },
+ /* GRP9 */
+ {
+ { "(bad)", XX, XX, XX },
+ { "cmpxchg8b", Eq, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "", VM, XX, XX }, /* See OP_VMX. */
+ { "vmptrst", Eq, XX, XX },
+ },
+ /* GRP10 */
+ {
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "psrlw", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "psraw", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "psllw", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ },
+ /* GRP11 */
+ {
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "psrld", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "psrad", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "pslld", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ },
+ /* GRP12 */
+ {
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "psrlq", MS, Ib, XX },
+ { "psrldq", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "psllq", MS, Ib, XX },
+ { "pslldq", MS, Ib, XX },
+ },
+ /* GRP13 */
+ {
+ { "fxsave", Ev, XX, XX },
+ { "fxrstor", Ev, XX, XX },
+ { "ldmxcsr", Ev, XX, XX },
+ { "stmxcsr", Ev, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "lfence", OP_0fae, 0, XX, XX },
+ { "mfence", OP_0fae, 0, XX, XX },
+ { "clflush", OP_0fae, 0, XX, XX },
+ },
+ /* GRP14 */
+ {
+ { "prefetchnta", Ev, XX, XX },
+ { "prefetcht0", Ev, XX, XX },
+ { "prefetcht1", Ev, XX, XX },
+ { "prefetcht2", Ev, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ },
+ /* GRPAMD */
+ {
+ { "prefetch", Eb, XX, XX },
+ { "prefetchw", Eb, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ },
+ /* GRPPADLCK1 */
+ {
+ { "xstore-rng", OP_0f07, 0, XX, XX },
+ { "xcrypt-ecb", OP_0f07, 0, XX, XX },
+ { "xcrypt-cbc", OP_0f07, 0, XX, XX },
+ { "xcrypt-ctr", OP_0f07, 0, XX, XX },
+ { "xcrypt-cfb", OP_0f07, 0, XX, XX },
+ { "xcrypt-ofb", OP_0f07, 0, XX, XX },
+ { "(bad)", OP_0f07, 0, XX, XX },
+ { "(bad)", OP_0f07, 0, XX, XX },
+ },
+ /* GRPPADLCK2 */
+ {
+ { "montmul", OP_0f07, 0, XX, XX },
+ { "xsha1", OP_0f07, 0, XX, XX },
+ { "xsha256", OP_0f07, 0, XX, XX },
+ { "(bad)", OP_0f07, 0, XX, XX },
+ { "(bad)", OP_0f07, 0, XX, XX },
+ { "(bad)", OP_0f07, 0, XX, XX },
+ { "(bad)", OP_0f07, 0, XX, XX },
+ { "(bad)", OP_0f07, 0, XX, XX },
+ }
+};
+
+static const struct dis386 prefix_user_table[][4] = {
+ /* PREGRP0 */
+ {
+ { "addps", XM, EX, XX },
+ { "addss", XM, EX, XX },
+ { "addpd", XM, EX, XX },
+ { "addsd", XM, EX, XX },
+ },
+ /* PREGRP1 */
+ {
+ { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX. */
+ { "", XM, EX, OPSIMD },
+ { "", XM, EX, OPSIMD },
+ { "", XM, EX, OPSIMD },
+ },
+ /* PREGRP2 */
+ {
+ { "cvtpi2ps", XM, EM, XX },
+ { "cvtsi2ssY", XM, Ev, XX },
+ { "cvtpi2pd", XM, EM, XX },
+ { "cvtsi2sdY", XM, Ev, XX },
+ },
+ /* PREGRP3 */
+ {
+ { "cvtps2pi", MX, EX, XX },
+ { "cvtss2siY", Gv, EX, XX },
+ { "cvtpd2pi", MX, EX, XX },
+ { "cvtsd2siY", Gv, EX, XX },
+ },
+ /* PREGRP4 */
+ {
+ { "cvttps2pi", MX, EX, XX },
+ { "cvttss2siY", Gv, EX, XX },
+ { "cvttpd2pi", MX, EX, XX },
+ { "cvttsd2siY", Gv, EX, XX },
+ },
+ /* PREGRP5 */
+ {
+ { "divps", XM, EX, XX },
+ { "divss", XM, EX, XX },
+ { "divpd", XM, EX, XX },
+ { "divsd", XM, EX, XX },
+ },
+ /* PREGRP6 */
+ {
+ { "maxps", XM, EX, XX },
+ { "maxss", XM, EX, XX },
+ { "maxpd", XM, EX, XX },
+ { "maxsd", XM, EX, XX },
+ },
+ /* PREGRP7 */
+ {
+ { "minps", XM, EX, XX },
+ { "minss", XM, EX, XX },
+ { "minpd", XM, EX, XX },
+ { "minsd", XM, EX, XX },
+ },
+ /* PREGRP8 */
+ {
+ { "movups", XM, EX, XX },
+ { "movss", XM, EX, XX },
+ { "movupd", XM, EX, XX },
+ { "movsd", XM, EX, XX },
+ },
+ /* PREGRP9 */
+ {
+ { "movups", EX, XM, XX },
+ { "movss", EX, XM, XX },
+ { "movupd", EX, XM, XX },
+ { "movsd", EX, XM, XX },
+ },
+ /* PREGRP10 */
+ {
+ { "mulps", XM, EX, XX },
+ { "mulss", XM, EX, XX },
+ { "mulpd", XM, EX, XX },
+ { "mulsd", XM, EX, XX },
+ },
+ /* PREGRP11 */
+ {
+ { "rcpps", XM, EX, XX },
+ { "rcpss", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ },
+ /* PREGRP12 */
+ {
+ { "rsqrtps", XM, EX, XX },
+ { "rsqrtss", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ },
+ /* PREGRP13 */
+ {
+ { "sqrtps", XM, EX, XX },
+ { "sqrtss", XM, EX, XX },
+ { "sqrtpd", XM, EX, XX },
+ { "sqrtsd", XM, EX, XX },
+ },
+ /* PREGRP14 */
+ {
+ { "subps", XM, EX, XX },
+ { "subss", XM, EX, XX },
+ { "subpd", XM, EX, XX },
+ { "subsd", XM, EX, XX },
+ },
+ /* PREGRP15 */
+ {
+ { "(bad)", XM, EX, XX },
+ { "cvtdq2pd", XM, EX, XX },
+ { "cvttpd2dq", XM, EX, XX },
+ { "cvtpd2dq", XM, EX, XX },
+ },
+ /* PREGRP16 */
+ {
+ { "cvtdq2ps", XM, EX, XX },
+ { "cvttps2dq",XM, EX, XX },
+ { "cvtps2dq",XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ },
+ /* PREGRP17 */
+ {
+ { "cvtps2pd", XM, EX, XX },
+ { "cvtss2sd", XM, EX, XX },
+ { "cvtpd2ps", XM, EX, XX },
+ { "cvtsd2ss", XM, EX, XX },
+ },
+ /* PREGRP18 */
+ {
+ { "maskmovq", MX, MS, XX },
+ { "(bad)", XM, EX, XX },
+ { "maskmovdqu", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ },
+ /* PREGRP19 */
+ {
+ { "movq", MX, EM, XX },
+ { "movdqu", XM, EX, XX },
+ { "movdqa", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ },
+ /* PREGRP20 */
+ {
+ { "movq", EM, MX, XX },
+ { "movdqu", EX, XM, XX },
+ { "movdqa", EX, XM, XX },
+ { "(bad)", EX, XM, XX },
+ },
+ /* PREGRP21 */
+ {
+ { "(bad)", EX, XM, XX },
+ { "movq2dq", XM, MS, XX },
+ { "movq", EX, XM, XX },
+ { "movdq2q", MX, XS, XX },
+ },
+ /* PREGRP22 */
+ {
+ { "pshufw", MX, EM, Ib },
+ { "pshufhw", XM, EX, Ib },
+ { "pshufd", XM, EX, Ib },
+ { "pshuflw", XM, EX, Ib },
+ },
+ /* PREGRP23 */
+ {
+ { "movd", Edq, MX, XX },
+ { "movq", XM, EX, XX },
+ { "movd", Edq, XM, XX },
+ { "(bad)", Ed, XM, XX },
+ },
+ /* PREGRP24 */
+ {
+ { "(bad)", MX, EX, XX },
+ { "(bad)", XM, EX, XX },
+ { "punpckhqdq", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ },
+ /* PREGRP25 */
+ {
+ { "movntq", EM, MX, XX },
+ { "(bad)", EM, XM, XX },
+ { "movntdq", EM, XM, XX },
+ { "(bad)", EM, XM, XX },
+ },
+ /* PREGRP26 */
+ {
+ { "(bad)", MX, EX, XX },
+ { "(bad)", XM, EX, XX },
+ { "punpcklqdq", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ },
+ /* PREGRP27 */
+ {
+ { "(bad)", MX, EX, XX },
+ { "(bad)", XM, EX, XX },
+ { "addsubpd", XM, EX, XX },
+ { "addsubps", XM, EX, XX },
+ },
+ /* PREGRP28 */
+ {
+ { "(bad)", MX, EX, XX },
+ { "(bad)", XM, EX, XX },
+ { "haddpd", XM, EX, XX },
+ { "haddps", XM, EX, XX },
+ },
+ /* PREGRP29 */
+ {
+ { "(bad)", MX, EX, XX },
+ { "(bad)", XM, EX, XX },
+ { "hsubpd", XM, EX, XX },
+ { "hsubps", XM, EX, XX },
+ },
+ /* PREGRP30 */
+ {
+ { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
+ { "movsldup", XM, EX, XX },
+ { "movlpd", XM, EX, XX },
+ { "movddup", XM, EX, XX },
+ },
+ /* PREGRP31 */
+ {
+ { "movhpX", XM, EX, SIMD_Fixup, 'l' },
+ { "movshdup", XM, EX, XX },
+ { "movhpd", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ },
+ /* PREGRP32 */
+ {
+ { "(bad)", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ { "lddqu", XM, M, XX },
+ },
+};
+
+static const struct dis386 x86_64_table[][2] = {
+ {
+ { "arpl", Ew, Gw, XX },
+ { "movs{||lq|xd}", Gv, Ed, XX },
+ },
+};
+
+#ifdef __KERNEL__
+#define INTERNAL_DISASSEMBLER_ERROR "<internal disassembler error>"
+#else /* __KERNEL__ */
+#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
+#endif /* __KERNEL__ */
+
+static void
+ckprefix (void)
+{
+ int newrex;
+ rex = 0;
+ prefixes = 0;
+ used_prefixes = 0;
+ rex_used = 0;
+ while (1)
+ {
+ FETCH_DATA (the_info, codep + 1);
+ newrex = 0;
+ switch (*codep)
+ {
+ /* REX prefixes family. */
+ case 0x40:
+ case 0x41:
+ case 0x42:
+ case 0x43:
+ case 0x44:
+ case 0x45:
+ case 0x46:
+ case 0x47:
+ case 0x48:
+ case 0x49:
+ case 0x4a:
+ case 0x4b:
+ case 0x4c:
+ case 0x4d:
+ case 0x4e:
+ case 0x4f:
+ if (mode_64bit)
+ newrex = *codep;
+ else
+ return;
+ break;
+ case 0xf3:
+ prefixes |= PREFIX_REPZ;
+ break;
+ case 0xf2:
+ prefixes |= PREFIX_REPNZ;
+ break;
+ case 0xf0:
+ prefixes |= PREFIX_LOCK;
+ break;
+ case 0x2e:
+ prefixes |= PREFIX_CS;
+ break;
+ case 0x36:
+ prefixes |= PREFIX_SS;
+ break;
+ case 0x3e:
+ prefixes |= PREFIX_DS;
+ break;
+ case 0x26:
+ prefixes |= PREFIX_ES;
+ break;
+ case 0x64:
+ prefixes |= PREFIX_FS;
+ break;
+ case 0x65:
+ prefixes |= PREFIX_GS;
+ break;
+ case 0x66:
+ prefixes |= PREFIX_DATA;
+ break;
+ case 0x67:
+ prefixes |= PREFIX_ADDR;
+ break;
+ case FWAIT_OPCODE:
+ /* fwait is really an instruction. If there are prefixes
+ before the fwait, they belong to the fwait, *not* to the
+ following instruction. */
+ if (prefixes)
+ {
+ prefixes |= PREFIX_FWAIT;
+ codep++;
+ return;
+ }
+ prefixes = PREFIX_FWAIT;
+ break;
+ default:
+ return;
+ }
+ /* Rex is ignored when followed by another prefix. */
+ if (rex)
+ {
+ oappend (prefix_name (rex, 0));
+ oappend (" ");
+ }
+ rex = newrex;
+ codep++;
+ }
+}
+
+/* Return the name of the prefix byte PREF, or NULL if PREF is not a
+ prefix byte. */
+
+static const char *
+prefix_name (int pref, int sizeflag)
+{
+ switch (pref)
+ {
+ /* REX prefixes family. */
+ case 0x40:
+ return "rex";
+ case 0x41:
+ return "rexZ";
+ case 0x42:
+ return "rexY";
+ case 0x43:
+ return "rexYZ";
+ case 0x44:
+ return "rexX";
+ case 0x45:
+ return "rexXZ";
+ case 0x46:
+ return "rexXY";
+ case 0x47:
+ return "rexXYZ";
+ case 0x48:
+ return "rex64";
+ case 0x49:
+ return "rex64Z";
+ case 0x4a:
+ return "rex64Y";
+ case 0x4b:
+ return "rex64YZ";
+ case 0x4c:
+ return "rex64X";
+ case 0x4d:
+ return "rex64XZ";
+ case 0x4e:
+ return "rex64XY";
+ case 0x4f:
+ return "rex64XYZ";
+ case 0xf3:
+ return "repz";
+ case 0xf2:
+ return "repnz";
+ case 0xf0:
+ return "lock";
+ case 0x2e:
+ return "cs";
+ case 0x36:
+ return "ss";
+ case 0x3e:
+ return "ds";
+ case 0x26:
+ return "es";
+ case 0x64:
+ return "fs";
+ case 0x65:
+ return "gs";
+ case 0x66:
+ return (sizeflag & DFLAG) ? "data16" : "data32";
+ case 0x67:
+ if (mode_64bit)
+ return (sizeflag & AFLAG) ? "addr32" : "addr64";
+ else
+ return (sizeflag & AFLAG) ? "addr16" : "addr32";
+ case FWAIT_OPCODE:
+ return "fwait";
+ default:
+ return NULL;
+ }
+}
+
+static char op1out[100], op2out[100], op3out[100];
+static int op_ad, op_index[3];
+static int two_source_ops;
+static bfd_vma op_address[3];
+static bfd_vma op_riprel[3];
+static bfd_vma start_pc;
+\f
+/*
+ * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
+ * (see topic "Redundant prefixes" in the "Differences from 8086"
+ * section of the "Virtual 8086 Mode" chapter.)
+ * 'pc' should be the address of this instruction, it will
+ * be used to print the target address if this is a relative jump or call
+ * The function returns the length of this instruction in bytes.
+ */
+
+static char intel_syntax;
+static char open_char;
+static char close_char;
+static char separator_char;
+static char scale_char;
+
+/* Here for backwards compatibility. When gdb stops using
+ print_insn_i386_att and print_insn_i386_intel these functions can
+ disappear, and print_insn_i386 be merged into print_insn. */
+int
+print_insn_i386_att (bfd_vma pc, disassemble_info *info)
+{
+ intel_syntax = 0;
+
+ return print_insn (pc, info);
+}
+
+int
+print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
+{
+ intel_syntax = 1;
+
+ return print_insn (pc, info);
+}
+
+int
+print_insn_i386 (bfd_vma pc, disassemble_info *info)
+{
+ intel_syntax = -1;
+
+ return print_insn (pc, info);
+}
+
+static int
+print_insn (bfd_vma pc, disassemble_info *info)
+{
+ const struct dis386 *dp;
+ int i;
+ char *first, *second, *third;
+ int needcomma;
+ unsigned char uses_SSE_prefix, uses_LOCK_prefix;
+ int sizeflag;
+ const char *p;
+ struct dis_private priv;
+
+ mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
+ || info->mach == bfd_mach_x86_64);
+
+ if (intel_syntax == (char) -1)
+ intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
+ || info->mach == bfd_mach_x86_64_intel_syntax);
+
+ if (info->mach == bfd_mach_i386_i386
+ || info->mach == bfd_mach_x86_64
+ || info->mach == bfd_mach_i386_i386_intel_syntax
+ || info->mach == bfd_mach_x86_64_intel_syntax)
+ priv.orig_sizeflag = AFLAG | DFLAG;
+ else if (info->mach == bfd_mach_i386_i8086)
+ priv.orig_sizeflag = 0;
+ else
+ abort ();
+
+ for (p = info->disassembler_options; p != NULL; )
+ {
+ if (strncmp (p, "x86-64", 6) == 0)
+ {
+ mode_64bit = 1;
+ priv.orig_sizeflag = AFLAG | DFLAG;
+ }
+ else if (strncmp (p, "i386", 4) == 0)
+ {
+ mode_64bit = 0;
+ priv.orig_sizeflag = AFLAG | DFLAG;
+ }
+ else if (strncmp (p, "i8086", 5) == 0)
+ {
+ mode_64bit = 0;
+ priv.orig_sizeflag = 0;
+ }
+ else if (strncmp (p, "intel", 5) == 0)
+ {
+ intel_syntax = 1;
+ }
+ else if (strncmp (p, "att", 3) == 0)
+ {
+ intel_syntax = 0;
+ }
+ else if (strncmp (p, "addr", 4) == 0)
+ {
+ if (p[4] == '1' && p[5] == '6')
+ priv.orig_sizeflag &= ~AFLAG;
+ else if (p[4] == '3' && p[5] == '2')
+ priv.orig_sizeflag |= AFLAG;
+ }
+ else if (strncmp (p, "data", 4) == 0)
+ {
+ if (p[4] == '1' && p[5] == '6')
+ priv.orig_sizeflag &= ~DFLAG;
+ else if (p[4] == '3' && p[5] == '2')
+ priv.orig_sizeflag |= DFLAG;
+ }
+ else if (strncmp (p, "suffix", 6) == 0)
+ priv.orig_sizeflag |= SUFFIX_ALWAYS;
+
+ p = strchr (p, ',');
+ if (p != NULL)
+ p++;
+ }
+
+ if (intel_syntax)
+ {
+ names64 = intel_names64;
+ names32 = intel_names32;
+ names16 = intel_names16;
+ names8 = intel_names8;
+ names8rex = intel_names8rex;
+ names_seg = intel_names_seg;
+ index16 = intel_index16;
+ open_char = '[';
+ close_char = ']';
+ separator_char = '+';
+ scale_char = '*';
+ }
+ else
+ {
+ names64 = att_names64;
+ names32 = att_names32;
+ names16 = att_names16;
+ names8 = att_names8;
+ names8rex = att_names8rex;
+ names_seg = att_names_seg;
+ index16 = att_index16;
+ open_char = '(';
+ close_char = ')';
+ separator_char = ',';
+ scale_char = ',';
+ }
+
+ /* The output looks better if we put 7 bytes on a line, since that
+ puts most long word instructions on a single line. */
+ info->bytes_per_line = 7;
+
+ info->private_data = &priv;
+ priv.max_fetched = priv.the_buffer;
+ priv.insn_start = pc;
+
+ obuf[0] = 0;
+ op1out[0] = 0;
+ op2out[0] = 0;
+ op3out[0] = 0;
+
+ op_index[0] = op_index[1] = op_index[2] = -1;
+
+ the_info = info;
+ start_pc = pc;
+ start_codep = priv.the_buffer;
+ codep = priv.the_buffer;
+
+#ifndef __KERNEL__
+ if (setjmp (priv.bailout) != 0)
+ {
+ const char *name;
+
+ /* Getting here means we tried for data but didn't get it. That
+ means we have an incomplete instruction of some sort. Just
+ print the first byte as a prefix or a .byte pseudo-op. */
+ if (codep > priv.the_buffer)
+ {
+ name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
+ if (name != NULL)
+ (*info->fprintf_func) (info->stream, "%s", name);
+ else
+ {
+ /* Just print the first byte as a .byte instruction. */
+ (*info->fprintf_func) (info->stream, ".byte 0x%x",
+ (unsigned int) priv.the_buffer[0]);
+ }
+
+ return 1;
+ }
+
+ return -1;
+ }
+#endif /* __KERNEL__ */
+
+ obufp = obuf;
+ ckprefix ();
+
+ insn_codep = codep;
+ sizeflag = priv.orig_sizeflag;
+
+ FETCH_DATA (info, codep + 1);
+ two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
+
+ if ((prefixes & PREFIX_FWAIT)
+ && ((*codep < 0xd8) || (*codep > 0xdf)))
+ {
+ const char *name;
+
+ /* fwait not followed by floating point instruction. Print the
+ first prefix, which is probably fwait itself. */
+ name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
+ if (name == NULL)
+ name = INTERNAL_DISASSEMBLER_ERROR;
+ (*info->fprintf_func) (info->stream, "%s", name);
+ return 1;
+ }
+
+ if (*codep == 0x0f)
+ {
+ FETCH_DATA (info, codep + 2);
+ dp = &dis386_twobyte[*++codep];
+ need_modrm = twobyte_has_modrm[*codep];
+ uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
+ uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
+ }
+ else
+ {
+ dp = &dis386[*codep];
+ need_modrm = onebyte_has_modrm[*codep];
+ uses_SSE_prefix = 0;
+ uses_LOCK_prefix = 0;
+ }
+ codep++;
+
+ if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))
+ {
+ oappend ("repz ");
+ used_prefixes |= PREFIX_REPZ;
+ }
+ if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))
+ {
+ oappend ("repnz ");
+ used_prefixes |= PREFIX_REPNZ;
+ }
+ if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
+ {
+ oappend ("lock ");
+ used_prefixes |= PREFIX_LOCK;
+ }
+
+ if (prefixes & PREFIX_ADDR)
+ {
+ sizeflag ^= AFLAG;
+ if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
+ {
+ if ((sizeflag & AFLAG) || mode_64bit)
+ oappend ("addr32 ");
+ else
+ oappend ("addr16 ");
+ used_prefixes |= PREFIX_ADDR;
+ }
+ }
+
+ if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
+ {
+ sizeflag ^= DFLAG;
+ if (dp->bytemode3 == cond_jump_mode
+ && dp->bytemode1 == v_mode
+ && !intel_syntax)
+ {
+ if (sizeflag & DFLAG)
+ oappend ("data32 ");
+ else
+ oappend ("data16 ");
+ used_prefixes |= PREFIX_DATA;
+ }
+ }
+
+ if (need_modrm)
+ {
+ FETCH_DATA (info, codep + 1);
+ mod = (*codep >> 6) & 3;
+ reg = (*codep >> 3) & 7;
+ rm = *codep & 7;
+ }
+
+ if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
+ {
+ dofloat (sizeflag);
+ }
+ else
+ {
+ int index;
+ if (dp->name == NULL)
+ {
+ switch (dp->bytemode1)
+ {
+ case USE_GROUPS:
+ dp = &grps[dp->bytemode2][reg];
+ break;
+
+ case USE_PREFIX_USER_TABLE:
+ index = 0;
+ used_prefixes |= (prefixes & PREFIX_REPZ);
+ if (prefixes & PREFIX_REPZ)
+ index = 1;
+ else
+ {
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ if (prefixes & PREFIX_DATA)
+ index = 2;
+ else
+ {
+ used_prefixes |= (prefixes & PREFIX_REPNZ);
+ if (prefixes & PREFIX_REPNZ)
+ index = 3;
+ }
+ }
+ dp = &prefix_user_table[dp->bytemode2][index];
+ break;
+
+ case X86_64_SPECIAL:
+ dp = &x86_64_table[dp->bytemode2][mode_64bit];
+ break;
+
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ break;
+ }
+ }
+
+ if (putop (dp->name, sizeflag) == 0)
+ {
+ obufp = op1out;
+ op_ad = 2;
+ if (dp->op1)
+ (*dp->op1) (dp->bytemode1, sizeflag);
+
+ obufp = op2out;
+ op_ad = 1;
+ if (dp->op2)
+ (*dp->op2) (dp->bytemode2, sizeflag);
+
+ obufp = op3out;
+ op_ad = 0;
+ if (dp->op3)
+ (*dp->op3) (dp->bytemode3, sizeflag);
+ }
+ }
+
+ /* See if any prefixes were not used. If so, print the first one
+ separately. If we don't do this, we'll wind up printing an
+ instruction stream which does not precisely correspond to the
+ bytes we are disassembling. */
+ if ((prefixes & ~used_prefixes) != 0)
+ {
+ const char *name;
+
+ name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
+ if (name == NULL)
+ name = INTERNAL_DISASSEMBLER_ERROR;
+ (*info->fprintf_func) (info->stream, "%s", name);
+ return 1;
+ }
+ if (rex & ~rex_used)
+ {
+ const char *name;
+ name = prefix_name (rex | 0x40, priv.orig_sizeflag);
+ if (name == NULL)
+ name = INTERNAL_DISASSEMBLER_ERROR;
+ (*info->fprintf_func) (info->stream, "%s ", name);
+ }
+
+ obufp = obuf + strlen (obuf);
+ for (i = strlen (obuf); i < 6; i++)
+ oappend (" ");
+ oappend (" ");
+ (*info->fprintf_func) (info->stream, "%s", obuf);
+
+ /* The enter and bound instructions are printed with operands in the same
+ order as the intel book; everything else is printed in reverse order. */
+ if (intel_syntax || two_source_ops)
+ {
+ first = op1out;
+ second = op2out;
+ third = op3out;
+ op_ad = op_index[0];
+ op_index[0] = op_index[2];
+ op_index[2] = op_ad;
+ }
+ else
+ {
+ first = op3out;
+ second = op2out;
+ third = op1out;
+ }
+ needcomma = 0;
+ if (*first)
+ {
+ if (op_index[0] != -1 && !op_riprel[0])
+ (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
+ else
+ (*info->fprintf_func) (info->stream, "%s", first);
+ needcomma = 1;
+ }
+ if (*second)
+ {
+ if (needcomma)
+ (*info->fprintf_func) (info->stream, ",");
+ if (op_index[1] != -1 && !op_riprel[1])
+ (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
+ else
+ (*info->fprintf_func) (info->stream, "%s", second);
+ needcomma = 1;
+ }
+ if (*third)
+ {
+ if (needcomma)
+ (*info->fprintf_func) (info->stream, ",");
+ if (op_index[2] != -1 && !op_riprel[2])
+ (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
+ else
+ (*info->fprintf_func) (info->stream, "%s", third);
+ }
+ for (i = 0; i < 3; i++)
+ if (op_index[i] != -1 && op_riprel[i])
+ {
+ (*info->fprintf_func) (info->stream, " # ");
+ (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
+ + op_address[op_index[i]]), info);
+ }
+ return codep - priv.the_buffer;
+}
+
+static const char *float_mem[] = {
+ /* d8 */
+ "fadd{s||s|}",
+ "fmul{s||s|}",
+ "fcom{s||s|}",
+ "fcomp{s||s|}",
+ "fsub{s||s|}",
+ "fsubr{s||s|}",
+ "fdiv{s||s|}",
+ "fdivr{s||s|}",
+ /* d9 */
+ "fld{s||s|}",
+ "(bad)",
+ "fst{s||s|}",
+ "fstp{s||s|}",
+ "fldenvIC",
+ "fldcw",
+ "fNstenvIC",
+ "fNstcw",
+ /* da */
+ "fiadd{l||l|}",
+ "fimul{l||l|}",
+ "ficom{l||l|}",
+ "ficomp{l||l|}",
+ "fisub{l||l|}",
+ "fisubr{l||l|}",
+ "fidiv{l||l|}",
+ "fidivr{l||l|}",
+ /* db */
+ "fild{l||l|}",
+ "fisttp{l||l|}",
+ "fist{l||l|}",
+ "fistp{l||l|}",
+ "(bad)",
+ "fld{t||t|}",
+ "(bad)",
+ "fstp{t||t|}",
+ /* dc */
+ "fadd{l||l|}",
+ "fmul{l||l|}",
+ "fcom{l||l|}",
+ "fcomp{l||l|}",
+ "fsub{l||l|}",
+ "fsubr{l||l|}",
+ "fdiv{l||l|}",
+ "fdivr{l||l|}",
+ /* dd */
+ "fld{l||l|}",
+ "fisttp{ll||ll|}",
+ "fst{l||l|}",
+ "fstp{l||l|}",
+ "frstorIC",
+ "(bad)",
+ "fNsaveIC",
+ "fNstsw",
+ /* de */
+ "fiadd",
+ "fimul",
+ "ficom",
+ "ficomp",
+ "fisub",
+ "fisubr",
+ "fidiv",
+ "fidivr",
+ /* df */
+ "fild",
+ "fisttp",
+ "fist",
+ "fistp",
+ "fbld",
+ "fild{ll||ll|}",
+ "fbstp",
+ "fistp{ll||ll|}",
+};
+
+static const unsigned char float_mem_mode[] = {
+ /* d8 */
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ /* d9 */
+ d_mode,
+ 0,
+ d_mode,
+ d_mode,
+ 0,
+ w_mode,
+ 0,
+ w_mode,
+ /* da */
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ /* db */
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ 0,
+ t_mode,
+ 0,
+ t_mode,
+ /* dc */
+ q_mode,
+ q_mode,
+ q_mode,
+ q_mode,
+ q_mode,
+ q_mode,
+ q_mode,
+ q_mode,
+ /* dd */
+ q_mode,
+ q_mode,
+ q_mode,
+ q_mode,
+ 0,
+ 0,
+ 0,
+ w_mode,
+ /* de */
+ w_mode,
+ w_mode,
+ w_mode,
+ w_mode,
+ w_mode,
+ w_mode,
+ w_mode,
+ w_mode,
+ /* df */
+ w_mode,
+ w_mode,
+ w_mode,
+ w_mode,
+ t_mode,
+ q_mode,
+ t_mode,
+ q_mode
+};
+
+#define ST OP_ST, 0
+#define STi OP_STi, 0
+
+#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
+#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
+#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
+#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
+#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
+#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
+#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
+#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
+#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
+
+static const struct dis386 float_reg[][8] = {
+ /* d8 */
+ {
+ { "fadd", ST, STi, XX },
+ { "fmul", ST, STi, XX },
+ { "fcom", STi, XX, XX },
+ { "fcomp", STi, XX, XX },
+ { "fsub", ST, STi, XX },
+ { "fsubr", ST, STi, XX },
+ { "fdiv", ST, STi, XX },
+ { "fdivr", ST, STi, XX },
+ },
+ /* d9 */
+ {
+ { "fld", STi, XX, XX },
+ { "fxch", STi, XX, XX },
+ { FGRPd9_2 },
+ { "(bad)", XX, XX, XX },
+ { FGRPd9_4 },
+ { FGRPd9_5 },
+ { FGRPd9_6 },
+ { FGRPd9_7 },
+ },
+ /* da */
+ {
+ { "fcmovb", ST, STi, XX },
+ { "fcmove", ST, STi, XX },
+ { "fcmovbe",ST, STi, XX },
+ { "fcmovu", ST, STi, XX },
+ { "(bad)", XX, XX, XX },
+ { FGRPda_5 },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ },
+ /* db */
+ {
+ { "fcmovnb",ST, STi, XX },
+ { "fcmovne",ST, STi, XX },
+ { "fcmovnbe",ST, STi, XX },
+ { "fcmovnu",ST, STi, XX },
+ { FGRPdb_4 },
+ { "fucomi", ST, STi, XX },
+ { "fcomi", ST, STi, XX },
+ { "(bad)", XX, XX, XX },
+ },
+ /* dc */
+ {
+ { "fadd", STi, ST, XX },
+ { "fmul", STi, ST, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+#if UNIXWARE_COMPAT
+ { "fsub", STi, ST, XX },
+ { "fsubr", STi, ST, XX },
+ { "fdiv", STi, ST, XX },
+ { "fdivr", STi, ST, XX },
+#else
+ { "fsubr", STi, ST, XX },
+ { "fsub", STi, ST, XX },
+ { "fdivr", STi, ST, XX },
+ { "fdiv", STi, ST, XX },
+#endif
+ },
+ /* dd */
+ {
+ { "ffree", STi, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "fst", STi, XX, XX },
+ { "fstp", STi, XX, XX },
+ { "fucom", STi, XX, XX },
+ { "fucomp", STi, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ },
+ /* de */
+ {
+ { "faddp", STi, ST, XX },
+ { "fmulp", STi, ST, XX },
+ { "(bad)", XX, XX, XX },
+ { FGRPde_3 },
+#if UNIXWARE_COMPAT
+ { "fsubp", STi, ST, XX },
+ { "fsubrp", STi, ST, XX },
+ { "fdivp", STi, ST, XX },
+ { "fdivrp", STi, ST, XX },
+#else
+ { "fsubrp", STi, ST, XX },
+ { "fsubp", STi, ST, XX },
+ { "fdivrp", STi, ST, XX },
+ { "fdivp", STi, ST, XX },
+#endif
+ },
+ /* df */
+ {
+ { "ffreep", STi, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { FGRPdf_4 },
+ { "fucomip",ST, STi, XX },
+ { "fcomip", ST, STi, XX },
+ { "(bad)", XX, XX, XX },
+ },
+};
+
+static char *fgrps[][8] = {
+ /* d9_2 0 */
+ {
+ "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+ },
+
+ /* d9_4 1 */
+ {
+ "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
+ },
+
+ /* d9_5 2 */
+ {
+ "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
+ },
+
+ /* d9_6 3 */
+ {
+ "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
+ },
+
+ /* d9_7 4 */
+ {
+ "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
+ },
+
+ /* da_5 5 */
+ {
+ "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+ },
+
+ /* db_4 6 */
+ {
+ "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
+ "fNsetpm(287 only)","(bad)","(bad)","(bad)",
+ },
+
+ /* de_3 7 */
+ {
+ "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+ },
+
+ /* df_4 8 */
+ {
+ "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+ },
+};
+
+static void
+dofloat (int sizeflag)
+{
+ const struct dis386 *dp;
+ unsigned char floatop;
+
+ floatop = codep[-1];
+
+ if (mod != 3)
+ {
+ int fp_indx = (floatop - 0xd8) * 8 + reg;
+
+ putop (float_mem[fp_indx], sizeflag);
+ obufp = op1out;
+ OP_E (float_mem_mode[fp_indx], sizeflag);
+ return;
+ }
+ /* Skip mod/rm byte. */
+ MODRM_CHECK;
+ codep++;
+
+ dp = &float_reg[floatop - 0xd8][reg];
+ if (dp->name == NULL)
+ {
+ putop (fgrps[dp->bytemode1][rm], sizeflag);
+
+ /* Instruction fnstsw is only one with strange arg. */
+ if (floatop == 0xdf && codep[-1] == 0xe0)
+ strcpy (op1out, names16[0]);
+ }
+ else
+ {
+ putop (dp->name, sizeflag);
+
+ obufp = op1out;
+ if (dp->op1)
+ (*dp->op1) (dp->bytemode1, sizeflag);
+ obufp = op2out;
+ if (dp->op2)
+ (*dp->op2) (dp->bytemode2, sizeflag);
+ }
+}
+
+static void
+OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ oappend ("%st");
+}
+
+static void
+OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ sprintf (scratchbuf, "%%st(%d)", rm);
+ oappend (scratchbuf + intel_syntax);
+}
+
+/* Capital letters in template are macros. */
+static int
+putop (const char *template, int sizeflag)
+{
+ const char *p;
+ int alt = 0;
+
+ for (p = template; *p; p++)
+ {
+ switch (*p)
+ {
+ default:
+ *obufp++ = *p;
+ break;
+ case '{':
+ alt = 0;
+ if (intel_syntax)
+ alt += 1;
+ if (mode_64bit)
+ alt += 2;
+ while (alt != 0)
+ {
+ while (*++p != '|')
+ {
+ if (*p == '}')
+ {
+ /* Alternative not valid. */
+ strcpy (obuf, "(bad)");
+ obufp = obuf + 5;
+ return 1;
+ }
+ else if (*p == '\0')
+ abort ();
+ }
+ alt--;
+ }
+ /* Fall through. */
+ case 'I':
+ alt = 1;
+ continue;
+ case '|':
+ while (*++p != '}')
+ {
+ if (*p == '\0')
+ abort ();
+ }
+ break;
+ case '}':
+ break;
+ case 'A':
+ if (intel_syntax)
+ break;
+ if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
+ *obufp++ = 'b';
+ break;
+ case 'B':
+ if (intel_syntax)
+ break;
+ if (sizeflag & SUFFIX_ALWAYS)
+ *obufp++ = 'b';
+ break;
+ case 'C':
+ if (intel_syntax && !alt)
+ break;
+ if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
+ {
+ if (sizeflag & DFLAG)
+ *obufp++ = intel_syntax ? 'd' : 'l';
+ else
+ *obufp++ = intel_syntax ? 'w' : 's';
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
+ break;
+ case 'E': /* For jcxz/jecxz */
+ if (mode_64bit)
+ {
+ if (sizeflag & AFLAG)
+ *obufp++ = 'r';
+ else
+ *obufp++ = 'e';
+ }
+ else
+ if (sizeflag & AFLAG)
+ *obufp++ = 'e';
+ used_prefixes |= (prefixes & PREFIX_ADDR);
+ break;
+ case 'F':
+ if (intel_syntax)
+ break;
+ if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
+ {
+ if (sizeflag & AFLAG)
+ *obufp++ = mode_64bit ? 'q' : 'l';
+ else
+ *obufp++ = mode_64bit ? 'l' : 'w';
+ used_prefixes |= (prefixes & PREFIX_ADDR);
+ }
+ break;
+ case 'H':
+ if (intel_syntax)
+ break;
+ if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
+ || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
+ {
+ used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
+ *obufp++ = ',';
+ *obufp++ = 'p';
+ if (prefixes & PREFIX_DS)
+ *obufp++ = 't';
+ else
+ *obufp++ = 'n';
+ }
+ break;
+ case 'J':
+ if (intel_syntax)
+ break;
+ *obufp++ = 'l';
+ break;
+ case 'L':
+ if (intel_syntax)
+ break;
+ if (sizeflag & SUFFIX_ALWAYS)
+ *obufp++ = 'l';
+ break;
+ case 'N':
+ if ((prefixes & PREFIX_FWAIT) == 0)
+ *obufp++ = 'n';
+ else
+ used_prefixes |= PREFIX_FWAIT;
+ break;
+ case 'O':
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ *obufp++ = 'o';
+ else
+ *obufp++ = 'd';
+ break;
+ case 'T':
+ if (intel_syntax)
+ break;
+ if (mode_64bit)
+ {
+ *obufp++ = 'q';
+ break;
+ }
+ /* Fall through. */
+ case 'P':
+ if (intel_syntax)
+ break;
+ if ((prefixes & PREFIX_DATA)
+ || (rex & REX_MODE64)
+ || (sizeflag & SUFFIX_ALWAYS))
+ {
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ *obufp++ = 'q';
+ else
+ {
+ if (sizeflag & DFLAG)
+ *obufp++ = 'l';
+ else
+ *obufp++ = 'w';
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
+ }
+ break;
+ case 'U':
+ if (intel_syntax)
+ break;
+ if (mode_64bit)
+ {
+ *obufp++ = 'q';
+ break;
+ }
+ /* Fall through. */
+ case 'Q':
+ if (intel_syntax && !alt)
+ break;
+ USED_REX (REX_MODE64);
+ if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
+ {
+ if (rex & REX_MODE64)
+ *obufp++ = 'q';
+ else
+ {
+ if (sizeflag & DFLAG)
+ *obufp++ = intel_syntax ? 'd' : 'l';
+ else
+ *obufp++ = 'w';
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
+ }
+ break;
+ case 'R':
+ USED_REX (REX_MODE64);
+ if (intel_syntax)
+ {
+ if (rex & REX_MODE64)
+ {
+ *obufp++ = 'q';
+ *obufp++ = 't';
+ }
+ else if (sizeflag & DFLAG)
+ {
+ *obufp++ = 'd';
+ *obufp++ = 'q';
+ }
+ else
+ {
+ *obufp++ = 'w';
+ *obufp++ = 'd';
+ }
+ }
+ else
+ {
+ if (rex & REX_MODE64)
+ *obufp++ = 'q';
+ else if (sizeflag & DFLAG)
+ *obufp++ = 'l';
+ else
+ *obufp++ = 'w';
+ }
+ if (!(rex & REX_MODE64))
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ case 'S':
+ if (intel_syntax)
+ break;
+ if (sizeflag & SUFFIX_ALWAYS)
+ {
+ if (rex & REX_MODE64)
+ *obufp++ = 'q';
+ else
+ {
+ if (sizeflag & DFLAG)
+ *obufp++ = 'l';
+ else
+ *obufp++ = 'w';
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
+ }
+ break;
+ case 'X':
+ if (prefixes & PREFIX_DATA)
+ *obufp++ = 'd';
+ else
+ *obufp++ = 's';
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ case 'Y':
+ if (intel_syntax)
+ break;
+ if (rex & REX_MODE64)
+ {
+ USED_REX (REX_MODE64);
+ *obufp++ = 'q';
+ }
+ break;
+ /* implicit operand size 'l' for i386 or 'q' for x86-64 */
+ case 'W':
+ /* operand size flag for cwtl, cbtw */
+ USED_REX (0);
+ if (rex)
+ *obufp++ = 'l';
+ else if (sizeflag & DFLAG)
+ *obufp++ = 'w';
+ else
+ *obufp++ = 'b';
+ if (intel_syntax)
+ {
+ if (rex)
+ {
+ *obufp++ = 'q';
+ *obufp++ = 'e';
+ }
+ if (sizeflag & DFLAG)
+ {
+ *obufp++ = 'd';
+ *obufp++ = 'e';
+ }
+ else
+ {
+ *obufp++ = 'w';
+ }
+ }
+ if (!rex)
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ }
+ alt = 0;
+ }
+ *obufp = 0;
+ return 0;
+}
+
+static void
+oappend (const char *s)
+{
+ strcpy (obufp, s);
+ obufp += strlen (s);
+}
+
+static void
+append_seg (void)
+{
+ if (prefixes & PREFIX_CS)
+ {
+ used_prefixes |= PREFIX_CS;
+ oappend ("%cs:" + intel_syntax);
+ }
+ if (prefixes & PREFIX_DS)
+ {
+ used_prefixes |= PREFIX_DS;
+ oappend ("%ds:" + intel_syntax);
+ }
+ if (prefixes & PREFIX_SS)
+ {
+ used_prefixes |= PREFIX_SS;
+ oappend ("%ss:" + intel_syntax);
+ }
+ if (prefixes & PREFIX_ES)
+ {
+ used_prefixes |= PREFIX_ES;
+ oappend ("%es:" + intel_syntax);
+ }
+ if (prefixes & PREFIX_FS)
+ {
+ used_prefixes |= PREFIX_FS;
+ oappend ("%fs:" + intel_syntax);
+ }
+ if (prefixes & PREFIX_GS)
+ {
+ used_prefixes |= PREFIX_GS;
+ oappend ("%gs:" + intel_syntax);
+ }
+}
+
+static void
+OP_indirE (int bytemode, int sizeflag)
+{
+ if (!intel_syntax)
+ oappend ("*");
+ OP_E (bytemode, sizeflag);
+}
+
+static void
+print_operand_value (char *buf, int hex, bfd_vma disp)
+{
+ if (mode_64bit)
+ {
+ if (hex)
+ {
+ char tmp[30];
+ int i;
+ buf[0] = '0';
+ buf[1] = 'x';
+ sprintf_vma (tmp, disp);
+ for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
+ strcpy (buf + 2, tmp + i);
+ }
+ else
+ {
+ bfd_signed_vma v = disp;
+ char tmp[30];
+ int i;
+ if (v < 0)
+ {
+ *(buf++) = '-';
+ v = -disp;
+ /* Check for possible overflow on 0x8000000000000000. */
+ if (v < 0)
+ {
+ strcpy (buf, "9223372036854775808");
+ return;
+ }
+ }
+ if (!v)
+ {
+ strcpy (buf, "0");
+ return;
+ }
+
+ i = 0;
+ tmp[29] = 0;
+ while (v)
+ {
+ tmp[28 - i] = (v % 10) + '0';
+ v /= 10;
+ i++;
+ }
+ strcpy (buf, tmp + 29 - i);
+ }
+ }
+ else
+ {
+ if (hex)
+ sprintf (buf, "0x%x", (unsigned int) disp);
+ else
+ sprintf (buf, "%d", (int) disp);
+ }
+}
+
+static void
+OP_E (int bytemode, int sizeflag)
+{
+ bfd_vma disp;
+ int add = 0;
+ int riprel = 0;
+ USED_REX (REX_EXTZ);
+ if (rex & REX_EXTZ)
+ add += 8;
+
+ /* Skip mod/rm byte. */
+ MODRM_CHECK;
+ codep++;
+
+ if (mod == 3)
+ {
+ switch (bytemode)
+ {
+ case b_mode:
+ USED_REX (0);
+ if (rex)
+ oappend (names8rex[rm + add]);
+ else
+ oappend (names8[rm + add]);
+ break;
+ case w_mode:
+ oappend (names16[rm + add]);
+ break;
+ case d_mode:
+ oappend (names32[rm + add]);
+ break;
+ case q_mode:
+ oappend (names64[rm + add]);
+ break;
+ case m_mode:
+ if (mode_64bit)
+ oappend (names64[rm + add]);
+ else
+ oappend (names32[rm + add]);
+ break;
+ case branch_v_mode:
+ if (mode_64bit)
+ oappend (names64[rm + add]);
+ else
+ {
+ if ((sizeflag & DFLAG) || bytemode != branch_v_mode)
+ oappend (names32[rm + add]);
+ else
+ oappend (names16[rm + add]);
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
+ break;
+ case v_mode:
+ case dq_mode:
+ case dqw_mode:
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ oappend (names64[rm + add]);
+ else if ((sizeflag & DFLAG) || bytemode != v_mode)
+ oappend (names32[rm + add]);
+ else
+ oappend (names16[rm + add]);
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ case 0:
+ break;
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ break;
+ }
+ return;
+ }
+
+ disp = 0;
+ append_seg ();
+
+ if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
+ {
+ int havesib;
+ int havebase;
+ int base;
+ int index = 0;
+ int scale = 0;
+
+ havesib = 0;
+ havebase = 1;
+ base = rm;
+
+ if (base == 4)
+ {
+ havesib = 1;
+ FETCH_DATA (the_info, codep + 1);
+ index = (*codep >> 3) & 7;
+ if (mode_64bit || index != 0x4)
+ /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
+ scale = (*codep >> 6) & 3;
+ base = *codep & 7;
+ USED_REX (REX_EXTY);
+ if (rex & REX_EXTY)
+ index += 8;
+ codep++;
+ }
+ base += add;
+
+ switch (mod)
+ {
+ case 0:
+ if ((base & 7) == 5)
+ {
+ havebase = 0;
+ if (mode_64bit && !havesib)
+ riprel = 1;
+ disp = get32s ();
+ }
+ break;
+ case 1:
+ FETCH_DATA (the_info, codep + 1);
+ disp = *codep++;
+ if ((disp & 0x80) != 0)
+ disp -= 0x100;
+ break;
+ case 2:
+ disp = get32s ();
+ break;
+ }
+
+ if (!intel_syntax)
+ if (mod != 0 || (base & 7) == 5)
+ {
+ print_operand_value (scratchbuf, !riprel, disp);
+ oappend (scratchbuf);
+ if (riprel)
+ {
+ set_op (disp, 1);
+ oappend ("(%rip)");
+ }
+ }
+
+ if (havebase || (havesib && (index != 4 || scale != 0)))
+ {
+ if (intel_syntax)
+ {
+ switch (bytemode)
+ {
+ case b_mode:
+ oappend ("BYTE PTR ");
+ break;
+ case w_mode:
+ case dqw_mode:
+ oappend ("WORD PTR ");
+ break;
+ case branch_v_mode:
+ case v_mode:
+ case dq_mode:
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ oappend ("QWORD PTR ");
+ else if ((sizeflag & DFLAG) || bytemode == dq_mode)
+ oappend ("DWORD PTR ");
+ else
+ oappend ("WORD PTR ");
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ case d_mode:
+ oappend ("DWORD PTR ");
+ break;
+ case q_mode:
+ oappend ("QWORD PTR ");
+ break;
+ case m_mode:
+ if (mode_64bit)
+ oappend ("QWORD PTR ");
+ else
+ oappend ("DWORD PTR ");
+ break;
+ case f_mode:
+ if (sizeflag & DFLAG)
+ {
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ oappend ("FWORD PTR ");
+ }
+ else
+ oappend ("DWORD PTR ");
+ break;
+ case t_mode:
+ oappend ("TBYTE PTR ");
+ break;
+ case x_mode:
+ oappend ("XMMWORD PTR ");
+ break;
+ default:
+ break;
+ }
+ }
+ *obufp++ = open_char;
+ if (intel_syntax && riprel)
+ oappend ("rip + ");
+ *obufp = '\0';
+ if (havebase)
+ oappend (mode_64bit && (sizeflag & AFLAG)
+ ? names64[base] : names32[base]);
+ if (havesib)
+ {
+ if (index != 4)
+ {
+ if (!intel_syntax || havebase)
+ {
+ *obufp++ = separator_char;
+ *obufp = '\0';
+ }
+ oappend (mode_64bit && (sizeflag & AFLAG)
+ ? names64[index] : names32[index]);
+ }
+ if (scale != 0 || (!intel_syntax && index != 4))
+ {
+ *obufp++ = scale_char;
+ *obufp = '\0';
+ sprintf (scratchbuf, "%d", 1 << scale);
+ oappend (scratchbuf);
+ }
+ }
+ if (intel_syntax && disp)
+ {
+ if ((bfd_signed_vma) disp > 0)
+ {
+ *obufp++ = '+';
+ *obufp = '\0';
+ }
+ else if (mod != 1)
+ {
+ *obufp++ = '-';
+ *obufp = '\0';
+ disp = - (bfd_signed_vma) disp;
+ }
+
+ print_operand_value (scratchbuf, mod != 1, disp);
+ oappend (scratchbuf);
+ }
+
+ *obufp++ = close_char;
+ *obufp = '\0';
+ }
+ else if (intel_syntax)
+ {
+ if (mod != 0 || (base & 7) == 5)
+ {
+ if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
+ | PREFIX_ES | PREFIX_FS | PREFIX_GS))
+ ;
+ else
+ {
+ oappend (names_seg[ds_reg - es_reg]);
+ oappend (":");
+ }
+ print_operand_value (scratchbuf, 1, disp);
+ oappend (scratchbuf);
+ }
+ }
+ }
+ else
+ { /* 16 bit address mode */
+ switch (mod)
+ {
+ case 0:
+ if (rm == 6)
+ {
+ disp = get16 ();
+ if ((disp & 0x8000) != 0)
+ disp -= 0x10000;
+ }
+ break;
+ case 1:
+ FETCH_DATA (the_info, codep + 1);
+ disp = *codep++;
+ if ((disp & 0x80) != 0)
+ disp -= 0x100;
+ break;
+ case 2:
+ disp = get16 ();
+ if ((disp & 0x8000) != 0)
+ disp -= 0x10000;
+ break;
+ }
+
+ if (!intel_syntax)
+ if (mod != 0 || rm == 6)
+ {
+ print_operand_value (scratchbuf, 0, disp);
+ oappend (scratchbuf);
+ }
+
+ if (mod != 0 || rm != 6)
+ {
+ *obufp++ = open_char;
+ *obufp = '\0';
+ oappend (index16[rm]);
+ if (intel_syntax && disp)
+ {
+ if ((bfd_signed_vma) disp > 0)
+ {
+ *obufp++ = '+';
+ *obufp = '\0';
+ }
+ else if (mod != 1)
+ {
+ *obufp++ = '-';
+ *obufp = '\0';
+ disp = - (bfd_signed_vma) disp;
+ }
+
+ print_operand_value (scratchbuf, mod != 1, disp);
+ oappend (scratchbuf);
+ }
+
+ *obufp++ = close_char;
+ *obufp = '\0';
+ }
+ else if (intel_syntax)
+ {
+ if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
+ | PREFIX_ES | PREFIX_FS | PREFIX_GS))
+ ;
+ else
+ {
+ oappend (names_seg[ds_reg - es_reg]);
+ oappend (":");
+ }
+ print_operand_value (scratchbuf, 1, disp & 0xffff);
+ oappend (scratchbuf);
+ }
+ }
+}
+
+static void
+OP_G (int bytemode, int sizeflag)
+{
+ int add = 0;
+ USED_REX (REX_EXTX);
+ if (rex & REX_EXTX)
+ add += 8;
+ switch (bytemode)
+ {
+ case b_mode:
+ USED_REX (0);
+ if (rex)
+ oappend (names8rex[reg + add]);
+ else
+ oappend (names8[reg + add]);
+ break;
+ case w_mode:
+ oappend (names16[reg + add]);
+ break;
+ case d_mode:
+ oappend (names32[reg + add]);
+ break;
+ case q_mode:
+ oappend (names64[reg + add]);
+ break;
+ case v_mode:
+ case dq_mode:
+ case dqw_mode:
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ oappend (names64[reg + add]);
+ else if ((sizeflag & DFLAG) || bytemode != v_mode)
+ oappend (names32[reg + add]);
+ else
+ oappend (names16[reg + add]);
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ case m_mode:
+ if (mode_64bit)
+ oappend (names64[reg + add]);
+ else
+ oappend (names32[reg + add]);
+ break;
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ break;
+ }
+}
+
+static bfd_vma
+get64 (void)
+{
+ bfd_vma x;
+#ifdef BFD64
+ unsigned int a;
+ unsigned int b;
+
+ FETCH_DATA (the_info, codep + 8);
+ a = *codep++ & 0xff;
+ a |= (*codep++ & 0xff) << 8;
+ a |= (*codep++ & 0xff) << 16;
+ a |= (*codep++ & 0xff) << 24;
+ b = *codep++ & 0xff;
+ b |= (*codep++ & 0xff) << 8;
+ b |= (*codep++ & 0xff) << 16;
+ b |= (*codep++ & 0xff) << 24;
+ x = a + ((bfd_vma) b << 32);
+#else
+ abort ();
+ x = 0;
+#endif
+ return x;
+}
+
+static bfd_signed_vma
+get32 (void)
+{
+ bfd_signed_vma x = 0;
+
+ FETCH_DATA (the_info, codep + 4);
+ x = *codep++ & (bfd_signed_vma) 0xff;
+ x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
+ x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
+ x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
+ return x;
+}
+
+static bfd_signed_vma
+get32s (void)
+{
+ bfd_signed_vma x = 0;
+
+ FETCH_DATA (the_info, codep + 4);
+ x = *codep++ & (bfd_signed_vma) 0xff;
+ x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
+ x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
+ x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
+
+ x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
+
+ return x;
+}
+
+static int
+get16 (void)
+{
+ int x = 0;
+
+ FETCH_DATA (the_info, codep + 2);
+ x = *codep++ & 0xff;
+ x |= (*codep++ & 0xff) << 8;
+ return x;
+}
+
+static void
+set_op (bfd_vma op, int riprel)
+{
+ op_index[op_ad] = op_ad;
+ if (mode_64bit)
+ {
+ op_address[op_ad] = op;
+ op_riprel[op_ad] = riprel;
+ }
+ else
+ {
+ /* Mask to get a 32-bit address. */
+ op_address[op_ad] = op & 0xffffffff;
+ op_riprel[op_ad] = riprel & 0xffffffff;
+ }
+}
+
+static void
+OP_REG (int code, int sizeflag)
+{
+ const char *s;
+ int add = 0;
+ USED_REX (REX_EXTZ);
+ if (rex & REX_EXTZ)
+ add = 8;
+
+ switch (code)
+ {
+ case indir_dx_reg:
+ if (intel_syntax)
+ s = "[dx]";
+ else
+ s = "(%dx)";
+ break;
+ case ax_reg: case cx_reg: case dx_reg: case bx_reg:
+ case sp_reg: case bp_reg: case si_reg: case di_reg:
+ s = names16[code - ax_reg + add];
+ break;
+ case es_reg: case ss_reg: case cs_reg:
+ case ds_reg: case fs_reg: case gs_reg:
+ s = names_seg[code - es_reg + add];
+ break;
+ case al_reg: case ah_reg: case cl_reg: case ch_reg:
+ case dl_reg: case dh_reg: case bl_reg: case bh_reg:
+ USED_REX (0);
+ if (rex)
+ s = names8rex[code - al_reg + add];
+ else
+ s = names8[code - al_reg];
+ break;
+ case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
+ case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
+ if (mode_64bit)
+ {
+ s = names64[code - rAX_reg + add];
+ break;
+ }
+ code += eAX_reg - rAX_reg;
+ /* Fall through. */
+ case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
+ case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ s = names64[code - eAX_reg + add];
+ else if (sizeflag & DFLAG)
+ s = names32[code - eAX_reg + add];
+ else
+ s = names16[code - eAX_reg + add];
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ default:
+ s = INTERNAL_DISASSEMBLER_ERROR;
+ break;
+ }
+ oappend (s);
+}
+
+static void
+OP_IMREG (int code, int sizeflag)
+{
+ const char *s;
+
+ switch (code)
+ {
+ case indir_dx_reg:
+ if (intel_syntax)
+ s = "[dx]";
+ else
+ s = "(%dx)";
+ break;
+ case ax_reg: case cx_reg: case dx_reg: case bx_reg:
+ case sp_reg: case bp_reg: case si_reg: case di_reg:
+ s = names16[code - ax_reg];
+ break;
+ case es_reg: case ss_reg: case cs_reg:
+ case ds_reg: case fs_reg: case gs_reg:
+ s = names_seg[code - es_reg];
+ break;
+ case al_reg: case ah_reg: case cl_reg: case ch_reg:
+ case dl_reg: case dh_reg: case bl_reg: case bh_reg:
+ USED_REX (0);
+ if (rex)
+ s = names8rex[code - al_reg];
+ else
+ s = names8[code - al_reg];
+ break;
+ case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
+ case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ s = names64[code - eAX_reg];
+ else if (sizeflag & DFLAG)
+ s = names32[code - eAX_reg];
+ else
+ s = names16[code - eAX_reg];
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ default:
+ s = INTERNAL_DISASSEMBLER_ERROR;
+ break;
+ }
+ oappend (s);
+}
+
+static void
+OP_I (int bytemode, int sizeflag)
+{
+ bfd_signed_vma op;
+ bfd_signed_vma mask = -1;
+
+ switch (bytemode)
+ {
+ case b_mode:
+ FETCH_DATA (the_info, codep + 1);
+ op = *codep++;
+ mask = 0xff;
+ break;
+ case q_mode:
+ if (mode_64bit)
+ {
+ op = get32s ();
+ break;
+ }
+ /* Fall through. */
+ case v_mode:
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ op = get32s ();
+ else if (sizeflag & DFLAG)
+ {
+ op = get32 ();
+ mask = 0xffffffff;
+ }
+ else
+ {
+ op = get16 ();
+ mask = 0xfffff;
+ }
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ case w_mode:
+ mask = 0xfffff;
+ op = get16 ();
+ break;
+ case const_1_mode:
+ if (intel_syntax)
+ oappend ("1");
+ return;
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ return;
+ }
+
+ op &= mask;
+ scratchbuf[0] = '$';
+ print_operand_value (scratchbuf + 1, 1, op);
+ oappend (scratchbuf + intel_syntax);
+ scratchbuf[0] = '\0';
+}
+
+static void
+OP_I64 (int bytemode, int sizeflag)
+{
+ bfd_signed_vma op;
+ bfd_signed_vma mask = -1;
+
+ if (!mode_64bit)
+ {
+ OP_I (bytemode, sizeflag);
+ return;
+ }
+
+ switch (bytemode)
+ {
+ case b_mode:
+ FETCH_DATA (the_info, codep + 1);
+ op = *codep++;
+ mask = 0xff;
+ break;
+ case v_mode:
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ op = get64 ();
+ else if (sizeflag & DFLAG)
+ {
+ op = get32 ();
+ mask = 0xffffffff;
+ }
+ else
+ {
+ op = get16 ();
+ mask = 0xfffff;
+ }
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ case w_mode:
+ mask = 0xfffff;
+ op = get16 ();
+ break;
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ return;
+ }
+
+ op &= mask;
+ scratchbuf[0] = '$';
+ print_operand_value (scratchbuf + 1, 1, op);
+ oappend (scratchbuf + intel_syntax);
+ scratchbuf[0] = '\0';
+}
+
+static void
+OP_sI (int bytemode, int sizeflag)
+{
+ bfd_signed_vma op;
+ bfd_signed_vma mask = -1;
+
+ switch (bytemode)
+ {
+ case b_mode:
+ FETCH_DATA (the_info, codep + 1);
+ op = *codep++;
+ if ((op & 0x80) != 0)
+ op -= 0x100;
+ mask = 0xffffffff;
+ break;
+ case v_mode:
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ op = get32s ();
+ else if (sizeflag & DFLAG)
+ {
+ op = get32s ();
+ mask = 0xffffffff;
+ }
+ else
+ {
+ mask = 0xffffffff;
+ op = get16 ();
+ if ((op & 0x8000) != 0)
+ op -= 0x10000;
+ }
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ case w_mode:
+ op = get16 ();
+ mask = 0xffffffff;
+ if ((op & 0x8000) != 0)
+ op -= 0x10000;
+ break;
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ return;
+ }
+
+ scratchbuf[0] = '$';
+ print_operand_value (scratchbuf + 1, 1, op);
+ oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_J (int bytemode, int sizeflag)
+{
+ bfd_vma disp;
+ bfd_vma mask = -1;
+
+ switch (bytemode)
+ {
+ case b_mode:
+ FETCH_DATA (the_info, codep + 1);
+ disp = *codep++;
+ if ((disp & 0x80) != 0)
+ disp -= 0x100;
+ break;
+ case v_mode:
+ if (sizeflag & DFLAG)
+ disp = get32s ();
+ else
+ {
+ disp = get16 ();
+ /* For some reason, a data16 prefix on a jump instruction
+ means that the pc is masked to 16 bits after the
+ displacement is added! */
+ mask = 0xffff;
+ }
+ break;
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ return;
+ }
+ disp = (start_pc + codep - start_codep + disp) & mask;
+ set_op (disp, 0);
+ print_operand_value (scratchbuf, 1, disp);
+ oappend (scratchbuf);
+}
+
+static void
+OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ oappend (names_seg[reg]);
+}
+
+static void
+OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
+{
+ int seg, offset;
+
+ if (sizeflag & DFLAG)
+ {
+ offset = get32 ();
+ seg = get16 ();
+ }
+ else
+ {
+ offset = get16 ();
+ seg = get16 ();
+ }
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ if (intel_syntax)
+ sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
+ else
+ sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
+ oappend (scratchbuf);
+}
+
+static void
+OP_OFF (int bytemode ATTRIBUTE_UNUSED, int sizeflag)
+{
+ bfd_vma off;
+
+ append_seg ();
+
+ if ((sizeflag & AFLAG) || mode_64bit)
+ off = get32 ();
+ else
+ off = get16 ();
+
+ if (intel_syntax)
+ {
+ if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
+ | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
+ {
+ oappend (names_seg[ds_reg - es_reg]);
+ oappend (":");
+ }
+ }
+ print_operand_value (scratchbuf, 1, off);
+ oappend (scratchbuf);
+}
+
+static void
+OP_OFF64 (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ bfd_vma off;
+
+ if (!mode_64bit)
+ {
+ OP_OFF (bytemode, sizeflag);
+ return;
+ }
+
+ append_seg ();
+
+ off = get64 ();
+
+ if (intel_syntax)
+ {
+ if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
+ | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
+ {
+ oappend (names_seg[ds_reg - es_reg]);
+ oappend (":");
+ }
+ }
+ print_operand_value (scratchbuf, 1, off);
+ oappend (scratchbuf);
+}
+
+static void
+ptr_reg (int code, int sizeflag)
+{
+ const char *s;
+
+ *obufp++ = open_char;
+ used_prefixes |= (prefixes & PREFIX_ADDR);
+ if (mode_64bit)
+ {
+ if (!(sizeflag & AFLAG))
+ s = names32[code - eAX_reg];
+ else
+ s = names64[code - eAX_reg];
+ }
+ else if (sizeflag & AFLAG)
+ s = names32[code - eAX_reg];
+ else
+ s = names16[code - eAX_reg];
+ oappend (s);
+ *obufp++ = close_char;
+ *obufp = 0;
+}
+
+static void
+OP_ESreg (int code, int sizeflag)
+{
+ if (intel_syntax)
+ {
+ if (codep[-1] & 1)
+ {
+ USED_REX (REX_MODE64);
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ if (rex & REX_MODE64)
+ oappend ("QWORD PTR ");
+ else if ((sizeflag & DFLAG))
+ oappend ("DWORD PTR ");
+ else
+ oappend ("WORD PTR ");
+ }
+ else
+ oappend ("BYTE PTR ");
+ }
+
+ oappend ("%es:" + intel_syntax);
+ ptr_reg (code, sizeflag);
+}
+
+static void
+OP_DSreg (int code, int sizeflag)
+{
+ if (intel_syntax)
+ {
+ if (codep[-1] != 0xd7 && (codep[-1] & 1))
+ {
+ USED_REX (REX_MODE64);
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ if (rex & REX_MODE64)
+ oappend ("QWORD PTR ");
+ else if ((sizeflag & DFLAG))
+ oappend ("DWORD PTR ");
+ else
+ oappend ("WORD PTR ");
+ }
+ else
+ oappend ("BYTE PTR ");
+ }
+
+ if ((prefixes
+ & (PREFIX_CS
+ | PREFIX_DS
+ | PREFIX_SS
+ | PREFIX_ES
+ | PREFIX_FS
+ | PREFIX_GS)) == 0)
+ prefixes |= PREFIX_DS;
+ append_seg ();
+ ptr_reg (code, sizeflag);
+}
+
+static void
+OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ int add = 0;
+ if (rex & REX_EXTX)
+ {
+ USED_REX (REX_EXTX);
+ add = 8;
+ }
+ else if (!mode_64bit && (prefixes & PREFIX_LOCK))
+ {
+ used_prefixes |= PREFIX_LOCK;
+ add = 8;
+ }
+ sprintf (scratchbuf, "%%cr%d", reg + add);
+ oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ int add = 0;
+ USED_REX (REX_EXTX);
+ if (rex & REX_EXTX)
+ add = 8;
+ if (intel_syntax)
+ sprintf (scratchbuf, "db%d", reg + add);
+ else
+ sprintf (scratchbuf, "%%db%d", reg + add);
+ oappend (scratchbuf);
+}
+
+static void
+OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ sprintf (scratchbuf, "%%tr%d", reg);
+ oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_Rd (int bytemode, int sizeflag)
+{
+ if (mod == 3)
+ OP_E (bytemode, sizeflag);
+ else
+ BadOp ();
+}
+
+static void
+OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ if (prefixes & PREFIX_DATA)
+ {
+ int add = 0;
+ USED_REX (REX_EXTX);
+ if (rex & REX_EXTX)
+ add = 8;
+ sprintf (scratchbuf, "%%xmm%d", reg + add);
+ }
+ else
+ sprintf (scratchbuf, "%%mm%d", reg);
+ oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ int add = 0;
+ USED_REX (REX_EXTX);
+ if (rex & REX_EXTX)
+ add = 8;
+ sprintf (scratchbuf, "%%xmm%d", reg + add);
+ oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_EM (int bytemode, int sizeflag)
+{
+ if (mod != 3)
+ {
+ if (intel_syntax && bytemode == v_mode)
+ {
+ bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
+ OP_E (bytemode, sizeflag);
+ return;
+ }
+
+ /* Skip mod/rm byte. */
+ MODRM_CHECK;
+ codep++;
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ if (prefixes & PREFIX_DATA)
+ {
+ int add = 0;
+
+ USED_REX (REX_EXTZ);
+ if (rex & REX_EXTZ)
+ add = 8;
+ sprintf (scratchbuf, "%%xmm%d", rm + add);
+ }
+ else
+ sprintf (scratchbuf, "%%mm%d", rm);
+ oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_EX (int bytemode, int sizeflag)
+{
+ int add = 0;
+ if (mod != 3)
+ {
+ if (intel_syntax && bytemode == v_mode)
+ {
+ switch (prefixes & (PREFIX_DATA|PREFIX_REPZ|PREFIX_REPNZ))
+ {
+ case 0: bytemode = x_mode; break;
+ case PREFIX_REPZ: bytemode = d_mode; used_prefixes |= PREFIX_REPZ; break;
+ case PREFIX_DATA: bytemode = x_mode; used_prefixes |= PREFIX_DATA; break;
+ case PREFIX_REPNZ: bytemode = q_mode; used_prefixes |= PREFIX_REPNZ; break;
+ default: bytemode = 0; break;
+ }
+ }
+ OP_E (bytemode, sizeflag);
+ return;
+ }
+ USED_REX (REX_EXTZ);
+ if (rex & REX_EXTZ)
+ add = 8;
+
+ /* Skip mod/rm byte. */
+ MODRM_CHECK;
+ codep++;
+ sprintf (scratchbuf, "%%xmm%d", rm + add);
+ oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_MS (int bytemode, int sizeflag)
+{
+ if (mod == 3)
+ OP_EM (bytemode, sizeflag);
+ else
+ BadOp ();
+}
+
+static void
+OP_XS (int bytemode, int sizeflag)
+{
+ if (mod == 3)
+ OP_EX (bytemode, sizeflag);
+ else
+ BadOp ();
+}
+
+static void
+OP_M (int bytemode, int sizeflag)
+{
+ if (mod == 3)
+ BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */
+ else
+ OP_E (bytemode, sizeflag);
+}
+
+static void
+OP_0f07 (int bytemode, int sizeflag)
+{
+ if (mod != 3 || rm != 0)
+ BadOp ();
+ else
+ OP_E (bytemode, sizeflag);
+}
+
+static void
+OP_0fae (int bytemode, int sizeflag)
+{
+ if (mod == 3)
+ {
+ if (reg == 7)
+ strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
+
+ if (reg < 5 || rm != 0)
+ {
+ BadOp (); /* bad sfence, mfence, or lfence */
+ return;
+ }
+ }
+ else if (reg != 7)
+ {
+ BadOp (); /* bad clflush */
+ return;
+ }
+
+ OP_E (bytemode, sizeflag);
+}
+
+static void
+NOP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ /* NOP with REPZ prefix is called PAUSE. */
+ if (prefixes == PREFIX_REPZ)
+ strcpy (obuf, "pause");
+}
+
+static const char *const Suffix3DNow[] = {
+/* 00 */ NULL, NULL, NULL, NULL,
+/* 04 */ NULL, NULL, NULL, NULL,
+/* 08 */ NULL, NULL, NULL, NULL,
+/* 0C */ "pi2fw", "pi2fd", NULL, NULL,
+/* 10 */ NULL, NULL, NULL, NULL,
+/* 14 */ NULL, NULL, NULL, NULL,
+/* 18 */ NULL, NULL, NULL, NULL,
+/* 1C */ "pf2iw", "pf2id", NULL, NULL,
+/* 20 */ NULL, NULL, NULL, NULL,
+/* 24 */ NULL, NULL, NULL, NULL,
+/* 28 */ NULL, NULL, NULL, NULL,
+/* 2C */ NULL, NULL, NULL, NULL,
+/* 30 */ NULL, NULL, NULL, NULL,
+/* 34 */ NULL, NULL, NULL, NULL,
+/* 38 */ NULL, NULL, NULL, NULL,
+/* 3C */ NULL, NULL, NULL, NULL,
+/* 40 */ NULL, NULL, NULL, NULL,
+/* 44 */ NULL, NULL, NULL, NULL,
+/* 48 */ NULL, NULL, NULL, NULL,
+/* 4C */ NULL, NULL, NULL, NULL,
+/* 50 */ NULL, NULL, NULL, NULL,
+/* 54 */ NULL, NULL, NULL, NULL,
+/* 58 */ NULL, NULL, NULL, NULL,
+/* 5C */ NULL, NULL, NULL, NULL,
+/* 60 */ NULL, NULL, NULL, NULL,
+/* 64 */ NULL, NULL, NULL, NULL,
+/* 68 */ NULL, NULL, NULL, NULL,
+/* 6C */ NULL, NULL, NULL, NULL,
+/* 70 */ NULL, NULL, NULL, NULL,
+/* 74 */ NULL, NULL, NULL, NULL,
+/* 78 */ NULL, NULL, NULL, NULL,
+/* 7C */ NULL, NULL, NULL, NULL,
+/* 80 */ NULL, NULL, NULL, NULL,
+/* 84 */ NULL, NULL, NULL, NULL,
+/* 88 */ NULL, NULL, "pfnacc", NULL,
+/* 8C */ NULL, NULL, "pfpnacc", NULL,
+/* 90 */ "pfcmpge", NULL, NULL, NULL,
+/* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
+/* 98 */ NULL, NULL, "pfsub", NULL,
+/* 9C */ NULL, NULL, "pfadd", NULL,
+/* A0 */ "pfcmpgt", NULL, NULL, NULL,
+/* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
+/* A8 */ NULL, NULL, "pfsubr", NULL,
+/* AC */ NULL, NULL, "pfacc", NULL,
+/* B0 */ "pfcmpeq", NULL, NULL, NULL,
+/* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
+/* B8 */ NULL, NULL, NULL, "pswapd",
+/* BC */ NULL, NULL, NULL, "pavgusb",
+/* C0 */ NULL, NULL, NULL, NULL,
+/* C4 */ NULL, NULL, NULL, NULL,
+/* C8 */ NULL, NULL, NULL, NULL,
+/* CC */ NULL, NULL, NULL, NULL,
+/* D0 */ NULL, NULL, NULL, NULL,
+/* D4 */ NULL, NULL, NULL, NULL,
+/* D8 */ NULL, NULL, NULL, NULL,
+/* DC */ NULL, NULL, NULL, NULL,
+/* E0 */ NULL, NULL, NULL, NULL,
+/* E4 */ NULL, NULL, NULL, NULL,
+/* E8 */ NULL, NULL, NULL, NULL,
+/* EC */ NULL, NULL, NULL, NULL,
+/* F0 */ NULL, NULL, NULL, NULL,
+/* F4 */ NULL, NULL, NULL, NULL,
+/* F8 */ NULL, NULL, NULL, NULL,
+/* FC */ NULL, NULL, NULL, NULL,
+};
+
+static void
+OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ const char *mnemonic;
+
+ FETCH_DATA (the_info, codep + 1);
+ /* AMD 3DNow! instructions are specified by an opcode suffix in the
+ place where an 8-bit immediate would normally go. ie. the last
+ byte of the instruction. */
+ obufp = obuf + strlen (obuf);
+ mnemonic = Suffix3DNow[*codep++ & 0xff];
+ if (mnemonic)
+ oappend (mnemonic);
+ else
+ {
+ /* Since a variable sized modrm/sib chunk is between the start
+ of the opcode (0x0f0f) and the opcode suffix, we need to do
+ all the modrm processing first, and don't know until now that
+ we have a bad opcode. This necessitates some cleaning up. */
+ op1out[0] = '\0';
+ op2out[0] = '\0';
+ BadOp ();
+ }
+}
+
+static const char *simd_cmp_op[] = {
+ "eq",
+ "lt",
+ "le",
+ "unord",
+ "neq",
+ "nlt",
+ "nle",
+ "ord"
+};
+
+static void
+OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ unsigned int cmp_type;
+
+ FETCH_DATA (the_info, codep + 1);
+ obufp = obuf + strlen (obuf);
+ cmp_type = *codep++ & 0xff;
+ if (cmp_type < 8)
+ {
+ char suffix1 = 'p', suffix2 = 's';
+ used_prefixes |= (prefixes & PREFIX_REPZ);
+ if (prefixes & PREFIX_REPZ)
+ suffix1 = 's';
+ else
+ {
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ if (prefixes & PREFIX_DATA)
+ suffix2 = 'd';
+ else
+ {
+ used_prefixes |= (prefixes & PREFIX_REPNZ);
+ if (prefixes & PREFIX_REPNZ)
+ suffix1 = 's', suffix2 = 'd';
+ }
+ }
+ sprintf (scratchbuf, "cmp%s%c%c",
+ simd_cmp_op[cmp_type], suffix1, suffix2);
+ used_prefixes |= (prefixes & PREFIX_REPZ);
+ oappend (scratchbuf);
+ }
+ else
+ {
+ /* We have a bad extension byte. Clean up. */
+ op1out[0] = '\0';
+ op2out[0] = '\0';
+ BadOp ();
+ }
+}
+
+static void
+SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
+{
+ /* Change movlps/movhps to movhlps/movlhps for 2 register operand
+ forms of these instructions. */
+ if (mod == 3)
+ {
+ char *p = obuf + strlen (obuf);
+ *(p + 1) = '\0';
+ *p = *(p - 1);
+ *(p - 1) = *(p - 2);
+ *(p - 2) = *(p - 3);
+ *(p - 3) = extrachar;
+ }
+}
+
+static void
+PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
+{
+ if (mod == 3 && reg == 1 && rm <= 1)
+ {
+ /* Override "sidt". */
+ char *p = obuf + strlen (obuf) - 4;
+
+ /* We might have a suffix when disassembling with -Msuffix. */
+ if (*p == 'i')
+ --p;
+
+ if (rm)
+ {
+ /* mwait %eax,%ecx */
+ strcpy (p, "mwait");
+ if (!intel_syntax)
+ strcpy (op1out, names32[0]);
+ }
+ else
+ {
+ /* monitor %eax,%ecx,%edx" */
+ strcpy (p, "monitor");
+ if (!intel_syntax)
+ {
+ if (!mode_64bit)
+ strcpy (op1out, names32[0]);
+ else if (!(prefixes & PREFIX_ADDR))
+ strcpy (op1out, names64[0]);
+ else
+ {
+ strcpy (op1out, names32[0]);
+ used_prefixes |= PREFIX_ADDR;
+ }
+ strcpy (op3out, names32[2]);
+ }
+ }
+ if (!intel_syntax)
+ {
+ strcpy (op2out, names32[1]);
+ two_source_ops = 1;
+ }
+
+ codep++;
+ }
+ else
+ OP_M (0, sizeflag);
+}
+
+static void
+SVME_Fixup (int bytemode, int sizeflag)
+{
+ const char *alt;
+ char *p;
+
+ switch (*codep)
+ {
+ case 0xd8:
+ alt = "vmrun";
+ break;
+ case 0xd9:
+ alt = "vmmcall";
+ break;
+ case 0xda:
+ alt = "vmload";
+ break;
+ case 0xdb:
+ alt = "vmsave";
+ break;
+ case 0xdc:
+ alt = "stgi";
+ break;
+ case 0xdd:
+ alt = "clgi";
+ break;
+ case 0xde:
+ alt = "skinit";
+ break;
+ case 0xdf:
+ alt = "invlpga";
+ break;
+ default:
+ OP_M (bytemode, sizeflag);
+ return;
+ }
+ /* Override "lidt". */
+ p = obuf + strlen (obuf) - 4;
+ /* We might have a suffix. */
+ if (*p == 'i')
+ --p;
+ strcpy (p, alt);
+ if (!(prefixes & PREFIX_ADDR))
+ {
+ ++codep;
+ return;
+ }
+ used_prefixes |= PREFIX_ADDR;
+ switch (*codep++)
+ {
+ case 0xdf:
+ strcpy (op2out, names32[1]);
+ two_source_ops = 1;
+ /* Fall through. */
+ case 0xd8:
+ case 0xda:
+ case 0xdb:
+ *obufp++ = open_char;
+ if (mode_64bit || (sizeflag & AFLAG))
+ alt = names32[0];
+ else
+ alt = names16[0];
+ strcpy (obufp, alt);
+ obufp += strlen (alt);
+ *obufp++ = close_char;
+ *obufp = '\0';
+ break;
+ }
+}
+
+static void
+INVLPG_Fixup (int bytemode, int sizeflag)
+{
+ const char *alt;
+
+ switch (*codep)
+ {
+ case 0xf8:
+ alt = "swapgs";
+ break;
+ case 0xf9:
+ alt = "rdtscp";
+ break;
+ default:
+ OP_M (bytemode, sizeflag);
+ return;
+ }
+ /* Override "invlpg". */
+ strcpy (obuf + strlen (obuf) - 6, alt);
+ codep++;
+}
+
+static void
+BadOp (void)
+{
+ /* Throw away prefixes and 1st. opcode byte. */
+ codep = insn_codep + 1;
+ oappend ("(bad)");
+}
+
+static void
+SEG_Fixup (int extrachar, int sizeflag)
+{
+ if (mod == 3)
+ {
+ /* We need to add a proper suffix with
+
+ movw %ds,%ax
+ movl %ds,%eax
+ movq %ds,%rax
+ movw %ax,%ds
+ movl %eax,%ds
+ movq %rax,%ds
+ */
+ const char *suffix;
+
+ if (prefixes & PREFIX_DATA)
+ suffix = "w";
+ else
+ {
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ suffix = "q";
+ else
+ suffix = "l";
+ }
+ strcat (obuf, suffix);
+ }
+ else
+ {
+ /* We need to fix the suffix for
+
+ movw %ds,(%eax)
+ movw %ds,(%rax)
+ movw (%eax),%ds
+ movw (%rax),%ds
+
+ Override "mov[l|q]". */
+ char *p = obuf + strlen (obuf) - 1;
+
+ /* We might not have a suffix. */
+ if (*p == 'v')
+ ++p;
+ *p = 'w';
+ }
+
+ OP_E (extrachar, sizeflag);
+}
+
+static void
+VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
+{
+ if (mod == 3 && reg == 0 && rm >=1 && rm <= 4)
+ {
+ /* Override "sgdt". */
+ char *p = obuf + strlen (obuf) - 4;
+
+ /* We might have a suffix when disassembling with -Msuffix. */
+ if (*p == 'g')
+ --p;
+
+ switch (rm)
+ {
+ case 1:
+ strcpy (p, "vmcall");
+ break;
+ case 2:
+ strcpy (p, "vmlaunch");
+ break;
+ case 3:
+ strcpy (p, "vmresume");
+ break;
+ case 4:
+ strcpy (p, "vmxoff");
+ break;
+ }
+
+ codep++;
+ }
+ else
+ OP_E (0, sizeflag);
+}
+
+static void
+OP_VMX (int bytemode, int sizeflag)
+{
+ used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
+ if (prefixes & PREFIX_DATA)
+ strcpy (obuf, "vmclear");
+ else if (prefixes & PREFIX_REPZ)
+ strcpy (obuf, "vmxon");
+ else
+ strcpy (obuf, "vmptrld");
+ OP_E (bytemode, sizeflag);
+}
--- /dev/null
+# Standard architecture specific commands for kdb.
+# These commands are appended to those in kdb/kdb_cmds, see that file for
+# restrictions.
+
+# Standard debugging information for first level support, invoked from archkdb*
+# commands that are defined in kdb/kdb_cmds.
+
+defcmd archkdbcommon "" "Common arch debugging"
+ set LINES 2000000
+ set BTAPROMPT 0
+ -summary
+ -id %eip-24
+ -cpu
+ -ps
+ -dmesg 600
+ -bt
+endefcmd
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Breakpoint Handling
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/ptrace.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+
+
+static char *kdba_rwtypes[] = { "Instruction(Register)", "Data Write",
+ "I/O", "Data Access"};
+
+/*
+ * Table describing processor architecture hardware
+ * breakpoint registers.
+ */
+
+static kdbhard_bp_t kdb_hardbreaks[KDB_MAXHARDBPT];
+
+/*
+ * kdba_db_trap
+ *
+ * Perform breakpoint processing upon entry to the
+ * processor debugger fault. Determine and print
+ * the active breakpoint.
+ *
+ * Parameters:
+ * regs Exception frame containing machine register state
+ * error Error number passed to kdb.
+ * Outputs:
+ * None.
+ * Returns:
+ * KDB_DB_BPT Standard instruction or data breakpoint encountered
+ * KDB_DB_SS Single Step fault ('ss' command or end of 'ssb' command)
+ * KDB_DB_SSB Single Step fault, caller should continue ('ssb' command)
+ * KDB_DB_SSBPT Single step over breakpoint
+ * KDB_DB_NOBPT No existing kdb breakpoint matches this debug exception
+ * Locking:
+ * None.
+ * Remarks:
+ * Yup, there be goto's here.
+ *
+ * If multiple processors receive debug exceptions simultaneously,
+ * one may be waiting at the kdb fence in kdb() while the user
+ * issues a 'bc' command to clear the breakpoint the processor
+ * which is waiting has already encountered. If this is the case,
+ * the debug registers will no longer match any entry in the
+ * breakpoint table, and we'll return the value KDB_DB_NOBPT.
+ * This can cause a panic in die_if_kernel(). It is safer to
+ * disable the breakpoint (bd), go until all processors are past
+ * the breakpoint then clear the breakpoint (bc). This code
+ * recognises a breakpoint even when disabled but not when it has
+ * been cleared.
+ *
+ * WARNING: This routine clears the debug state. It should be called
+ * once per debug and the result cached.
+ */
+
+kdb_dbtrap_t
+kdba_db_trap(struct pt_regs *regs, int error_unused)
+{
+ kdb_machreg_t dr6;
+ kdb_machreg_t dr7;
+ int rw, reg;
+ int i;
+ kdb_dbtrap_t rv = KDB_DB_BPT;
+ kdb_bp_t *bp;
+
+ if (KDB_NULL_REGS(regs))
+ return KDB_DB_NOBPT;
+
+ dr6 = kdba_getdr6();
+ dr7 = kdba_getdr7();
+
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdb: dr6 0x%lx dr7 0x%lx\n", dr6, dr7);
+ if (dr6 & DR6_BS) {
+ if (KDB_STATE(SSBPT)) {
+ if (KDB_DEBUG(BP))
+ kdb_printf("ssbpt\n");
+ KDB_STATE_CLEAR(SSBPT);
+ for(i=0,bp=kdb_breakpoints;
+ i < KDB_MAXBPT;
+ i++, bp++) {
+ if (KDB_DEBUG(BP))
+ kdb_printf("bp 0x%p enabled %d delayed %d global %d cpu %d\n",
+ bp, bp->bp_enabled, bp->bp_delayed, bp->bp_global, bp->bp_cpu);
+ if (!bp->bp_enabled)
+ continue;
+ if (!bp->bp_global && bp->bp_cpu != smp_processor_id())
+ continue;
+ if (KDB_DEBUG(BP))
+ kdb_printf("bp for this cpu\n");
+ if (bp->bp_delayed) {
+ bp->bp_delayed = 0;
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_installbp\n");
+ kdba_installbp(regs, bp);
+ if (!KDB_STATE(DOING_SS)) {
+ regs->eflags &= ~EF_TF;
+ return(KDB_DB_SSBPT);
+ }
+ break;
+ }
+ }
+ if (i == KDB_MAXBPT) {
+ kdb_printf("kdb: Unable to find delayed breakpoint\n");
+ }
+ if (!KDB_STATE(DOING_SS)) {
+ regs->eflags &= ~EF_TF;
+ return(KDB_DB_NOBPT);
+ }
+ /* FALLTHROUGH */
+ }
+
+ /*
+ * KDB_STATE_DOING_SS is set when the kernel debugger is using
+ * the processor trap flag to single-step a processor. If a
+ * single step trap occurs and this flag is clear, the SS trap
+ * will be ignored by KDB and the kernel will be allowed to deal
+ * with it as necessary (e.g. for ptrace).
+ */
+ if (!KDB_STATE(DOING_SS))
+ goto unknown;
+
+ /* single step */
+ rv = KDB_DB_SS; /* Indicate single step */
+ if (KDB_STATE(DOING_SSB)) {
+ unsigned char instruction[2];
+
+ kdb_id1(regs->eip);
+ if (kdb_getarea(instruction, regs->eip) ||
+ (instruction[0]&0xf0) == 0xe0 || /* short disp jumps */
+ (instruction[0]&0xf0) == 0x70 || /* Misc. jumps */
+ instruction[0] == 0xc2 || /* ret */
+ instruction[0] == 0x9a || /* call */
+ (instruction[0]&0xf8) == 0xc8 || /* enter, leave, iret, int, */
+ ((instruction[0] == 0x0f) &&
+ ((instruction[1]&0xf0)== 0x80))
+ ) {
+ /*
+ * End the ssb command here.
+ */
+ KDB_STATE_CLEAR(DOING_SSB);
+ KDB_STATE_CLEAR(DOING_SS);
+ } else {
+ rv = KDB_DB_SSB; /* Indicate ssb - dismiss immediately */
+ }
+ } else {
+ /*
+ * Print current insn
+ */
+ kdb_printf("SS trap at ");
+ kdb_symbol_print(regs->eip, NULL, KDB_SP_DEFAULT|KDB_SP_NEWLINE);
+ kdb_id1(regs->eip);
+ KDB_STATE_CLEAR(DOING_SS);
+ }
+
+ if (rv != KDB_DB_SSB)
+ regs->eflags &= ~EF_TF;
+ }
+
+ if (dr6 & DR6_B0) {
+ rw = DR7_RW0(dr7);
+ reg = 0;
+ goto handle;
+ }
+
+ if (dr6 & DR6_B1) {
+ rw = DR7_RW1(dr7);
+ reg = 1;
+ goto handle;
+ }
+
+ if (dr6 & DR6_B2) {
+ rw = DR7_RW2(dr7);
+ reg = 2;
+ goto handle;
+ }
+
+ if (dr6 & DR6_B3) {
+ rw = DR7_RW3(dr7);
+ reg = 3;
+ goto handle;
+ }
+
+ if (rv > 0)
+ goto handled;
+
+ goto unknown; /* dismiss */
+
+handle:
+ /*
+ * Set Resume Flag
+ */
+ regs->eflags |= EF_RF;
+
+ /*
+ * Determine which breakpoint was encountered.
+ */
+ for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) {
+ if (!(bp->bp_free)
+ && (bp->bp_global || bp->bp_cpu == smp_processor_id())
+ && (bp->bp_hard)
+ && (bp->bp_hard->bph_reg == reg)) {
+ /*
+ * Hit this breakpoint.
+ */
+ kdb_printf("%s breakpoint #%d at " kdb_bfd_vma_fmt "\n",
+ kdba_rwtypes[rw],
+ i, bp->bp_addr);
+
+ /*
+ * For an instruction breakpoint, disassemble
+ * the current instruction.
+ */
+ if (rw == 0) {
+ kdb_id1(regs->eip);
+ }
+
+ goto handled;
+ }
+ }
+
+unknown:
+ regs->eflags |= EF_RF; /* Supress further faults */
+ rv = KDB_DB_NOBPT; /* Cause kdb() to return */
+
+handled:
+
+ /*
+ * Clear the pending exceptions.
+ */
+ kdba_putdr6(0);
+
+ return rv;
+}
+
+/*
+ * kdba_bp_trap
+ *
+ * Perform breakpoint processing upon entry to the
+ * processor breakpoint instruction fault. Determine and print
+ * the active breakpoint.
+ *
+ * Parameters:
+ * regs Exception frame containing machine register state
+ * error Error number passed to kdb.
+ * Outputs:
+ * None.
+ * Returns:
+ * 0 Standard instruction or data breakpoint encountered
+ * 1 Single Step fault ('ss' command)
+ * 2 Single Step fault, caller should continue ('ssb' command)
+ * 3 No existing kdb breakpoint matches this debug exception
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ * If multiple processors receive debug exceptions simultaneously,
+ * one may be waiting at the kdb fence in kdb() while the user
+ * issues a 'bc' command to clear the breakpoint the processor which
+ * is waiting has already encountered. If this is the case, the
+ * debug registers will no longer match any entry in the breakpoint
+ * table, and we'll return the value '3'. This can cause a panic
+ * in die_if_kernel(). It is safer to disable the breakpoint (bd),
+ * 'go' until all processors are past the breakpoint then clear the
+ * breakpoint (bc). This code recognises a breakpoint even when
+ * disabled but not when it has been cleared.
+ *
+ * WARNING: This routine resets the eip. It should be called
+ * once per breakpoint and the result cached.
+ */
+
+kdb_dbtrap_t
+kdba_bp_trap(struct pt_regs *regs, int error_unused)
+{
+ int i;
+ kdb_dbtrap_t rv;
+ kdb_bp_t *bp;
+
+ if (KDB_NULL_REGS(regs))
+ return KDB_DB_NOBPT;
+
+ /*
+ * Determine which breakpoint was encountered.
+ */
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_bp_trap: eip=0x%lx (not adjusted) "
+ "eflags=0x%lx regs=0x%p esp=0x%lx\n",
+ regs->eip, regs->eflags, regs, regs->esp);
+
+ rv = KDB_DB_NOBPT; /* Cause kdb() to return */
+
+ for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) {
+ if (bp->bp_free)
+ continue;
+ if (!bp->bp_global && bp->bp_cpu != smp_processor_id())
+ continue;
+ if ((void *)bp->bp_addr == (void *)(regs->eip - bp->bp_adjust)) {
+ /* Hit this breakpoint. */
+ regs->eip -= bp->bp_adjust;
+ kdb_printf("Instruction(i) breakpoint #%d at 0x%lx (adjusted)\n",
+ i, regs->eip);
+ kdb_id1(regs->eip);
+ rv = KDB_DB_BPT;
+ bp->bp_delay = 1;
+ /* SSBPT is set when the kernel debugger must single
+ * step a task in order to re-establish an instruction
+ * breakpoint which uses the instruction replacement
+ * mechanism. It is cleared by any action that removes
+ * the need to single-step the breakpoint.
+ */
+ KDB_STATE_SET(SSBPT);
+ break;
+ }
+ }
+
+ return rv;
+}
+
+/*
+ * kdba_handle_bp
+ *
+ * Handle an instruction-breakpoint trap. Called when re-installing
+ * an enabled breakpoint which has has the bp_delay bit set.
+ *
+ * Parameters:
+ * Returns:
+ * Locking:
+ * Remarks:
+ *
+ * Ok, we really need to:
+ * 1) Restore the original instruction byte
+ * 2) Single Step
+ * 3) Restore breakpoint instruction
+ * 4) Continue.
+ *
+ *
+ */
+
+static void
+kdba_handle_bp(struct pt_regs *regs, kdb_bp_t *bp)
+{
+ if (KDB_NULL_REGS(regs))
+ return;
+
+ if (KDB_DEBUG(BP))
+ kdb_printf("regs->eip = 0x%lx\n", regs->eip);
+
+ /*
+ * Setup single step
+ */
+ kdba_setsinglestep(regs);
+
+ /*
+ * Reset delay attribute
+ */
+ bp->bp_delay = 0;
+ bp->bp_delayed = 1;
+}
+
+
+/*
+ * kdba_bptype
+ *
+ * Return a string describing type of breakpoint.
+ *
+ * Parameters:
+ * bph Pointer to hardware breakpoint description
+ * Outputs:
+ * None.
+ * Returns:
+ * Character string.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+char *
+kdba_bptype(kdbhard_bp_t *bph)
+{
+ char *mode;
+
+ mode = kdba_rwtypes[bph->bph_mode];
+
+ return mode;
+}
+
+/*
+ * kdba_printbpreg
+ *
+ * Print register name assigned to breakpoint
+ *
+ * Parameters:
+ * bph Pointer hardware breakpoint structure
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+static void
+kdba_printbpreg(kdbhard_bp_t *bph)
+{
+ kdb_printf(" in dr%ld", bph->bph_reg);
+}
+
+/*
+ * kdba_printbp
+ *
+ * Print string describing hardware breakpoint.
+ *
+ * Parameters:
+ * bph Pointer to hardware breakpoint description
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+void
+kdba_printbp(kdb_bp_t *bp)
+{
+ kdb_printf("\n is enabled");
+ if (bp->bp_hardtype) {
+ kdba_printbpreg(bp->bp_hard);
+ if (bp->bp_hard->bph_mode != 0) {
+ kdb_printf(" for %d bytes",
+ bp->bp_hard->bph_length+1);
+ }
+ }
+}
+
+/*
+ * kdba_parsebp
+ *
+ * Parse architecture dependent portion of the
+ * breakpoint command.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero for success, a kdb diagnostic for failure
+ * Locking:
+ * None.
+ * Remarks:
+ * for Ia32 architure, data access, data write and
+ * I/O breakpoints are supported in addition to instruction
+ * breakpoints.
+ *
+ * {datar|dataw|io|inst} [length]
+ */
+
+int
+kdba_parsebp(int argc, const char **argv, int *nextargp, kdb_bp_t *bp)
+{
+ int nextarg = *nextargp;
+ int diag;
+ kdbhard_bp_t *bph = &bp->bp_template;
+
+ bph->bph_mode = 0; /* Default to instruction breakpoint */
+ bph->bph_length = 0; /* Length must be zero for insn bp */
+ if ((argc + 1) != nextarg) {
+ if (strnicmp(argv[nextarg], "datar", sizeof("datar")) == 0) {
+ bph->bph_mode = 3;
+ } else if (strnicmp(argv[nextarg], "dataw", sizeof("dataw")) == 0) {
+ bph->bph_mode = 1;
+ } else if (strnicmp(argv[nextarg], "io", sizeof("io")) == 0) {
+ bph->bph_mode = 2;
+ } else if (strnicmp(argv[nextarg], "inst", sizeof("inst")) == 0) {
+ bph->bph_mode = 0;
+ } else {
+ return KDB_ARGCOUNT;
+ }
+
+ bph->bph_length = 3; /* Default to 4 byte */
+
+ nextarg++;
+
+ if ((argc + 1) != nextarg) {
+ unsigned long len;
+
+ diag = kdbgetularg((char *)argv[nextarg],
+ &len);
+ if (diag)
+ return diag;
+
+
+ if ((len > 4) || (len == 3))
+ return KDB_BADLENGTH;
+
+ bph->bph_length = len;
+ bph->bph_length--; /* Normalize for debug register */
+ nextarg++;
+ }
+
+ if ((argc + 1) != nextarg)
+ return KDB_ARGCOUNT;
+
+ /*
+ * Indicate to architecture independent level that
+ * a hardware register assignment is required to enable
+ * this breakpoint.
+ */
+
+ bph->bph_free = 0;
+ } else {
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_bp: no args, forcehw is %d\n", bp->bp_forcehw);
+ if (bp->bp_forcehw) {
+ /*
+ * We are forced to use a hardware register for this
+ * breakpoint because either the bph or bpha
+ * commands were used to establish this breakpoint.
+ */
+ bph->bph_free = 0;
+ } else {
+ /*
+ * Indicate to architecture dependent level that
+ * the instruction replacement breakpoint technique
+ * should be used for this breakpoint.
+ */
+ bph->bph_free = 1;
+ bp->bp_adjust = 1; /* software, int 3 is one byte */
+ }
+ }
+
+ if (bph->bph_mode != 2 && kdba_verify_rw(bp->bp_addr, bph->bph_length+1)) {
+ kdb_printf("Invalid address for breakpoint, ignoring bp command\n");
+ return KDB_BADADDR;
+ }
+
+ *nextargp = nextarg;
+ return 0;
+}
+
+/*
+ * kdba_allocbp
+ *
+ * Associate a hardware register with a breakpoint.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * A pointer to the allocated register kdbhard_bp_t structure for
+ * success, Null and a non-zero diagnostic for failure.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+kdbhard_bp_t *
+kdba_allocbp(kdbhard_bp_t *bph, int *diagp)
+{
+ int i;
+ kdbhard_bp_t *newbph;
+
+ for(i=0,newbph=kdb_hardbreaks; i < KDB_MAXHARDBPT; i++, newbph++) {
+ if (newbph->bph_free) {
+ break;
+ }
+ }
+
+ if (i == KDB_MAXHARDBPT) {
+ *diagp = KDB_TOOMANYDBREGS;
+ return NULL;
+ }
+
+ *diagp = 0;
+
+ /*
+ * Copy data from template. Can't just copy the entire template
+ * here because the register number in kdb_hardbreaks must be
+ * preserved.
+ */
+ newbph->bph_data = bph->bph_data;
+ newbph->bph_write = bph->bph_write;
+ newbph->bph_mode = bph->bph_mode;
+ newbph->bph_length = bph->bph_length;
+
+ /*
+ * Mark entry allocated.
+ */
+ newbph->bph_free = 0;
+
+ return newbph;
+}
+
+/*
+ * kdba_freebp
+ *
+ * Deallocate a hardware breakpoint
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero for success, a kdb diagnostic for failure
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+void
+kdba_freebp(kdbhard_bp_t *bph)
+{
+ bph->bph_free = 1;
+}
+
+/*
+ * kdba_initbp
+ *
+ * Initialize the breakpoint table for the hardware breakpoint
+ * register.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero for success, a kdb diagnostic for failure
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ * There is one entry per register. On the ia32 architecture
+ * all the registers are interchangeable, so no special allocation
+ * criteria are required.
+ */
+
+void
+kdba_initbp(void)
+{
+ int i;
+ kdbhard_bp_t *bph;
+
+ /*
+ * Clear the hardware breakpoint table
+ */
+
+ memset(kdb_hardbreaks, '\0', sizeof(kdb_hardbreaks));
+
+ for(i=0,bph=kdb_hardbreaks; i<KDB_MAXHARDBPT; i++, bph++) {
+ bph->bph_reg = i;
+ bph->bph_free = 1;
+ }
+}
+
+/*
+ * kdba_installbp
+ *
+ * Install a breakpoint
+ *
+ * Parameters:
+ * regs Exception frame
+ * bp Breakpoint structure for the breakpoint to be installed
+ * Outputs:
+ * None.
+ * Returns:
+ * 0 if breakpoint installed.
+ * Locking:
+ * None.
+ * Remarks:
+ * For hardware breakpoints, a debug register is allocated
+ * and assigned to the breakpoint. If no debug register is
+ * available, a warning message is printed and the breakpoint
+ * is disabled.
+ *
+ * For instruction replacement breakpoints, we must single-step
+ * over the replaced instruction at this point so we can re-install
+ * the breakpoint instruction after the single-step. SSBPT is set
+ * when the breakpoint is initially hit and is cleared by any action
+ * that removes the need for single-step over the breakpoint.
+ */
+
+int
+kdba_installbp(struct pt_regs *regs, kdb_bp_t *bp)
+{
+ /*
+ * Install the breakpoint, if it is not already installed.
+ */
+
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdba_installbp bp_installed %d\n", bp->bp_installed);
+ }
+ if (!KDB_STATE(SSBPT))
+ bp->bp_delay = 0;
+ if (!bp->bp_installed) {
+ if (bp->bp_hardtype) {
+ kdba_installdbreg(bp);
+ bp->bp_installed = 1;
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdba_installbp hardware reg %ld at " kdb_bfd_vma_fmt "\n",
+ bp->bp_hard->bph_reg, bp->bp_addr);
+ }
+ } else if (bp->bp_delay) {
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_installbp delayed bp\n");
+ kdba_handle_bp(regs, bp);
+ } else {
+ if (kdb_getarea_size(&(bp->bp_inst), bp->bp_addr, 1) ||
+ kdb_putword(bp->bp_addr, IA32_BREAKPOINT_INSTRUCTION, 1)) {
+ kdb_printf("kdba_installbp failed to set software breakpoint at 0x%lx\n", bp->bp_addr);
+ return(1);
+ }
+ bp->bp_installed = 1;
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_installbp instruction 0x%x at " kdb_bfd_vma_fmt "\n",
+ IA32_BREAKPOINT_INSTRUCTION, bp->bp_addr);
+ }
+ }
+ return(0);
+}
+
+/*
+ * kdba_removebp
+ *
+ * Make a breakpoint ineffective.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+int
+kdba_removebp(kdb_bp_t *bp)
+{
+ /*
+ * For hardware breakpoints, remove it from the active register,
+ * for software breakpoints, restore the instruction stream.
+ */
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdba_removebp bp_installed %d\n", bp->bp_installed);
+ }
+ if (bp->bp_installed) {
+ if (bp->bp_hardtype) {
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdb: removing hardware reg %ld at " kdb_bfd_vma_fmt "\n",
+ bp->bp_hard->bph_reg, bp->bp_addr);
+ }
+ kdba_removedbreg(bp);
+ } else {
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdb: restoring instruction 0x%x at " kdb_bfd_vma_fmt "\n",
+ bp->bp_inst, bp->bp_addr);
+ if (kdb_putword(bp->bp_addr, bp->bp_inst, 1))
+ return(1);
+ }
+ bp->bp_installed = 0;
+ }
+ return(0);
+}
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Stack Traceback
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kallsyms.h>
+#include <linux/irq.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <asm/system.h>
+
+/* On a 4K stack kernel, hardirq_ctx and softirq_ctx are [NR_CPUS] arrays. The
+ * first element of each per-cpu stack is a struct thread_info.
+ */
+void
+kdba_get_stack_info_alternate(kdb_machreg_t addr, int cpu,
+ struct kdb_activation_record *ar)
+{
+#ifdef CONFIG_4KSTACKS
+ struct thread_info *tinfo;
+ static int first_time = 1;
+ static struct thread_info **kdba_hardirq_ctx, **kdba_softirq_ctx;
+ if (first_time) {
+ kdb_symtab_t symtab;
+ kdbgetsymval("hardirq_ctx", &symtab);
+ kdba_hardirq_ctx = (struct thread_info **)symtab.sym_start;
+ kdbgetsymval("softirq_ctx", &symtab);
+ kdba_softirq_ctx = (struct thread_info **)symtab.sym_start;
+ first_time = 0;
+ }
+ tinfo = (struct thread_info *)(addr & -THREAD_SIZE);
+ if (cpu < 0) {
+ /* Arbitrary address, see if it falls within any of the irq
+ * stacks
+ */
+ int found = 0;
+ for_each_online_cpu(cpu) {
+ if (tinfo == kdba_hardirq_ctx[cpu] ||
+ tinfo == kdba_softirq_ctx[cpu]) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ return;
+ }
+ if (tinfo == kdba_hardirq_ctx[cpu] ||
+ tinfo == kdba_softirq_ctx[cpu]) {
+ ar->stack.physical_start = (kdb_machreg_t)tinfo;
+ ar->stack.physical_end = ar->stack.physical_start + THREAD_SIZE;
+ ar->stack.logical_start = ar->stack.physical_start +
+ sizeof(struct thread_info);
+ ar->stack.logical_end = ar->stack.physical_end;
+ ar->stack.next = tinfo->previous_esp;
+ if (tinfo == kdba_hardirq_ctx[cpu])
+ ar->stack.id = "hardirq_ctx";
+ else
+ ar->stack.id = "softirq_ctx";
+ }
+#endif /* CONFIG_4KSTACKS */
+}
+
+typedef struct __kdb_activation_record {
+ kdb_machreg_t start; /* -> start of activation record */
+ kdb_machreg_t end; /* -> end+1 of activation record */
+ kdb_machreg_t ret; /* Return address to caller */
+ kdb_machreg_t oldfp; /* Frame pointer for caller's frame */
+ kdb_machreg_t fp; /* Frame pointer for callee's frame */
+ kdb_machreg_t arg0; /* -> First argument on stack (in previous ar) */
+ unsigned long locals; /* Bytes allocated for local variables */
+ unsigned long regs; /* Bytes allocated for saved registers */
+ unsigned long args; /* Bytes allocated for arguments (in previous ar) */
+ unsigned long setup; /* Bytes allocated for setup data */
+} kdb_ar_t;
+
+#define KDB_STACK_DIRECTION (-1) /* Stack grows down */
+
+/*
+ * kdba_find_return_1
+ *
+ * Given a starting point on the stack and symtab data for the
+ * current function, scan up the stack looking for a return
+ * address for this function.
+ * Inputs:
+ * sp Starting stack pointer for scan
+ * ss Start of stack for current process
+ * symtab kallsyms symbol data for the function
+ * assume When false, do not apply tests that have to assume a branch is valid
+ * Outputs:
+ * None.
+ * Returns:
+ * Position on stack of return address, 0 if not found.
+ * Locking:
+ * None.
+ * Remarks:
+ * This is sensitive to the calling sequence generated by gcc.
+ */
+
+static kdb_machreg_t
+kdba_find_return_1(kdb_machreg_t sp, kdb_machreg_t ss, const kdb_symtab_t *symtab, int assume)
+{
+ kdb_machreg_t ret;
+ kdb_symtab_t caller_symtab;
+ unsigned long disp8;
+ unsigned long disp32;
+ unsigned char code[7];
+#define retaddr(off) code[sizeof(code)+(off)]
+
+ for (;ret = 0, sp & (THREAD_SIZE-1);sp += 4) {
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" sp=0x%lx", sp);
+ }
+ if (kdb_getword(&ret, sp, 4))
+ break;
+ if (ret > PAGE_SIZE)
+ kdbnearsym(ret, &caller_symtab);
+ else
+ memset(&caller_symtab, 0, sizeof(caller_symtab));
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" ret=");
+ kdb_symbol_print(ret, &caller_symtab, KDB_SP_DEFAULT|KDB_SP_SYMSIZE);
+ }
+ if (!caller_symtab.sym_name) {
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf("\n");
+ }
+ continue; /* not a valid kernel address */
+ }
+ KDB_STATE_SET(SUPPRESS);
+ if (kdb_getarea(code, ret-sizeof(code)) ||
+ kdb_getword(&disp32, ret-4, 4) ||
+ kdb_getword(&disp8, ret-1, 1))
+ continue; /* not a valid return address */
+ if (retaddr(-5) == 0xe8) {
+ /* call disp32 */
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" call disp32");
+ }
+ if (ret + (s32) disp32 == symtab->sym_start) {
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" matched");
+ }
+ break; /* call to this function */
+ }
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" failed");
+ }
+ } else if (strcmp(caller_symtab.sym_name, "ret_from_intr") == 0
+ && ret == caller_symtab.sym_start) {
+ /* ret_from_intr is pushed on stack for interrupts */
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" ret_from_intr matched");
+ }
+ break; /* special case, hand crafted frame */
+ } else if (!assume) {
+ /* All following tests cannot validate the target address so they
+ * must assume that the return address is valid.
+ */
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf("\n");
+ }
+ continue;
+ } else if (retaddr(-7) == 0xff && retaddr(-6) == 0x14 && retaddr(-5) == 0x85) {
+ /* call *disp32(,%eax,4), used by syscall.
+ * Cannot calculate address, assume it is valid
+ * if the current function name starts with
+ * 'sys_' or 'old_'.
+ */
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" call *0xnnnn(,%%eax,4)");
+ }
+ if (strncmp(symtab->sym_name, "sys_", 4) == 0 ||
+ strncmp(symtab->sym_name, "old_", 4) == 0) {
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" assume valid");
+ }
+ break; /* probably call to this function */
+ }
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" failed");
+ }
+ } else if (retaddr(-2) == 0xff &&
+ ((retaddr(-1) & 0xf8) == 0xd0 || (retaddr(-1) & 0xf8) == 0x10)) {
+ /* call *%reg. Cannot validate, have to assume
+ * it is valid.
+ */
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" call *%%reg, assume valid");
+ }
+ break; /* hope it is a call to this function */
+ } else if (retaddr(-3) == 0xff && (retaddr(-2) & 0xf8) == 0x50) {
+ /* call *disp8(%reg). Cannot validate, have to assume
+ * it is valid.
+ */
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" call *disp8(%%reg), assume valid");
+ }
+ break; /* hope it is a call to this function */
+ } else if (retaddr(-6) == 0xff && (retaddr(-5) & 0xf8) == 0x90) {
+ /* call *disp32(%reg). Cannot validate, have to assume
+ * it is valid.
+ */
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" call *disp32(%%reg), assume valid");
+ }
+ break; /* hope it is a call to this function */
+ }
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf("\n");
+ }
+ }
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" end ret=0x%lx sp=0x%lx\n", ret, sp);
+ }
+ if (ret)
+ return sp;
+ return 0;
+}
+
+/*
+ * kdba_find_return
+ *
+ * Given a starting point on the stack and symtab data for the
+ * current function, scan up the stack looking for a return
+ * address for this function.
+ * Inputs:
+ * sp Starting stack pointer for scan
+ * ss Start of stack for current process
+ * symtab kallsyms symbol data for the function
+ * Outputs:
+ * None.
+ * Returns:
+ * Position on stack of return address, 0 if not found.
+ * Locking:
+ * None.
+ * Remarks:
+ * This is sensitive to the calling sequence generated by gcc.
+ */
+
+static kdb_machreg_t
+kdba_find_return(kdb_machreg_t sp, kdb_machreg_t ss, const kdb_symtab_t *symtab)
+{
+ kdb_machreg_t ret;
+
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" kdba_find_return: start\n");
+ }
+
+ if ((sp & -THREAD_SIZE) != ss) {
+ kdb_printf(" sp is in wrong stack 0x%lx 0x%lx 0x%lx\n", sp, ss, sp & -THREAD_SIZE);
+ return 0;
+ }
+
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" kdba_find_return_1(assume==0)\n");
+ }
+ if ((ret = kdba_find_return_1(sp, ss, symtab, 0)))
+ return ret;
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" kdba_find_return_1(assume==1)\n");
+ }
+ ret = kdba_find_return_1(sp, ss, symtab, 1);
+ return ret;
+}
+
+/*
+ * kdba_prologue
+ *
+ * This function analyzes a gcc-generated function prototype
+ * with or without frame pointers to determine the amount of
+ * automatic storage and register save storage is used on the
+ * stack of the target function. It only counts instructions
+ * that have been executed up to but excluding the current eip.
+ * Inputs:
+ * code Start address of function code to analyze
+ * pc Current program counter within function
+ * sp Current stack pointer for function
+ * fp Current frame pointer for function, may not be valid
+ * ss Start of stack for current process.
+ * caller 1 if looking for data on the caller frame, 0 for callee.
+ * Outputs:
+ * ar Activation record, all fields may be set. fp and oldfp
+ * are 0 if they cannot be extracted. return is 0 if the
+ * code cannot find a valid return address. args and arg0
+ * are 0 if the number of arguments cannot be safely
+ * calculated.
+ * Returns:
+ * 1 if prologue is valid, 0 otherwise. If pc is 0 treat it as a
+ * valid prologue to allow bt on wild branches.
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ * A prologue for ia32 generally looks like:
+ *
+ * pushl %ebp [All functions, but only if
+ * movl %esp, %ebp compiled with frame pointers]
+ * subl $auto, %esp [some functions]
+ * pushl %reg [some functions]
+ * pushl %reg [some functions]
+ *
+ * FIXME: Mike Galbraith says that gcc 2.95 can generate a slightly
+ * different prologue. No support for gcc 2.95 yet.
+ */
+
+int
+kdba_prologue(const kdb_symtab_t *symtab, kdb_machreg_t pc, kdb_machreg_t sp,
+ kdb_machreg_t fp, kdb_machreg_t ss, int caller, kdb_ar_t *ar)
+{
+ kdb_machreg_t ret_p, code = symtab->sym_start;
+ int oldfp_present = 0, unwound = 0;
+ unsigned char instruction[6];
+
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf("kdba_prologue: code=0x%lx %s pc=0x%lx sp=0x%lx fp=0x%lx\n",
+ code, symtab->sym_name, pc, sp, fp);
+ }
+
+ /* Special case for wild branches. Assumes top of stack is return address */
+ if (pc == 0) {
+ memset(ar, 0, sizeof(*ar));
+ ar->setup = 4;
+ ar->end = sp;
+ ar->start = ar->end + 4;
+ kdb_getword(&(ar->ret), sp, 4);
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" pc==0: ret=0x%lx\n", ar->ret);
+ }
+ return(1);
+ }
+
+ if (code == 0 || sp & 3 || ss != (sp & -THREAD_SIZE))
+ return(0);
+
+ ar->end = sp; /* End of activation record +1 */
+
+ /* Special cases galore when the caller pc is within entry.S.
+ * The return address for these routines is outside the kernel,
+ * so the normal algorithm to find the frame does not work.
+ * Hand craft the frame to no setup, regs, locals etc, assume 6
+ * parameters.
+ * This list was extracted from entry.S by looking for all call
+ * instructions that were eventually followed by RESTORE_ALL,
+ * take the label before each such instruction.
+ */
+ if (caller &&
+ (strcmp(symtab->sym_name, "lcall7") == 0 ||
+ strcmp(symtab->sym_name, "lcall27") == 0 ||
+ strcmp(symtab->sym_name, "kdb_call") == 0 ||
+ strcmp(symtab->sym_name, "system_call") == 0 ||
+ strcmp(symtab->sym_name, "tracesys") == 0 ||
+ strcmp(symtab->sym_name, "signal_return") == 0 ||
+ strcmp(symtab->sym_name, "v86_signal_return") == 0 ||
+ strcmp(symtab->sym_name, "tracesys") == 0 ||
+ strcmp(symtab->sym_name, "tracesys_exit") == 0 ||
+ strcmp(symtab->sym_name, "handle_softirq") == 0 ||
+ strcmp(symtab->sym_name, "reschedule") == 0 ||
+ strcmp(symtab->sym_name, "error_code") == 0 ||
+ strcmp(symtab->sym_name, "device_not_available") == 0 ||
+ strcmp(symtab->sym_name, "nmi") == 0)) {
+ ar->start = ar->end + 6*4; /* 6 parameters */
+ if ((ar->start & -THREAD_SIZE) != ss)
+ ar->start = 0;
+ return(1);
+ }
+
+ ar->setup = 4; /* Return address is always on stack */
+
+ /* Kludge. If we are sitting on 'ret' then the stack has been unwound,
+ * ignore all the startup code.
+ */
+ if (kdb_getarea(instruction[0], pc))
+ return(0);
+ if (instruction[0] == 0xc3) {
+ /* ret */
+ unwound = 1;
+ }
+
+ if (kdb_getarea(instruction, code))
+ return(0);
+ if (!unwound && code < pc && instruction[0] == 0x55) {
+ /* pushl %ebp */
+ ar->setup += 4; /* Frame pointer is on stack */
+ oldfp_present = 1;
+ ++code;
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" pushl %%ebp\n");
+ }
+ if (code < pc && instruction[0] == 0x89 && instruction[1] == 0xe5) {
+ /* movl %esp,%ebp */
+ if (fp >= sp && (fp & -THREAD_SIZE) == ss)
+ ar->fp = fp; /* %ebp has been set */
+ code += 2;
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" movl %%esp,%%ebp, fp=0x%lx\n", ar->fp);
+ }
+ }
+ }
+
+ if (!unwound && code < pc) {
+ if (instruction[0] == 0x83 && instruction[1] == 0xec) {
+ /* subl $xx,%esp */
+ kdb_getword(&(ar->locals), (unsigned long)(instruction+2), 1);
+ code += 3;
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" subl $xx,%%esp, locals=%ld\n", ar->locals);
+ }
+ } else if (instruction[0] == 0x81 && instruction[1] == 0xec) {
+ /* subl $xxxxxxxx,%esp */
+ kdb_getword(&(ar->locals), (unsigned long)(instruction+2), 4);
+ code += 6;
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" subl $xxxxxxxx,%%esp, locals=%ld\n", ar->locals);
+ }
+ }
+ }
+
+ while (!unwound && code < pc &&
+ kdb_getarea(instruction, code) == 0 &&
+ (instruction[0] & 0xf8) == 0x50) {
+ /* pushl %reg */
+ ar->regs += 4;
+ ++code;
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" pushl %%reg, regs=%ld\n", ar->regs);
+ }
+ }
+
+ /* Check the return address. It must point within the kernel
+ * and the code at that location must be a valid entry sequence.
+ */
+ if (ar->fp) {
+ ret_p = ar->fp + ar->setup;
+ }
+ else {
+ ret_p = ar->end + ar->regs + ar->locals + ar->setup;
+ }
+ ret_p -= 4;
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" ret_p(0)=0x%lx\n", ret_p);
+ }
+ ar->ret = 0;
+ if ((ret_p & -THREAD_SIZE) == ss &&
+ (ret_p = kdba_find_return(ret_p, ss, symtab))) {
+ kdb_getword(&(ar->ret), ret_p, 4);
+ }
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" ret_p(1)=0x%lx ret=0x%lx\n", ret_p, ar->ret);
+ }
+ if (ar->ret) {
+ ar->fp = ret_p - ar->setup + 4; /* "accurate" fp */
+ ar->start = ret_p + 4;
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" fp=0x%lx start=0x%lx\n", ar->fp, ar->start);
+ }
+ }
+ if (oldfp_present) {
+ if (ar->fp)
+ kdb_getword(&(ar->oldfp), ar->fp, 4);
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" oldfp=0x%lx", ar->oldfp);
+ }
+ if (ar->oldfp <= ar->fp || (ar->oldfp & -THREAD_SIZE) != ss) {
+ ar->oldfp = 0;
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" (out of range)");
+ }
+ }
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf("\n");
+ }
+ }
+ return(1);
+}
+
+/*
+ * kdb_get_next_ar
+ *
+ * Get the next activation record from the stack.
+ *
+ * Inputs:
+ * arend Last byte +1 of the activation record. sp for the first
+ * frame, start of callee's activation record otherwise.
+ * pc Current program counter within this function. pc for
+ * the first frame, caller's return address otherwise.
+ * fp Current frame pointer. Register fp for the first
+ * frame, oldfp otherwise. 0 if not known.
+ * ss Start of stack for the current process.
+ * Outputs:
+ * ar Activation record.
+ * symtab kallsyms symbol table data for the calling function.
+ * Returns:
+ * 1 if ar is usable, 0 if not.
+ * Locking:
+ * None.
+ * Remarks:
+ * Activation Record format, assuming a stack that grows down
+ * (KDB_STACK_DIRECTION == -1).
+ *
+ * +-----------------------------+ ^ =====================
+ * | Return address, frame 3 | |
+ * +-----------------------------+ |
+ * | Frame Pointer, frame 3 |>--'
+ * +-----------------------------+<--.
+ * | Locals and automatics, | |
+ * | frame 2. (variable size) | | AR 2
+ * +-----------------------------+ |
+ * | Save registers, | |
+ * | frame 2. (variable size) | |
+ * +-----------------------------+ |
+ * | Arguments to frame 1, | |
+ * | (variable size) | |
+ * +-----------------------------+ | =====================
+ * | Return address, frame 2 | |
+ * +-----------------------------+ |
+ * | Frame Pointer, frame 2 |>--'
+ * +-----------------------------+<--.
+ * | Locals and automatics, | |
+ * | frame 1. (variable size) | | AR 1
+ * +-----------------------------+ |
+ * | Save registers, | |
+ * | frame 1. (variable size) | |
+ * +-----------------------------+ |
+ * | Arguments to frame 0, | |
+ * | (variable size) | |
+ * +-----------------------------+ | -- (5) =====================
+ * | Return address, frame 1 | |
+ * +-----------------------------+ | -- (0)
+ * | Frame Pointer, frame 1 |>--'
+ * +-----------------------------+ -- (1), (2)
+ * | Locals and automatics, |
+ * | frame 0. (variable size) | AR 0
+ * +-----------------------------+ -- (3)
+ * | Save registers, |
+ * | frame 0. (variable size) |
+ * +-----------------------------+ -- (4) =====================
+ *
+ * The stack for the top frame can be in one of several states.
+ * (0) Immediately on entry to the function, stack pointer (sp) is
+ * here.
+ * (1) If the function was compiled with frame pointers and the 'push
+ * fp' instruction has been executed then the pointer to the
+ * previous frame is on the stack. However there is no guarantee
+ * that this saved pointer is valid, the calling function might
+ * not have frame pointers. sp is adjusted by wordsize after
+ * 'push fp'.
+ * (2) If the function was compiled with frame pointers and the 'copy
+ * sp to fp' instruction has been executed then fp points here.
+ * (3) If the function startup has 'adjust sp by 0xnn bytes' and that
+ * instruction has been executed then sp has been adjusted by
+ * 0xnn bytes for local and automatic variables.
+ * (4) If the function startup has one or more 'push reg' instructions
+ * and any have been executed then sp has been adjusted by
+ * wordsize bytes for each register saved.
+ *
+ * As the function exits it rewinds the stack, typically to (1) then (0).
+ *
+ * The stack entries for the lower frames is normally are in state (5).
+ * (5) Arguments for the called frame are on to the stack.
+ * However lower frames can be incomplete if there is an interrupt in
+ * progress.
+ *
+ * An activation record runs from the return address for a function
+ * through to the return address for the next function or sp, whichever
+ * comes first. For each activation record we extract :-
+ *
+ * start Address of the activation record.
+ * end Address of the last byte+1 in the activation record.
+ * ret Return address to caller.
+ * oldfp Frame pointer to previous frame, 0 if this function was
+ * not compiled with frame pointers.
+ * fp Frame pointer for the current frame, 0 if this function
+ * was not compiled with frame pointers or fp has not been
+ * set yet.
+ * arg0 Address of the first argument (in the previous activation
+ * record).
+ * locals Bytes allocated to locals and automatics.
+ * regs Bytes allocated to saved registers.
+ * args Bytes allocated to arguments (in the previous activation
+ * record).
+ * setup Bytes allocated to setup data on stack (return address,
+ * frame pointer).
+ *
+ * Although the kernel might be compiled with frame pointers, we still
+ * have to assume the worst and validate the frame. Some calls from
+ * asm code to C code might not use frame pointers. Third party binary
+ * only modules might be compiled without frame pointers, even when the
+ * rest of the kernel has frame pointers. Some routines are always
+ * compiled with frame pointers, even if the overall kernel is not. A
+ * routine compiled with frame pointers can be called from a routine
+ * without frame pointers, the previous "frame pointer" is saved on
+ * stack but it contains garbage.
+ *
+ * We check the object code to see if it saved a frame pointer and we
+ * validate that pointer. Basically frame pointers are hints.
+ */
+
+#define FORCE_ARG(ar,n) (ar)->setup = (ar)->locals = (ar)->regs = \
+ (ar)->fp = (ar)->oldfp = (ar)->ret = 0; \
+ (ar)->start = (ar)->end - KDB_STACK_DIRECTION*(n)*sizeof(unsigned long);
+
+int
+kdb_get_next_ar(kdb_machreg_t arend, kdb_machreg_t pc, kdb_machreg_t fp,
+ kdb_machreg_t ss, kdb_ar_t *ar, kdb_symtab_t *symtab)
+{
+ static char namebuf1[KSYM_NAME_LEN+1]; /* accessed from outside */
+ static char namebuf2[KSYM_NAME_LEN+1]; /* accessed from callees */
+
+ if (KDB_DEBUG(AR)) {
+ kdb_printf("kdb_get_next_ar: arend=0x%lx pc=0x%lx fp=0x%lx\n",
+ arend, pc, fp);
+ }
+
+ memset(ar, 0, sizeof(*ar));
+ if (kdbnearsym(pc, symtab)) {
+ strcpy(namebuf1, symtab->sym_name);
+ symtab->sym_name = namebuf1;
+ } else {
+ symtab->sym_name = "<unknown>";
+ symtab->mod_name = "kernel";
+ if (KDB_DEBUG(AR)) {
+ kdb_printf("kdb_get_next_ar: callee not in kernel\n");
+ }
+ pc = 0;
+ }
+
+ if (!kdba_prologue(symtab, pc, arend, fp, ss, 0, ar)) {
+ if (KDB_DEBUG(AR)) {
+ kdb_printf("kdb_get_next_ar: callee prologue failed\n");
+ }
+ return(0);
+ }
+ if (KDB_DEBUG(AR)) {
+ kdb_printf("kdb_get_next_ar: callee activation record\n");
+ kdb_printf(" start=0x%lx end=0x%lx ret=0x%lx oldfp=0x%lx fp=0x%lx\n",
+ ar->start, ar->end, ar->ret, ar->oldfp, ar->fp);
+ kdb_printf(" locals=%ld regs=%ld setup=%ld\n",
+ ar->locals, ar->regs, ar->setup);
+ }
+
+ if (ar->ret) {
+ /* Run the caller code to get arguments to callee function */
+ kdb_symtab_t caller_symtab;
+ kdb_ar_t caller_ar;
+ memset(&caller_ar, 0, sizeof(caller_ar));
+ if (kdbnearsym(ar->ret, &caller_symtab)) {
+ strcpy(namebuf2, caller_symtab.sym_name);
+ caller_symtab.sym_name = namebuf2;
+ }
+ if (caller_symtab.sym_name == NULL) {
+ if (KDB_DEBUG(AR)) {
+ kdb_printf("kdb_get_next_ar: caller not in kernel\n");
+ }
+ } else if (kdba_prologue(&caller_symtab, ar->ret,
+ ar->start, ar->oldfp, ss, 1, &caller_ar)) {
+ /* some caller data extracted */ ;
+ } else if (strcmp(symtab->sym_name, "do_exit") == 0) {
+ /* non-standard caller, force one argument */
+ FORCE_ARG(&caller_ar, 1);
+ } else if (KDB_DEBUG(AR)) {
+ kdb_printf("kdb_get_next_ar: caller prologue failed\n");
+ }
+ if (KDB_DEBUG(AR)) {
+ kdb_printf("kdb_get_next_ar: caller activation record\n");
+ kdb_printf(" start=0x%lx end=0x%lx ret=0x%lx"
+ " oldfp=0x%lx fp=0x%lx\n",
+ caller_ar.start, caller_ar.end, caller_ar.ret,
+ caller_ar.oldfp, caller_ar.fp);
+ kdb_printf(" locals=%ld regs=%ld args=%ld setup=%ld\n",
+ caller_ar.locals, caller_ar.regs,
+ caller_ar.args, caller_ar.setup);
+ }
+ if (caller_ar.start) {
+ ar->args = KDB_STACK_DIRECTION*(caller_ar.end - caller_ar.start) -
+ (caller_ar.setup + caller_ar.locals + caller_ar.regs);
+ if (ar->args < 0)
+ ar->args = 0;
+ if (ar->args) {
+ ar->arg0 = ar->start -
+ KDB_STACK_DIRECTION*(ar->args - sizeof (ar->args));
+ if (KDB_DEBUG(AR)) {
+ kdb_printf(" callee arg0=0x%lx args=%ld\n",
+ ar->arg0, ar->args);
+ }
+ }
+ }
+ }
+
+ return(1);
+}
+
+/*
+ * bt_print_one
+ *
+ * Print one back trace entry.
+ *
+ * Inputs:
+ * eip Current program counter, or return address.
+ * esp Stack pointer esp when at eip.
+ * ar Activation record for this frame.
+ * symtab Information about symbol that eip falls within.
+ * argcount Maximum number of arguments to print.
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ * None.
+ */
+
+static void
+bt_print_one(kdb_machreg_t eip, kdb_machreg_t esp, const kdb_ar_t *ar,
+ const kdb_symtab_t *symtab, int argcount)
+{
+ int btsymarg = 0;
+ kdb_machreg_t word;
+
+ kdbgetintenv("BTSYMARG", &btsymarg);
+
+ kdb_printf("%08lx", esp);
+ kdb_symbol_print(eip, symtab, KDB_SP_SPACEB|KDB_SP_VALUE);
+ if (argcount && ar->args) {
+ int i, argc = ar->args / 4;
+
+ kdb_printf(" (");
+ if (argc > argcount)
+ argc = argcount;
+
+ for(i=1; i<=argc; i++){
+ kdb_machreg_t argp = ar->arg0 - ar->args + 4*i;
+
+ if (i != 1)
+ kdb_printf(" ");
+ kdb_getword(&word, argp, sizeof(word));
+ kdb_printf("%lx", word);
+ }
+ kdb_printf(")");
+ }
+ kdb_printf("\n");
+ if (argcount && ar->args && btsymarg) {
+ int i, argc = ar->args / 4;
+ kdb_symtab_t arg_symtab;
+ kdb_machreg_t arg;
+ for(i=1; i<=argc; i++){
+ kdb_machreg_t argp = ar->arg0 - ar->args + 4*i;
+ kdb_getword(&arg, argp, sizeof(arg));
+ if (kdbnearsym(arg, &arg_symtab)) {
+ kdb_printf(" ");
+ kdb_symbol_print(arg, &arg_symtab, KDB_SP_DEFAULT|KDB_SP_NEWLINE);
+ }
+ }
+ }
+}
+
+/*
+ * kdba_bt_stack
+ *
+ * Inputs:
+ * addr Pointer to Address provided to 'bt' command, if any.
+ * argcount
+ * p Pointer to task for 'btp' command.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * mds comes in handy when examining the stack to do a manual
+ * traceback.
+ */
+
+static int
+kdba_bt_stack(kdb_machreg_t addr, int argcount, const struct task_struct *p)
+{
+ kdb_ar_t ar;
+ kdb_machreg_t eip, esp, ebp, ss, cs, esp_base;
+ kdb_symtab_t symtab;
+ int count;
+
+ /*
+ * The caller may have supplied an address at which the
+ * stack traceback operation should begin. This address
+ * is assumed by this code to point to a return-address
+ * on the stack to be traced back.
+ *
+ * The end result of this will make it appear as if a function
+ * entitled '<unknown>' was called from the function which
+ * contains return-address.
+ */
+ if (addr) {
+ eip = 0;
+ ebp = 0;
+ esp = addr;
+ cs = __KERNEL_CS; /* have to assume kernel space */
+ } else {
+ if (task_curr(p)) {
+ struct kdb_running_process *krp = kdb_running_process + task_cpu(p);
+ struct pt_regs *regs;
+
+ if (!krp->seqno) {
+ kdb_printf("Process did not save state, cannot backtrace\n");
+ kdb_ps1(p);
+ return 0;
+ }
+ regs = krp->regs;
+ if (KDB_NULL_REGS(regs))
+ return KDB_BADREG;
+ kdba_getregcontents("eip", regs, &eip);
+ kdba_getregcontents("ebp", regs, &ebp);
+ /* CONFIG_4KSTACKS means multiple values for esp, use the last one */
+ esp = krp->arch.esp;
+ kdba_getregcontents("xcs", regs, &cs);
+ }
+ else {
+ /* Not on cpu, assume blocked. Blocked i386 tasks do
+ * not have pt_regs. p->thread.{esp,eip} are set, esp
+ * points to the ebp value, assume kernel space.
+ */
+ eip = p->thread.eip;
+ esp = p->thread.esp;
+ ebp = *(unsigned long *)esp;
+ cs = __KERNEL_CS;
+ }
+ esp_base = (unsigned long)(p->thread_info);
+ }
+ ss = esp & -THREAD_SIZE;
+
+ if ((cs & 0xffff) != __KERNEL_CS) {
+ kdb_printf("Stack is not in kernel space, backtrace not available\n");
+ return 0;
+ }
+
+ kdb_printf("ESP EIP Function (args)\n");
+
+ /*
+ * Run through the activation records and print them.
+ */
+
+ for (count = 0; count < 200; ++count) {
+ if (!kdb_get_next_ar(esp, eip, ebp, ss, &ar, &symtab)) {
+ struct thread_info *tinfo = (struct thread_info *)ss;
+ esp = tinfo->previous_esp;
+ if (!esp)
+ break;
+ ss = esp & -THREAD_SIZE;
+ kdb_printf("=================\n");
+ }
+
+ if (strcmp("ret_from_intr", symtab.sym_name) == 0 ||
+ strcmp("error_code", symtab.sym_name) == 0) {
+ if (strcmp("ret_from_intr", symtab.sym_name) == 0) {
+ /*
+ * Non-standard frame. ret_from_intr is
+ * preceded by 9 registers (ebx, ecx, edx, esi,
+ * edi, ebp, eax, ds, cs), original eax and the
+ * return address for a total of 11 words.
+ */
+ ar.start = ar.end + 11*4;
+ }
+ if (strcmp("error_code", symtab.sym_name) == 0) {
+ /*
+ * Non-standard frame. error_code is preceded
+ * by two parameters (-> registers, error code),
+ * 9 registers (ebx, ecx, edx, esi, edi, ebp,
+ * eax, ds, cs), original eax and the return
+ * address for a total of 13 words.
+ */
+ ar.start = ar.end + 13*4;
+ }
+ /* Print the non-standard entry without args */
+ bt_print_one(eip, esp, &ar, &symtab, 0);
+ kdb_printf("Interrupt registers:\n");
+ kdba_dumpregs((struct pt_regs *)(ar.end), NULL, NULL);
+ /* Step the frame to the interrupted code */
+ kdb_getword(&eip, ar.start-4, 4);
+ ebp = 0;
+ esp = ar.start;
+ if ((((struct pt_regs *)(ar.end))->xcs & 0xffff) != __KERNEL_CS) {
+ kdb_printf("Interrupt from user space, end of kernel trace\n");
+ break;
+ }
+ continue;
+ }
+
+ bt_print_one(eip, esp, &ar, &symtab, argcount);
+
+ if (ar.ret == 0)
+ break; /* End of frames */
+ eip = ar.ret;
+ ebp = ar.oldfp;
+ esp = ar.start;
+ }
+ if (count >= 200)
+ kdb_printf("bt truncated, count limit reached\n");
+
+ return 0;
+}
+
+/*
+ * kdba_bt_address
+ *
+ * Do a backtrace starting at a specified stack address. Use this if the
+ * heuristics get the i386 stack decode wrong.
+ *
+ * Inputs:
+ * addr Address provided to 'bt' command.
+ * argcount
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * mds %esp comes in handy when examining the stack to do a manual
+ * traceback.
+ */
+
+int
+kdba_bt_address(kdb_machreg_t addr, int argcount)
+{
+ return kdba_bt_stack(addr, argcount, NULL);
+}
+
+/*
+ * kdba_bt_process
+ *
+ * Do a backtrace for a specified process.
+ *
+ * Inputs:
+ * p Struct task pointer extracted by 'bt' command.
+ * argcount
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ */
+
+int
+kdba_bt_process(const struct task_struct *p, int argcount)
+{
+ return kdba_bt_stack(0, argcount, p);
+}
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Instruction Disassembly
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <stdarg.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+
+/*
+ * kdba_dis_getsym
+ *
+ * Get a symbol for the disassembler.
+ *
+ * Parameters:
+ * addr Address for which to get symbol
+ * dip Pointer to disassemble_info
+ * Returns:
+ * 0
+ * Locking:
+ * Remarks:
+ * Not used for kdb.
+ */
+
+/* ARGSUSED */
+static int
+kdba_dis_getsym(bfd_vma addr, disassemble_info *dip)
+{
+
+ return 0;
+}
+
+/*
+ * kdba_printaddress
+ *
+ * Print (symbolically) an address.
+ *
+ * Parameters:
+ * addr Address for which to get symbol
+ * dip Pointer to disassemble_info
+ * flag True if a ":<tab>" sequence should follow the address
+ * Returns:
+ * 0
+ * Locking:
+ * Remarks:
+ *
+ */
+
+/* ARGSUSED */
+static void
+kdba_printaddress(kdb_machreg_t addr, disassemble_info *dip, int flag)
+{
+ kdb_symtab_t symtab;
+ int spaces = 5;
+ unsigned int offset;
+
+ /*
+ * Print a symbol name or address as necessary.
+ */
+ kdbnearsym(addr, &symtab);
+ if (symtab.sym_name) {
+ /* Do not use kdb_symbol_print here, it always does
+ * kdb_printf but we want dip->fprintf_func.
+ */
+ dip->fprintf_func(dip->stream,
+ kdb_machreg_fmt0 " %s", addr, symtab.sym_name);
+ if ((offset = addr - symtab.sym_start) == 0) {
+ spaces += 4;
+ }
+ else {
+ unsigned int o = offset;
+ while (o >>= 4)
+ --spaces;
+ dip->fprintf_func(dip->stream, "+0x%x", offset);
+ }
+
+ } else {
+ dip->fprintf_func(dip->stream, kdb_machreg_fmt0, addr);
+ }
+
+ if (flag) {
+ if (spaces < 1) {
+ spaces = 1;
+ }
+ dip->fprintf_func(dip->stream, ":%*s", spaces, " ");
+ }
+}
+
+/*
+ * kdba_dis_printaddr
+ *
+ * Print (symbolically) an address. Called by GNU disassembly
+ * code via disassemble_info structure.
+ *
+ * Parameters:
+ * addr Address for which to get symbol
+ * dip Pointer to disassemble_info
+ * Returns:
+ * 0
+ * Locking:
+ * Remarks:
+ * This function will never append ":<tab>" to the printed
+ * symbolic address.
+ */
+
+static void
+kdba_dis_printaddr(bfd_vma addr, disassemble_info *dip)
+{
+ kdba_printaddress(addr, dip, 0);
+}
+
+/*
+ * kdba_dis_getmem
+ *
+ * Fetch 'length' bytes from 'addr' into 'buf'.
+ *
+ * Parameters:
+ * addr Address for which to get symbol
+ * buf Address of buffer to fill with bytes from 'addr'
+ * length Number of bytes to fetch
+ * dip Pointer to disassemble_info
+ * Returns:
+ * 0 if data is available, otherwise error.
+ * Locking:
+ * Remarks:
+ *
+ */
+
+/* ARGSUSED */
+static int
+kdba_dis_getmem(bfd_vma addr, bfd_byte *buf, unsigned int length, disassemble_info *dip)
+{
+ return kdb_getarea_size(buf, addr, length);
+}
+
+/*
+ * kdba_id_parsemode
+ *
+ * Parse IDMODE environment variable string and
+ * set appropriate value into "disassemble_info" structure.
+ *
+ * Parameters:
+ * mode Mode string
+ * dip Disassemble_info structure pointer
+ * Returns:
+ * Locking:
+ * Remarks:
+ * We handle the values 'x86' and '8086' to enable either
+ * 32-bit instruction set or 16-bit legacy instruction set.
+ */
+
+int
+kdba_id_parsemode(const char *mode, disassemble_info *dip)
+{
+
+ if (mode) {
+ if (strcmp(mode, "x86") == 0) {
+ dip->mach = bfd_mach_i386_i386;
+ } else if (strcmp(mode, "8086") == 0) {
+ dip->mach = bfd_mach_i386_i8086;
+ } else {
+ return KDB_BADMODE;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * kdba_check_pc
+ *
+ * Check that the pc is satisfactory.
+ *
+ * Parameters:
+ * pc Program Counter Value.
+ * Returns:
+ * None
+ * Locking:
+ * None.
+ * Remarks:
+ * Can change pc.
+ */
+
+void
+kdba_check_pc(kdb_machreg_t *pc)
+{
+ /* No action */
+}
+
+/*
+ * kdba_id_printinsn
+ *
+ * Format and print a single instruction at 'pc'. Return the
+ * length of the instruction.
+ *
+ * Parameters:
+ * pc Program Counter Value.
+ * dip Disassemble_info structure pointer
+ * Returns:
+ * Length of instruction, -1 for error.
+ * Locking:
+ * None.
+ * Remarks:
+ * Depends on 'IDMODE' environment variable.
+ */
+
+int
+kdba_id_printinsn(kdb_machreg_t pc, disassemble_info *dip)
+{
+ kdba_printaddress(pc, dip, 1);
+ return print_insn_i386_att(pc, dip);
+}
+
+/*
+ * kdba_id_init
+ *
+ * Initialize the architecture dependent elements of
+ * the disassembly information structure
+ * for the GNU disassembler.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+void __init
+kdba_id_init(disassemble_info *dip)
+{
+ dip->read_memory_func = kdba_dis_getmem;
+ dip->print_address_func = kdba_dis_printaddr;
+ dip->symbol_at_address_func = kdba_dis_getsym;
+
+ dip->flavour = bfd_target_elf_flavour;
+ dip->arch = bfd_arch_i386;
+ dip->mach = bfd_mach_i386_i386;
+ dip->endian = BFD_ENDIAN_LITTLE;
+
+ dip->display_endian = BFD_ENDIAN_LITTLE;
+}
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Console I/O handler
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2006 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/console.h>
+#include <linux/ctype.h>
+#include <linux/keyboard.h>
+#include <linux/serial.h>
+#include <linux/serial_reg.h>
+
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <asm/pc_keyb.h>
+
+#ifdef CONFIG_VT_CONSOLE
+#define KDB_BLINK_LED 1
+#else
+#undef KDB_BLINK_LED
+#endif
+
+#ifdef CONFIG_KDB_USB
+struct kdb_usb_exchange kdb_usb_infos;
+
+EXPORT_SYMBOL(kdb_usb_infos);
+
+static unsigned char kdb_usb_keycode[256] = {
+ 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
+ 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
+ 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
+ 27, 43, 84, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
+ 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
+ 72, 73, 82, 83, 86,127,116,117, 85, 89, 90, 91, 92, 93, 94, 95,
+ 120,121,122,123,134,138,130,132,128,129,131,137,133,135,136,113,
+ 115,114, 0, 0, 0,124, 0,181,182,183,184,185,186,187,188,189,
+ 190,191,192,193,194,195,196,197,198, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
+ 150,158,159,128,136,177,178,176,142,152,173,140
+};
+
+/* get_usb_char
+ * This function drives the UHCI controller,
+ * fetch the USB scancode and decode it
+ */
+static int get_usb_char(void)
+{
+ static int usb_lock;
+ unsigned char keycode, spec;
+ extern u_short plain_map[], shift_map[], ctrl_map[];
+
+ /* Is USB initialized ? */
+ if (!kdb_usb_infos.poll_func || !kdb_usb_infos.urb || !kdb_usb_infos.buffer)
+ return -1;
+
+ /* Transfer char if they are present */
+ (*kdb_usb_infos.poll_func)(kdb_usb_infos.uhci, (struct urb *)kdb_usb_infos.urb);
+
+ spec = kdb_usb_infos.buffer[0];
+ keycode = kdb_usb_infos.buffer[2];
+ kdb_usb_infos.buffer[0] = (char)0;
+ kdb_usb_infos.buffer[2] = (char)0;
+
+ if(kdb_usb_infos.buffer[3])
+ return -1;
+
+ /* A normal key is pressed, decode it */
+ if(keycode)
+ keycode = kdb_usb_keycode[keycode];
+
+ /* 2 Keys pressed at one time ? */
+ if (spec && keycode) {
+ switch(spec)
+ {
+ case 0x2:
+ case 0x20: /* Shift */
+ return shift_map[keycode];
+ case 0x1:
+ case 0x10: /* Ctrl */
+ return ctrl_map[keycode];
+ case 0x4:
+ case 0x40: /* Alt */
+ break;
+ }
+ }
+ else {
+ if(keycode) { /* If only one key pressed */
+ switch(keycode)
+ {
+ case 0x1C: /* Enter */
+ return 13;
+
+ case 0x3A: /* Capslock */
+ usb_lock ? (usb_lock = 0) : (usb_lock = 1);
+ break;
+ case 0x0E: /* Backspace */
+ return 8;
+ case 0x0F: /* TAB */
+ return 9;
+ case 0x77: /* Pause */
+ break ;
+ default:
+ if(!usb_lock) {
+ return plain_map[keycode];
+ }
+ else {
+ return shift_map[keycode];
+ }
+ }
+ }
+ }
+ return -1;
+}
+#endif /* CONFIG_KDB_USB */
+
+/*
+ * This module contains code to read characters from the keyboard or a serial
+ * port.
+ *
+ * It is used by the kernel debugger, and is polled, not interrupt driven.
+ *
+ */
+
+#ifdef KDB_BLINK_LED
+/*
+ * send: Send a byte to the keyboard controller. Used primarily to
+ * alter LED settings.
+ */
+
+static void
+kdb_kbdsend(unsigned char byte)
+{
+ int timeout;
+ for (timeout = 200 * 1000; timeout && (inb(KBD_STATUS_REG) & KBD_STAT_IBF); timeout--);
+ outb(byte, KBD_DATA_REG);
+ udelay(40);
+ for (timeout = 200 * 1000; timeout && (~inb(KBD_STATUS_REG) & KBD_STAT_OBF); timeout--);
+ inb(KBD_DATA_REG);
+ udelay(40);
+}
+
+static void
+kdb_toggleled(int led)
+{
+ static int leds;
+
+ leds ^= led;
+
+ kdb_kbdsend(KBD_CMD_SET_LEDS);
+ kdb_kbdsend((unsigned char)leds);
+}
+#endif /* KDB_BLINK_LED */
+
+#if defined(CONFIG_SERIAL_8250_CONSOLE) || defined(CONFIG_SERIAL_CORE_CONSOLE)
+#define CONFIG_SERIAL_CONSOLE
+#endif
+
+#if defined(CONFIG_SERIAL_CONSOLE)
+
+struct kdb_serial kdb_serial;
+
+static unsigned int
+serial_inp(struct kdb_serial *kdb_serial, unsigned long offset)
+{
+ offset <<= kdb_serial->ioreg_shift;
+
+ switch (kdb_serial->io_type) {
+ case SERIAL_IO_MEM:
+ return readb((void __iomem *)(kdb_serial->iobase + offset));
+ break;
+ default:
+ return inb(kdb_serial->iobase + offset);
+ break;
+ }
+}
+
+/* Check if there is a byte ready at the serial port */
+static int get_serial_char(void)
+{
+ unsigned char ch;
+
+ if (kdb_serial.iobase == 0)
+ return -1;
+
+ if (serial_inp(&kdb_serial, UART_LSR) & UART_LSR_DR) {
+ ch = serial_inp(&kdb_serial, UART_RX);
+ if (ch == 0x7f)
+ ch = 8;
+ return ch;
+ }
+ return -1;
+}
+#endif /* CONFIG_SERIAL_CONSOLE */
+
+#ifdef CONFIG_VT_CONSOLE
+
+static int kbd_exists = -1;
+
+/*
+ * Check if the keyboard controller has a keypress for us.
+ * Some parts (Enter Release, LED change) are still blocking polled here,
+ * but hopefully they are all short.
+ */
+static int get_kbd_char(void)
+{
+ int scancode, scanstatus;
+ static int shift_lock; /* CAPS LOCK state (0-off, 1-on) */
+ static int shift_key; /* Shift next keypress */
+ static int ctrl_key;
+ u_short keychar;
+ extern u_short plain_map[], shift_map[], ctrl_map[];
+
+ if (kbd_exists <= 0) {
+ if (kbd_exists == 0)
+ return -1;
+
+ if (inb(KBD_STATUS_REG) == 0xff && inb(KBD_DATA_REG) == 0xff) {
+ kbd_exists = 0;
+ return -1;
+ }
+ kbd_exists = 1;
+ }
+
+ if ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0)
+ return -1;
+
+ /*
+ * Fetch the scancode
+ */
+ scancode = inb(KBD_DATA_REG);
+ scanstatus = inb(KBD_STATUS_REG);
+
+ /*
+ * Ignore mouse events.
+ */
+ if (scanstatus & KBD_STAT_MOUSE_OBF)
+ return -1;
+
+ /*
+ * Ignore release, trigger on make
+ * (except for shift keys, where we want to
+ * keep the shift state so long as the key is
+ * held down).
+ */
+
+ if (((scancode&0x7f) == 0x2a) || ((scancode&0x7f) == 0x36)) {
+ /*
+ * Next key may use shift table
+ */
+ if ((scancode & 0x80) == 0) {
+ shift_key=1;
+ } else {
+ shift_key=0;
+ }
+ return -1;
+ }
+
+ if ((scancode&0x7f) == 0x1d) {
+ /*
+ * Left ctrl key
+ */
+ if ((scancode & 0x80) == 0) {
+ ctrl_key = 1;
+ } else {
+ ctrl_key = 0;
+ }
+ return -1;
+ }
+
+ if ((scancode & 0x80) != 0)
+ return -1;
+
+ scancode &= 0x7f;
+
+ /*
+ * Translate scancode
+ */
+
+ if (scancode == 0x3a) {
+ /*
+ * Toggle caps lock
+ */
+ shift_lock ^= 1;
+
+#ifdef KDB_BLINK_LED
+ kdb_toggleled(0x4);
+#endif
+ return -1;
+ }
+
+ if (scancode == 0x0e) {
+ /*
+ * Backspace
+ */
+ return 8;
+ }
+
+ /* Special Key */
+ switch (scancode) {
+ case 0xF: /* Tab */
+ return 9;
+ case 0x53: /* Del */
+ return 4;
+ case 0x47: /* Home */
+ return 1;
+ case 0x4F: /* End */
+ return 5;
+ case 0x4B: /* Left */
+ return 2;
+ case 0x48: /* Up */
+ return 16;
+ case 0x50: /* Down */
+ return 14;
+ case 0x4D: /* Right */
+ return 6;
+ }
+
+ if (scancode == 0xe0) {
+ return -1;
+ }
+
+ /*
+ * For Japanese 86/106 keyboards
+ * See comment in drivers/char/pc_keyb.c.
+ * - Masahiro Adegawa
+ */
+ if (scancode == 0x73) {
+ scancode = 0x59;
+ } else if (scancode == 0x7d) {
+ scancode = 0x7c;
+ }
+
+ if (!shift_lock && !shift_key && !ctrl_key) {
+ keychar = plain_map[scancode];
+ } else if (shift_lock || shift_key) {
+ keychar = shift_map[scancode];
+ } else if (ctrl_key) {
+ keychar = ctrl_map[scancode];
+ } else {
+ keychar = 0x0020;
+ kdb_printf("Unknown state/scancode (%d)\n", scancode);
+ }
+ keychar &= 0x0fff;
+ if (keychar == '\t')
+ keychar = ' ';
+ switch (KTYP(keychar)) {
+ case KT_LETTER:
+ case KT_LATIN:
+ if (isprint(keychar))
+ break; /* printable characters */
+ /* drop through */
+ case KT_SPEC:
+ if (keychar == K_ENTER)
+ break;
+ /* drop through */
+ default:
+ return(-1); /* ignore unprintables */
+ }
+
+ if ((scancode & 0x7f) == 0x1c) {
+ /*
+ * enter key. All done. Absorb the release scancode.
+ */
+ while ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0)
+ ;
+
+ /*
+ * Fetch the scancode
+ */
+ scancode = inb(KBD_DATA_REG);
+ scanstatus = inb(KBD_STATUS_REG);
+
+ while (scanstatus & KBD_STAT_MOUSE_OBF) {
+ scancode = inb(KBD_DATA_REG);
+ scanstatus = inb(KBD_STATUS_REG);
+ }
+ return 13;
+ }
+
+ return keychar & 0xff;
+}
+#endif /* CONFIG_VT_CONSOLE */
+
+#ifdef KDB_BLINK_LED
+
+/* Leave numlock alone, setting it messes up laptop keyboards with the keypad
+ * mapped over normal keys.
+ */
+static int kdba_blink_mask = 0x1 | 0x4;
+
+#define BOGOMIPS (boot_cpu_data.loops_per_jiffy/(500000/HZ))
+static int blink_led(void)
+{
+ static long delay;
+
+ if (kbd_exists == 0)
+ return -1;
+
+ if (--delay < 0) {
+ if (BOGOMIPS == 0) /* early kdb */
+ delay = 150000000/1000; /* arbitrary bogomips */
+ else
+ delay = 150000000/BOGOMIPS; /* Roughly 1 second when polling */
+ kdb_toggleled(kdba_blink_mask);
+ }
+ return -1;
+}
+#endif
+
+get_char_func poll_funcs[] = {
+#if defined(CONFIG_VT_CONSOLE)
+ get_kbd_char,
+#endif
+#if defined(CONFIG_SERIAL_CONSOLE)
+ get_serial_char,
+#endif
+#ifdef KDB_BLINK_LED
+ blink_led,
+#endif
+#ifdef CONFIG_KDB_USB
+ get_usb_char,
+#endif
+ NULL
+};
+
+/*
+ * On some Compaq Deskpro's, there is a keyboard freeze many times after
+ * exiting from the kdb. As kdb's keyboard handler is not interrupt-driven and
+ * uses a polled interface, it makes more sense to disable motherboard keyboard
+ * controller's OBF interrupts during kdb's polling.In case, of interrupts
+ * remaining enabled during kdb's polling, it may cause un-necessary
+ * interrupts being signalled during keypresses, which are also sometimes seen
+ * as spurious interrupts after exiting from kdb. This hack to disable OBF
+ * interrupts before entry to kdb and re-enabling them at kdb exit point also
+ * solves the keyboard freeze issue. These functions are called from
+ * kdb_local(), hence these are arch. specific setup and cleanup functions
+ * executing only on the local processor - ashishk@sco.com
+ */
+
+void kdba_local_arch_setup(void)
+{
+#ifdef CONFIG_VT_CONSOLE
+ unsigned char c;
+
+ while (kbd_read_status() & KBD_STAT_IBF);
+ kbd_write_command(KBD_CCMD_READ_MODE);
+ udelay(1000);
+ while (kbd_read_status() & KBD_STAT_IBF);
+ while ( !(kbd_read_status() & KBD_STAT_OBF) );
+ c = kbd_read_input();
+ c &= ~KBD_MODE_KBD_INT;
+ while (kbd_read_status() & KBD_STAT_IBF);
+ kbd_write_command(KBD_CCMD_WRITE_MODE);
+ udelay(1000);
+ while (kbd_read_status() & KBD_STAT_IBF);
+ kbd_write_output(c);
+ udelay(1000);
+ while (kbd_read_status() & KBD_STAT_IBF);
+ udelay(1000);
+#endif /* CONFIG_VT_CONSOLE */
+}
+
+void kdba_local_arch_cleanup(void)
+{
+#ifdef CONFIG_VT_CONSOLE
+ unsigned char c;
+
+ while (kbd_read_status() & KBD_STAT_IBF);
+ kbd_write_command(KBD_CCMD_READ_MODE);
+ udelay(1000);
+ while (kbd_read_status() & KBD_STAT_IBF);
+ while ( !(kbd_read_status() & KBD_STAT_OBF) );
+ c = kbd_read_input();
+ c |= KBD_MODE_KBD_INT;
+ while (kbd_read_status() & KBD_STAT_IBF);
+ kbd_write_command(KBD_CCMD_WRITE_MODE);
+ udelay(1000);
+ while (kbd_read_status() & KBD_STAT_IBF);
+ kbd_write_output(c);
+ udelay(1000);
+ while (kbd_read_status() & KBD_STAT_IBF);
+ udelay(1000);
+#endif /* CONFIG_VT_CONSOLE */
+}
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Support Functions
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2006 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/string.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/ptrace.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/hardirq.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+
+#include <asm/processor.h>
+#include <asm/msr.h>
+#include <asm/uaccess.h>
+#include <asm/desc.h>
+
+#define NMI_VECTOR 0x02
+
+enum {
+ GATE_INTERRUPT = 0xE,
+ GATE_TRAP = 0xF,
+ GATE_CALL = 0xC,
+};
+
+/* Copied from arch/i386/kernel/traps.c */
+
+extern struct desc_struct idt_table[256];
+
+#define _set_gate(gate_addr,type,dpl,addr,seg) \
+do { \
+ int __d0, __d1; \
+ __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
+ "movw %4,%%dx\n\t" \
+ "movl %%eax,%0\n\t" \
+ "movl %%edx,%1" \
+ :"=m" (*((long *) (gate_addr))), \
+ "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \
+ :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
+ "3" ((char *) (addr)),"2" ((seg) << 16)); \
+} while (0)
+
+static void __init set_trap_gate(unsigned int n, void *addr)
+{
+ _set_gate(idt_table+n,15,0,addr,__KERNEL_CS);
+}
+
+/* End of copy from arch/i386/kernel/traps.c */
+
+
+
+fastcall void smp_kdb_interrupt(struct pt_regs *regs);
+struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
+
+
+void set_intr_gate(unsigned int n, void *addr)
+{
+ _set_gate(idt_table+n,14,0,addr,__KERNEL_CS);
+}
+
+static kdb_machreg_t
+kdba_getcr(int regnum)
+{
+ kdb_machreg_t contents = 0;
+ switch(regnum) {
+ case 0:
+ __asm__ ("movl %%cr0,%0\n\t":"=r"(contents));
+ break;
+ case 1:
+ break;
+ case 2:
+ __asm__ ("movl %%cr2,%0\n\t":"=r"(contents));
+ break;
+ case 3:
+ __asm__ ("movl %%cr3,%0\n\t":"=r"(contents));
+ break;
+ case 4:
+ __asm__ ("movl %%cr4,%0\n\t":"=r"(contents));
+ break;
+ default:
+ break;
+ }
+
+ return contents;
+}
+
+static void
+kdba_putdr(int regnum, kdb_machreg_t contents)
+{
+ switch(regnum) {
+ case 0:
+ __asm__ ("movl %0,%%db0\n\t"::"r"(contents));
+ break;
+ case 1:
+ __asm__ ("movl %0,%%db1\n\t"::"r"(contents));
+ break;
+ case 2:
+ __asm__ ("movl %0,%%db2\n\t"::"r"(contents));
+ break;
+ case 3:
+ __asm__ ("movl %0,%%db3\n\t"::"r"(contents));
+ break;
+ case 4:
+ case 5:
+ break;
+ case 6:
+ __asm__ ("movl %0,%%db6\n\t"::"r"(contents));
+ break;
+ case 7:
+ __asm__ ("movl %0,%%db7\n\t"::"r"(contents));
+ break;
+ default:
+ break;
+ }
+}
+
+static kdb_machreg_t
+kdba_getdr(int regnum)
+{
+ kdb_machreg_t contents = 0;
+ switch(regnum) {
+ case 0:
+ __asm__ ("movl %%db0,%0\n\t":"=r"(contents));
+ break;
+ case 1:
+ __asm__ ("movl %%db1,%0\n\t":"=r"(contents));
+ break;
+ case 2:
+ __asm__ ("movl %%db2,%0\n\t":"=r"(contents));
+ break;
+ case 3:
+ __asm__ ("movl %%db3,%0\n\t":"=r"(contents));
+ break;
+ case 4:
+ case 5:
+ break;
+ case 6:
+ __asm__ ("movl %%db6,%0\n\t":"=r"(contents));
+ break;
+ case 7:
+ __asm__ ("movl %%db7,%0\n\t":"=r"(contents));
+ break;
+ default:
+ break;
+ }
+
+ return contents;
+}
+
+kdb_machreg_t
+kdba_getdr6(void)
+{
+ return kdba_getdr(6);
+}
+
+kdb_machreg_t
+kdba_getdr7(void)
+{
+ return kdba_getdr(7);
+}
+
+void
+kdba_putdr6(kdb_machreg_t contents)
+{
+ kdba_putdr(6, contents);
+}
+
+static void
+kdba_putdr7(kdb_machreg_t contents)
+{
+ kdba_putdr(7, contents);
+}
+
+void
+kdba_installdbreg(kdb_bp_t *bp)
+{
+ kdb_machreg_t dr7;
+
+ dr7 = kdba_getdr7();
+
+ kdba_putdr(bp->bp_hard->bph_reg, bp->bp_addr);
+
+ dr7 |= DR7_GE;
+ if (cpu_has_de)
+ set_in_cr4(X86_CR4_DE);
+
+ switch (bp->bp_hard->bph_reg){
+ case 0:
+ DR7_RW0SET(dr7,bp->bp_hard->bph_mode);
+ DR7_LEN0SET(dr7,bp->bp_hard->bph_length);
+ DR7_G0SET(dr7);
+ break;
+ case 1:
+ DR7_RW1SET(dr7,bp->bp_hard->bph_mode);
+ DR7_LEN1SET(dr7,bp->bp_hard->bph_length);
+ DR7_G1SET(dr7);
+ break;
+ case 2:
+ DR7_RW2SET(dr7,bp->bp_hard->bph_mode);
+ DR7_LEN2SET(dr7,bp->bp_hard->bph_length);
+ DR7_G2SET(dr7);
+ break;
+ case 3:
+ DR7_RW3SET(dr7,bp->bp_hard->bph_mode);
+ DR7_LEN3SET(dr7,bp->bp_hard->bph_length);
+ DR7_G3SET(dr7);
+ break;
+ default:
+ kdb_printf("kdb: Bad debug register!! %ld\n",
+ bp->bp_hard->bph_reg);
+ break;
+ }
+
+ kdba_putdr7(dr7);
+ return;
+}
+
+void
+kdba_removedbreg(kdb_bp_t *bp)
+{
+ int regnum;
+ kdb_machreg_t dr7;
+
+ if (!bp->bp_hard)
+ return;
+
+ regnum = bp->bp_hard->bph_reg;
+
+ dr7 = kdba_getdr7();
+
+ kdba_putdr(regnum, 0);
+
+ switch (regnum) {
+ case 0:
+ DR7_G0CLR(dr7);
+ DR7_L0CLR(dr7);
+ break;
+ case 1:
+ DR7_G1CLR(dr7);
+ DR7_L1CLR(dr7);
+ break;
+ case 2:
+ DR7_G2CLR(dr7);
+ DR7_L2CLR(dr7);
+ break;
+ case 3:
+ DR7_G3CLR(dr7);
+ DR7_L3CLR(dr7);
+ break;
+ default:
+ kdb_printf("kdb: Bad debug register!! %d\n", regnum);
+ break;
+ }
+
+ kdba_putdr7(dr7);
+}
+
+
+/*
+ * kdba_getregcontents
+ *
+ * Return the contents of the register specified by the
+ * input string argument. Return an error if the string
+ * does not match a machine register.
+ *
+ * The following pseudo register names are supported:
+ * ®s - Prints address of exception frame
+ * kesp - Prints kernel stack pointer at time of fault
+ * cesp - Prints current kernel stack pointer, inside kdb
+ * ceflags - Prints current flags, inside kdb
+ * %<regname> - Uses the value of the registers at the
+ * last time the user process entered kernel
+ * mode, instead of the registers at the time
+ * kdb was entered.
+ *
+ * Parameters:
+ * regname Pointer to string naming register
+ * regs Pointer to structure containing registers.
+ * Outputs:
+ * *contents Pointer to unsigned long to recieve register contents
+ * Returns:
+ * 0 Success
+ * KDB_BADREG Invalid register name
+ * Locking:
+ * None.
+ * Remarks:
+ * If kdb was entered via an interrupt from the kernel itself then
+ * ss and esp are *not* on the stack.
+ */
+
+static struct kdbregs {
+ char *reg_name;
+ size_t reg_offset;
+} kdbreglist[] = {
+ { "eax", offsetof(struct pt_regs, eax) },
+ { "ebx", offsetof(struct pt_regs, ebx) },
+ { "ecx", offsetof(struct pt_regs, ecx) },
+ { "edx", offsetof(struct pt_regs, edx) },
+
+ { "esi", offsetof(struct pt_regs, esi) },
+ { "edi", offsetof(struct pt_regs, edi) },
+ { "esp", offsetof(struct pt_regs, esp) },
+ { "eip", offsetof(struct pt_regs, eip) },
+
+ { "ebp", offsetof(struct pt_regs, ebp) },
+ { "xss", offsetof(struct pt_regs, xss) },
+ { "xcs", offsetof(struct pt_regs, xcs) },
+ { "eflags", offsetof(struct pt_regs, eflags) },
+
+ { "xds", offsetof(struct pt_regs, xds) },
+ { "xes", offsetof(struct pt_regs, xes) },
+ { "origeax", offsetof(struct pt_regs, orig_eax) },
+
+};
+
+static const int nkdbreglist = sizeof(kdbreglist) / sizeof(struct kdbregs);
+
+static struct kdbregs dbreglist[] = {
+ { "dr0", 0 },
+ { "dr1", 1 },
+ { "dr2", 2 },
+ { "dr3", 3 },
+ { "dr6", 6 },
+ { "dr7", 7 },
+};
+
+static const int ndbreglist = sizeof(dbreglist) / sizeof(struct kdbregs);
+
+int
+kdba_getregcontents(const char *regname,
+ struct pt_regs *regs,
+ kdb_machreg_t *contents)
+{
+ int i;
+
+ if (strcmp(regname, "cesp") == 0) {
+ asm volatile("movl %%esp,%0":"=m" (*contents));
+ return 0;
+ }
+
+ if (strcmp(regname, "ceflags") == 0) {
+ unsigned long flags;
+ local_save_flags(flags);
+ *contents = flags;
+ return 0;
+ }
+
+ if (regname[0] == '%') {
+ /* User registers: %%e[a-c]x, etc */
+ regname++;
+ regs = (struct pt_regs *)
+ (kdb_current_task->thread.esp0 - sizeof(struct pt_regs));
+ }
+
+ for (i=0; i<ndbreglist; i++) {
+ if (strnicmp(dbreglist[i].reg_name,
+ regname,
+ strlen(regname)) == 0)
+ break;
+ }
+
+ if ((i < ndbreglist)
+ && (strlen(dbreglist[i].reg_name) == strlen(regname))) {
+ *contents = kdba_getdr(dbreglist[i].reg_offset);
+ return 0;
+ }
+
+ if (!regs) {
+ kdb_printf("%s: pt_regs not available, use bt* or pid to select a different task\n", __FUNCTION__);
+ return KDB_BADREG;
+ }
+
+ if (strcmp(regname, "®s") == 0) {
+ *contents = (unsigned long)regs;
+ return 0;
+ }
+
+ if (strcmp(regname, "kesp") == 0) {
+ *contents = (unsigned long)regs + sizeof(struct pt_regs);
+ if ((regs->xcs & 0xffff) == __KERNEL_CS) {
+ /* esp and ss are not on stack */
+ *contents -= 2*4;
+ }
+ return 0;
+ }
+
+ for (i=0; i<nkdbreglist; i++) {
+ if (strnicmp(kdbreglist[i].reg_name,
+ regname,
+ strlen(regname)) == 0)
+ break;
+ }
+
+ if ((i < nkdbreglist)
+ && (strlen(kdbreglist[i].reg_name) == strlen(regname))) {
+ if ((regs->xcs & 0xffff) == __KERNEL_CS) {
+ /* No cpl switch, esp and ss are not on stack */
+ if (strcmp(kdbreglist[i].reg_name, "esp") == 0) {
+ *contents = (kdb_machreg_t)regs +
+ sizeof(struct pt_regs) - 2*4;
+ return(0);
+ }
+ if (strcmp(kdbreglist[i].reg_name, "xss") == 0) {
+ asm volatile(
+ "pushl %%ss\n"
+ "popl %0\n"
+ :"=m" (*contents));
+ return(0);
+ }
+ }
+ *contents = *(unsigned long *)((unsigned long)regs +
+ kdbreglist[i].reg_offset);
+ return(0);
+ }
+
+ return KDB_BADREG;
+}
+
+/*
+ * kdba_setregcontents
+ *
+ * Set the contents of the register specified by the
+ * input string argument. Return an error if the string
+ * does not match a machine register.
+ *
+ * Supports modification of user-mode registers via
+ * %<register-name>
+ *
+ * Parameters:
+ * regname Pointer to string naming register
+ * regs Pointer to structure containing registers.
+ * contents Unsigned long containing new register contents
+ * Outputs:
+ * Returns:
+ * 0 Success
+ * KDB_BADREG Invalid register name
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+int
+kdba_setregcontents(const char *regname,
+ struct pt_regs *regs,
+ unsigned long contents)
+{
+ int i;
+
+ if (regname[0] == '%') {
+ regname++;
+ regs = (struct pt_regs *)
+ (kdb_current_task->thread.esp0 - sizeof(struct pt_regs));
+ }
+
+ for (i=0; i<ndbreglist; i++) {
+ if (strnicmp(dbreglist[i].reg_name,
+ regname,
+ strlen(regname)) == 0)
+ break;
+ }
+
+ if ((i < ndbreglist)
+ && (strlen(dbreglist[i].reg_name) == strlen(regname))) {
+ kdba_putdr(dbreglist[i].reg_offset, contents);
+ return 0;
+ }
+
+ if (!regs) {
+ kdb_printf("%s: pt_regs not available, use bt* or pid to select a different task\n", __FUNCTION__);
+ return KDB_BADREG;
+ }
+
+ for (i=0; i<nkdbreglist; i++) {
+ if (strnicmp(kdbreglist[i].reg_name,
+ regname,
+ strlen(regname)) == 0)
+ break;
+ }
+
+ if ((i < nkdbreglist)
+ && (strlen(kdbreglist[i].reg_name) == strlen(regname))) {
+ *(unsigned long *)((unsigned long)regs
+ + kdbreglist[i].reg_offset) = contents;
+ return 0;
+ }
+
+ return KDB_BADREG;
+}
+
+/*
+ * kdba_dumpregs
+ *
+ * Dump the specified register set to the display.
+ *
+ * Parameters:
+ * regs Pointer to structure containing registers.
+ * type Character string identifying register set to dump
+ * extra string further identifying register (optional)
+ * Outputs:
+ * Returns:
+ * 0 Success
+ * Locking:
+ * None.
+ * Remarks:
+ * This function will dump the general register set if the type
+ * argument is NULL (struct pt_regs). The alternate register
+ * set types supported by this function:
+ *
+ * d Debug registers
+ * c Control registers
+ * u User registers at most recent entry to kernel
+ * for the process currently selected with "pid" command.
+ * Following not yet implemented:
+ * m Model Specific Registers (extra defines register #)
+ * r Memory Type Range Registers (extra defines register)
+ */
+
+int
+kdba_dumpregs(struct pt_regs *regs,
+ const char *type,
+ const char *extra)
+{
+ int i;
+ int count = 0;
+
+ if (type
+ && (type[0] == 'u')) {
+ type = NULL;
+ regs = (struct pt_regs *)
+ (kdb_current_task->thread.esp0 - sizeof(struct pt_regs));
+ }
+
+ if (type == NULL) {
+ struct kdbregs *rlp;
+ kdb_machreg_t contents;
+
+ if (!regs) {
+ kdb_printf("%s: pt_regs not available, use bt* or pid to select a different task\n", __FUNCTION__);
+ return KDB_BADREG;
+ }
+
+ for (i=0, rlp=kdbreglist; i<nkdbreglist; i++,rlp++) {
+ kdb_printf("%s = ", rlp->reg_name);
+ kdba_getregcontents(rlp->reg_name, regs, &contents);
+ kdb_printf("0x%08lx ", contents);
+ if ((++count % 4) == 0)
+ kdb_printf("\n");
+ }
+
+ kdb_printf("®s = 0x%p\n", regs);
+
+ return 0;
+ }
+
+ switch (type[0]) {
+ case 'd':
+ {
+ unsigned long dr[8];
+
+ for(i=0; i<8; i++) {
+ if ((i == 4) || (i == 5)) continue;
+ dr[i] = kdba_getdr(i);
+ }
+ kdb_printf("dr0 = 0x%08lx dr1 = 0x%08lx dr2 = 0x%08lx dr3 = 0x%08lx\n",
+ dr[0], dr[1], dr[2], dr[3]);
+ kdb_printf("dr6 = 0x%08lx dr7 = 0x%08lx\n",
+ dr[6], dr[7]);
+ return 0;
+ }
+ case 'c':
+ {
+ unsigned long cr[5];
+
+ for (i=0; i<5; i++) {
+ cr[i] = kdba_getcr(i);
+ }
+ kdb_printf("cr0 = 0x%08lx cr1 = 0x%08lx cr2 = 0x%08lx cr3 = 0x%08lx\ncr4 = 0x%08lx\n",
+ cr[0], cr[1], cr[2], cr[3], cr[4]);
+ return 0;
+ }
+ case 'm':
+ break;
+ case 'r':
+ break;
+ default:
+ return KDB_BADREG;
+ }
+
+ /* NOTREACHED */
+ return 0;
+}
+EXPORT_SYMBOL(kdba_dumpregs);
+
+kdb_machreg_t
+kdba_getpc(struct pt_regs *regs)
+{
+ return regs ? regs->eip : 0;
+}
+
+int
+kdba_setpc(struct pt_regs *regs, kdb_machreg_t newpc)
+{
+ if (KDB_NULL_REGS(regs))
+ return KDB_BADREG;
+ regs->eip = newpc;
+ KDB_STATE_SET(IP_ADJUSTED);
+ return 0;
+}
+
+/*
+ * kdba_main_loop
+ *
+ * Do any architecture specific set up before entering the main kdb loop.
+ * The primary function of this routine is to make all processes look the
+ * same to kdb, kdb must be able to list a process without worrying if the
+ * process is running or blocked, so make all process look as though they
+ * are blocked.
+ *
+ * Inputs:
+ * reason The reason KDB was invoked
+ * error The hardware-defined error code
+ * error2 kdb's current reason code. Initially error but can change
+ * acording to kdb state.
+ * db_result Result from break or debug point.
+ * regs The exception frame at time of fault/breakpoint. If reason
+ * is SILENT or CPU_UP then regs is NULL, otherwise it should
+ * always be valid.
+ * Returns:
+ * 0 KDB was invoked for an event which it wasn't responsible
+ * 1 KDB handled the event for which it was invoked.
+ * Outputs:
+ * Sets eip and esp in current->thread.
+ * Locking:
+ * None.
+ * Remarks:
+ * none.
+ */
+
+int
+kdba_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error,
+ kdb_dbtrap_t db_result, struct pt_regs *regs)
+{
+ int ret;
+ kdb_save_running(regs);
+ ret = kdb_main_loop(reason, reason2, error, db_result, regs);
+ kdb_unsave_running(regs);
+ return ret;
+}
+
+void
+kdba_disableint(kdb_intstate_t *state)
+{
+ unsigned long *fp = (unsigned long *)state;
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ *fp = flags;
+}
+
+void
+kdba_restoreint(kdb_intstate_t *state)
+{
+ unsigned long flags = *(int *)state;
+ local_irq_restore(flags);
+}
+
+void
+kdba_setsinglestep(struct pt_regs *regs)
+{
+ if (KDB_NULL_REGS(regs))
+ return;
+ if (regs->eflags & EF_IE)
+ KDB_STATE_SET(A_IF);
+ else
+ KDB_STATE_CLEAR(A_IF);
+ regs->eflags = (regs->eflags | EF_TF) & ~EF_IE;
+}
+
+void
+kdba_clearsinglestep(struct pt_regs *regs)
+{
+ if (KDB_NULL_REGS(regs))
+ return;
+ if (KDB_STATE(A_IF))
+ regs->eflags |= EF_IE;
+ else
+ regs->eflags &= ~EF_IE;
+}
+
+int asmlinkage
+kdba_setjmp(kdb_jmp_buf *jb)
+{
+#if defined(CONFIG_FRAME_POINTER)
+ __asm__ ("movl 8(%esp), %eax\n\t"
+ "movl %ebx, 0(%eax)\n\t"
+ "movl %esi, 4(%eax)\n\t"
+ "movl %edi, 8(%eax)\n\t"
+ "movl (%esp), %ecx\n\t"
+ "movl %ecx, 12(%eax)\n\t"
+ "leal 8(%esp), %ecx\n\t"
+ "movl %ecx, 16(%eax)\n\t"
+ "movl 4(%esp), %ecx\n\t"
+ "movl %ecx, 20(%eax)\n\t");
+#else /* CONFIG_FRAME_POINTER */
+ __asm__ ("movl 4(%esp), %eax\n\t"
+ "movl %ebx, 0(%eax)\n\t"
+ "movl %esi, 4(%eax)\n\t"
+ "movl %edi, 8(%eax)\n\t"
+ "movl %ebp, 12(%eax)\n\t"
+ "leal 4(%esp), %ecx\n\t"
+ "movl %ecx, 16(%eax)\n\t"
+ "movl 0(%esp), %ecx\n\t"
+ "movl %ecx, 20(%eax)\n\t");
+#endif /* CONFIG_FRAME_POINTER */
+ return 0;
+}
+
+void asmlinkage
+kdba_longjmp(kdb_jmp_buf *jb, int reason)
+{
+#if defined(CONFIG_FRAME_POINTER)
+ __asm__("movl 8(%esp), %ecx\n\t"
+ "movl 12(%esp), %eax\n\t"
+ "movl 20(%ecx), %edx\n\t"
+ "movl 0(%ecx), %ebx\n\t"
+ "movl 4(%ecx), %esi\n\t"
+ "movl 8(%ecx), %edi\n\t"
+ "movl 12(%ecx), %ebp\n\t"
+ "movl 16(%ecx), %esp\n\t"
+ "jmp *%edx\n");
+#else /* CONFIG_FRAME_POINTER */
+ __asm__("movl 4(%esp), %ecx\n\t"
+ "movl 8(%esp), %eax\n\t"
+ "movl 20(%ecx), %edx\n\t"
+ "movl 0(%ecx), %ebx\n\t"
+ "movl 4(%ecx), %esi\n\t"
+ "movl 8(%ecx), %edi\n\t"
+ "movl 12(%ecx), %ebp\n\t"
+ "movl 16(%ecx), %esp\n\t"
+ "jmp *%edx\n");
+#endif /* CONFIG_FRAME_POINTER */
+}
+
+/*
+ * kdba_pt_regs
+ *
+ * Format a struct pt_regs
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * If no address is supplied, it uses regs.
+ */
+
+static int
+kdba_pt_regs(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int diag;
+ kdb_machreg_t addr;
+ long offset = 0;
+ int nextarg;
+ struct pt_regs *p;
+ static const char *fmt = " %-11.11s 0x%lx\n";
+
+ if (argc == 0) {
+ addr = (kdb_machreg_t) regs;
+ } else if (argc == 1) {
+ nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
+ if (diag)
+ return diag;
+ } else {
+ return KDB_ARGCOUNT;
+ }
+
+ p = (struct pt_regs *) addr;
+ kdb_printf("struct pt_regs 0x%p-0x%p\n", p, (unsigned char *)p + sizeof(*p) - 1);
+ kdb_print_nameval("ebx", p->ebx);
+ kdb_print_nameval("ecx", p->ecx);
+ kdb_print_nameval("edx", p->edx);
+ kdb_print_nameval("esi", p->esi);
+ kdb_print_nameval("edi", p->edi);
+ kdb_print_nameval("ebp", p->ebp);
+ kdb_print_nameval("eax", p->eax);
+ kdb_printf(fmt, "xds", p->xds);
+ kdb_printf(fmt, "xes", p->xes);
+ kdb_print_nameval("orig_eax", p->orig_eax);
+ kdb_print_nameval("eip", p->eip);
+ kdb_printf(fmt, "xcs", p->xcs);
+ kdb_printf(fmt, "eflags", p->eflags);
+ kdb_printf(fmt, "esp", p->esp);
+ kdb_printf(fmt, "xss", p->xss);
+ return 0;
+}
+
+/*
+ * kdba_stackdepth
+ *
+ * Print processes that are using more than a specific percentage of their
+ * stack.
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * If no percentage is supplied, it uses 60.
+ */
+
+static void
+kdba_stackdepth1(struct task_struct *p, unsigned long esp)
+{
+ struct thread_info *tinfo;
+ int used;
+ const char *type;
+ kdb_ps1(p);
+ do {
+ tinfo = (struct thread_info *)(esp & -THREAD_SIZE);
+ used = sizeof(*tinfo) + THREAD_SIZE - (esp & (THREAD_SIZE-1));
+ type = NULL;
+ if (task_curr(p)) {
+ struct kdb_activation_record ar;
+ memset(&ar, 0, sizeof(ar));
+ kdba_get_stack_info_alternate(esp, -1, &ar);
+ type = ar.stack.id;
+ }
+ if (!type)
+ type = "process";
+ kdb_printf(" %s stack %p esp %lx used %d\n", type, tinfo, esp, used);
+ esp = tinfo->previous_esp;
+ } while (esp);
+}
+
+static int
+kdba_stackdepth(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int diag, cpu, threshold, used, over;
+ long percentage;
+ unsigned long esp;
+ long offset = 0;
+ int nextarg;
+ struct task_struct *p, *g;
+ struct kdb_running_process *krp;
+ struct thread_info *tinfo;
+
+ if (argc == 0) {
+ percentage = 60;
+ } else if (argc == 1) {
+ nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &percentage, &offset, NULL, regs);
+ if (diag)
+ return diag;
+ } else {
+ return KDB_ARGCOUNT;
+ }
+ percentage = max_t(int, percentage, 1);
+ percentage = min_t(int, percentage, 100);
+ threshold = ((2 * THREAD_SIZE * percentage) / 100 + 1) >> 1;
+ kdb_printf("stackdepth: processes using more than %ld%% (%d bytes) of stack\n",
+ percentage, threshold);
+
+ /* Run the active tasks first, they can have multiple stacks */
+ for (cpu = 0, krp = kdb_running_process; cpu < NR_CPUS; ++cpu, ++krp) {
+ if (!cpu_online(cpu))
+ continue;
+ p = krp->p;
+ esp = krp->arch.esp;
+ over = 0;
+ do {
+ tinfo = (struct thread_info *)(esp & -THREAD_SIZE);
+ used = sizeof(*tinfo) + THREAD_SIZE - (esp & (THREAD_SIZE-1));
+ if (used >= threshold)
+ over = 1;
+ esp = tinfo->previous_esp;
+ } while (esp);
+ if (over)
+ kdba_stackdepth1(p, krp->arch.esp);
+ }
+ /* Now the tasks that are not on cpus */
+ do_each_thread(g, p) {
+ if (task_curr(p))
+ continue;
+ esp = p->thread.esp;
+ used = sizeof(*tinfo) + THREAD_SIZE - (esp & (THREAD_SIZE-1));
+ over = used >= threshold;
+ if (over)
+ kdba_stackdepth1(p, esp);
+ } while_each_thread(g, p);
+
+ return 0;
+}
+
+
+asmlinkage int kdb_call(void);
+
+/* Executed once on each cpu at startup. */
+void
+kdba_cpu_up(void)
+{
+}
+
+/*
+ * kdba_init
+ *
+ * Architecture specific initialization.
+ *
+ * Parameters:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ * None.
+ */
+
+void __init
+kdba_init(void)
+{
+ kdb_register("pt_regs", kdba_pt_regs, "address", "Format struct pt_regs", 0);
+ kdb_register("stackdepth", kdba_stackdepth, "[percentage]", "Print processes using >= stack percentage", 0);
+
+ return;
+}
+
+static int __init
+kdba_late_init(void)
+{
+#ifdef CONFIG_SMP
+ set_intr_gate(KDB_VECTOR, kdb_interrupt);
+#endif
+ set_trap_gate(KDBENTER_VECTOR, kdb_call);
+ return 0;
+}
+
+__initcall(kdba_late_init);
+
+/*
+ * kdba_adjust_ip
+ *
+ * Architecture specific adjustment of instruction pointer before leaving
+ * kdb.
+ *
+ * Parameters:
+ * reason The reason KDB was invoked
+ * error The hardware-defined error code
+ * regs The exception frame at time of fault/breakpoint. If reason
+ * is SILENT or CPU_UP then regs is NULL, otherwise it should
+ * always be valid.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ * noop on ix86.
+ */
+
+void
+kdba_adjust_ip(kdb_reason_t reason, int error, struct pt_regs *regs)
+{
+ return;
+}
+
+void
+kdba_set_current_task(const struct task_struct *p)
+{
+ kdb_current_task = p;
+ if (task_curr(p)) {
+ struct kdb_running_process *krp = kdb_running_process + kdb_process_cpu(p);
+ kdb_current_regs = krp->regs;
+ return;
+ }
+ kdb_current_regs = NULL;
+}
+
+int
+kdba_putarea_size(unsigned long to_xxx, void *from, size_t size)
+{
+ mm_segment_t oldfs = get_fs();
+ int r;
+
+ if (to_xxx < PAGE_OFFSET)
+ return kdb_putuserarea_size(to_xxx, from, size);
+
+ set_fs(KERNEL_DS);
+ r = __copy_to_user_inatomic((void __user *)to_xxx, from, size);
+ set_fs(oldfs);
+ return r;
+}
+
+int
+kdba_getarea_size(void *to, unsigned long from_xxx, size_t size)
+{
+ mm_segment_t oldfs = get_fs();
+ int r;
+
+ if (from_xxx < PAGE_OFFSET)
+ return kdb_getuserarea_size(to, from_xxx, size);
+
+ set_fs(KERNEL_DS);
+ r = __copy_from_user_inatomic(to, (void __user *)from_xxx, size);
+ set_fs(oldfs);
+ return r;
+}
+
+int
+kdba_verify_rw(unsigned long addr, size_t size)
+{
+ unsigned char data[size];
+ return(kdba_getarea_size(data, addr, size) || kdba_putarea_size(addr, data, size));
+}
+
+#ifdef CONFIG_SMP
+
+#include <mach_ipi.h>
+
+/* When first entering KDB, try a normal IPI. That reduces backtrace problems
+ * on the other cpus.
+ */
+void
+smp_kdb_stop(void)
+{
+ /*
+ * Using send_IPI_mask below rather than send_IPI_allbutself
+ * allows kdb to work with "maxcpus=N" on a machine with more.
+ * However, it broke kdb(KDB_REASON_SILENT,,) in smpboot.c.
+ */
+ if (!KDB_FLAG(NOIPI)) {
+ cpumask_t cpu_mask = cpu_online_map;
+ cpu_clear(smp_processor_id(), cpu_mask);
+ send_IPI_mask(cpu_mask, KDB_VECTOR);
+ }
+}
+
+/* The normal KDB IPI handler */
+fastcall void
+smp_kdb_interrupt(struct pt_regs *regs)
+{
+ irq_enter();
+ ack_APIC_irq();
+ kdb_ipi(regs, NULL);
+ irq_exit();
+}
+
+/* Invoked once from kdb_wait_for_cpus when waiting for cpus. For those cpus
+ * that have not responded to the normal KDB interrupt yet, hit them with an
+ * NMI event.
+ */
+void
+kdba_wait_for_cpus(void)
+{
+ int c;
+ if (KDB_FLAG(CATASTROPHIC))
+ return;
+ kdb_printf(" Sending NMI to cpus that have not responded yet\n");
+ for_each_online_cpu(c)
+ if (kdb_running_process[c].seqno < kdb_seqno - 1)
+ send_IPI_mask(cpumask_of_cpu(c), NMI_VECTOR);
+}
+
+#endif /* CONFIG_SMP */
#define UNWIND_ESPFIX_STACK
#endif
+ENTRY(kdb_interrupt) \
+ pushl $(0xf8); \
+ SAVE_ALL \
+ movl %esp,%eax; \
+ call smp_kdb_interrupt; \
+ jmp ret_from_intr;
+
+
ENTRY(divide_error)
RING0_INT_FRAME
pushl $0 # no error code
/* The include is where all of the SMP etc. interrupts come from */
#include "entry_arch.h"
+#ifdef CONFIG_KDB
+
+ENTRY(kdb_call)
+ CFI_STARTPROC
+ pushl %eax # save orig EAX
+ SAVE_ALL
+ pushl %esp # struct pt_regs
+ pushl $0 # error_code
+ pushl $1 # KDB_REASON_ENTER
+ call kdb
+ addl $12,%esp # remove args
+ jmp restore_all
+ CFI_ENDPROC
+
+#ifdef CONFIG_SMP
+BUILD_INTERRUPT(kdb_interrupt,KDB_VECTOR)
+#endif /* CONFIG_SMP */
+
+#endif /* CONFIG_KDB */
+
ENTRY(divide_error)
RING0_INT_FRAME
pushl $0 # no error code
#include <linux/mca.h>
#endif
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#endif /* CONFIG_KDB */
+
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#ifdef CONFIG_DEBUG_BUGVERBOSE
do {
+ unsigned char ljmp;
unsigned short line;
char *file;
char c;
- if (__get_user(line, (unsigned short __user *)(eip + 2)))
+ if (__get_user(ljmp, (unsigned char __user *)(eip + 2)))
+ break;
+ if (ljmp == 0xea) {
+ if (__get_user(line, (unsigned short __user *)(eip + 7)))
+ break;
+ if (__get_user(file, (char * __user *)(eip + 3)))
+ break;
+ } else {
+ if (__get_user(line, (unsigned short __user *)(eip + 2)))
+ break;
+ if (__get_user(file, (char * __user *)(eip + 4)))
+ break;
+ }
+ if ((unsigned long)file < PAGE_OFFSET || __get_user(c, file))
break;
- if (__get_user(file, (char * __user *)(eip + 4)) ||
- (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
- file = "<bad filename>";
printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line);
return;
bust_spinlocks(0);
die.lock_owner = -1;
spin_unlock_irqrestore(&die.lock, flags);
+#ifdef CONFIG_KDB
+ kdb_diemsg = str;
+ kdb(KDB_REASON_OOPS, err, regs);
+#endif /* CONFIG_KDB */
if (!regs)
return;
}
DO_VM86_ERROR_INFO( 0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->eip)
-#ifndef CONFIG_KPROBES
+#if !defined(CONFIG_KPROBES) && !defined(CONFIG_KDB)
DO_VM86_ERROR( 3, SIGTRAP, "int3", int3)
#endif
DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow)
static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
{
+#ifdef CONFIG_KDB
+ (void)kdb(KDB_REASON_NMI, reason, regs);
+#endif /* CONFIG_KDB */
#ifdef CONFIG_MCA
/* Might actually be able to figure out what the guilty party
* is. */
printk(" on CPU%d, eip %08lx, registers:\n",
smp_processor_id(), regs->eip);
show_registers(regs);
+#ifdef CONFIG_KDB
+ kdb(KDB_REASON_NMI, 0, regs);
+#endif /* CONFIG_KDB */
console_silent();
spin_unlock(&nmi_print_lock);
bust_spinlocks(0);
/* Only the BSP gets external NMIs from the system. */
if (!smp_processor_id())
reason = get_nmi_reason();
-
+
+#if defined(CONFIG_SMP) && defined(CONFIG_KDB)
+ /*
+ * Call the kernel debugger to see if this NMI is due
+ * to an KDB requested IPI. If so, kdb will handle it.
+ */
+ if (kdb_ipi(regs, NULL)) {
+ return;
+ }
+#endif /* defined(CONFIG_SMP) && defined(CONFIG_KDB) */
+
if (!(reason & 0xc0)) {
if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT)
== NOTIFY_STOP)
#ifdef CONFIG_KPROBES
fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code)
{
+#ifdef CONFIG_KDB
+ if (kdb(KDB_REASON_BREAK, error_code, regs))
+ return;
+#endif
if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP)
== NOTIFY_STOP)
return;
restore_interrupts(regs);
do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL);
}
-#endif
+#else /* !CONFIG_KPROBES */
+#ifdef CONFIG_KDB
+fastcall void do_int3(struct pt_regs * regs, long error_code)
+{
+ if (kdb(KDB_REASON_BREAK, error_code, regs))
+ return;
+ do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL);
+}
+#endif /* CONFIG_KDB */
+#endif /* !CONFIG_KPROBES */
/*
* Our handling of the processor debug registers is non-trivial.
get_debugreg(condition, 6);
+#ifdef CONFIG_KDB
+ if (kdb(KDB_REASON_DEBUG, error_code, regs))
+ return;
+#endif /* CONFIG_KDB */
+
if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
SIGTRAP) == NOTIFY_STOP)
return;
and restore instructions. It's useful for tracking down spinlock
problems, but slow! If you're unsure, select N.
+config KDB
+ bool "Built-in Kernel Debugger support"
+ depends on DEBUG_KERNEL
+ select KALLSYMS
+ select KALLSYMS_ALL
+ help
+ This option provides a built-in kernel debugger. The built-in
+ kernel debugger contains commands which allow memory to be examined,
+ instructions to be disassembled and breakpoints to be set. For details,
+ see Documentation/kdb/kdb.mm and the manual pages kdb_bt, kdb_ss, etc.
+ Kdb can also be used via the serial port. Set up the system to
+ have a serial console (see Documentation/serial-console.txt).
+ The key sequence <escape>KDB on the serial port will cause the
+ kernel debugger to be entered with input from the serial port and
+ output to the serial console. If unsure, say N.
+
+config KDB_MODULES
+ tristate "KDB modules"
+ depends on KDB
+ help
+ KDB can be extended by adding your own modules, in directory
+ kdb/modules. This option selects the way that these modules should
+ be compiled, as free standing modules (select M) or built into the
+ kernel (select Y). If unsure say M.
+
+config KDB_MODULES_XP
+ tristate
+ depends on KDB_MODULES && IA64_SGI_SN_XP
+ default y if (KDB_MODULES = y && IA64_SGI_SN_XP = y)
+ default m
+
+config KDB_OFF
+ bool "KDB off by default"
+ depends on KDB
+ help
+ Normally kdb is activated by default, as long as CONFIG_KDB is set.
+ If you want to ship a kernel with kdb support but only have kdb
+ turned on when the user requests it then select this option. When
+ compiled with CONFIG_KDB_OFF, kdb ignores all events unless you boot
+ with kdb=on or you echo "1" > /proc/sys/kernel/kdb. This option also
+ works in reverse, if kdb is normally activated, you can boot with
+ kdb=off or echo "0" > /proc/sys/kernel/kdb to deactivate kdb. If
+ unsure, say N.
+
+config KDB_CONTINUE_CATASTROPHIC
+ int "KDB continues after catastrophic errors"
+ depends on KDB
+ default "0"
+ help
+ This integer controls the behaviour of kdb when the kernel gets a
+ catastrophic error, i.e. for a panic, oops, NMI or other watchdog
+ tripping. CONFIG_KDB_CONTINUE_CATASTROPHIC interacts with
+ /proc/sys/kernel/kdb and CONFIG_LKCD_DUMP (if your kernel has the
+ LKCD patch).
+ When KDB is active (/proc/sys/kernel/kdb == 1) and a catastrophic
+ error occurs, nothing extra happens until you type 'go'.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 0 (default). The first time
+ you type 'go', kdb warns you. The second time you type 'go', KDB
+ tries to continue - no guarantees that the kernel is still usable.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 1. KDB tries to continue - no
+ guarantees that the kernel is still usable.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 2. If your kernel has the LKCD
+ patch and LKCD is configured to take a dump then KDB forces a dump.
+ Whether or not a dump is taken, KDB forces a reboot.
+ When KDB is not active (/proc/sys/kernel/kdb == 0) and a catastrophic
+ error occurs, the following steps are automatic, no human
+ intervention is required.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 0 (default) or 1. KDB attempts
+ to continue - no guarantees that the kernel is still usable.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 2. If your kernel has the LKCD
+ patch and LKCD is configured to take a dump then KDB automatically
+ forces a dump. Whether or not a dump is taken, KDB forces a
+ reboot.
+ If you are not sure, say 0.
+
+config KDB_USB
+ bool "Support for USB Keyboard in KDB (OHCI only)"
+ depends on KDB && USB_OHCI_HCD
+ help
+ If you want to use kdb from a OHCI USB keyboard then say Y here. If you
+ say N then kdb can only be used from a PC (AT) keyboard or a serial
+ console.
+
config SYSVIPC_COMPAT
bool
depends on COMPAT && SYSVIPC
core-$(CONFIG_IA64_SGI_SN2) += arch/ia64/sn/
core-$(CONFIG_XEN) += arch/ia64/xen/
+drivers-$(CONFIG_KDB) += arch/$(ARCH)/kdb/
drivers-$(CONFIG_PCI) += arch/ia64/pci/
drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/
drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/
--- /dev/null
+2006-09-20 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-ia64-1.
+
+2006-09-15 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc7-ia64-1.
+
+2006-08-29 Keith Owens <kaos@sgi.com>
+
+ * Rewrite all backtrace code.
+ * kdb v4.4-2.6.18-rc5-ia64-2.
+
+2006-08-28 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc5-ia64-1.
+
+2006-08-08 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc4-ia64-1.
+
+2006-08-04 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc3-ia64-1.
+
+2006-07-18 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc2-ia64-1.
+
+2006-07-12 Keith Owens <kaos@sgi.com>
+
+ * Remove dead KDB_REASON codes.
+ * sparse cleanups.
+ * kdb v4.4-2.6.18-rc1-ia64-2.
+
+2006-07-07 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc1-ia64-1.
+
+2006-07-04 Keith Owens <kaos@sgi.com>
+
+ * Delete kdba_enable_lbr, kdba_disable_lbr, kdba_print_lbr,
+ page_fault_mca. Only ever implemented on x86, difficult to maintain
+ and rarely used in the field.
+ * Replace #ifdef KDB_HAVE_LONGJMP with #ifdef kdba_setjmp.
+ * kdb v4.4-2.6.17-ia64-2.
+
+2006-06-19 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-ia64-1.
+
+2006-05-25 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-rc5-ia64-1.
+
+2006-05-15 Keith Owens <kaos@sgi.com>
+
+ * Refresh bfd related files from binutils 2.16.91.0.2.
+ * kdb v4.4-2.6.17-rc4-ia64-2.
+
+2006-05-12 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-rc4-ia64-1.
+
+2006-04-28 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-rc3-ia64-1.
+
+2006-04-22 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-rc2-ia64-1.
+
+2006-04-11 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-rc1-ia64-1.
+
+2006-03-30 Keith Owens <kaos@sgi.com>
+
+ * Change CONFIG_LKCD to CONFIG_LKCD_DUMP.
+ * kdb v4.4-2.6.16-ia64-3.
+
+2006-03-24 Keith Owens <kaos@sgi.com>
+
+ * Use INIT to interrupt cpus that do not respond to a normal kdb IPI.
+ * Remove KDBA_MCA_TRACE from arch/ia64/kernel/mca.c.
+ * kdb v4.4-2.6.16-ia64-2.
+
+2006-03-21 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.16-ia64-1.
+
+2006-03-14 Nathan Scott <nathans@sgi.com>
+
+ * kdb v4.4-2.6.16-rc6-ia64-1.
+
+2006-02-28 Nathan Scott <nathans@sgi.com>
+
+ * kdb v4.4-2.6.16-rc5-ia64-1.
+
+2006-02-20 Nathan Scott <nathans@sgi.com>
+
+ * kdb v4.4-2.6.16-rc4-ia64-1.
+
+2006-02-07 Keith Owens <kaos@sgi.com>
+
+ * Change kdb_running_process_save from a static array to a pointer.
+ gcc 4.0 objects to forward declarations for arrays with an incomplete
+ type.
+ * kdb v4.4-2.6.16-rc2-ia64-3.
+
+2006-02-06 Keith Owens <kaos@sgi.com>
+
+ * Change CONFIG_CRASH_DUMP to CONFIG_LKCD.
+ * kdb v4.4-2.6.16-rc2-ia64-2.
+
+2006-02-06 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.16-rc2-ia64-1.
+
+2006-02-01 Keith Owens <kaos@sgi.com>
+
+ * Handlers: check that the task is in kernel space before looking at
+ the thread_info bits.
+ * Expose kdb_running_process_save[] so 'pid R' can get the original
+ process, even when the MCA/INIT handlers are being used.
+ * kdb v4.4-2.6.16-rc1-ia64-3.
+
+2006-01-19 Keith Owens <kaos@sgi.com>
+
+ * Add back some kdb changes to xpc_main that were lost due to a patch
+ conflict.
+ * kdb v4.4-2.6.16-rc1-ia64-2.
+
+2006-01-18 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.16-rc1-ia64-1.
+
+2006-01-10 Keith Owens <kaos@sgi.com>
+
+ * Build kdba_pod for generic as well as sn2 kernels and test at run
+ time if the platform is sn2.
+ * kdb v4.4-2.6.15-ia64-3.
+
+2006-01-08 Keith Owens <kaos@sgi.com>
+
+ * Convert xpc to use DIE_KDEBUG_ENTER and DIE_KDEBUG_LEAVE.
+ * Add debug option for xpc.
+ * break.b always sets a debug trap number of 0 , so pass that to kdb as
+ well as the normal kdb traaps.
+ * kdb v4.4-2.6.15-ia64-2.
+
+2006-01-04 Keith Owens <kaos@sgi.com>
+
+ * Remove some inlines and the last vestige of CONFIG_NUMA_REPLICATE.
+ * Read the keyboard acknowledgment after sending a character. SuSE
+ Bugzilla 60240.
+ * kdb v4.4-2.6.15-ia64-1.
+
+2005-12-25 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.15-rc7-ia64-1.
+
+2005-12-20 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.15-rc6-ia64-1.
+
+2005-12-06 Keith Owens <kaos@sgi.com>
+
+ * Use RECOVERY flag in MCA handler.
+ * kdb v4.4-2.6.15-rc5-ia64-2.
+
+2005-12-05 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.15-rc5-ia64-1.
+
+2005-12-02 Keith Owens <kaos@sgi.com>
+
+ * Reinstate hook for debug trap, the patch chunk was accidentally
+ dropped in 2.6.15-rc1.
+ * kdb v4.4-2.6.15-rc4-ia64-1.
+
+2005-11-30 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.15-rc3-ia64-1.
+
+2005-11-21 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.15-rc2-ia64-1.
+
+2005-11-15 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.15-rc1-ia64-1.
+
+2005-10-28 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.14-ia64-1.
+
+2005-10-21 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.14-rc5-ia64-1.
+
+2005-10-11 Keith Owens <kaos@sgi.com>
+
+ * Handle removal of USB keyboard. Aaron Young, SGI
+ * kdb v4.4-2.6.14-rc4-ia64-1.
+
+2005-10-04 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.14-rc3-ia64-1.
+
+2005-09-21 Keith Owens <kaos@sgi.com>
+
+ * Support kdb_current_task in register display and modify commands.
+ * kdb v4.4-2.6.14-rc2-ia64-1.
+
+2005-09-20 Keith Owens <kaos@sgi.com>
+
+ * Coexist with kprobes.
+ * Coexist with MCA/INIT rewrite.
+ * Add KDB_ENTER_SLAVE to handle concurrent entry to kdb from multiple
+ cpus.
+ * Add handlers command to control whether the MCA/INIT task or the
+ original task is displayed.
+ * Namespace clean up, remove unused kdba_sw_interrupt.
+ * kdb v4.4-2.6.14-rc1-ia64-1.
+
+2005-08-29 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.13-ia64-1.
+
+2005-08-24 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.13-rc7-ia64-1.
+
+2005-08-08 Keith Owens <kaos@sgi.com>
+
+ * Add minstate command.
+ * kdb v4.4-2.6.13-rc6-ia64-1.
+
+2005-08-02 Keith Owens <kaos@sgi.com>
+
+ * Replace hard coded kdb declarations with #include <asm/sections>.
+ * kdb v4.4-2.6.13-rc5-ia64-1.
+
+2005-07-30 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.13-rc4-ia64-1.
+
+2005-07-22 Keith Owens <kaos@sgi.com>
+
+ * Handle INIT delivered while in physical mode.
+ * kdb v4.4-2.6.13-rc3-ia64-2.
+
+2005-07-19 Keith Owens <kaos@sgi.com>
+
+ * Add support for USB keyboard (OHCI only). Aaron Young, SGI.
+ * kdb v4.4-2.6.13-rc3-ia64-1.
+
+2005-07-08 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.13-rc2-ia64-1.
+
+2005-07-01 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.13-rc1-ia64-1.
+
+2005-06-18 Keith Owens <kaos@sgi.com>
+
+ * Standard IA64 code now works around break.b setting cr.iim to 0
+ instead of the break number. Remove the kdb workaround.
+ * kdb v4.4-2.6.12-ia64-1.
+
+2005-06-08 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.12-rc6-ia64-1.
+
+2005-05-25 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.12-rc5-ia64-1.
+
+2005-05-24 Keith Owens <kaos@sgi.com>
+
+ * break.b sets cr.iim to 0 instead of the break number. Deal with it.
+ * kdb v4.4-2.6.12-rc4-ia64-3.
+
+2005-05-14 Keith Owens <kaos@sgi.com>
+
+ * Correct MCA path after calling kdba_mca_bspstore_fixup().
+ Mark Larson, SGI.
+ * Tell the user that MCA/INIT is recoverable so kdb is not entered.
+ * kdb v4.4-2.6.12-rc4-ia64-2.
+
+2005-05-08 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.12-rc4-ia64-1.
+
+2005-04-21 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.12-rc3-ia64-1.
+
+2005-04-06 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.12-rc2-ia64-1.
+
+2005-04-04 Keith Owens <kaos@sgi.com>
+
+ * More tweaks to cope with invalid old bspstore in MCA handler.
+ * kdb v4.4-2.6.12-rc1-ia64-2.
+
+2005-03-29 Keith Owens <kaos@sgi.com>
+
+ * Replace __copy_to_user with __copy_to_user_inatomic.
+ * MCA handler, do not use old_bspstore if it is in region 4 or below.
+ * kdb v4.4-2.6.12-rc1-ia64-1.
+
+2005-03-08 Keith Owens <kaos@sgi.com>
+
+ * Coexistence patches for lkcd. Jason Uhlenkott, SGI.
+ * kdb v4.4-2.6.11-ia64-2.
+
+2005-03-03 Keith Owens <kaos@sgi.com>
+
+ * kdb-v4.4-2.6.11-ia64-1.
+
+2005-02-14 Keith Owens <kaos@sgi.com>
+
+ * kdb-v4.4-2.6.11-rc4-ia64-1.
+
+2005-02-08 Keith Owens <kaos@sgi.com>
+
+ * kdb-v4.4-2.6.11-rc3-bk4-ia64-1.
+
+2005-02-03 Keith Owens <kaos@sgi.com>
+
+ * kdb-v4.4-2.6.11-rc3-ia64-1.
+
+2005-01-27 Keith Owens <kaos@sgi.com>
+
+ * kdb-v4.4-2.6.11-rc2-ia64-1.
+
+2005-01-20 Keith Owens <kaos@sgi.com>
+
+ * MCA and INIT stacks moved to per-cpu area.
+ * kdb-v4.4-2.6.11-rc1-bk7-ia64-1.
+
+2005-01-12 Keith Owens <kaos@sgi.com>
+
+ * ia64_spinlock_contention_pre3_4_end is in base kernel, remove from kdb.
+ * Use last ditch allocator if unwind cannot allocate memory.
+ * kdb-v4.4-2.6.11-rc1-ia64-1.
+
+2004-12-25 Keith Owens <kaos@sgi.com>
+
+ * Add cpuinfo command.
+ * kdb-v4.4-2.6.10-ia64-1.
+
+2004-12-07 Keith Owens <kaos@sgi.com>
+
+ * Clean up error path in kdba_mca_init.
+ * kdb-v4.4-2.6.10-rc3-ia64-1.
+
+2004-11-15 Keith Owens <kaos@sgi.com>
+
+ * kdb-v4.4-2.6.10-rc2-ia64-1.
+
+2004-10-29 Keith Owens <kaos@sgi.com>
+
+ * kdb-v4.4-2.6.10-rc1-ia64-1.
+
+2004-10-19 Keith Owens <kaos@sgi.com>
+
+ * kdb-v4.4-2.6.9-ia64-1.
+
+2004-10-12 Keith Owens <kaos@sgi.com>
+
+ * kdb-v4.4-2.6.9-rc4-ia64-1.
+
+2004-10-01 Keith Owens <kaos@sgi.com>
+
+ * kdb-v4.4-2.6.9-rc3-ia64-1.
+
+2004-09-30 Keith Owens <kaos@sgi.com>
+
+ * Add stackdepth command.
+ * kdb-v4.4-2.6.9-rc2-ia64-3.
+
+2004-09-16 Keith Owens <kaos@sgi.com>
+
+ * Fixes for current in region 5 instead of 7 (idle task on cpu 0).
+ * kdb-v4.4-2.6.9-rc2-ia64-2.
+
+2004-09-14 Keith Owens <kaos@sgi.com>
+
+ * kdb-v4.4-2.6.9-rc2-ia64-1.
+
+2004-08-27 Keith Owens <kaos@sgi.com>
+
+ * kdb-v4.4-2.6.9-rc1-ia64-1.
+
+2004-08-14 Keith Owens <kaos@sgi.com>
+
+ * kdb-v4.4-2.6.8-ia64-1.
+
+2004-08-12 Keith Owens <kaos@sgi.com>
+
+ * kdb-v4.4-2.6.8-rc4-ia64-1.
+
+2004-08-04 Keith Owens <kaos@sgi.com>
+
+ * kdb-v4.4-2.6.8-rc3-ia64-1.
+
+2004-07-18 Keith Owens <kaos@sgi.com>
+
+ * New config name for SN serial console.
+ * kdb-v4.4-2.6.8-rc2-ia64-1.
+
+2004-07-12 Keith Owens <kaos@sgi.com>
+
+ * kdb-v4.4-2.6.8-rc1-ia64-1.
+
+2004-06-30 Keith Owens <kaos@sgi.com>
+
+ * kdb-v4.4-2.6.7-ia64-040629-1.
+
+2004-06-16 Keith Owens <kaos@sgi.com>
+
+ * Coexist with 2.6.7-ia64-040619.
+ * kdb-v4.4-2.6.7-ia64-040619-1.
+
+2004-06-16 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.7-ia64-1.
+
+2004-06-10 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.7-rc3-ia64-1.
+
+2004-06-09 Keith Owens <kaos@sgi.com>
+
+ * Namespace clean up. Mark code/variables as static when it is only
+ used in one file, delete dead code/variables.
+ * Saved interrupt state requires long, not int.
+ * kdb v4.4-2.6.7-rc2-ia64-3.
+
+2004-06-08 Keith Owens <kaos@sgi.com>
+
+ * Whitespace clean up, no code changes.
+ * kdb v4.4-2.6.7-rc2-2.
+
+2004-06-07 Keith Owens <kaos@sgi.com>
+
+ * Force KALLSYMS and KALLSYMS_ALL for CONFIG_KDB.
+ * kdb v4.4-2.6.7-rc2-1.
+
+2004-06-06 Keith Owens <kaos@sgi.com>
+
+ * Add standard archkdb commands.
+ * Move kdb_{get,put}userarea_size definitions to linux/kdb.h.
+ * kdb v4.4-2.6.6-ia64-040521-2.
+
+2004-05-25 Keith Owens <kaos@sgi.com>
+
+ * Update Kconfig text.
+ * kdb v4.4-2.6.6-ia64-040521-1.
+
+2004-05-23 Keith Owens <kaos@sgi.com>
+
+ * Move bfd.h and ansidecl.h from arch/$(ARCH)/kdb to include/asm-$(ARCH).
+ * ia64-opc.c needs kdbprivate.h after common reorganisation.
+ * Update copyright notices.
+ * kdb v4.4-2.6.6-ia64-1.
+
+2004-05-60 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.6.6-rc3-ia64-1.
+
+2004-05-60 Keith Owens <kaos@sgi.com>
+
+ * Tweak WAR for backtrace through contended spinlocks.
+ * kdb v4.3-2.6.6-rc2-ia64-1.
+
+2004-04-30 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.6.6-rc1-ia64-1.
+
+2004-04-15 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.6.5-ia64-040413-1.
+
+2004-03-06 Keith Owens <kaos@sgi.com>
+
+ * Use kdb_print for unwind debugging.
+ * kdb v4.3-2.6.4-rc2-ia64-1.
+
+2004-02-29 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.6.4-rc1-ia64-1.
+
+2004-02-18 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.6.3-ia64-1.
+
+2004-02-17 Keith Owens <kaos@sgi.com>
+
+ * Reconcile 2.6-test versions from Xavier Bru (Bull), Greg Banks (SGI),
+ Jim Houston (Concurrent Computer Corp).
+ * Reconcile with kdb v4.3-2.4.23-ia64-0312??-1.
+ * Reconcile with salinfo changes.
+ * Port WAR for backtrace from spinlock contention from 2.4 to 2.6.
+ * Merge PGS FIFO tweak with SERIAL_IO_MEM and concurrent support for
+ multiple consoles (no USB consoles yet).
+ * Update pt_regs output to match the order of struct pt_regs.
+ * KDB wrappers for interrupts handlers now return the handler's return code.
+ * tpa and tpav commands from Anonymous.
+ * Reconcile with mca changes.
+ * Upgrade to 2.6.3-rc3.
+ * kdb v4.3-2.6.3-rc3-ia64-1.
+
+2003-10-22 Xavier Bru <xavier.bru@bull.net>
+ * Merge to 2.6.0-test7
+2003-10-20 Philippe Garrigues <Philippe.Garrigues@bull.net>
+ * Enable FIFO in UART
+2003-09-08 Xavier Bru <xavier.bru@bull.net>
+ * Merge to 2.6.0-test4
+2003-03-21 Xavier Bru <xavier.bru@bull.net>
+ * Merge kdb v4.0 on 2.5.64 ia64
+ * new kernel parameters support
+ * new kallsyms support
+
+2003-10-24 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.4.23-pre8-cset-1.1069.1.143-to-1.1108-ia64-1.
+
+2003-10-03 Keith Owens <kaos@sgi.com>
+
+ * After MCA, copy the saved RSE registers from ia64_mca_bspstore to the
+ stack of the failing process.
+ * Abort backtrace when we hit IVT, no unwind data which confuses
+ unw_unwind().
+ * Workaround for backtrace through spinlock contention called from leaf
+ functions.
+ * kdb v4.3-2.4.22-ia64-030909-1.
+
+2003-07-20 Keith Owens <kaos@sgi.com>
+
+ * MCA rendezvous timeout affects kdb_wait_for_cpus_secs.
+ * Support SGI L1 console.
+ * kdb v4.3-2.4.21-ia64-030702-2.
+
+2003-07-08 Keith Owens <kaos@sgi.com>
+
+ * print_symbol() in mca.c does something useful when kdb is installed.
+ * Unwind and SAL changes removed from kdb, they are in the base kernel.
+ * kdb v4.3-2.4.21-ia64-030702-1.
+
+2003-06-20 Keith Owens <kaos@sgi.com>
+
+ * Add CONFIG_KDB_CONTINUE_CATASTROPHIC.
+ * Do not send IPI if the machine state does not require them.
+ * Correct definition of KDB_ENTER().
+ * Workaround for broken init monarch handler.
+ * Monarch cpu must get to kdb, even if it was interrupted in user space.
+ * Unwind fixes.
+ * Generalize ia64_spinlock_contention name.
+ * Add kdba_fru for SN machines.
+ * Correct test for cpu number.
+ * kdb v4.3-2.4.20-ia64-020821-1.
+
+2003-05-02 Keith Owens <kaos@sgi.com>
+
+ * Add kdba_fp_value().
+ * Limit backtrace size to catch loops.
+ * Print spinlock name in ia64_spinlock_contention.
+ * Tweak INIT slave stack lock and handler.
+ * Add read/write access to user pages. Vamsi Krishna S., IBM
+ * Rename cpu_is_online to cpu_online, as in 2.5.
+ * Clean up USB keyboard support.
+ * Clean up serial console support.
+ * kdb v4.2-2.4.20-ia64-020821-1.
+
+2003-04-04 Keith Owens <kaos@sgi.com>
+
+ * Add support for INIT slave interrupts.
+ * Tell SAL to always rendezvous on MCA.
+ * No lock on SAL rendezvous call.
+ * Include unwind.c from 2.4.21-pre5.
+ * Rename cpu_online to cpu_is_online.
+ * Workarounds for scheduler bugs.
+ * kdb v4.1-2.4.20-ia64-020821-1.
+
+2003-03-16 Keith Owens <kaos@sgi.com>
+
+ * Each cpu saves its state as it enters kdb or before it enters code
+ which cannot call kdb, converting kdb from a pull to a push model.
+ * Clean up kdb interaction with CONFIG_SERIAL_CONSOLE.
+ * Removal of special cases for i386 backtrace from common code
+ simplifies the architecture code.
+ * Add support for MCA events (both main and rendezvous) plus INIT
+ monarch event.
+ * Correct decode of brl.
+ * Move kdba_print_nameval to common code.
+ * Generalize kdba unwind handlers.
+ * Fix decode of sal records (fix included in later ia64 kernels).
+ * Handle multiple pt_regs in stack (fix included in later ia64 kernels).
+ * Clean up debug code in unwind (fix included in later ia64 kernels).
+ * Move kdb break numbers to their own file so it can be used in asm.
+ * kdb v4.0-2.4.20-ia64-021210-1.
+
+2003-02-03 Keith Owens <kaos@sgi.com>
+
+ * Register kdb commands early.
+ * Handle KDB_ENTER() when kdb=off.
+ * Optimize __kdba_getarea_size when width is a constant.
+ * Decode oops via kallsyms if it is available.
+ * Update copyright notices to 2003.
+ * Add commands to dump struct pt_regs and switch_stack.
+ * Handle padding from unw_init_running for switch_stack.
+ * Add dummy kdba_local_arch_setup/kdba_local_arch_cleanup.
+ * Warning for pod mode.
+ * Add command history and editing. Sonic Zhang.
+ * kdb_toggleled is conditional on KDB_BLINK_LED. Bernhard Fischer.
+ * Allow tab on serial line for symbol completion.
+ * Ignore KDB_ENTER() when kdb is already running.
+ * kdb v3.0-2.4.20-ia64-021210-1.
+
+2003-01-23 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.20-ia64-021210.
+ * kdb v2.5-2.4.20-ia64-021210-1.
+
+2002-11-14 Keith Owens <kaos@sgi.com>
+
+ * General clean up of handling for breakpoints and single stepping over
+ software breakpoints.
+ * kdb v2.5-2.4.19-ia64-020821-1.
+
+2002-10-31 Keith Owens <kaos@sgi.com>
+
+ * Remove kdb_eframe_t.
+ * Sanity check if we have pt_regs.
+ * Remove kdba_getcurrentframe().
+ * Comments for coexistence with O(1) scheduler.
+ * kdb v2.4-2.4.19-ia64-020821-1.
+
+2002-10-15 Keith Owens <kaos@sgi.com>
+
+ * Minimize differences between patches for 2.4 and 2.5 kernels.
+ * kdb v2.3-2.4.19-ia64-020821-2.
+
+2002-08-10 Keith Owens <kaos@sgi.com>
+
+ * Verify rw address for instruction breakpoint.
+ * Replace kdb_port with kdb_serial to support memory mapped I/O.
+ David Mosberger.
+ Note: This needs kdb v2.3-2.4.18-common-2 or later.
+ * kdb v2.3-2.4.18-ia64-020722-2.
+
+2002-08-07 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.18-ia64-020722.
+ * Remove individual SGI copyrights, the general SGI copyright applies.
+ * Clean up disassembly layout. Hugh Dickins, Keith Owens.
+ * Remove fixed KDB_MAX_COMMANDS size.
+ * Add set_fs() around __copy_to_user on kernel addresses.
+ Randolph Chung.
+ * Position ia64 for CONFIG_NUMA_REPLICATE.
+ * Stacked registers modification support. Sebastien Lelarge.
+ * USB keyboard support. Sebastien Lelarge.
+ * kdb v2.3-2.4.18-ia64-020722-1.
+
+2002-03-20 Keith Owens <kaos@sgi.com>
+
+ * Sync with 2.4.17-sn2.
+ * Add pod command.
+
+2002-02-20 Keith Owens <kaos@sgi.com>
+
+ * Call kdb from mca handler. Jenna S. Hall, Intel.
+ * kdb v2.1-2.4.17-ia64-011226-2.
+
+2002-01-18 Keith Owens <kaos@sgi.com>
+
+ * Replace kdb_get/putword with kdb_get/putarea functions.
+ * Wrap kdb references in #ifdef CONFIG_KDB.
+ * Delete sample i386 code.
+ * Refuse to update kernel text on NUMA systems.
+ * Reject hardware breakpoints, not supported yet.
+ * kdb v2.1-2.4.17-ia64-011226-1.
+
+2002-01-07 Keith Owens <kaos@sgi.com>
+
+ * Split kdb for ia64 as kdb v2.0-2.4.17-ia64-011226-1.
--- /dev/null
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+#
+
+obj-y := kdba_bt.o kdba_bp.o kdba_io.o kdbasupport.o \
+ cpu-ia64-opc.o ia64-dis.o ia64-opc.o kdba_id.o kdba_jmp.o
+
+# fru does not compile on 2.6.
+# obj-$(CONFIG_IA64_SGI_SN2) += kdba_fru.o
+obj-$(CONFIG_IA64_SGI_SN2) += kdba_pod.o
+obj-$(CONFIG_IA64_GENERIC) += kdba_pod.o
+
+override CFLAGS := $(CFLAGS:%-pg=% )
+
+AFLAGS_kdba_jmp.o += $(AFLAGS_KERNEL)
+
+USE_STANDARD_AS_RULE := true
--- /dev/null
+/* Copyright 1998, 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use.
+ * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as
+ * required.
+ * Keith Owens <kaos@sgi.com> 15 May 2006
+ */
+
+/* Logically, this code should be part of libopcode but since some of
+ the operand insertion/extraction functions help bfd to implement
+ relocations, this code is included as part of cpu-ia64.c. This
+ avoids circular dependencies between libopcode and libbfd and also
+ obviates the need for applications to link in libopcode when all
+ they really want is libbfd.
+
+ --davidm Mon Apr 13 22:14:02 1998 */
+
+#ifdef __KERNEL__
+#include "ia64-opc.h"
+#else /* __KERNEL__ */
+#include "../opcodes/ia64-opc.h"
+#endif /* __KERNEL__ */
+
+#define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
+
+static const char*
+ins_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED,
+ ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED)
+{
+ return "internal error---this shouldn't happen";
+}
+
+static const char*
+ext_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED,
+ ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED)
+{
+ return "internal error---this shouldn't happen";
+}
+
+static const char*
+ins_const (const struct ia64_operand *self ATTRIBUTE_UNUSED,
+ ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static const char*
+ext_const (const struct ia64_operand *self ATTRIBUTE_UNUSED,
+ ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static const char*
+ins_reg (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ if (value >= 1u << self->field[0].bits)
+ return "register number out of range";
+
+ *code |= value << self->field[0].shift;
+ return 0;
+}
+
+static const char*
+ext_reg (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ *valuep = ((code >> self->field[0].shift)
+ & ((1u << self->field[0].bits) - 1));
+ return 0;
+}
+
+static const char*
+ins_immu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ ia64_insn new = 0;
+ int i;
+
+ for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
+ {
+ new |= ((value & ((((ia64_insn) 1) << self->field[i].bits) - 1))
+ << self->field[i].shift);
+ value >>= self->field[i].bits;
+ }
+ if (value)
+ return "integer operand out of range";
+
+ *code |= new;
+ return 0;
+}
+
+static const char*
+ext_immu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ BFD_HOST_U_64_BIT value = 0;
+ int i, bits = 0, total = 0;
+
+ for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
+ {
+ bits = self->field[i].bits;
+ value |= ((code >> self->field[i].shift)
+ & ((((BFD_HOST_U_64_BIT) 1) << bits) - 1)) << total;
+ total += bits;
+ }
+ *valuep = value;
+ return 0;
+}
+
+static const char*
+ins_immus8 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ if (value & 0x7)
+ return "value not an integer multiple of 8";
+ return ins_immu (self, value >> 3, code);
+}
+
+static const char*
+ext_immus8 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ const char *result;
+
+ result = ext_immu (self, code, valuep);
+ if (result)
+ return result;
+
+ *valuep = *valuep << 3;
+ return 0;
+}
+
+static const char*
+ins_imms_scaled (const struct ia64_operand *self, ia64_insn value,
+ ia64_insn *code, int scale)
+{
+ BFD_HOST_64_BIT svalue = value, sign_bit = 0;
+ ia64_insn new = 0;
+ int i;
+
+ svalue >>= scale;
+
+ for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
+ {
+ new |= ((svalue & ((((ia64_insn) 1) << self->field[i].bits) - 1))
+ << self->field[i].shift);
+ sign_bit = (svalue >> (self->field[i].bits - 1)) & 1;
+ svalue >>= self->field[i].bits;
+ }
+ if ((!sign_bit && svalue != 0) || (sign_bit && svalue != -1))
+ return "integer operand out of range";
+
+ *code |= new;
+ return 0;
+}
+
+static const char*
+ext_imms_scaled (const struct ia64_operand *self, ia64_insn code,
+ ia64_insn *valuep, int scale)
+{
+ int i, bits = 0, total = 0;
+ BFD_HOST_64_BIT val = 0, sign;
+
+ for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
+ {
+ bits = self->field[i].bits;
+ val |= ((code >> self->field[i].shift)
+ & ((((BFD_HOST_U_64_BIT) 1) << bits) - 1)) << total;
+ total += bits;
+ }
+ /* sign extend: */
+ sign = (BFD_HOST_64_BIT) 1 << (total - 1);
+ val = (val ^ sign) - sign;
+
+ *valuep = (val << scale);
+ return 0;
+}
+
+static const char*
+ins_imms (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ return ins_imms_scaled (self, value, code, 0);
+}
+
+static const char*
+ins_immsu4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
+
+ return ins_imms_scaled (self, value, code, 0);
+}
+
+static const char*
+ext_imms (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ return ext_imms_scaled (self, code, valuep, 0);
+}
+
+static const char*
+ins_immsm1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ --value;
+ return ins_imms_scaled (self, value, code, 0);
+}
+
+static const char*
+ins_immsm1u4 (const struct ia64_operand *self, ia64_insn value,
+ ia64_insn *code)
+{
+ value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
+
+ --value;
+ return ins_imms_scaled (self, value, code, 0);
+}
+
+static const char*
+ext_immsm1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ const char *res = ext_imms_scaled (self, code, valuep, 0);
+
+ ++*valuep;
+ return res;
+}
+
+static const char*
+ins_imms1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ return ins_imms_scaled (self, value, code, 1);
+}
+
+static const char*
+ext_imms1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ return ext_imms_scaled (self, code, valuep, 1);
+}
+
+static const char*
+ins_imms4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ return ins_imms_scaled (self, value, code, 4);
+}
+
+static const char*
+ext_imms4 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ return ext_imms_scaled (self, code, valuep, 4);
+}
+
+static const char*
+ins_imms16 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ return ins_imms_scaled (self, value, code, 16);
+}
+
+static const char*
+ext_imms16 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ return ext_imms_scaled (self, code, valuep, 16);
+}
+
+static const char*
+ins_cimmu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ ia64_insn mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
+ return ins_immu (self, value ^ mask, code);
+}
+
+static const char*
+ext_cimmu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ const char *result;
+ ia64_insn mask;
+
+ mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
+ result = ext_immu (self, code, valuep);
+ if (!result)
+ {
+ mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
+ *valuep ^= mask;
+ }
+ return result;
+}
+
+static const char*
+ins_cnt (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ --value;
+ if (value >= ((BFD_HOST_U_64_BIT) 1) << self->field[0].bits)
+ return "count out of range";
+
+ *code |= value << self->field[0].shift;
+ return 0;
+}
+
+static const char*
+ext_cnt (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ *valuep = ((code >> self->field[0].shift)
+ & ((((BFD_HOST_U_64_BIT) 1) << self->field[0].bits) - 1)) + 1;
+ return 0;
+}
+
+static const char*
+ins_cnt2b (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ --value;
+
+ if (value > 2)
+ return "count must be in range 1..3";
+
+ *code |= value << self->field[0].shift;
+ return 0;
+}
+
+static const char*
+ext_cnt2b (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ *valuep = ((code >> self->field[0].shift) & 0x3) + 1;
+ return 0;
+}
+
+static const char*
+ins_cnt2c (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ switch (value)
+ {
+ case 0: value = 0; break;
+ case 7: value = 1; break;
+ case 15: value = 2; break;
+ case 16: value = 3; break;
+ default: return "count must be 0, 7, 15, or 16";
+ }
+ *code |= value << self->field[0].shift;
+ return 0;
+}
+
+static const char*
+ext_cnt2c (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ ia64_insn value;
+
+ value = (code >> self->field[0].shift) & 0x3;
+ switch (value)
+ {
+ case 0: value = 0; break;
+ case 1: value = 7; break;
+ case 2: value = 15; break;
+ case 3: value = 16; break;
+ }
+ *valuep = value;
+ return 0;
+}
+
+static const char*
+ins_inc3 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
+{
+ BFD_HOST_64_BIT val = value;
+ BFD_HOST_U_64_BIT sign = 0;
+
+ if (val < 0)
+ {
+ sign = 0x4;
+ value = -value;
+ }
+ switch (value)
+ {
+ case 1: value = 3; break;
+ case 4: value = 2; break;
+ case 8: value = 1; break;
+ case 16: value = 0; break;
+ default: return "count must be +/- 1, 4, 8, or 16";
+ }
+ *code |= (sign | value) << self->field[0].shift;
+ return 0;
+}
+
+static const char*
+ext_inc3 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
+{
+ BFD_HOST_64_BIT val;
+ int negate;
+
+ val = (code >> self->field[0].shift) & 0x7;
+ negate = val & 0x4;
+ switch (val & 0x3)
+ {
+ case 0: val = 16; break;
+ case 1: val = 8; break;
+ case 2: val = 4; break;
+ case 3: val = 1; break;
+ }
+ if (negate)
+ val = -val;
+
+ *valuep = val;
+ return 0;
+}
+
+#define CST IA64_OPND_CLASS_CST
+#define REG IA64_OPND_CLASS_REG
+#define IND IA64_OPND_CLASS_IND
+#define ABS IA64_OPND_CLASS_ABS
+#define REL IA64_OPND_CLASS_REL
+
+#define SDEC IA64_OPND_FLAG_DECIMAL_SIGNED
+#define UDEC IA64_OPND_FLAG_DECIMAL_UNSIGNED
+
+const struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT] =
+ {
+ /* constants: */
+ { CST, ins_const, ext_const, "NIL", {{ 0, 0}}, 0, "<none>" },
+ { CST, ins_const, ext_const, "ar.csd", {{ 0, 0}}, 0, "ar.csd" },
+ { CST, ins_const, ext_const, "ar.ccv", {{ 0, 0}}, 0, "ar.ccv" },
+ { CST, ins_const, ext_const, "ar.pfs", {{ 0, 0}}, 0, "ar.pfs" },
+ { CST, ins_const, ext_const, "1", {{ 0, 0}}, 0, "1" },
+ { CST, ins_const, ext_const, "8", {{ 0, 0}}, 0, "8" },
+ { CST, ins_const, ext_const, "16", {{ 0, 0}}, 0, "16" },
+ { CST, ins_const, ext_const, "r0", {{ 0, 0}}, 0, "r0" },
+ { CST, ins_const, ext_const, "ip", {{ 0, 0}}, 0, "ip" },
+ { CST, ins_const, ext_const, "pr", {{ 0, 0}}, 0, "pr" },
+ { CST, ins_const, ext_const, "pr.rot", {{ 0, 0}}, 0, "pr.rot" },
+ { CST, ins_const, ext_const, "psr", {{ 0, 0}}, 0, "psr" },
+ { CST, ins_const, ext_const, "psr.l", {{ 0, 0}}, 0, "psr.l" },
+ { CST, ins_const, ext_const, "psr.um", {{ 0, 0}}, 0, "psr.um" },
+
+ /* register operands: */
+ { REG, ins_reg, ext_reg, "ar", {{ 7, 20}}, 0, /* AR3 */
+ "an application register" },
+ { REG, ins_reg, ext_reg, "b", {{ 3, 6}}, 0, /* B1 */
+ "a branch register" },
+ { REG, ins_reg, ext_reg, "b", {{ 3, 13}}, 0, /* B2 */
+ "a branch register"},
+ { REG, ins_reg, ext_reg, "cr", {{ 7, 20}}, 0, /* CR */
+ "a control register"},
+ { REG, ins_reg, ext_reg, "f", {{ 7, 6}}, 0, /* F1 */
+ "a floating-point register" },
+ { REG, ins_reg, ext_reg, "f", {{ 7, 13}}, 0, /* F2 */
+ "a floating-point register" },
+ { REG, ins_reg, ext_reg, "f", {{ 7, 20}}, 0, /* F3 */
+ "a floating-point register" },
+ { REG, ins_reg, ext_reg, "f", {{ 7, 27}}, 0, /* F4 */
+ "a floating-point register" },
+ { REG, ins_reg, ext_reg, "p", {{ 6, 6}}, 0, /* P1 */
+ "a predicate register" },
+ { REG, ins_reg, ext_reg, "p", {{ 6, 27}}, 0, /* P2 */
+ "a predicate register" },
+ { REG, ins_reg, ext_reg, "r", {{ 7, 6}}, 0, /* R1 */
+ "a general register" },
+ { REG, ins_reg, ext_reg, "r", {{ 7, 13}}, 0, /* R2 */
+ "a general register" },
+ { REG, ins_reg, ext_reg, "r", {{ 7, 20}}, 0, /* R3 */
+ "a general register" },
+ { REG, ins_reg, ext_reg, "r", {{ 2, 20}}, 0, /* R3_2 */
+ "a general register r0-r3" },
+
+ /* indirect operands: */
+ { IND, ins_reg, ext_reg, "cpuid", {{7, 20}}, 0, /* CPUID_R3 */
+ "a cpuid register" },
+ { IND, ins_reg, ext_reg, "dbr", {{7, 20}}, 0, /* DBR_R3 */
+ "a dbr register" },
+ { IND, ins_reg, ext_reg, "dtr", {{7, 20}}, 0, /* DTR_R3 */
+ "a dtr register" },
+ { IND, ins_reg, ext_reg, "itr", {{7, 20}}, 0, /* ITR_R3 */
+ "an itr register" },
+ { IND, ins_reg, ext_reg, "ibr", {{7, 20}}, 0, /* IBR_R3 */
+ "an ibr register" },
+ { IND, ins_reg, ext_reg, "", {{7, 20}}, 0, /* MR3 */
+ "an indirect memory address" },
+ { IND, ins_reg, ext_reg, "msr", {{7, 20}}, 0, /* MSR_R3 */
+ "an msr register" },
+ { IND, ins_reg, ext_reg, "pkr", {{7, 20}}, 0, /* PKR_R3 */
+ "a pkr register" },
+ { IND, ins_reg, ext_reg, "pmc", {{7, 20}}, 0, /* PMC_R3 */
+ "a pmc register" },
+ { IND, ins_reg, ext_reg, "pmd", {{7, 20}}, 0, /* PMD_R3 */
+ "a pmd register" },
+ { IND, ins_reg, ext_reg, "rr", {{7, 20}}, 0, /* RR_R3 */
+ "an rr register" },
+
+ /* immediate operands: */
+ { ABS, ins_cimmu, ext_cimmu, 0, {{ 5, 20 }}, UDEC, /* CCNT5 */
+ "a 5-bit count (0-31)" },
+ { ABS, ins_cnt, ext_cnt, 0, {{ 2, 27 }}, UDEC, /* CNT2a */
+ "a 2-bit count (1-4)" },
+ { ABS, ins_cnt2b, ext_cnt2b, 0, {{ 2, 27 }}, UDEC, /* CNT2b */
+ "a 2-bit count (1-3)" },
+ { ABS, ins_cnt2c, ext_cnt2c, 0, {{ 2, 30 }}, UDEC, /* CNT2c */
+ "a count (0, 7, 15, or 16)" },
+ { ABS, ins_immu, ext_immu, 0, {{ 5, 14}}, UDEC, /* CNT5 */
+ "a 5-bit count (0-31)" },
+ { ABS, ins_immu, ext_immu, 0, {{ 6, 27}}, UDEC, /* CNT6 */
+ "a 6-bit count (0-63)" },
+ { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 20}}, UDEC, /* CPOS6a */
+ "a 6-bit bit pos (0-63)" },
+ { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 14}}, UDEC, /* CPOS6b */
+ "a 6-bit bit pos (0-63)" },
+ { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 31}}, UDEC, /* CPOS6c */
+ "a 6-bit bit pos (0-63)" },
+ { ABS, ins_imms, ext_imms, 0, {{ 1, 36}}, SDEC, /* IMM1 */
+ "a 1-bit integer (-1, 0)" },
+ { ABS, ins_immu, ext_immu, 0, {{ 2, 13}}, UDEC, /* IMMU2 */
+ "a 2-bit unsigned (0-3)" },
+ { ABS, ins_immu, ext_immu, 0, {{ 7, 13}}, 0, /* IMMU7a */
+ "a 7-bit unsigned (0-127)" },
+ { ABS, ins_immu, ext_immu, 0, {{ 7, 20}}, 0, /* IMMU7b */
+ "a 7-bit unsigned (0-127)" },
+ { ABS, ins_immu, ext_immu, 0, {{ 7, 13}}, UDEC, /* SOF */
+ "a frame size (register count)" },
+ { ABS, ins_immu, ext_immu, 0, {{ 7, 20}}, UDEC, /* SOL */
+ "a local register count" },
+ { ABS, ins_immus8,ext_immus8,0, {{ 4, 27}}, UDEC, /* SOR */
+ "a rotating register count (integer multiple of 8)" },
+ { ABS, ins_imms, ext_imms, 0, /* IMM8 */
+ {{ 7, 13}, { 1, 36}}, SDEC,
+ "an 8-bit integer (-128-127)" },
+ { ABS, ins_immsu4, ext_imms, 0, /* IMM8U4 */
+ {{ 7, 13}, { 1, 36}}, SDEC,
+ "an 8-bit signed integer for 32-bit unsigned compare (-128-127)" },
+ { ABS, ins_immsm1, ext_immsm1, 0, /* IMM8M1 */
+ {{ 7, 13}, { 1, 36}}, SDEC,
+ "an 8-bit integer (-127-128)" },
+ { ABS, ins_immsm1u4, ext_immsm1, 0, /* IMM8M1U4 */
+ {{ 7, 13}, { 1, 36}}, SDEC,
+ "an 8-bit integer for 32-bit unsigned compare (-127-(-1),1-128,0x100000000)" },
+ { ABS, ins_immsm1, ext_immsm1, 0, /* IMM8M1U8 */
+ {{ 7, 13}, { 1, 36}}, SDEC,
+ "an 8-bit integer for 64-bit unsigned compare (-127-(-1),1-128,0x10000000000000000)" },
+ { ABS, ins_immu, ext_immu, 0, {{ 2, 33}, { 7, 20}}, 0, /* IMMU9 */
+ "a 9-bit unsigned (0-511)" },
+ { ABS, ins_imms, ext_imms, 0, /* IMM9a */
+ {{ 7, 6}, { 1, 27}, { 1, 36}}, SDEC,
+ "a 9-bit integer (-256-255)" },
+ { ABS, ins_imms, ext_imms, 0, /* IMM9b */
+ {{ 7, 13}, { 1, 27}, { 1, 36}}, SDEC,
+ "a 9-bit integer (-256-255)" },
+ { ABS, ins_imms, ext_imms, 0, /* IMM14 */
+ {{ 7, 13}, { 6, 27}, { 1, 36}}, SDEC,
+ "a 14-bit integer (-8192-8191)" },
+ { ABS, ins_imms1, ext_imms1, 0, /* IMM17 */
+ {{ 7, 6}, { 8, 24}, { 1, 36}}, 0,
+ "a 17-bit integer (-65536-65535)" },
+ { ABS, ins_immu, ext_immu, 0, {{20, 6}, { 1, 36}}, 0, /* IMMU21 */
+ "a 21-bit unsigned" },
+ { ABS, ins_imms, ext_imms, 0, /* IMM22 */
+ {{ 7, 13}, { 9, 27}, { 5, 22}, { 1, 36}}, SDEC,
+ "a 22-bit signed integer" },
+ { ABS, ins_immu, ext_immu, 0, /* IMMU24 */
+ {{21, 6}, { 2, 31}, { 1, 36}}, 0,
+ "a 24-bit unsigned" },
+ { ABS, ins_imms16,ext_imms16,0, {{27, 6}, { 1, 36}}, 0, /* IMM44 */
+ "a 44-bit unsigned (least 16 bits ignored/zeroes)" },
+ { ABS, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0, /* IMMU62 */
+ "a 62-bit unsigned" },
+ { ABS, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0, /* IMMU64 */
+ "a 64-bit unsigned" },
+ { ABS, ins_inc3, ext_inc3, 0, {{ 3, 13}}, SDEC, /* INC3 */
+ "an increment (+/- 1, 4, 8, or 16)" },
+ { ABS, ins_cnt, ext_cnt, 0, {{ 4, 27}}, UDEC, /* LEN4 */
+ "a 4-bit length (1-16)" },
+ { ABS, ins_cnt, ext_cnt, 0, {{ 6, 27}}, UDEC, /* LEN6 */
+ "a 6-bit length (1-64)" },
+ { ABS, ins_immu, ext_immu, 0, {{ 4, 20}}, 0, /* MBTYPE4 */
+ "a mix type (@rev, @mix, @shuf, @alt, or @brcst)" },
+ { ABS, ins_immu, ext_immu, 0, {{ 8, 20}}, 0, /* MBTYPE8 */
+ "an 8-bit mix type" },
+ { ABS, ins_immu, ext_immu, 0, {{ 6, 14}}, UDEC, /* POS6 */
+ "a 6-bit bit pos (0-63)" },
+ { REL, ins_imms4, ext_imms4, 0, {{ 7, 6}, { 2, 33}}, 0, /* TAG13 */
+ "a branch tag" },
+ { REL, ins_imms4, ext_imms4, 0, {{ 9, 24}}, 0, /* TAG13b */
+ "a branch tag" },
+ { REL, ins_imms4, ext_imms4, 0, {{20, 6}, { 1, 36}}, 0, /* TGT25 */
+ "a branch target" },
+ { REL, ins_imms4, ext_imms4, 0, /* TGT25b */
+ {{ 7, 6}, {13, 20}, { 1, 36}}, 0,
+ "a branch target" },
+ { REL, ins_imms4, ext_imms4, 0, {{20, 13}, { 1, 36}}, 0, /* TGT25c */
+ "a branch target" },
+ { REL, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0, /* TGT64 */
+ "a branch target" },
+
+ { ABS, ins_const, ext_const, 0, {{0, 0}}, 0, /* LDXMOV */
+ "ldxmov target" },
+ };
--- /dev/null
+/* This file is automatically generated by ia64-gen. Do not edit! */
+
+/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use.
+ * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as
+ * required.
+ * Keith Owens <kaos@sgi.com> 15 May 2006
+ */
+
+static const char * const ia64_strings[] = {
+ "", "0", "1", "a", "acq", "add", "addl", "addp4", "adds", "alloc", "and",
+ "andcm", "b", "bias", "br", "break", "brl", "brp", "bsw", "c", "call",
+ "cexit", "chk", "cloop", "clr", "clrrrb", "cmp", "cmp4", "cmp8xchg16",
+ "cmpxchg1", "cmpxchg2", "cmpxchg4", "cmpxchg8", "cond", "cover", "ctop",
+ "czx1", "czx2", "d", "dep", "dpnt", "dptk", "e", "epc", "eq", "excl",
+ "exit", "exp", "extr", "f", "fabs", "fadd", "famax", "famin", "fand",
+ "fandcm", "fault", "fc", "fchkf", "fclass", "fclrf", "fcmp", "fcvt",
+ "fetchadd4", "fetchadd8", "few", "fill", "flushrs", "fma", "fmax",
+ "fmerge", "fmin", "fmix", "fmpy", "fms", "fneg", "fnegabs", "fnma",
+ "fnmpy", "fnorm", "for", "fpabs", "fpack", "fpamax", "fpamin", "fpcmp",
+ "fpcvt", "fpma", "fpmax", "fpmerge", "fpmin", "fpmpy", "fpms", "fpneg",
+ "fpnegabs", "fpnma", "fpnmpy", "fprcpa", "fprsqrta", "frcpa", "frsqrta",
+ "fselect", "fsetc", "fsub", "fswap", "fsxt", "fwb", "fx", "fxor", "fxu",
+ "g", "ga", "ge", "getf", "geu", "gt", "gtu", "h", "hint", "hu", "i", "ia",
+ "imp", "invala", "itc", "itr", "l", "ld1", "ld16", "ld2", "ld4", "ld8",
+ "ldf", "ldf8", "ldfd", "ldfe", "ldfp8", "ldfpd", "ldfps", "ldfs", "le",
+ "leu", "lfetch", "loadrs", "loop", "lr", "lt", "ltu", "lu", "m", "many",
+ "mf", "mix1", "mix2", "mix4", "mov", "movl", "mux1", "mux2", "nc", "ne",
+ "neq", "nge", "ngt", "nl", "nle", "nlt", "nm", "nop", "nr", "ns", "nt1",
+ "nt2", "nta", "nz", "or", "orcm", "ord", "pack2", "pack4", "padd1",
+ "padd2", "padd4", "pavg1", "pavg2", "pavgsub1", "pavgsub2", "pcmp1",
+ "pcmp2", "pcmp4", "pmax1", "pmax2", "pmin1", "pmin2", "pmpy2", "pmpyshr2",
+ "popcnt", "pr", "probe", "psad1", "pshl2", "pshl4", "pshladd2", "pshr2",
+ "pshr4", "pshradd2", "psub1", "psub2", "psub4", "ptc", "ptr", "r", "raz",
+ "rel", "ret", "rfi", "rsm", "rum", "rw", "s", "s0", "s1", "s2", "s3",
+ "sa", "se", "setf", "shl", "shladd", "shladdp4", "shr", "shrp", "sig",
+ "spill", "spnt", "sptk", "srlz", "ssm", "sss", "st1", "st16", "st2",
+ "st4", "st8", "stf", "stf8", "stfd", "stfe", "stfs", "sub", "sum", "sxt1",
+ "sxt2", "sxt4", "sync", "tak", "tbit", "thash", "tnat", "tpa", "trunc",
+ "ttag", "u", "unc", "unord", "unpack1", "unpack2", "unpack4", "uss",
+ "uus", "uuu", "w", "wexit", "wtop", "x", "xchg1", "xchg2", "xchg4",
+ "xchg8", "xf", "xma", "xmpy", "xor", "xuf", "z", "zxt1", "zxt2", "zxt4",
+};
+
+static const struct ia64_dependency
+dependencies[] = {
+ { "ALAT", 0, 0, 0, -1, NULL, },
+ { "AR[BSP]", 26, 0, 2, 17, NULL, },
+ { "AR[BSPSTORE]", 26, 0, 2, 18, NULL, },
+ { "AR[CFLG]", 26, 0, 2, 27, NULL, },
+ { "AR[CCV]", 26, 0, 2, 32, NULL, },
+ { "AR[CSD]", 26, 0, 2, 25, NULL, },
+ { "AR[EC]", 26, 0, 2, 66, NULL, },
+ { "AR[EFLAG]", 26, 0, 2, 24, NULL, },
+ { "AR[FCR]", 26, 0, 2, 21, NULL, },
+ { "AR[FDR]", 26, 0, 2, 30, NULL, },
+ { "AR[FIR]", 26, 0, 2, 29, NULL, },
+ { "AR[FPSR].sf0.controls", 30, 0, 2, -1, NULL, },
+ { "AR[FPSR].sf1.controls", 30, 0, 2, -1, NULL, },
+ { "AR[FPSR].sf2.controls", 30, 0, 2, -1, NULL, },
+ { "AR[FPSR].sf3.controls", 30, 0, 2, -1, NULL, },
+ { "AR[FPSR].sf0.flags", 30, 0, 2, -1, NULL, },
+ { "AR[FPSR].sf1.flags", 30, 0, 2, -1, NULL, },
+ { "AR[FPSR].sf2.flags", 30, 0, 2, -1, NULL, },
+ { "AR[FPSR].sf3.flags", 30, 0, 2, -1, NULL, },
+ { "AR[FPSR].traps", 30, 0, 2, -1, NULL, },
+ { "AR[FPSR].rv", 30, 0, 2, -1, NULL, },
+ { "AR[FSR]", 26, 0, 2, 28, NULL, },
+ { "AR[ITC]", 26, 0, 2, 44, NULL, },
+ { "AR[K%], % in 0 - 7", 1, 0, 2, -1, NULL, },
+ { "AR[LC]", 26, 0, 2, 65, NULL, },
+ { "AR[PFS]", 26, 0, 2, 64, NULL, },
+ { "AR[PFS]", 26, 0, 2, 64, NULL, },
+ { "AR[PFS]", 26, 0, 0, 64, NULL, },
+ { "AR[RNAT]", 26, 0, 2, 19, NULL, },
+ { "AR[RSC]", 26, 0, 2, 16, NULL, },
+ { "AR[SSD]", 26, 0, 2, 26, NULL, },
+ { "AR[UNAT]{%}, % in 0 - 63", 2, 0, 2, -1, NULL, },
+ { "AR%, % in 8-15, 20, 22-23, 31, 33-35, 37-39, 41-43, 45-47, 67-111", 3, 0, 0, -1, NULL, },
+ { "AR%, % in 48-63, 112-127", 4, 0, 2, -1, NULL, },
+ { "BR%, % in 0 - 7", 5, 0, 2, -1, NULL, },
+ { "BR%, % in 0 - 7", 5, 0, 0, -1, NULL, },
+ { "BR%, % in 0 - 7", 5, 0, 2, -1, NULL, },
+ { "CFM", 6, 0, 2, -1, NULL, },
+ { "CFM", 6, 0, 2, -1, NULL, },
+ { "CFM", 6, 0, 2, -1, NULL, },
+ { "CFM", 6, 0, 2, -1, NULL, },
+ { "CFM", 6, 0, 0, -1, NULL, },
+ { "CPUID#", 7, 0, 5, -1, NULL, },
+ { "CR[CMCV]", 27, 0, 3, 74, NULL, },
+ { "CR[DCR]", 27, 0, 3, 0, NULL, },
+ { "CR[EOI]", 27, 0, 7, 67, "SC Section 10.8.3.4", },
+ { "CR[GPTA]", 27, 0, 3, 9, NULL, },
+ { "CR[IFA]", 27, 0, 1, 20, NULL, },
+ { "CR[IFA]", 27, 0, 3, 20, NULL, },
+ { "CR[IFS]", 27, 0, 3, 23, NULL, },
+ { "CR[IFS]", 27, 0, 1, 23, NULL, },
+ { "CR[IFS]", 27, 0, 1, 23, NULL, },
+ { "CR[IHA]", 27, 0, 3, 25, NULL, },
+ { "CR[IIM]", 27, 0, 3, 24, NULL, },
+ { "CR[IIP]", 27, 0, 3, 19, NULL, },
+ { "CR[IIP]", 27, 0, 1, 19, NULL, },
+ { "CR[IIPA]", 27, 0, 3, 22, NULL, },
+ { "CR[IPSR]", 27, 0, 3, 16, NULL, },
+ { "CR[IPSR]", 27, 0, 1, 16, NULL, },
+ { "CR[IRR%], % in 0 - 3", 8, 0, 3, -1, NULL, },
+ { "CR[ISR]", 27, 0, 3, 17, NULL, },
+ { "CR[ITIR]", 27, 0, 3, 21, NULL, },
+ { "CR[ITIR]", 27, 0, 1, 21, NULL, },
+ { "CR[ITM]", 27, 0, 3, 1, NULL, },
+ { "CR[ITV]", 27, 0, 3, 72, NULL, },
+ { "CR[IVA]", 27, 0, 4, 2, NULL, },
+ { "CR[IVR]", 27, 0, 7, 65, "SC Section 10.8.3.2", },
+ { "CR[LID]", 27, 0, 7, 64, "SC Section 10.8.3.1", },
+ { "CR[LRR%], % in 0 - 1", 9, 0, 3, -1, NULL, },
+ { "CR[PMV]", 27, 0, 3, 73, NULL, },
+ { "CR[PTA]", 27, 0, 3, 8, NULL, },
+ { "CR[TPR]", 27, 0, 3, 66, NULL, },
+ { "CR[TPR]", 27, 0, 7, 66, "SC Section 10.8.3.3", },
+ { "CR%, % in 3-7, 10-15, 18, 26-63, 75-79, 82-127", 10, 0, 0, -1, NULL, },
+ { "DBR#", 11, 0, 2, -1, NULL, },
+ { "DBR#", 11, 0, 3, -1, NULL, },
+ { "DTC", 0, 0, 3, -1, NULL, },
+ { "DTC", 0, 0, 2, -1, NULL, },
+ { "DTC", 0, 0, 0, -1, NULL, },
+ { "DTC", 0, 0, 2, -1, NULL, },
+ { "DTC_LIMIT*", 0, 0, 2, -1, NULL, },
+ { "DTR", 0, 0, 3, -1, NULL, },
+ { "DTR", 0, 0, 2, -1, NULL, },
+ { "DTR", 0, 0, 3, -1, NULL, },
+ { "DTR", 0, 0, 0, -1, NULL, },
+ { "DTR", 0, 0, 2, -1, NULL, },
+ { "FR%, % in 0 - 1", 12, 0, 0, -1, NULL, },
+ { "FR%, % in 2 - 127", 13, 0, 2, -1, NULL, },
+ { "FR%, % in 2 - 127", 13, 0, 0, -1, NULL, },
+ { "GR0", 14, 0, 0, -1, NULL, },
+ { "GR%, % in 1 - 127", 15, 0, 0, -1, NULL, },
+ { "GR%, % in 1 - 127", 15, 0, 2, -1, NULL, },
+ { "IBR#", 16, 0, 2, -1, NULL, },
+ { "InService*", 17, 0, 3, -1, NULL, },
+ { "InService*", 17, 0, 2, -1, NULL, },
+ { "InService*", 17, 0, 2, -1, NULL, },
+ { "IP", 0, 0, 0, -1, NULL, },
+ { "ITC", 0, 0, 4, -1, NULL, },
+ { "ITC", 0, 0, 2, -1, NULL, },
+ { "ITC", 0, 0, 0, -1, NULL, },
+ { "ITC", 0, 0, 4, -1, NULL, },
+ { "ITC", 0, 0, 2, -1, NULL, },
+ { "ITC_LIMIT*", 0, 0, 2, -1, NULL, },
+ { "ITR", 0, 0, 2, -1, NULL, },
+ { "ITR", 0, 0, 4, -1, NULL, },
+ { "ITR", 0, 0, 2, -1, NULL, },
+ { "ITR", 0, 0, 0, -1, NULL, },
+ { "ITR", 0, 0, 4, -1, NULL, },
+ { "memory", 0, 0, 0, -1, NULL, },
+ { "MSR#", 18, 0, 5, -1, NULL, },
+ { "PKR#", 19, 0, 3, -1, NULL, },
+ { "PKR#", 19, 0, 0, -1, NULL, },
+ { "PKR#", 19, 0, 2, -1, NULL, },
+ { "PKR#", 19, 0, 2, -1, NULL, },
+ { "PMC#", 20, 0, 2, -1, NULL, },
+ { "PMC#", 20, 0, 7, -1, "SC+3 Section 12.1.1", },
+ { "PMD#", 21, 0, 2, -1, NULL, },
+ { "PR0", 0, 0, 0, -1, NULL, },
+ { "PR%, % in 1 - 15", 22, 0, 2, -1, NULL, },
+ { "PR%, % in 1 - 15", 22, 0, 2, -1, NULL, },
+ { "PR%, % in 1 - 15", 22, 0, 0, -1, NULL, },
+ { "PR%, % in 16 - 62", 23, 0, 2, -1, NULL, },
+ { "PR%, % in 16 - 62", 23, 0, 2, -1, NULL, },
+ { "PR%, % in 16 - 62", 23, 0, 0, -1, NULL, },
+ { "PR63", 24, 0, 2, -1, NULL, },
+ { "PR63", 24, 0, 2, -1, NULL, },
+ { "PR63", 24, 0, 0, -1, NULL, },
+ { "PSR.ac", 28, 0, 1, 3, NULL, },
+ { "PSR.ac", 28, 0, 3, 3, NULL, },
+ { "PSR.ac", 28, 0, 2, 3, NULL, },
+ { "PSR.be", 28, 0, 1, 1, NULL, },
+ { "PSR.be", 28, 0, 3, 1, NULL, },
+ { "PSR.be", 28, 0, 2, 1, NULL, },
+ { "PSR.bn", 28, 0, 2, 44, NULL, },
+ { "PSR.cpl", 28, 0, 1, 32, NULL, },
+ { "PSR.da", 28, 0, 3, 38, NULL, },
+ { "PSR.db", 28, 0, 3, 24, NULL, },
+ { "PSR.db", 28, 0, 2, 24, NULL, },
+ { "PSR.db", 28, 0, 3, 24, NULL, },
+ { "PSR.dd", 28, 0, 3, 39, NULL, },
+ { "PSR.dfh", 28, 0, 3, 19, NULL, },
+ { "PSR.dfh", 28, 0, 2, 19, NULL, },
+ { "PSR.dfl", 28, 0, 3, 18, NULL, },
+ { "PSR.dfl", 28, 0, 2, 18, NULL, },
+ { "PSR.di", 28, 0, 3, 22, NULL, },
+ { "PSR.di", 28, 0, 2, 22, NULL, },
+ { "PSR.dt", 28, 0, 3, 17, NULL, },
+ { "PSR.dt", 28, 0, 2, 17, NULL, },
+ { "PSR.ed", 28, 0, 3, 43, NULL, },
+ { "PSR.i", 28, 0, 2, 14, NULL, },
+ { "PSR.i", 28, 0, 3, 14, NULL, },
+ { "PSR.ia", 28, 0, 0, 14, NULL, },
+ { "PSR.ic", 28, 0, 2, 13, NULL, },
+ { "PSR.ic", 28, 0, 3, 13, NULL, },
+ { "PSR.id", 28, 0, 0, 14, NULL, },
+ { "PSR.is", 28, 0, 0, 14, NULL, },
+ { "PSR.it", 28, 0, 3, 14, NULL, },
+ { "PSR.lp", 28, 0, 2, 25, NULL, },
+ { "PSR.lp", 28, 0, 3, 25, NULL, },
+ { "PSR.lp", 28, 0, 3, 25, NULL, },
+ { "PSR.mc", 28, 0, 0, 35, NULL, },
+ { "PSR.mfh", 28, 0, 2, 5, NULL, },
+ { "PSR.mfl", 28, 0, 2, 4, NULL, },
+ { "PSR.pk", 28, 0, 3, 15, NULL, },
+ { "PSR.pk", 28, 0, 2, 15, NULL, },
+ { "PSR.pp", 28, 0, 2, 21, NULL, },
+ { "PSR.ri", 28, 0, 0, 41, NULL, },
+ { "PSR.rt", 28, 0, 2, 27, NULL, },
+ { "PSR.rt", 28, 0, 3, 27, NULL, },
+ { "PSR.rt", 28, 0, 3, 27, NULL, },
+ { "PSR.si", 28, 0, 2, 23, NULL, },
+ { "PSR.si", 28, 0, 3, 23, NULL, },
+ { "PSR.sp", 28, 0, 2, 20, NULL, },
+ { "PSR.sp", 28, 0, 3, 20, NULL, },
+ { "PSR.ss", 28, 0, 3, 40, NULL, },
+ { "PSR.tb", 28, 0, 3, 26, NULL, },
+ { "PSR.tb", 28, 0, 2, 26, NULL, },
+ { "PSR.up", 28, 0, 2, 2, NULL, },
+ { "RR#", 25, 0, 3, -1, NULL, },
+ { "RR#", 25, 0, 2, -1, NULL, },
+ { "RSE", 29, 0, 2, -1, NULL, },
+ { "ALAT", 0, 1, 0, -1, NULL, },
+ { "AR[BSP]", 26, 1, 2, 17, NULL, },
+ { "AR[BSPSTORE]", 26, 1, 2, 18, NULL, },
+ { "AR[CCV]", 26, 1, 2, 32, NULL, },
+ { "AR[CFLG]", 26, 1, 2, 27, NULL, },
+ { "AR[CSD]", 26, 1, 2, 25, NULL, },
+ { "AR[EC]", 26, 1, 2, 66, NULL, },
+ { "AR[EFLAG]", 26, 1, 2, 24, NULL, },
+ { "AR[FCR]", 26, 1, 2, 21, NULL, },
+ { "AR[FDR]", 26, 1, 2, 30, NULL, },
+ { "AR[FIR]", 26, 1, 2, 29, NULL, },
+ { "AR[FPSR].sf0.controls", 30, 1, 2, -1, NULL, },
+ { "AR[FPSR].sf1.controls", 30, 1, 2, -1, NULL, },
+ { "AR[FPSR].sf2.controls", 30, 1, 2, -1, NULL, },
+ { "AR[FPSR].sf3.controls", 30, 1, 2, -1, NULL, },
+ { "AR[FPSR].sf0.flags", 30, 1, 0, -1, NULL, },
+ { "AR[FPSR].sf0.flags", 30, 1, 2, -1, NULL, },
+ { "AR[FPSR].sf0.flags", 30, 1, 2, -1, NULL, },
+ { "AR[FPSR].sf1.flags", 30, 1, 0, -1, NULL, },
+ { "AR[FPSR].sf1.flags", 30, 1, 2, -1, NULL, },
+ { "AR[FPSR].sf1.flags", 30, 1, 2, -1, NULL, },
+ { "AR[FPSR].sf2.flags", 30, 1, 0, -1, NULL, },
+ { "AR[FPSR].sf2.flags", 30, 1, 2, -1, NULL, },
+ { "AR[FPSR].sf2.flags", 30, 1, 2, -1, NULL, },
+ { "AR[FPSR].sf3.flags", 30, 1, 0, -1, NULL, },
+ { "AR[FPSR].sf3.flags", 30, 1, 2, -1, NULL, },
+ { "AR[FPSR].sf3.flags", 30, 1, 2, -1, NULL, },
+ { "AR[FPSR].rv", 30, 1, 2, -1, NULL, },
+ { "AR[FPSR].traps", 30, 1, 2, -1, NULL, },
+ { "AR[FSR]", 26, 1, 2, 28, NULL, },
+ { "AR[ITC]", 26, 1, 2, 44, NULL, },
+ { "AR[K%], % in 0 - 7", 1, 1, 2, -1, NULL, },
+ { "AR[LC]", 26, 1, 2, 65, NULL, },
+ { "AR[PFS]", 26, 1, 0, 64, NULL, },
+ { "AR[PFS]", 26, 1, 2, 64, NULL, },
+ { "AR[PFS]", 26, 1, 2, 64, NULL, },
+ { "AR[RNAT]", 26, 1, 2, 19, NULL, },
+ { "AR[RSC]", 26, 1, 2, 16, NULL, },
+ { "AR[UNAT]{%}, % in 0 - 63", 2, 1, 2, -1, NULL, },
+ { "AR%, % in 8-15, 20, 22-23, 31, 33-35, 37-39, 41-43, 45-47, 67-111", 3, 1, 0, -1, NULL, },
+ { "AR%, % in 48 - 63, 112-127", 4, 1, 2, -1, NULL, },
+ { "BR%, % in 0 - 7", 5, 1, 2, -1, NULL, },
+ { "BR%, % in 0 - 7", 5, 1, 2, -1, NULL, },
+ { "BR%, % in 0 - 7", 5, 1, 2, -1, NULL, },
+ { "BR%, % in 0 - 7", 5, 1, 0, -1, NULL, },
+ { "CFM", 6, 1, 2, -1, NULL, },
+ { "CPUID#", 7, 1, 0, -1, NULL, },
+ { "CR[CMCV]", 27, 1, 2, 74, NULL, },
+ { "CR[DCR]", 27, 1, 2, 0, NULL, },
+ { "CR[EOI]", 27, 1, 7, 67, "SC Section 10.8.3.4", },
+ { "CR[GPTA]", 27, 1, 2, 9, NULL, },
+ { "CR[IFA]", 27, 1, 2, 20, NULL, },
+ { "CR[IFS]", 27, 1, 2, 23, NULL, },
+ { "CR[IHA]", 27, 1, 2, 25, NULL, },
+ { "CR[IIM]", 27, 1, 2, 24, NULL, },
+ { "CR[IIP]", 27, 1, 2, 19, NULL, },
+ { "CR[IIPA]", 27, 1, 2, 22, NULL, },
+ { "CR[IPSR]", 27, 1, 2, 16, NULL, },
+ { "CR[IRR%], % in 0 - 3", 8, 1, 2, -1, NULL, },
+ { "CR[ISR]", 27, 1, 2, 17, NULL, },
+ { "CR[ITIR]", 27, 1, 2, 21, NULL, },
+ { "CR[ITM]", 27, 1, 2, 1, NULL, },
+ { "CR[ITV]", 27, 1, 2, 72, NULL, },
+ { "CR[IVA]", 27, 1, 2, 2, NULL, },
+ { "CR[IVR]", 27, 1, 7, 65, "SC", },
+ { "CR[LID]", 27, 1, 7, 64, "SC", },
+ { "CR[LRR%], % in 0 - 1", 9, 1, 2, -1, NULL, },
+ { "CR[PMV]", 27, 1, 2, 73, NULL, },
+ { "CR[PTA]", 27, 1, 2, 8, NULL, },
+ { "CR[TPR]", 27, 1, 2, 66, NULL, },
+ { "CR%, % in 3-7, 10-15, 18, 26-63, 75-79, 82-127", 10, 1, 0, -1, NULL, },
+ { "DBR#", 11, 1, 2, -1, NULL, },
+ { "DTC", 0, 1, 0, -1, NULL, },
+ { "DTC", 0, 1, 2, -1, NULL, },
+ { "DTC", 0, 1, 2, -1, NULL, },
+ { "DTC_LIMIT*", 0, 1, 2, -1, NULL, },
+ { "DTR", 0, 1, 2, -1, NULL, },
+ { "DTR", 0, 1, 2, -1, NULL, },
+ { "DTR", 0, 1, 2, -1, NULL, },
+ { "DTR", 0, 1, 0, -1, NULL, },
+ { "FR%, % in 0 - 1", 12, 1, 0, -1, NULL, },
+ { "FR%, % in 2 - 127", 13, 1, 2, -1, NULL, },
+ { "GR0", 14, 1, 0, -1, NULL, },
+ { "GR%, % in 1 - 127", 15, 1, 2, -1, NULL, },
+ { "IBR#", 16, 1, 2, -1, NULL, },
+ { "InService*", 17, 1, 7, -1, "SC", },
+ { "IP", 0, 1, 0, -1, NULL, },
+ { "ITC", 0, 1, 0, -1, NULL, },
+ { "ITC", 0, 1, 2, -1, NULL, },
+ { "ITC", 0, 1, 2, -1, NULL, },
+ { "ITR", 0, 1, 2, -1, NULL, },
+ { "ITR", 0, 1, 2, -1, NULL, },
+ { "ITR", 0, 1, 0, -1, NULL, },
+ { "memory", 0, 1, 0, -1, NULL, },
+ { "MSR#", 18, 1, 7, -1, "SC", },
+ { "PKR#", 19, 1, 0, -1, NULL, },
+ { "PKR#", 19, 1, 0, -1, NULL, },
+ { "PKR#", 19, 1, 2, -1, NULL, },
+ { "PMC#", 20, 1, 2, -1, NULL, },
+ { "PMD#", 21, 1, 2, -1, NULL, },
+ { "PR0", 0, 1, 0, -1, NULL, },
+ { "PR%, % in 1 - 15", 22, 1, 0, -1, NULL, },
+ { "PR%, % in 1 - 15", 22, 1, 0, -1, NULL, },
+ { "PR%, % in 1 - 15", 22, 1, 2, -1, NULL, },
+ { "PR%, % in 1 - 15", 22, 1, 2, -1, NULL, },
+ { "PR%, % in 16 - 62", 23, 1, 0, -1, NULL, },
+ { "PR%, % in 16 - 62", 23, 1, 0, -1, NULL, },
+ { "PR%, % in 16 - 62", 23, 1, 2, -1, NULL, },
+ { "PR%, % in 16 - 62", 23, 1, 2, -1, NULL, },
+ { "PR63", 24, 1, 0, -1, NULL, },
+ { "PR63", 24, 1, 0, -1, NULL, },
+ { "PR63", 24, 1, 2, -1, NULL, },
+ { "PR63", 24, 1, 2, -1, NULL, },
+ { "PSR.ac", 28, 1, 2, 3, NULL, },
+ { "PSR.be", 28, 1, 2, 1, NULL, },
+ { "PSR.bn", 28, 1, 2, 44, NULL, },
+ { "PSR.cpl", 28, 1, 2, 32, NULL, },
+ { "PSR.da", 28, 1, 2, 38, NULL, },
+ { "PSR.db", 28, 1, 2, 24, NULL, },
+ { "PSR.dd", 28, 1, 2, 39, NULL, },
+ { "PSR.dfh", 28, 1, 2, 19, NULL, },
+ { "PSR.dfl", 28, 1, 2, 18, NULL, },
+ { "PSR.di", 28, 1, 2, 22, NULL, },
+ { "PSR.dt", 28, 1, 2, 17, NULL, },
+ { "PSR.ed", 28, 1, 2, 43, NULL, },
+ { "PSR.i", 28, 1, 2, 14, NULL, },
+ { "PSR.ia", 28, 1, 2, 14, NULL, },
+ { "PSR.ic", 28, 1, 2, 13, NULL, },
+ { "PSR.id", 28, 1, 2, 14, NULL, },
+ { "PSR.is", 28, 1, 2, 14, NULL, },
+ { "PSR.it", 28, 1, 2, 14, NULL, },
+ { "PSR.lp", 28, 1, 2, 25, NULL, },
+ { "PSR.mc", 28, 1, 2, 35, NULL, },
+ { "PSR.mfh", 28, 1, 0, 5, NULL, },
+ { "PSR.mfh", 28, 1, 2, 5, NULL, },
+ { "PSR.mfh", 28, 1, 2, 5, NULL, },
+ { "PSR.mfl", 28, 1, 0, 4, NULL, },
+ { "PSR.mfl", 28, 1, 2, 4, NULL, },
+ { "PSR.mfl", 28, 1, 2, 4, NULL, },
+ { "PSR.pk", 28, 1, 2, 15, NULL, },
+ { "PSR.pp", 28, 1, 2, 21, NULL, },
+ { "PSR.ri", 28, 1, 2, 41, NULL, },
+ { "PSR.rt", 28, 1, 2, 27, NULL, },
+ { "PSR.si", 28, 1, 2, 23, NULL, },
+ { "PSR.sp", 28, 1, 2, 20, NULL, },
+ { "PSR.ss", 28, 1, 2, 40, NULL, },
+ { "PSR.tb", 28, 1, 2, 26, NULL, },
+ { "PSR.up", 28, 1, 2, 2, NULL, },
+ { "RR#", 25, 1, 2, -1, NULL, },
+ { "RSE", 29, 1, 2, -1, NULL, },
+ { "PR63", 24, 2, 6, -1, NULL, },
+};
+
+static const unsigned short dep0[] = {
+ 96, 267, 2139, 2312,
+};
+
+static const unsigned short dep1[] = {
+ 40, 41, 96, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2312, 4135,
+ 20613,
+};
+
+static const unsigned short dep2[] = {
+ 96, 267, 2165, 2166, 2168, 2169, 2171, 2172, 2174, 2329, 2332, 2333, 2336,
+ 2337, 2340, 2341,
+};
+
+static const unsigned short dep3[] = {
+ 40, 41, 96, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2329, 2332,
+ 2333, 2336, 2337, 2340, 2341, 4135, 20613,
+};
+
+static const unsigned short dep4[] = {
+ 96, 267, 22645, 22646, 22648, 22649, 22651, 22652, 22654, 22809, 22812, 22813,
+ 22816, 22817, 22820, 22821,
+};
+
+static const unsigned short dep5[] = {
+ 40, 41, 96, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 4135, 20613,
+ 22809, 22812, 22813, 22816, 22817, 22820, 22821,
+};
+
+static const unsigned short dep6[] = {
+ 96, 267, 2165, 2166, 2168, 2169, 2171, 2172, 2174, 2329, 2330, 2332, 2334,
+ 2336, 2338, 2340,
+};
+
+static const unsigned short dep7[] = {
+ 40, 41, 96, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2329, 2330,
+ 2333, 2334, 2337, 2338, 2341, 4135, 20613,
+};
+
+static const unsigned short dep8[] = {
+ 96, 267, 2165, 2166, 2168, 2169, 2171, 2172, 2174, 2329, 2331, 2333, 2335,
+ 2337, 2339, 2341,
+};
+
+static const unsigned short dep9[] = {
+ 40, 41, 96, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2329, 2331,
+ 2332, 2335, 2336, 2339, 2340, 4135, 20613,
+};
+
+static const unsigned short dep10[] = {
+ 96, 267, 2165, 2166, 2168, 2169, 2171, 2172, 2174, 2329, 2330, 2331, 2332,
+ 2333, 2334, 2335, 2336, 2337, 2338, 2339, 2340, 2341,
+};
+
+static const unsigned short dep11[] = {
+ 40, 41, 96, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2329, 2330,
+ 2331, 2332, 2333, 2334, 2335, 2336, 2337, 2338, 2339, 2340, 2341, 4135, 20613,
+
+};
+
+static const unsigned short dep12[] = {
+ 96, 267, 2379,
+};
+
+static const unsigned short dep13[] = {
+ 40, 41, 96, 156, 174, 175, 267, 2082, 2083, 2165, 2167, 2168, 2170, 2171,
+ 2173, 2174, 4135,
+};
+
+static const unsigned short dep14[] = {
+ 96, 155, 267, 310, 2379, 28852, 29002,
+};
+
+static const unsigned short dep15[] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 28, 29, 30, 31, 32, 33, 40, 41, 96, 144, 156, 174, 175,
+ 267, 310, 2082, 2083, 2165, 2167, 2168, 2170, 2171, 2173, 2174, 4135, 28852,
+ 29002,
+};
+
+static const unsigned short dep16[] = {
+ 1, 6, 40, 96, 134, 182, 187, 226, 267, 297, 2379, 28852, 29002,
+};
+
+static const unsigned short dep17[] = {
+ 1, 25, 27, 38, 40, 41, 96, 156, 158, 159, 174, 175, 182, 187, 226, 267, 297,
+ 2082, 2083, 2165, 2167, 2168, 2170, 2171, 2173, 2174, 4135, 28852, 29002,
+
+};
+
+static const unsigned short dep18[] = {
+ 1, 40, 51, 96, 182, 226, 233, 267, 28852, 29002,
+};
+
+static const unsigned short dep19[] = {
+ 1, 38, 40, 41, 96, 153, 174, 182, 226, 233, 267, 4135, 28852, 29002,
+};
+
+static const unsigned short dep20[] = {
+ 40, 96, 226, 267,
+};
+
+static const unsigned short dep21[] = {
+ 96, 174, 226, 267,
+};
+
+static const unsigned short dep22[] = {
+ 1, 40, 96, 128, 129, 131, 132, 133, 134, 135, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 150, 151, 152, 153, 154, 155, 156, 159, 160, 161,
+ 162, 163, 164, 165, 166, 169, 170, 171, 172, 173, 174, 175, 176, 177, 182,
+ 226, 267, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306,
+ 307, 308, 309, 310, 311, 312, 313, 315, 316, 318, 319, 320, 321, 322, 323,
+ 324, 325, 326, 327, 328, 28852, 29002,
+};
+
+static const unsigned short dep23[] = {
+ 1, 38, 40, 41, 50, 51, 55, 58, 72, 96, 134, 174, 182, 226, 267, 294, 295,
+ 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310,
+ 311, 312, 313, 315, 316, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327,
+ 328, 4135, 28852, 29002,
+};
+
+static const unsigned short dep24[] = {
+ 96, 133, 267, 296,
+};
+
+static const unsigned short dep25[] = {
+ 96, 134, 174, 267, 296,
+};
+
+static const unsigned short dep26[] = {
+ 96, 134, 267, 297,
+};
+
+static const unsigned short dep27[] = {
+ 25, 26, 96, 97, 100, 104, 107, 134, 156, 174, 267, 297,
+};
+
+static const unsigned short dep28[] = {
+ 40, 41, 96, 174, 267, 2165, 2167, 2168, 2170, 2171, 2173, 2174, 4135,
+};
+
+static const unsigned short dep29[] = {
+ 1, 25, 40, 96, 182, 214, 215, 226, 267, 2082, 2270, 2273, 2379, 28852, 29002,
+
+};
+
+static const unsigned short dep30[] = {
+ 1, 6, 38, 40, 41, 96, 134, 156, 174, 175, 182, 214, 216, 226, 267, 2082, 2083,
+ 2165, 2167, 2168, 2170, 2171, 2173, 2174, 2271, 2273, 4135, 28852, 29002,
+
+};
+
+static const unsigned short dep31[] = {
+ 96, 267,
+};
+
+static const unsigned short dep32[] = {
+ 96, 174, 267, 2082, 2084,
+};
+
+static const unsigned short dep33[] = {
+ 40, 41, 96, 156, 174, 175, 267, 2165, 2167, 2168, 2170, 2171, 2173, 2174,
+ 4135,
+};
+
+static const unsigned short dep34[] = {
+ 6, 37, 38, 39, 96, 124, 125, 187, 226, 267, 292, 293, 2379,
+};
+
+static const unsigned short dep35[] = {
+ 6, 37, 40, 41, 96, 156, 174, 175, 187, 226, 267, 292, 293, 331, 2165, 2167,
+ 2168, 2170, 2171, 2173, 2174, 4135,
+};
+
+static const unsigned short dep36[] = {
+ 24, 96, 213, 267, 2379,
+};
+
+static const unsigned short dep37[] = {
+ 24, 40, 41, 96, 156, 174, 175, 213, 267, 2165, 2167, 2168, 2170, 2171, 2173,
+ 2174, 4135,
+};
+
+static const unsigned short dep38[] = {
+ 6, 24, 37, 38, 39, 96, 124, 125, 187, 213, 226, 267, 292, 293, 2379,
+};
+
+static const unsigned short dep39[] = {
+ 6, 24, 37, 40, 41, 96, 156, 174, 175, 187, 213, 226, 267, 292, 293, 331, 2165,
+ 2167, 2168, 2170, 2171, 2173, 2174, 4135,
+};
+
+static const unsigned short dep40[] = {
+ 1, 6, 38, 40, 41, 96, 134, 156, 174, 175, 182, 214, 216, 226, 267, 2165, 2167,
+ 2168, 2170, 2171, 2173, 2174, 2271, 2273, 4135, 28852, 29002,
+};
+
+static const unsigned short dep41[] = {
+ 96, 174, 267,
+};
+
+static const unsigned short dep42[] = {
+ 15, 96, 196, 197, 267, 2135, 2310, 18593, 18594, 18746, 18747, 18749, 18750,
+ 22645, 22646, 22647, 22649, 22650, 22652, 22653, 22809, 22812, 22813, 22816,
+ 22817, 22820, 22821,
+};
+
+static const unsigned short dep43[] = {
+ 11, 19, 20, 40, 41, 96, 174, 196, 198, 267, 2134, 2135, 2136, 2165, 2166,
+ 2169, 2172, 2310, 4135, 16524, 16526, 18746, 18748, 18749, 18751, 22809, 22812,
+ 22813, 22816, 22817, 22820, 22821,
+};
+
+static const unsigned short dep44[] = {
+ 15, 16, 17, 18, 96, 196, 197, 199, 200, 202, 203, 205, 206, 267, 2135, 2310,
+ 18593, 18594, 18746, 18747, 18749, 18750, 22645, 22646, 22647, 22649, 22650,
+ 22652, 22653, 22809, 22812, 22813, 22816, 22817, 22820, 22821,
+};
+
+static const unsigned short dep45[] = {
+ 11, 12, 13, 14, 19, 20, 40, 41, 96, 174, 196, 198, 199, 201, 202, 204, 205,
+ 207, 267, 2134, 2135, 2136, 2165, 2166, 2169, 2172, 2310, 4135, 16524, 16526,
+ 18746, 18748, 18749, 18751, 22809, 22812, 22813, 22816, 22817, 22820, 22821,
+
+};
+
+static const unsigned short dep46[] = {
+ 16, 96, 199, 200, 267, 2135, 2310, 18593, 18594, 18746, 18747, 18749, 18750,
+ 22645, 22646, 22647, 22649, 22650, 22652, 22653, 22809, 22812, 22813, 22816,
+ 22817, 22820, 22821,
+};
+
+static const unsigned short dep47[] = {
+ 12, 19, 20, 40, 41, 96, 174, 199, 201, 267, 2134, 2135, 2136, 2165, 2166,
+ 2169, 2172, 2310, 4135, 16524, 16526, 18746, 18748, 18749, 18751, 22809, 22812,
+ 22813, 22816, 22817, 22820, 22821,
+};
+
+static const unsigned short dep48[] = {
+ 17, 96, 202, 203, 267, 2135, 2310, 18593, 18594, 18746, 18747, 18749, 18750,
+ 22645, 22646, 22647, 22649, 22650, 22652, 22653, 22809, 22812, 22813, 22816,
+ 22817, 22820, 22821,
+};
+
+static const unsigned short dep49[] = {
+ 13, 19, 20, 40, 41, 96, 174, 202, 204, 267, 2134, 2135, 2136, 2165, 2166,
+ 2169, 2172, 2310, 4135, 16524, 16526, 18746, 18748, 18749, 18751, 22809, 22812,
+ 22813, 22816, 22817, 22820, 22821,
+};
+
+static const unsigned short dep50[] = {
+ 18, 96, 205, 206, 267, 2135, 2310, 18593, 18594, 18746, 18747, 18749, 18750,
+ 22645, 22646, 22647, 22649, 22650, 22652, 22653, 22809, 22812, 22813, 22816,
+ 22817, 22820, 22821,
+};
+
+static const unsigned short dep51[] = {
+ 14, 19, 20, 40, 41, 96, 174, 205, 207, 267, 2134, 2135, 2136, 2165, 2166,
+ 2169, 2172, 2310, 4135, 16524, 16526, 18746, 18748, 18749, 18751, 22809, 22812,
+ 22813, 22816, 22817, 22820, 22821,
+};
+
+static const unsigned short dep52[] = {
+ 15, 96, 196, 197, 267, 2135, 2310, 18593, 18594, 18746, 18747, 18749, 18750,
+
+};
+
+static const unsigned short dep53[] = {
+ 11, 19, 20, 40, 41, 96, 174, 196, 198, 267, 2134, 2135, 2136, 2165, 2166,
+ 2169, 2172, 2310, 4135, 16524, 16526, 18746, 18748, 18749, 18751,
+};
+
+static const unsigned short dep54[] = {
+ 15, 16, 17, 18, 96, 196, 197, 199, 200, 202, 203, 205, 206, 267, 2135, 2310,
+ 18593, 18594, 18746, 18747, 18749, 18750,
+};
+
+static const unsigned short dep55[] = {
+ 11, 12, 13, 14, 19, 20, 40, 41, 96, 174, 196, 198, 199, 201, 202, 204, 205,
+ 207, 267, 2134, 2135, 2136, 2165, 2166, 2169, 2172, 2310, 4135, 16524, 16526,
+ 18746, 18748, 18749, 18751,
+};
+
+static const unsigned short dep56[] = {
+ 16, 96, 199, 200, 267, 2135, 2310, 18593, 18594, 18746, 18747, 18749, 18750,
+
+};
+
+static const unsigned short dep57[] = {
+ 12, 19, 20, 40, 41, 96, 174, 199, 201, 267, 2134, 2135, 2136, 2165, 2166,
+ 2169, 2172, 2310, 4135, 16524, 16526, 18746, 18748, 18749, 18751,
+};
+
+static const unsigned short dep58[] = {
+ 17, 96, 202, 203, 267, 2135, 2310, 18593, 18594, 18746, 18747, 18749, 18750,
+
+};
+
+static const unsigned short dep59[] = {
+ 13, 19, 20, 40, 41, 96, 174, 202, 204, 267, 2134, 2135, 2136, 2165, 2166,
+ 2169, 2172, 2310, 4135, 16524, 16526, 18746, 18748, 18749, 18751,
+};
+
+static const unsigned short dep60[] = {
+ 18, 96, 205, 206, 267, 2135, 2310, 18593, 18594, 18746, 18747, 18749, 18750,
+
+};
+
+static const unsigned short dep61[] = {
+ 14, 19, 20, 40, 41, 96, 174, 205, 207, 267, 2134, 2135, 2136, 2165, 2166,
+ 2169, 2172, 2310, 4135, 16524, 16526, 18746, 18748, 18749, 18751,
+};
+
+static const unsigned short dep62[] = {
+ 96, 267, 2135, 2310, 18593, 18594, 18746, 18747, 18749, 18750,
+};
+
+static const unsigned short dep63[] = {
+ 40, 41, 96, 174, 267, 2134, 2135, 2136, 2165, 2166, 2169, 2172, 2310, 4135,
+ 16524, 16526, 18746, 18748, 18749, 18751,
+};
+
+static const unsigned short dep64[] = {
+ 11, 96, 192, 267,
+};
+
+static const unsigned short dep65[] = {
+ 11, 40, 41, 96, 174, 192, 267, 2165, 2166, 2169, 2172, 4135,
+};
+
+static const unsigned short dep66[] = {
+ 11, 40, 41, 96, 174, 267, 2165, 2166, 2169, 2172, 4135,
+};
+
+static const unsigned short dep67[] = {
+ 12, 96, 193, 267,
+};
+
+static const unsigned short dep68[] = {
+ 11, 40, 41, 96, 174, 193, 267, 2165, 2166, 2169, 2172, 4135,
+};
+
+static const unsigned short dep69[] = {
+ 13, 96, 194, 267,
+};
+
+static const unsigned short dep70[] = {
+ 11, 40, 41, 96, 174, 194, 267, 2165, 2166, 2169, 2172, 4135,
+};
+
+static const unsigned short dep71[] = {
+ 14, 96, 195, 267,
+};
+
+static const unsigned short dep72[] = {
+ 11, 40, 41, 96, 174, 195, 267, 2165, 2166, 2169, 2172, 4135,
+};
+
+static const unsigned short dep73[] = {
+ 15, 96, 197, 198, 267,
+};
+
+static const unsigned short dep74[] = {
+ 40, 41, 96, 174, 197, 198, 267, 2165, 2166, 2169, 2172, 4135,
+};
+
+static const unsigned short dep75[] = {
+ 40, 41, 96, 174, 267, 2165, 2166, 2169, 2172, 4135,
+};
+
+static const unsigned short dep76[] = {
+ 16, 96, 200, 201, 267,
+};
+
+static const unsigned short dep77[] = {
+ 40, 41, 96, 174, 200, 201, 267, 2165, 2166, 2169, 2172, 4135,
+};
+
+static const unsigned short dep78[] = {
+ 17, 96, 203, 204, 267,
+};
+
+static const unsigned short dep79[] = {
+ 40, 41, 96, 174, 203, 204, 267, 2165, 2166, 2169, 2172, 4135,
+};
+
+static const unsigned short dep80[] = {
+ 18, 96, 206, 207, 267,
+};
+
+static const unsigned short dep81[] = {
+ 40, 41, 96, 174, 206, 207, 267, 2165, 2166, 2169, 2172, 4135,
+};
+
+static const unsigned short dep82[] = {
+ 15, 19, 20, 40, 41, 96, 156, 174, 175, 267, 2165, 2166, 2169, 2172, 4135,
+
+};
+
+static const unsigned short dep83[] = {
+ 15, 16, 19, 20, 40, 41, 96, 156, 174, 175, 267, 2165, 2166, 2169, 2172, 4135,
+
+};
+
+static const unsigned short dep84[] = {
+ 15, 17, 19, 20, 40, 41, 96, 156, 174, 175, 267, 2165, 2166, 2169, 2172, 4135,
+
+};
+
+static const unsigned short dep85[] = {
+ 15, 18, 19, 20, 40, 41, 96, 156, 174, 175, 267, 2165, 2166, 2169, 2172, 4135,
+
+};
+
+static const unsigned short dep86[] = {
+ 15, 96, 196, 197, 267,
+};
+
+static const unsigned short dep87[] = {
+ 11, 19, 20, 40, 41, 96, 174, 196, 198, 267, 2165, 2166, 2169, 2172, 4135,
+
+};
+
+static const unsigned short dep88[] = {
+ 15, 16, 17, 18, 96, 196, 197, 199, 200, 202, 203, 205, 206, 267,
+};
+
+static const unsigned short dep89[] = {
+ 11, 12, 13, 14, 19, 20, 40, 41, 96, 174, 196, 198, 199, 201, 202, 204, 205,
+ 207, 267, 2165, 2166, 2169, 2172, 4135,
+};
+
+static const unsigned short dep90[] = {
+ 16, 96, 199, 200, 267,
+};
+
+static const unsigned short dep91[] = {
+ 12, 19, 20, 40, 41, 96, 174, 199, 201, 267, 2165, 2166, 2169, 2172, 4135,
+
+};
+
+static const unsigned short dep92[] = {
+ 17, 96, 202, 203, 267,
+};
+
+static const unsigned short dep93[] = {
+ 13, 19, 20, 40, 41, 96, 174, 202, 204, 267, 2165, 2166, 2169, 2172, 4135,
+
+};
+
+static const unsigned short dep94[] = {
+ 18, 96, 205, 206, 267,
+};
+
+static const unsigned short dep95[] = {
+ 14, 19, 20, 40, 41, 96, 174, 205, 207, 267, 2165, 2166, 2169, 2172, 4135,
+
+};
+
+static const unsigned short dep96[] = {
+ 15, 96, 196, 197, 267, 2165, 2166, 2167, 2169, 2170, 2172, 2173, 2329, 2332,
+ 2333, 2336, 2337, 2340, 2341,
+};
+
+static const unsigned short dep97[] = {
+ 11, 19, 20, 40, 41, 96, 174, 196, 198, 267, 2134, 2135, 2136, 2165, 2166,
+ 2169, 2172, 2329, 2332, 2333, 2336, 2337, 2340, 2341, 4135, 16524, 16526,
+
+};
+
+static const unsigned short dep98[] = {
+ 15, 16, 17, 18, 96, 196, 197, 199, 200, 202, 203, 205, 206, 267, 2165, 2166,
+ 2167, 2169, 2170, 2172, 2173, 2329, 2332, 2333, 2336, 2337, 2340, 2341,
+};
+
+static const unsigned short dep99[] = {
+ 11, 12, 13, 14, 19, 20, 40, 41, 96, 174, 196, 198, 199, 201, 202, 204, 205,
+ 207, 267, 2134, 2135, 2136, 2165, 2166, 2169, 2172, 2329, 2332, 2333, 2336,
+ 2337, 2340, 2341, 4135, 16524, 16526,
+};
+
+static const unsigned short dep100[] = {
+ 16, 96, 199, 200, 267, 2165, 2166, 2167, 2169, 2170, 2172, 2173, 2329, 2332,
+ 2333, 2336, 2337, 2340, 2341,
+};
+
+static const unsigned short dep101[] = {
+ 12, 19, 20, 40, 41, 96, 174, 199, 201, 267, 2134, 2135, 2136, 2165, 2166,
+ 2169, 2172, 2329, 2332, 2333, 2336, 2337, 2340, 2341, 4135, 16524, 16526,
+
+};
+
+static const unsigned short dep102[] = {
+ 17, 96, 202, 203, 267, 2165, 2166, 2167, 2169, 2170, 2172, 2173, 2329, 2332,
+ 2333, 2336, 2337, 2340, 2341,
+};
+
+static const unsigned short dep103[] = {
+ 13, 19, 20, 40, 41, 96, 174, 202, 204, 267, 2134, 2135, 2136, 2165, 2166,
+ 2169, 2172, 2329, 2332, 2333, 2336, 2337, 2340, 2341, 4135, 16524, 16526,
+
+};
+
+static const unsigned short dep104[] = {
+ 18, 96, 205, 206, 267, 2165, 2166, 2167, 2169, 2170, 2172, 2173, 2329, 2332,
+ 2333, 2336, 2337, 2340, 2341,
+};
+
+static const unsigned short dep105[] = {
+ 14, 19, 20, 40, 41, 96, 174, 205, 207, 267, 2134, 2135, 2136, 2165, 2166,
+ 2169, 2172, 2329, 2332, 2333, 2336, 2337, 2340, 2341, 4135, 16524, 16526,
+
+};
+
+static const unsigned short dep106[] = {
+ 15, 96, 196, 197, 267, 22645, 22646, 22647, 22649, 22650, 22652, 22653, 22809,
+ 22812, 22813, 22816, 22817, 22820, 22821,
+};
+
+static const unsigned short dep107[] = {
+ 11, 19, 20, 40, 41, 96, 174, 196, 198, 267, 2134, 2135, 2136, 2165, 2166,
+ 2169, 2172, 4135, 16524, 16526, 22809, 22812, 22813, 22816, 22817, 22820,
+ 22821,
+};
+
+static const unsigned short dep108[] = {
+ 15, 16, 17, 18, 96, 196, 197, 199, 200, 202, 203, 205, 206, 267, 22645, 22646,
+ 22647, 22649, 22650, 22652, 22653, 22809, 22812, 22813, 22816, 22817, 22820,
+ 22821,
+};
+
+static const unsigned short dep109[] = {
+ 11, 12, 13, 14, 19, 20, 40, 41, 96, 174, 196, 198, 199, 201, 202, 204, 205,
+ 207, 267, 2134, 2135, 2136, 2165, 2166, 2169, 2172, 4135, 16524, 16526, 22809,
+ 22812, 22813, 22816, 22817, 22820, 22821,
+};
+
+static const unsigned short dep110[] = {
+ 16, 96, 199, 200, 267, 22645, 22646, 22647, 22649, 22650, 22652, 22653, 22809,
+ 22812, 22813, 22816, 22817, 22820, 22821,
+};
+
+static const unsigned short dep111[] = {
+ 12, 19, 20, 40, 41, 96, 174, 199, 201, 267, 2134, 2135, 2136, 2165, 2166,
+ 2169, 2172, 4135, 16524, 16526, 22809, 22812, 22813, 22816, 22817, 22820,
+ 22821,
+};
+
+static const unsigned short dep112[] = {
+ 17, 96, 202, 203, 267, 22645, 22646, 22647, 22649, 22650, 22652, 22653, 22809,
+ 22812, 22813, 22816, 22817, 22820, 22821,
+};
+
+static const unsigned short dep113[] = {
+ 13, 19, 20, 40, 41, 96, 174, 202, 204, 267, 2134, 2135, 2136, 2165, 2166,
+ 2169, 2172, 4135, 16524, 16526, 22809, 22812, 22813, 22816, 22817, 22820,
+ 22821,
+};
+
+static const unsigned short dep114[] = {
+ 18, 96, 205, 206, 267, 22645, 22646, 22647, 22649, 22650, 22652, 22653, 22809,
+ 22812, 22813, 22816, 22817, 22820, 22821,
+};
+
+static const unsigned short dep115[] = {
+ 14, 19, 20, 40, 41, 96, 174, 205, 207, 267, 2134, 2135, 2136, 2165, 2166,
+ 2169, 2172, 4135, 16524, 16526, 22809, 22812, 22813, 22816, 22817, 22820,
+ 22821,
+};
+
+static const unsigned short dep116[] = {
+ 96, 267, 2165, 2166, 2167, 2169, 2170, 2172, 2173, 2329, 2332, 2333, 2336,
+ 2337, 2340, 2341,
+};
+
+static const unsigned short dep117[] = {
+ 40, 41, 96, 174, 267, 2134, 2135, 2136, 2165, 2166, 2169, 2172, 2329, 2332,
+ 2333, 2336, 2337, 2340, 2341, 4135, 16524, 16526,
+};
+
+static const unsigned short dep118[] = {
+ 96, 267, 22645, 22646, 22647, 22649, 22650, 22652, 22653, 22809, 22812, 22813,
+ 22816, 22817, 22820, 22821,
+};
+
+static const unsigned short dep119[] = {
+ 40, 41, 96, 174, 267, 2134, 2135, 2136, 2165, 2166, 2169, 2172, 4135, 16524,
+ 16526, 22809, 22812, 22813, 22816, 22817, 22820, 22821,
+};
+
+static const unsigned short dep120[] = {
+ 19, 20, 40, 41, 96, 174, 267, 2134, 2135, 2136, 2165, 2166, 2169, 2172, 2310,
+ 4135, 16524, 16526, 18746, 18748, 18749, 18751,
+};
+
+static const unsigned short dep121[] = {
+ 40, 41, 96, 156, 174, 175, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172,
+ 4135, 20613,
+};
+
+static const unsigned short dep122[] = {
+ 96, 267, 2083, 2084, 2271, 2272,
+};
+
+static const unsigned short dep123[] = {
+ 40, 41, 96, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2270, 2272,
+ 4135, 20613,
+};
+
+static const unsigned short dep124[] = {
+ 40, 41, 96, 174, 267, 2082, 2084, 2165, 2166, 2169, 2172, 2312, 4135, 20613,
+
+};
+
+static const unsigned short dep125[] = {
+ 96, 267, 14454, 14456, 14457, 14459, 14460, 14462, 14620, 14621, 14624, 14625,
+ 14628, 14629,
+};
+
+static const unsigned short dep126[] = {
+ 40, 41, 96, 174, 267, 2137, 2138, 2139, 4135, 14620, 14621, 14624, 14625,
+ 14628, 14629, 20613, 24693, 24694, 24697, 24700,
+};
+
+static const unsigned short dep127[] = {
+ 96, 121, 123, 124, 126, 267, 288, 289, 292, 293,
+};
+
+static const unsigned short dep128[] = {
+ 40, 41, 96, 174, 267, 288, 289, 292, 293, 4135, 24693, 24694, 24697, 24700,
+
+};
+
+static const unsigned short dep129[] = {
+ 40, 41, 96, 174, 267, 2165, 2166, 2169, 2172, 2312, 4135, 20613,
+};
+
+static const unsigned short dep130[] = {
+ 40, 41, 96, 118, 121, 124, 174, 267, 2312, 4135, 20613, 24693,
+};
+
+static const unsigned short dep131[] = {
+ 6, 24, 26, 27, 96, 187, 213, 216, 267, 2081, 2269,
+};
+
+static const unsigned short dep132[] = {
+ 40, 41, 96, 174, 187, 213, 215, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172,
+ 2269, 4135, 20613,
+};
+
+static const unsigned short dep133[] = {
+ 6, 24, 25, 26, 40, 41, 96, 174, 267, 2081, 2165, 2166, 2169, 2172, 2312, 4135,
+ 20613,
+};
+
+static const unsigned short dep134[] = {
+ 0, 40, 41, 96, 156, 174, 175, 267, 2165, 2166, 2169, 2172, 4135,
+};
+
+static const unsigned short dep135[] = {
+ 0, 96, 181, 267,
+};
+
+static const unsigned short dep136[] = {
+ 0, 40, 41, 96, 156, 174, 175, 181, 267, 2165, 2166, 2169, 2172, 4135,
+};
+
+static const unsigned short dep137[] = {
+ 40, 41, 96, 174, 181, 267, 2165, 2166, 2169, 2172, 4135,
+};
+
+static const unsigned short dep138[] = {
+ 2, 28, 96, 183, 217, 267, 28852, 29002,
+};
+
+static const unsigned short dep139[] = {
+ 1, 2, 28, 29, 96, 168, 169, 174, 183, 217, 267, 28852, 29002,
+};
+
+static const unsigned short dep140[] = {
+ 1, 28, 29, 38, 40, 41, 96, 168, 169, 174, 183, 217, 267, 4135, 28852, 29002,
+
+};
+
+static const unsigned short dep141[] = {
+ 0, 40, 41, 96, 174, 181, 267, 2165, 2166, 2169, 2172, 4135,
+};
+
+static const unsigned short dep142[] = {
+ 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 28, 29, 30, 31, 96, 182, 183, 184, 185, 186, 188, 189, 190, 191, 192, 193,
+ 194, 195, 197, 198, 200, 201, 203, 204, 206, 207, 208, 209, 210, 211, 217,
+ 218, 219, 267, 2071, 2081, 2260, 2269, 28852, 29002,
+};
+
+static const unsigned short dep143[] = {
+ 29, 40, 41, 96, 134, 174, 182, 183, 184, 185, 186, 188, 189, 190, 191, 192,
+ 193, 194, 195, 197, 198, 200, 201, 203, 204, 206, 207, 208, 209, 210, 211,
+ 217, 218, 219, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2260, 2269,
+ 4135, 20613, 28852, 29002,
+};
+
+static const unsigned short dep144[] = {
+ 96, 267, 14463, 14465, 14466, 14468, 14497, 14498, 14513, 14630, 14631, 14651,
+ 14652, 14654, 14655, 14664,
+};
+
+static const unsigned short dep145[] = {
+ 40, 41, 96, 173, 174, 267, 2165, 2166, 2169, 2172, 4135, 14630, 14631, 14651,
+ 14652, 14654, 14655, 14664,
+};
+
+static const unsigned short dep146[] = {
+ 14463, 14465, 14466, 14468, 14497, 14498, 14513, 14630, 14631, 14651, 14652,
+ 14654, 14655, 14664,
+};
+
+static const unsigned short dep147[] = {
+ 173, 14630, 14631, 14651, 14652, 14654, 14655, 14664,
+};
+
+static const unsigned short dep148[] = {
+ 96, 267, 14464, 14465, 14467, 14468, 14476, 14477, 14478, 14479, 14480, 14481,
+ 14482, 14483, 14485, 14488, 14489, 14497, 14498, 14499, 14500, 14501, 14506,
+ 14507, 14508, 14509, 14513, 14630, 14631, 14637, 14638, 14639, 14640, 14642,
+ 14644, 14651, 14652, 14654, 14655, 14656, 14657, 14660, 14661, 14664,
+};
+
+static const unsigned short dep149[] = {
+ 40, 41, 72, 96, 134, 174, 267, 2165, 2166, 2169, 2172, 4135, 14630, 14631,
+ 14637, 14638, 14639, 14640, 14642, 14644, 14651, 14652, 14654, 14655, 14656,
+ 14657, 14660, 14661, 14664,
+};
+
+static const unsigned short dep150[] = {
+ 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 28, 29, 30, 31, 40, 41, 96, 134, 171, 174, 267, 2071, 2081, 2165, 2166, 2169,
+ 2172, 2312, 4135, 20613, 28852,
+};
+
+static const unsigned short dep151[] = {
+ 43, 44, 45, 46, 47, 48, 49, 50, 52, 53, 54, 55, 56, 57, 58, 60, 61, 62, 63,
+ 64, 65, 67, 69, 70, 71, 72, 93, 95, 96, 228, 229, 230, 231, 232, 233, 234,
+ 235, 236, 237, 238, 240, 241, 242, 243, 244, 246, 248, 249, 250, 266, 267,
+ 2116, 2295,
+};
+
+static const unsigned short dep152[] = {
+ 40, 41, 95, 96, 134, 153, 174, 228, 229, 230, 231, 232, 233, 234, 235, 236,
+ 237, 238, 240, 241, 242, 243, 244, 246, 248, 249, 250, 266, 267, 2137, 2138,
+ 2139, 2165, 2166, 2169, 2172, 2295, 4135, 20613,
+};
+
+static const unsigned short dep153[] = {
+ 59, 94, 96, 239, 266, 267, 2139, 2312,
+};
+
+static const unsigned short dep154[] = {
+ 40, 41, 43, 44, 46, 48, 49, 51, 52, 53, 54, 56, 57, 60, 61, 63, 64, 65, 66,
+ 67, 69, 70, 71, 93, 94, 96, 134, 153, 174, 239, 266, 267, 2107, 2116, 2165,
+ 2166, 2169, 2172, 2312, 4135, 20613,
+};
+
+static const unsigned short dep155[] = {
+ 2, 28, 41, 96, 183, 217, 226, 267, 2139, 2312, 28852, 29002,
+};
+
+static const unsigned short dep156[] = {
+ 2, 25, 26, 28, 29, 38, 40, 41, 96, 168, 169, 174, 183, 217, 226, 267, 2312,
+ 4135, 20613, 28852, 29002,
+};
+
+static const unsigned short dep157[] = {
+ 96, 128, 129, 131, 132, 136, 137, 140, 141, 142, 143, 144, 145, 146, 147,
+ 149, 152, 153, 157, 158, 161, 162, 163, 164, 165, 167, 168, 170, 171, 172,
+ 173, 175, 176, 177, 267, 294, 295, 299, 301, 302, 303, 304, 306, 308, 312,
+ 315, 316, 318, 319, 320, 321, 323, 324, 325, 327, 328,
+};
+
+static const unsigned short dep158[] = {
+ 40, 41, 72, 96, 134, 174, 267, 294, 295, 299, 301, 302, 303, 304, 306, 308,
+ 312, 315, 316, 318, 319, 320, 321, 323, 324, 325, 327, 328, 2137, 2138, 2139,
+ 2165, 2166, 2169, 2172, 4135, 20613,
+};
+
+static const unsigned short dep159[] = {
+ 96, 127, 129, 130, 132, 161, 162, 177, 267, 294, 295, 315, 316, 318, 319,
+ 328,
+};
+
+static const unsigned short dep160[] = {
+ 40, 41, 96, 173, 174, 267, 294, 295, 315, 316, 318, 319, 328, 2137, 2138,
+ 2139, 2165, 2166, 2169, 2172, 4135, 20613,
+};
+
+static const unsigned short dep161[] = {
+ 40, 41, 96, 129, 132, 134, 137, 138, 141, 143, 145, 147, 149, 150, 152, 156,
+ 157, 159, 160, 161, 162, 164, 165, 167, 169, 170, 172, 174, 176, 177, 267,
+ 2165, 2166, 2169, 2172, 2312, 4135, 20613,
+};
+
+static const unsigned short dep162[] = {
+ 40, 41, 96, 129, 132, 161, 162, 174, 177, 267, 2165, 2166, 2169, 2172, 2312,
+ 4135, 20613,
+};
+
+static const unsigned short dep163[] = {
+ 40, 41, 75, 76, 81, 83, 96, 110, 134, 163, 174, 178, 267, 2137, 2138, 2139,
+ 2165, 2166, 2169, 2172, 2312, 4135, 20613,
+};
+
+static const unsigned short dep164[] = {
+ 40, 41, 75, 76, 81, 83, 96, 110, 134, 135, 136, 138, 139, 163, 174, 178, 267,
+ 2137, 2138, 2139, 2165, 2166, 2169, 2172, 4135, 20613,
+};
+
+static const unsigned short dep165[] = {
+ 76, 77, 96, 100, 101, 254, 255, 267, 269, 270,
+};
+
+static const unsigned short dep166[] = {
+ 40, 41, 47, 62, 77, 79, 85, 96, 98, 101, 134, 153, 174, 178, 254, 255, 267,
+ 269, 270, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 4135, 20613,
+};
+
+static const unsigned short dep167[] = {
+ 40, 41, 47, 62, 77, 79, 96, 98, 101, 103, 105, 134, 153, 174, 178, 254, 255,
+ 267, 269, 270, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 4135, 20613,
+};
+
+static const unsigned short dep168[] = {
+ 96, 267, 12466, 12467, 12617,
+};
+
+static const unsigned short dep169[] = {
+ 40, 41, 96, 134, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 4135,
+ 12617, 20613,
+};
+
+static const unsigned short dep170[] = {
+ 96, 267, 6218, 6219, 6396,
+};
+
+static const unsigned short dep171[] = {
+ 40, 41, 96, 134, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 4135,
+ 6396, 20613,
+};
+
+static const unsigned short dep172[] = {
+ 96, 267, 6236, 6409,
+};
+
+static const unsigned short dep173[] = {
+ 40, 41, 96, 134, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 4135,
+ 6409, 20613,
+};
+
+static const unsigned short dep174[] = {
+ 96, 267, 6254, 6255, 6256, 6257, 6420, 6422, 8469,
+};
+
+static const unsigned short dep175[] = {
+ 40, 41, 96, 134, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 4135,
+ 6257, 6421, 6422, 8303, 8468, 20613,
+};
+
+static const unsigned short dep176[] = {
+ 96, 267, 6258, 6259, 6423,
+};
+
+static const unsigned short dep177[] = {
+ 40, 41, 96, 134, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 4135,
+ 6423, 20613,
+};
+
+static const unsigned short dep178[] = {
+ 96, 267, 6260, 6424,
+};
+
+static const unsigned short dep179[] = {
+ 40, 41, 96, 134, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 4135,
+ 6424, 20613,
+};
+
+static const unsigned short dep180[] = {
+ 96, 267, 10349, 10515,
+};
+
+static const unsigned short dep181[] = {
+ 40, 41, 96, 134, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 4135,
+ 10515, 20613,
+};
+
+static const unsigned short dep182[] = {
+ 76, 77, 81, 82, 96, 100, 101, 254, 255, 257, 258, 267, 269, 270,
+};
+
+static const unsigned short dep183[] = {
+ 40, 41, 47, 62, 77, 79, 82, 85, 96, 98, 101, 134, 153, 174, 178, 254, 255,
+ 257, 259, 267, 269, 270, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 4135, 20613,
+
+};
+
+static const unsigned short dep184[] = {
+ 76, 77, 96, 100, 101, 103, 104, 254, 255, 267, 269, 270, 271, 272,
+};
+
+static const unsigned short dep185[] = {
+ 40, 41, 47, 62, 77, 79, 96, 98, 101, 103, 105, 134, 153, 174, 178, 254, 255,
+ 267, 269, 270, 271, 272, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 4135, 20613,
+
+};
+
+static const unsigned short dep186[] = {
+ 40, 41, 96, 134, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2312,
+ 4135, 12467, 20613,
+};
+
+static const unsigned short dep187[] = {
+ 40, 41, 96, 134, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2312,
+ 4135, 6218, 20613,
+};
+
+static const unsigned short dep188[] = {
+ 40, 41, 96, 134, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2312,
+ 4135, 6236, 20613,
+};
+
+static const unsigned short dep189[] = {
+ 40, 41, 96, 134, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2312,
+ 4135, 6256, 8302, 20613,
+};
+
+static const unsigned short dep190[] = {
+ 40, 41, 96, 134, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2312,
+ 4135, 6258, 20613,
+};
+
+static const unsigned short dep191[] = {
+ 40, 41, 96, 134, 173, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172,
+ 2312, 4135, 6259, 6260, 20613,
+};
+
+static const unsigned short dep192[] = {
+ 40, 41, 96, 134, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2312,
+ 4135, 10349, 20613,
+};
+
+static const unsigned short dep193[] = {
+ 40, 41, 96, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2312, 4135,
+ 6186, 20613,
+};
+
+static const unsigned short dep194[] = {
+ 76, 78, 79, 96, 97, 98, 99, 253, 254, 267, 268, 269,
+};
+
+static const unsigned short dep195[] = {
+ 40, 41, 77, 78, 82, 84, 96, 99, 101, 103, 106, 134, 174, 178, 253, 255, 267,
+ 268, 270, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 4135, 20613,
+};
+
+static const unsigned short dep196[] = {
+ 76, 78, 79, 80, 96, 97, 98, 99, 102, 253, 254, 256, 267, 268, 269,
+};
+
+static const unsigned short dep197[] = {
+ 40, 41, 77, 78, 80, 82, 84, 96, 99, 101, 102, 103, 106, 134, 174, 178, 253,
+ 255, 256, 267, 268, 270, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 4135, 20613,
+
+};
+
+static const unsigned short dep198[] = {
+ 76, 78, 79, 83, 84, 85, 96, 97, 98, 99, 253, 254, 259, 260, 267, 268, 269,
+
+};
+
+static const unsigned short dep199[] = {
+ 40, 41, 77, 78, 82, 84, 96, 99, 101, 134, 174, 178, 253, 255, 258, 260, 267,
+ 268, 270, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 4135, 20613,
+};
+
+static const unsigned short dep200[] = {
+ 76, 78, 79, 96, 97, 98, 99, 105, 106, 107, 253, 254, 267, 268, 269, 272, 273,
+
+};
+
+static const unsigned short dep201[] = {
+ 40, 41, 77, 78, 96, 99, 101, 103, 106, 134, 174, 178, 253, 255, 267, 268,
+ 270, 271, 273, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 4135, 20613,
+};
+
+static const unsigned short dep202[] = {
+ 40, 41, 46, 70, 96, 174, 178, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172,
+ 2312, 4135, 20613,
+};
+
+static const unsigned short dep203[] = {
+ 40, 41, 96, 174, 178, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2312,
+ 4135, 20613,
+};
+
+static const unsigned short dep204[] = {
+ 40, 41, 76, 81, 83, 96, 134, 174, 178, 267, 2137, 2138, 2139, 2165, 2166,
+ 2169, 2172, 2312, 4135, 20613,
+};
+
+static const unsigned short dep205[] = {
+ 40, 41, 96, 156, 174, 175, 267, 2134, 2135, 2136, 2137, 2138, 2139, 2165,
+ 2166, 2169, 2172, 4135, 16524, 16526, 20613,
+};
+
+static const unsigned short dep206[] = {
+ 40, 41, 76, 81, 83, 96, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172,
+ 4135, 20613,
+};
+
+static const unsigned short dep207[] = {
+ 40, 41, 77, 78, 96, 99, 134, 174, 253, 255, 267, 268, 270, 2137, 2138, 2139,
+ 2165, 2166, 2169, 2172, 4135, 20613,
+};
+
+static const unsigned short dep208[] = {
+ 40, 41, 75, 76, 81, 83, 96, 108, 110, 127, 128, 130, 131, 134, 135, 136, 138,
+ 139, 146, 163, 174, 178, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2312,
+ 4135, 20613,
+};
+
+static const unsigned short dep209[] = {
+ 5, 96, 186, 267, 2139, 2312,
+};
+
+static const unsigned short dep210[] = {
+ 40, 41, 75, 76, 81, 83, 96, 108, 110, 127, 128, 130, 131, 134, 135, 136, 138,
+ 139, 146, 163, 174, 178, 186, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172,
+ 2312, 4135, 20613,
+};
+
+static const unsigned short dep211[] = {
+ 40, 41, 44, 75, 76, 81, 83, 96, 108, 110, 127, 128, 130, 131, 134, 135, 136,
+ 138, 139, 146, 148, 163, 174, 178, 267, 2137, 2138, 2139, 2165, 2166, 2169,
+ 2172, 2312, 4135, 20613,
+};
+
+static const unsigned short dep212[] = {
+ 0, 96, 181, 267, 2139, 2312,
+};
+
+static const unsigned short dep213[] = {
+ 0, 40, 41, 75, 76, 81, 83, 96, 108, 110, 127, 128, 130, 131, 134, 135, 136,
+ 138, 139, 146, 163, 174, 178, 181, 267, 2137, 2138, 2139, 2165, 2166, 2169,
+ 2172, 2312, 4135, 20613,
+};
+
+static const unsigned short dep214[] = {
+ 0, 40, 41, 44, 75, 76, 81, 83, 96, 108, 110, 127, 128, 130, 131, 134, 135,
+ 136, 138, 139, 146, 148, 163, 174, 178, 181, 267, 2137, 2138, 2139, 2165,
+ 2166, 2169, 2172, 2312, 4135, 20613,
+};
+
+static const unsigned short dep215[] = {
+ 31, 40, 41, 75, 76, 81, 83, 96, 108, 110, 127, 128, 130, 131, 134, 135, 136,
+ 138, 139, 146, 163, 174, 178, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172,
+ 2312, 4135, 20613,
+};
+
+static const unsigned short dep216[] = {
+ 0, 96, 181, 267, 2312, 26714,
+};
+
+static const unsigned short dep217[] = {
+ 0, 96, 108, 181, 267, 274,
+};
+
+static const unsigned short dep218[] = {
+ 0, 40, 41, 75, 76, 81, 83, 96, 110, 127, 128, 130, 131, 134, 135, 136, 138,
+ 139, 146, 163, 174, 178, 181, 267, 274, 2137, 2138, 2139, 2165, 2166, 2169,
+ 2172, 4135, 20613,
+};
+
+static const unsigned short dep219[] = {
+ 0, 5, 40, 41, 75, 76, 81, 83, 96, 110, 127, 128, 130, 131, 134, 135, 136,
+ 138, 139, 146, 163, 174, 178, 181, 267, 274, 2137, 2138, 2139, 2165, 2166,
+ 2169, 2172, 4135, 20613,
+};
+
+static const unsigned short dep220[] = {
+ 0, 31, 96, 108, 181, 219, 267, 274,
+};
+
+static const unsigned short dep221[] = {
+ 0, 40, 41, 75, 76, 81, 83, 96, 110, 127, 128, 130, 131, 134, 135, 136, 138,
+ 139, 146, 163, 174, 178, 181, 219, 267, 274, 2137, 2138, 2139, 2165, 2166,
+ 2169, 2172, 4135, 20613,
+};
+
+static const unsigned short dep222[] = {
+ 0, 96, 108, 181, 267, 274, 2139, 2312,
+};
+
+static const unsigned short dep223[] = {
+ 0, 4, 40, 41, 75, 76, 81, 83, 96, 108, 110, 127, 128, 130, 131, 134, 135,
+ 136, 138, 139, 146, 163, 174, 178, 181, 267, 274, 2137, 2138, 2139, 2165,
+ 2166, 2169, 2172, 2312, 4135, 20613,
+};
+
+static const unsigned short dep224[] = {
+ 0, 4, 5, 40, 41, 75, 76, 81, 83, 96, 108, 110, 127, 128, 130, 131, 134, 135,
+ 136, 138, 139, 146, 163, 174, 178, 181, 267, 274, 2137, 2138, 2139, 2165,
+ 2166, 2169, 2172, 2312, 4135, 20613,
+};
+
+static const unsigned short dep225[] = {
+ 0, 40, 41, 75, 76, 81, 83, 96, 108, 110, 127, 128, 130, 131, 134, 135, 136,
+ 138, 139, 146, 163, 174, 178, 181, 267, 274, 2137, 2138, 2139, 2165, 2166,
+ 2169, 2172, 2312, 4135, 20613,
+};
+
+static const unsigned short dep226[] = {
+ 40, 41, 96, 174, 267, 2134, 2135, 2136, 2165, 2166, 2169, 2172, 2312, 4135,
+ 16524, 16526, 20613,
+};
+
+static const unsigned short dep227[] = {
+ 0, 40, 41, 75, 76, 81, 83, 96, 110, 127, 128, 130, 131, 134, 135, 136, 138,
+ 139, 146, 163, 174, 178, 181, 267, 274, 2137, 2138, 2139, 2165, 2166, 2169,
+ 2172, 2312, 4135, 20613,
+};
+
+static const unsigned short dep228[] = {
+ 0, 31, 96, 108, 181, 219, 267, 274, 2139, 2312,
+};
+
+static const unsigned short dep229[] = {
+ 0, 40, 41, 75, 76, 81, 83, 96, 110, 127, 128, 130, 131, 134, 135, 136, 138,
+ 139, 146, 163, 174, 178, 181, 219, 267, 274, 2137, 2138, 2139, 2165, 2166,
+ 2169, 2172, 2312, 4135, 20613,
+};
+
+static const unsigned short dep230[] = {
+ 40, 41, 75, 76, 81, 83, 96, 108, 110, 127, 128, 130, 131, 134, 135, 136, 138,
+ 139, 146, 163, 174, 178, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2310,
+ 4135, 16524, 16526, 18746, 18748, 18749, 18751, 20613,
+};
+
+static const unsigned short dep231[] = {
+ 40, 41, 44, 75, 76, 81, 83, 96, 108, 110, 127, 128, 130, 131, 134, 135, 136,
+ 138, 139, 146, 148, 163, 174, 178, 267, 2137, 2138, 2139, 2165, 2166, 2169,
+ 2172, 2310, 4135, 16524, 16526, 18746, 18748, 18749, 18751, 20613,
+};
+
+static const unsigned short dep232[] = {
+ 0, 96, 181, 267, 2135, 2310, 18593, 18594, 18746, 18747, 18749, 18750,
+};
+
+static const unsigned short dep233[] = {
+ 0, 40, 41, 75, 76, 81, 83, 96, 108, 110, 127, 128, 130, 131, 134, 135, 136,
+ 138, 139, 146, 163, 174, 178, 181, 267, 2137, 2138, 2139, 2165, 2166, 2169,
+ 2172, 2310, 4135, 16524, 16526, 18746, 18748, 18749, 18751, 20613,
+};
+
+static const unsigned short dep234[] = {
+ 0, 40, 41, 44, 75, 76, 81, 83, 96, 108, 110, 127, 128, 130, 131, 134, 135,
+ 136, 138, 139, 146, 148, 163, 174, 178, 181, 267, 2137, 2138, 2139, 2165,
+ 2166, 2169, 2172, 2310, 4135, 16524, 16526, 18746, 18748, 18749, 18751, 20613,
+
+};
+
+static const unsigned short dep235[] = {
+ 0, 96, 181, 267, 2136, 2310, 18593, 18594, 18746, 18747, 18749, 18750,
+};
+
+static const unsigned short dep236[] = {
+ 96, 267, 2135, 2139, 2310, 2312, 18593, 18594, 18746, 18747, 18749, 18750,
+
+};
+
+static const unsigned short dep237[] = {
+ 40, 41, 75, 76, 81, 83, 96, 108, 110, 127, 128, 130, 131, 134, 135, 136, 138,
+ 139, 146, 163, 174, 178, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2310,
+ 2312, 4135, 16524, 16526, 18746, 18748, 18749, 18751, 20613,
+};
+
+static const unsigned short dep238[] = {
+ 40, 41, 44, 75, 76, 81, 83, 96, 108, 110, 127, 128, 130, 131, 134, 135, 136,
+ 138, 139, 146, 148, 163, 174, 178, 267, 2137, 2138, 2139, 2165, 2166, 2169,
+ 2172, 2310, 2312, 4135, 16524, 16526, 18746, 18748, 18749, 18751, 20613,
+};
+
+static const unsigned short dep239[] = {
+ 0, 96, 181, 267, 2135, 2139, 2310, 2312, 18593, 18594, 18746, 18747, 18749,
+ 18750,
+};
+
+static const unsigned short dep240[] = {
+ 0, 40, 41, 75, 76, 81, 83, 96, 108, 110, 127, 128, 130, 131, 134, 135, 136,
+ 138, 139, 146, 163, 174, 178, 181, 267, 2137, 2138, 2139, 2165, 2166, 2169,
+ 2172, 2310, 2312, 4135, 16524, 16526, 18746, 18748, 18749, 18751, 20613,
+};
+
+static const unsigned short dep241[] = {
+ 0, 40, 41, 44, 75, 76, 81, 83, 96, 108, 110, 127, 128, 130, 131, 134, 135,
+ 136, 138, 139, 146, 148, 163, 174, 178, 181, 267, 2137, 2138, 2139, 2165,
+ 2166, 2169, 2172, 2310, 2312, 4135, 16524, 16526, 18746, 18748, 18749, 18751,
+ 20613,
+};
+
+static const unsigned short dep242[] = {
+ 0, 96, 181, 267, 2136, 2139, 2310, 2312, 18593, 18594, 18746, 18747, 18749,
+ 18750,
+};
+
+static const unsigned short dep243[] = {
+ 0, 40, 41, 75, 76, 81, 83, 96, 110, 127, 128, 130, 131, 134, 135, 136, 138,
+ 139, 146, 163, 174, 178, 181, 267, 274, 2134, 2135, 2136, 2137, 2138, 2139,
+ 2165, 2166, 2169, 2172, 4135, 16524, 16526, 20613,
+};
+
+static const unsigned short dep244[] = {
+ 40, 41, 75, 96, 134, 148, 174, 267, 2165, 2166, 2169, 2172, 4135,
+};
+
+static const unsigned short dep245[] = {
+ 40, 41, 75, 96, 134, 135, 139, 148, 174, 267, 2165, 2166, 2169, 2172, 4135,
+
+};
+
+static const unsigned short dep246[] = {
+ 40, 41, 75, 96, 134, 148, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172,
+ 2312, 4135, 20613,
+};
+
+static const unsigned short dep247[] = {
+ 40, 41, 75, 96, 134, 135, 139, 148, 174, 267, 2137, 2138, 2139, 2165, 2166,
+ 2169, 2172, 2312, 4135, 20613,
+};
+
+static const unsigned short dep248[] = {
+ 40, 41, 96, 174, 267, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2310, 4135,
+ 16524, 16526, 18746, 18748, 18749, 18751, 20613,
+};
+
+static const unsigned short dep249[] = {
+ 0, 40, 41, 75, 76, 81, 83, 96, 110, 127, 128, 130, 131, 134, 135, 136, 138,
+ 139, 146, 163, 174, 178, 181, 267, 274, 2134, 2135, 2136, 2137, 2138, 2139,
+ 2165, 2166, 2169, 2172, 2312, 4135, 16524, 16526, 20613,
+};
+
+static const unsigned short dep250[] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 24, 26, 27, 28, 29, 30, 31, 96, 182, 183, 184, 185, 186, 187, 188, 189,
+ 190, 191, 192, 193, 194, 195, 197, 198, 200, 201, 203, 204, 206, 207, 208,
+ 209, 210, 211, 213, 216, 217, 218, 219, 267, 2071, 2081, 2139, 2260, 2269,
+ 2312, 28852, 29002,
+};
+
+static const unsigned short dep251[] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 24, 25, 26, 28, 29, 30, 31, 40, 41, 96, 134, 171, 174, 182, 183, 184,
+ 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 197, 198, 200, 201,
+ 203, 204, 206, 207, 208, 209, 210, 211, 213, 215, 217, 218, 219, 267, 2071,
+ 2081, 2137, 2138, 2139, 2165, 2166, 2169, 2172, 2260, 2269, 2312, 4135, 20613,
+ 28852, 29002,
+};
+
+#define NELS(X) (sizeof(X)/sizeof(X[0]))
+static const struct ia64_opcode_dependency
+op_dependencies[] = {
+ { NELS(dep1), dep1, NELS(dep0), dep0, },
+ { NELS(dep3), dep3, NELS(dep2), dep2, },
+ { NELS(dep5), dep5, NELS(dep4), dep4, },
+ { NELS(dep7), dep7, NELS(dep6), dep6, },
+ { NELS(dep9), dep9, NELS(dep8), dep8, },
+ { NELS(dep11), dep11, NELS(dep10), dep10, },
+ { NELS(dep13), dep13, NELS(dep12), dep12, },
+ { NELS(dep15), dep15, NELS(dep14), dep14, },
+ { NELS(dep17), dep17, NELS(dep16), dep16, },
+ { NELS(dep19), dep19, NELS(dep18), dep18, },
+ { NELS(dep21), dep21, NELS(dep20), dep20, },
+ { NELS(dep23), dep23, NELS(dep22), dep22, },
+ { NELS(dep25), dep25, NELS(dep24), dep24, },
+ { NELS(dep27), dep27, NELS(dep26), dep26, },
+ { NELS(dep28), dep28, NELS(dep12), dep12, },
+ { NELS(dep30), dep30, NELS(dep29), dep29, },
+ { NELS(dep32), dep32, NELS(dep31), dep31, },
+ { NELS(dep33), dep33, NELS(dep12), dep12, },
+ { NELS(dep35), dep35, NELS(dep34), dep34, },
+ { NELS(dep37), dep37, NELS(dep36), dep36, },
+ { NELS(dep39), dep39, NELS(dep38), dep38, },
+ { NELS(dep40), dep40, NELS(dep29), dep29, },
+ { NELS(dep41), dep41, NELS(dep31), dep31, },
+ { NELS(dep43), dep43, NELS(dep42), dep42, },
+ { NELS(dep45), dep45, NELS(dep44), dep44, },
+ { NELS(dep47), dep47, NELS(dep46), dep46, },
+ { NELS(dep49), dep49, NELS(dep48), dep48, },
+ { NELS(dep51), dep51, NELS(dep50), dep50, },
+ { NELS(dep53), dep53, NELS(dep52), dep52, },
+ { NELS(dep55), dep55, NELS(dep54), dep54, },
+ { NELS(dep57), dep57, NELS(dep56), dep56, },
+ { NELS(dep59), dep59, NELS(dep58), dep58, },
+ { NELS(dep61), dep61, NELS(dep60), dep60, },
+ { NELS(dep63), dep63, NELS(dep62), dep62, },
+ { NELS(dep65), dep65, NELS(dep64), dep64, },
+ { NELS(dep66), dep66, NELS(dep31), dep31, },
+ { NELS(dep68), dep68, NELS(dep67), dep67, },
+ { NELS(dep70), dep70, NELS(dep69), dep69, },
+ { NELS(dep72), dep72, NELS(dep71), dep71, },
+ { NELS(dep74), dep74, NELS(dep73), dep73, },
+ { NELS(dep75), dep75, NELS(dep31), dep31, },
+ { NELS(dep77), dep77, NELS(dep76), dep76, },
+ { NELS(dep79), dep79, NELS(dep78), dep78, },
+ { NELS(dep81), dep81, NELS(dep80), dep80, },
+ { NELS(dep82), dep82, NELS(dep31), dep31, },
+ { NELS(dep83), dep83, NELS(dep31), dep31, },
+ { NELS(dep84), dep84, NELS(dep31), dep31, },
+ { NELS(dep85), dep85, NELS(dep31), dep31, },
+ { NELS(dep87), dep87, NELS(dep86), dep86, },
+ { NELS(dep89), dep89, NELS(dep88), dep88, },
+ { NELS(dep91), dep91, NELS(dep90), dep90, },
+ { NELS(dep93), dep93, NELS(dep92), dep92, },
+ { NELS(dep95), dep95, NELS(dep94), dep94, },
+ { NELS(dep97), dep97, NELS(dep96), dep96, },
+ { NELS(dep99), dep99, NELS(dep98), dep98, },
+ { NELS(dep101), dep101, NELS(dep100), dep100, },
+ { NELS(dep103), dep103, NELS(dep102), dep102, },
+ { NELS(dep105), dep105, NELS(dep104), dep104, },
+ { NELS(dep107), dep107, NELS(dep106), dep106, },
+ { NELS(dep109), dep109, NELS(dep108), dep108, },
+ { NELS(dep111), dep111, NELS(dep110), dep110, },
+ { NELS(dep113), dep113, NELS(dep112), dep112, },
+ { NELS(dep115), dep115, NELS(dep114), dep114, },
+ { NELS(dep117), dep117, NELS(dep116), dep116, },
+ { NELS(dep119), dep119, NELS(dep118), dep118, },
+ { NELS(dep120), dep120, NELS(dep62), dep62, },
+ { NELS(dep121), dep121, NELS(dep31), dep31, },
+ { NELS(dep123), dep123, NELS(dep122), dep122, },
+ { NELS(dep124), dep124, NELS(dep0), dep0, },
+ { NELS(dep126), dep126, NELS(dep125), dep125, },
+ { NELS(dep128), dep128, NELS(dep127), dep127, },
+ { NELS(dep129), dep129, NELS(dep0), dep0, },
+ { NELS(dep130), dep130, NELS(dep0), dep0, },
+ { NELS(dep132), dep132, NELS(dep131), dep131, },
+ { NELS(dep133), dep133, NELS(dep0), dep0, },
+ { NELS(dep134), dep134, NELS(dep31), dep31, },
+ { NELS(dep136), dep136, NELS(dep135), dep135, },
+ { NELS(dep137), dep137, NELS(dep135), dep135, },
+ { NELS(dep139), dep139, NELS(dep138), dep138, },
+ { NELS(dep140), dep140, NELS(dep138), dep138, },
+ { NELS(dep141), dep141, NELS(dep135), dep135, },
+ { NELS(dep143), dep143, NELS(dep142), dep142, },
+ { NELS(dep145), dep145, NELS(dep144), dep144, },
+ { NELS(dep147), dep147, NELS(dep146), dep146, },
+ { NELS(dep149), dep149, NELS(dep148), dep148, },
+ { NELS(dep150), dep150, NELS(dep0), dep0, },
+ { NELS(dep152), dep152, NELS(dep151), dep151, },
+ { NELS(dep154), dep154, NELS(dep153), dep153, },
+ { NELS(dep156), dep156, NELS(dep155), dep155, },
+ { NELS(dep158), dep158, NELS(dep157), dep157, },
+ { NELS(dep160), dep160, NELS(dep159), dep159, },
+ { NELS(dep161), dep161, NELS(dep0), dep0, },
+ { NELS(dep162), dep162, NELS(dep0), dep0, },
+ { NELS(dep163), dep163, NELS(dep0), dep0, },
+ { NELS(dep164), dep164, NELS(dep31), dep31, },
+ { NELS(dep166), dep166, NELS(dep165), dep165, },
+ { NELS(dep167), dep167, NELS(dep165), dep165, },
+ { NELS(dep169), dep169, NELS(dep168), dep168, },
+ { NELS(dep171), dep171, NELS(dep170), dep170, },
+ { NELS(dep173), dep173, NELS(dep172), dep172, },
+ { NELS(dep175), dep175, NELS(dep174), dep174, },
+ { NELS(dep177), dep177, NELS(dep176), dep176, },
+ { NELS(dep179), dep179, NELS(dep178), dep178, },
+ { NELS(dep181), dep181, NELS(dep180), dep180, },
+ { NELS(dep183), dep183, NELS(dep182), dep182, },
+ { NELS(dep185), dep185, NELS(dep184), dep184, },
+ { NELS(dep186), dep186, NELS(dep0), dep0, },
+ { NELS(dep187), dep187, NELS(dep0), dep0, },
+ { NELS(dep188), dep188, NELS(dep0), dep0, },
+ { NELS(dep189), dep189, NELS(dep0), dep0, },
+ { NELS(dep190), dep190, NELS(dep0), dep0, },
+ { NELS(dep191), dep191, NELS(dep0), dep0, },
+ { NELS(dep192), dep192, NELS(dep0), dep0, },
+ { NELS(dep193), dep193, NELS(dep0), dep0, },
+ { NELS(dep195), dep195, NELS(dep194), dep194, },
+ { NELS(dep197), dep197, NELS(dep196), dep196, },
+ { NELS(dep199), dep199, NELS(dep198), dep198, },
+ { NELS(dep201), dep201, NELS(dep200), dep200, },
+ { NELS(dep202), dep202, NELS(dep0), dep0, },
+ { NELS(dep203), dep203, NELS(dep0), dep0, },
+ { NELS(dep204), dep204, NELS(dep0), dep0, },
+ { NELS(dep205), dep205, NELS(dep31), dep31, },
+ { NELS(dep206), dep206, NELS(dep31), dep31, },
+ { NELS(dep207), dep207, NELS(dep194), dep194, },
+ { NELS(dep208), dep208, NELS(dep0), dep0, },
+ { NELS(dep210), dep210, NELS(dep209), dep209, },
+ { NELS(dep211), dep211, NELS(dep0), dep0, },
+ { NELS(dep213), dep213, NELS(dep212), dep212, },
+ { NELS(dep214), dep214, NELS(dep212), dep212, },
+ { NELS(dep215), dep215, NELS(dep0), dep0, },
+ { NELS(dep213), dep213, NELS(dep216), dep216, },
+ { NELS(dep218), dep218, NELS(dep217), dep217, },
+ { NELS(dep219), dep219, NELS(dep217), dep217, },
+ { NELS(dep221), dep221, NELS(dep220), dep220, },
+ { NELS(dep223), dep223, NELS(dep222), dep222, },
+ { NELS(dep224), dep224, NELS(dep222), dep222, },
+ { NELS(dep225), dep225, NELS(dep222), dep222, },
+ { NELS(dep226), dep226, NELS(dep0), dep0, },
+ { NELS(dep227), dep227, NELS(dep222), dep222, },
+ { NELS(dep229), dep229, NELS(dep228), dep228, },
+ { NELS(dep230), dep230, NELS(dep62), dep62, },
+ { NELS(dep231), dep231, NELS(dep62), dep62, },
+ { NELS(dep233), dep233, NELS(dep232), dep232, },
+ { NELS(dep234), dep234, NELS(dep232), dep232, },
+ { NELS(dep233), dep233, NELS(dep235), dep235, },
+ { NELS(dep237), dep237, NELS(dep236), dep236, },
+ { NELS(dep238), dep238, NELS(dep236), dep236, },
+ { NELS(dep240), dep240, NELS(dep239), dep239, },
+ { NELS(dep241), dep241, NELS(dep239), dep239, },
+ { NELS(dep240), dep240, NELS(dep242), dep242, },
+ { NELS(dep243), dep243, NELS(dep217), dep217, },
+ { NELS(dep244), dep244, NELS(dep31), dep31, },
+ { NELS(dep245), dep245, NELS(dep31), dep31, },
+ { NELS(dep246), dep246, NELS(dep0), dep0, },
+ { NELS(dep247), dep247, NELS(dep0), dep0, },
+ { NELS(dep248), dep248, NELS(dep62), dep62, },
+ { NELS(dep249), dep249, NELS(dep222), dep222, },
+ { 0, NULL, 0, NULL, },
+ { NELS(dep251), dep251, NELS(dep250), dep250, },
+};
+
+static const struct ia64_completer_table
+completer_table[] = {
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 88 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 88 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, 576, -1, 0, 1, 6 },
+ { 0x0, 0x0, 0, 639, -1, 0, 1, 17 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 157 },
+ { 0x0, 0x0, 0, 738, -1, 0, 1, 17 },
+ { 0x0, 0x0, 0, 2164, -1, 0, 1, 10 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 9 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 13 },
+ { 0x1, 0x1, 0, -1, -1, 13, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 33 },
+ { 0x0, 0x0, 0, 2372, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 33 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 33 },
+ { 0x0, 0x0, 0, 1122, -1, 0, 1, 122 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 44 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 40 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 78 },
+ { 0x0, 0x0, 0, 2212, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, 2439, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, 2216, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 33 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 33 },
+ { 0x0, 0x0, 0, 2218, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, 2448, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, 2451, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 33 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 33 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 33 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, 2473, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 33 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 33 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, 2476, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 24 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 24 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 24 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 24 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 33 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 35 },
+ { 0x0, 0x0, 0, 2484, -1, 0, 1, 29 },
+ { 0x0, 0x0, 0, 1391, -1, 0, 1, 33 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 40 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 33 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 157 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 77 },
+ { 0x0, 0x0, 0, 1439, -1, 0, 1, 124 },
+ { 0x0, 0x0, 0, 1448, -1, 0, 1, 124 },
+ { 0x0, 0x0, 0, 1457, -1, 0, 1, 124 },
+ { 0x0, 0x0, 0, 1459, -1, 0, 1, 125 },
+ { 0x0, 0x0, 0, 1461, -1, 0, 1, 125 },
+ { 0x0, 0x0, 0, 1470, -1, 0, 1, 124 },
+ { 0x0, 0x0, 0, 1479, -1, 0, 1, 124 },
+ { 0x0, 0x0, 0, 1488, -1, 0, 1, 124 },
+ { 0x0, 0x0, 0, 1497, -1, 0, 1, 124 },
+ { 0x0, 0x0, 0, 1506, -1, 0, 1, 124 },
+ { 0x0, 0x0, 0, 1515, -1, 0, 1, 124 },
+ { 0x0, 0x0, 0, 1525, -1, 0, 1, 124 },
+ { 0x0, 0x0, 0, 1535, -1, 0, 1, 124 },
+ { 0x0, 0x0, 0, 1545, -1, 0, 1, 124 },
+ { 0x0, 0x0, 0, 1554, -1, 0, 1, 140 },
+ { 0x0, 0x0, 0, 1560, -1, 0, 1, 145 },
+ { 0x0, 0x0, 0, 1566, -1, 0, 1, 145 },
+ { 0x0, 0x0, 0, 1572, -1, 0, 1, 140 },
+ { 0x0, 0x0, 0, 1578, -1, 0, 1, 145 },
+ { 0x0, 0x0, 0, 1584, -1, 0, 1, 145 },
+ { 0x0, 0x0, 0, 1590, -1, 0, 1, 140 },
+ { 0x0, 0x0, 0, 1596, -1, 0, 1, 145 },
+ { 0x0, 0x0, 0, 1602, -1, 0, 1, 145 },
+ { 0x0, 0x0, 0, 1608, -1, 0, 1, 140 },
+ { 0x0, 0x0, 0, 1614, -1, 0, 1, 145 },
+ { 0x0, 0x0, 0, 1620, -1, 0, 1, 140 },
+ { 0x0, 0x0, 0, 1626, -1, 0, 1, 145 },
+ { 0x0, 0x0, 0, 1632, -1, 0, 1, 140 },
+ { 0x0, 0x0, 0, 1638, -1, 0, 1, 145 },
+ { 0x0, 0x0, 0, 1644, -1, 0, 1, 140 },
+ { 0x0, 0x0, 0, 1650, -1, 0, 1, 145 },
+ { 0x0, 0x0, 0, 1656, -1, 0, 1, 145 },
+ { 0x0, 0x0, 0, 1660, -1, 0, 1, 151 },
+ { 0x0, 0x0, 0, 1664, -1, 0, 1, 153 },
+ { 0x0, 0x0, 0, 1668, -1, 0, 1, 153 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 79 },
+ { 0x0, 0x0, 0, 256, -1, 0, 1, 40 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 33 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 67 },
+ { 0x1, 0x1, 0, 1148, -1, 20, 1, 67 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 68 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 69 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 69 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 70 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 71 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 72 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 86 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 87 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 89 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 90 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 91 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 92 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 97 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 98 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 99 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 100 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 101 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 102 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 103 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 106 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 107 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 108 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 109 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 110 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 111 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 112 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 113 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 158 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 158 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 158 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 71 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 157 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, 2824, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, 2825, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, 2176, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, 2177, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, 2839, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, 2840, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, 2841, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, 2842, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, 2843, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, 2826, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, 2827, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 11 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 84 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 83 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x1, 0x1, 0, -1, -1, 13, 1, 0 },
+ { 0x0, 0x0, 0, 2845, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 84 },
+ { 0x0, 0x0, 0, 1948, -1, 0, 1, 131 },
+ { 0x0, 0x0, 0, 1950, -1, 0, 1, 138 },
+ { 0x0, 0x0, 0, 1952, -1, 0, 1, 132 },
+ { 0x0, 0x0, 0, 1954, -1, 0, 1, 132 },
+ { 0x0, 0x0, 0, 1956, -1, 0, 1, 131 },
+ { 0x0, 0x0, 0, 1958, -1, 0, 1, 138 },
+ { 0x0, 0x0, 0, 1960, -1, 0, 1, 131 },
+ { 0x0, 0x0, 0, 1962, -1, 0, 1, 138 },
+ { 0x0, 0x0, 0, 1965, -1, 0, 1, 131 },
+ { 0x0, 0x0, 0, 1968, -1, 0, 1, 138 },
+ { 0x0, 0x0, 0, 1971, -1, 0, 1, 150 },
+ { 0x0, 0x0, 0, 1972, -1, 0, 1, 156 },
+ { 0x0, 0x0, 0, 1973, -1, 0, 1, 150 },
+ { 0x0, 0x0, 0, 1974, -1, 0, 1, 156 },
+ { 0x0, 0x0, 0, 1975, -1, 0, 1, 150 },
+ { 0x0, 0x0, 0, 1976, -1, 0, 1, 156 },
+ { 0x0, 0x0, 0, 1977, -1, 0, 1, 150 },
+ { 0x0, 0x0, 0, 1978, -1, 0, 1, 156 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 82 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 120 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 118 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 120 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 119 },
+ { 0x0, 0x0, 0, 1669, -1, 0, 1, 136 },
+ { 0x0, 0x0, 0, 1670, -1, 0, 1, 136 },
+ { 0x0, 0x0, 0, 1671, -1, 0, 1, 136 },
+ { 0x0, 0x0, 0, 1672, -1, 0, 1, 136 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 0, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 1, 223, -1, 0, 1, 12 },
+ { 0x1, 0x1, 2, -1, -1, 27, 1, 12 },
+ { 0x0, 0x0, 3, -1, 1322, 0, 0, -1 },
+ { 0x0, 0x0, 3, -1, 1323, 0, 0, -1 },
+ { 0x1, 0x1, 3, 2715, 1432, 33, 1, 127 },
+ { 0x1, 0x1, 3, 2716, 1441, 33, 1, 127 },
+ { 0x1, 0x1, 3, 2717, 1450, 33, 1, 127 },
+ { 0x1, 0x1, 3, 2718, 1463, 33, 1, 127 },
+ { 0x1, 0x1, 3, 2719, 1472, 33, 1, 127 },
+ { 0x1, 0x1, 3, 2720, 1481, 33, 1, 127 },
+ { 0x1, 0x1, 3, 2721, 1490, 33, 1, 127 },
+ { 0x1, 0x1, 3, 2722, 1499, 33, 1, 127 },
+ { 0x1, 0x1, 3, 2723, 1508, 33, 1, 127 },
+ { 0x1, 0x1, 3, 2724, 1517, 33, 1, 127 },
+ { 0x1, 0x1, 3, 2725, 1527, 33, 1, 127 },
+ { 0x1, 0x1, 3, 2726, 1537, 33, 1, 127 },
+ { 0x1, 0x1, 3, 2727, 1550, 33, 1, 142 },
+ { 0x1, 0x1, 3, 2728, 1556, 33, 1, 147 },
+ { 0x1, 0x1, 3, 2729, 1562, 33, 1, 147 },
+ { 0x1, 0x1, 3, 2730, 1568, 33, 1, 142 },
+ { 0x1, 0x1, 3, 2731, 1574, 33, 1, 147 },
+ { 0x1, 0x1, 3, 2732, 1580, 33, 1, 147 },
+ { 0x1, 0x1, 3, 2733, 1586, 33, 1, 142 },
+ { 0x1, 0x1, 3, 2734, 1592, 33, 1, 147 },
+ { 0x1, 0x1, 3, 2735, 1598, 33, 1, 147 },
+ { 0x1, 0x1, 3, 2736, 1604, 33, 1, 142 },
+ { 0x1, 0x1, 3, 2737, 1610, 33, 1, 147 },
+ { 0x1, 0x1, 3, 2738, 1616, 33, 1, 142 },
+ { 0x1, 0x1, 3, 2739, 1622, 33, 1, 147 },
+ { 0x1, 0x1, 3, 2740, 1628, 33, 1, 142 },
+ { 0x1, 0x1, 3, 2741, 1634, 33, 1, 147 },
+ { 0x1, 0x1, 3, 2742, 1640, 33, 1, 142 },
+ { 0x1, 0x1, 3, 2743, 1646, 33, 1, 147 },
+ { 0x1, 0x1, 3, 2744, 1652, 33, 1, 147 },
+ { 0x1, 0x1, 3, -1, -1, 27, 1, 40 },
+ { 0x0, 0x0, 4, 2178, 1407, 0, 1, 135 },
+ { 0x0, 0x0, 4, 2179, 1409, 0, 1, 135 },
+ { 0x0, 0x0, 4, 2180, 1411, 0, 1, 134 },
+ { 0x0, 0x0, 4, 2181, 1413, 0, 1, 134 },
+ { 0x0, 0x0, 4, 2182, 1415, 0, 1, 134 },
+ { 0x0, 0x0, 4, 2183, 1417, 0, 1, 134 },
+ { 0x0, 0x0, 4, 2184, 1419, 0, 1, 134 },
+ { 0x0, 0x0, 4, 2185, 1421, 0, 1, 134 },
+ { 0x0, 0x0, 4, 2186, 1423, 0, 1, 134 },
+ { 0x0, 0x0, 4, 2187, 1425, 0, 1, 134 },
+ { 0x0, 0x0, 4, 2188, 1427, 0, 1, 136 },
+ { 0x0, 0x0, 4, 2189, 1429, 0, 1, 136 },
+ { 0x1, 0x1, 4, -1, 1436, 33, 1, 130 },
+ { 0x5, 0x5, 4, 534, 1435, 32, 1, 124 },
+ { 0x1, 0x1, 4, -1, 1445, 33, 1, 130 },
+ { 0x5, 0x5, 4, 535, 1444, 32, 1, 124 },
+ { 0x1, 0x1, 4, -1, 1454, 33, 1, 130 },
+ { 0x5, 0x5, 4, 536, 1453, 32, 1, 124 },
+ { 0x1, 0x1, 4, -1, 1458, 32, 1, 125 },
+ { 0x1, 0x1, 4, -1, 1460, 32, 1, 125 },
+ { 0x1, 0x1, 4, -1, 1467, 33, 1, 130 },
+ { 0x5, 0x5, 4, 537, 1466, 32, 1, 124 },
+ { 0x1, 0x1, 4, -1, 1476, 33, 1, 130 },
+ { 0x5, 0x5, 4, 538, 1475, 32, 1, 124 },
+ { 0x1, 0x1, 4, -1, 1485, 33, 1, 130 },
+ { 0x5, 0x5, 4, 539, 1484, 32, 1, 124 },
+ { 0x1, 0x1, 4, -1, 1494, 33, 1, 130 },
+ { 0x5, 0x5, 4, 540, 1493, 32, 1, 124 },
+ { 0x1, 0x1, 4, -1, 1503, 33, 1, 130 },
+ { 0x5, 0x5, 4, 541, 1502, 32, 1, 124 },
+ { 0x1, 0x1, 4, -1, 1512, 33, 1, 130 },
+ { 0x5, 0x5, 4, 542, 1511, 32, 1, 124 },
+ { 0x1, 0x1, 4, -1, 1522, 33, 1, 130 },
+ { 0x5, 0x5, 4, 1018, 1520, 32, 1, 124 },
+ { 0x1, 0x1, 4, -1, 1532, 33, 1, 130 },
+ { 0x5, 0x5, 4, 1019, 1530, 32, 1, 124 },
+ { 0x1, 0x1, 4, -1, 1542, 33, 1, 130 },
+ { 0x5, 0x5, 4, 1020, 1540, 32, 1, 124 },
+ { 0x1, 0x21, 10, 1991, -1, 33, 1, 3 },
+ { 0x200001, 0x200001, 10, 1992, -1, 12, 1, 3 },
+ { 0x1, 0x21, 10, 410, -1, 33, 1, 3 },
+ { 0x200001, 0x200001, 10, 2048, -1, 12, 1, 3 },
+ { 0x0, 0x0, 10, -1, 2049, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2050, 0, 0, -1 },
+ { 0x0, 0x0, 10, 1995, -1, 0, 1, 3 },
+ { 0x1, 0x1, 10, 1996, -1, 12, 1, 3 },
+ { 0x1, 0x1, 10, 1997, -1, 33, 1, 3 },
+ { 0x200001, 0x200001, 10, 1998, -1, 12, 1, 3 },
+ { 0x0, 0x0, 10, 420, -1, 0, 1, 3 },
+ { 0x1, 0x1, 10, 2054, -1, 12, 1, 3 },
+ { 0x1, 0x1, 10, 424, -1, 33, 1, 3 },
+ { 0x200001, 0x200001, 10, 2056, -1, 12, 1, 3 },
+ { 0x0, 0x0, 10, 428, -1, 0, 1, 3 },
+ { 0x1, 0x1, 10, 2058, -1, 12, 1, 3 },
+ { 0x1, 0x1, 10, 432, -1, 33, 1, 3 },
+ { 0x200001, 0x200001, 10, 2060, -1, 12, 1, 3 },
+ { 0x0, 0x0, 10, 436, -1, 0, 1, 3 },
+ { 0x1, 0x1, 10, 2062, -1, 12, 1, 3 },
+ { 0x1, 0x1, 10, 440, -1, 33, 1, 3 },
+ { 0x200001, 0x200001, 10, 2064, -1, 12, 1, 3 },
+ { 0x1, 0x21, 10, 2011, -1, 33, 1, 3 },
+ { 0x200001, 0x200001, 10, 2012, -1, 12, 1, 3 },
+ { 0x1, 0x21, 10, 450, -1, 33, 1, 3 },
+ { 0x200001, 0x200001, 10, 2070, -1, 12, 1, 3 },
+ { 0x0, 0x0, 10, -1, 2071, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2072, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2075, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2076, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2077, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2078, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2079, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2080, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2081, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2082, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2083, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2084, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2085, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2086, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2087, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2088, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2089, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2090, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2091, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2092, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2093, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2094, 0, 0, -1 },
+ { 0x1, 0x21, 10, 2015, -1, 33, 1, 3 },
+ { 0x200001, 0x200001, 10, 2016, -1, 12, 1, 3 },
+ { 0x1, 0x21, 10, 458, -1, 33, 1, 3 },
+ { 0x200001, 0x200001, 10, 2096, -1, 12, 1, 3 },
+ { 0x0, 0x0, 10, -1, 2097, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2098, 0, 0, -1 },
+ { 0x0, 0x0, 10, 2019, -1, 0, 1, 3 },
+ { 0x1, 0x1, 10, 2020, -1, 12, 1, 3 },
+ { 0x1, 0x1, 10, 2021, -1, 33, 1, 3 },
+ { 0x200001, 0x200001, 10, 2022, -1, 12, 1, 3 },
+ { 0x0, 0x0, 10, 468, -1, 0, 1, 3 },
+ { 0x1, 0x1, 10, 2102, -1, 12, 1, 3 },
+ { 0x1, 0x1, 10, 472, -1, 33, 1, 3 },
+ { 0x200001, 0x200001, 10, 2104, -1, 12, 1, 3 },
+ { 0x0, 0x0, 10, 476, -1, 0, 1, 3 },
+ { 0x1, 0x1, 10, 2106, -1, 12, 1, 3 },
+ { 0x1, 0x1, 10, 480, -1, 33, 1, 3 },
+ { 0x200001, 0x200001, 10, 2108, -1, 12, 1, 3 },
+ { 0x0, 0x0, 10, 484, -1, 0, 1, 3 },
+ { 0x1, 0x1, 10, 2110, -1, 12, 1, 3 },
+ { 0x1, 0x1, 10, 488, -1, 33, 1, 3 },
+ { 0x200001, 0x200001, 10, 2112, -1, 12, 1, 3 },
+ { 0x1, 0x21, 10, 2035, -1, 33, 1, 3 },
+ { 0x200001, 0x200001, 10, 2036, -1, 12, 1, 3 },
+ { 0x1, 0x21, 10, 498, -1, 33, 1, 3 },
+ { 0x200001, 0x200001, 10, 2118, -1, 12, 1, 3 },
+ { 0x0, 0x0, 10, -1, 2119, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2120, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2123, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2124, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2125, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2126, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2127, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2128, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2129, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2130, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2131, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2132, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2133, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2134, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2135, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2136, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2137, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2138, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2139, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2140, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2141, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2142, 0, 0, -1 },
+ { 0x1, 0x1, 10, 2039, -1, 36, 1, 3 },
+ { 0x1000001, 0x1000001, 10, 2040, -1, 12, 1, 3 },
+ { 0x1, 0x1, 10, 2041, -1, 36, 1, 3 },
+ { 0x1000001, 0x1000001, 10, 2042, -1, 12, 1, 3 },
+ { 0x0, 0x0, 10, -1, 2143, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2145, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2147, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2149, 0, 0, -1 },
+ { 0x1, 0x1, 10, 2043, -1, 36, 1, 3 },
+ { 0x1000001, 0x1000001, 10, 2044, -1, 12, 1, 3 },
+ { 0x1, 0x1, 10, 2045, -1, 36, 1, 3 },
+ { 0x1000001, 0x1000001, 10, 2046, -1, 12, 1, 3 },
+ { 0x0, 0x0, 10, -1, 2151, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2153, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2155, 0, 0, -1 },
+ { 0x0, 0x0, 10, -1, 2157, 0, 0, -1 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x200001, 0x4200001, 11, 1993, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x1, 0x1, 11, 298, -1, 33, 1, 3 },
+ { 0x0, 0x0, 11, 2051, -1, 0, 1, 3 },
+ { 0x1, 0x1, 11, 2052, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x1, 0x1, 11, 1999, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x0, 0x0, 11, 306, -1, 0, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x200001, 0x200001, 11, 2001, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x1, 0x1, 11, 308, -1, 33, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x1, 0x1, 11, 2003, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x0, 0x0, 11, 310, -1, 0, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x200001, 0x200001, 11, 2005, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x1, 0x1, 11, 312, -1, 33, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x1, 0x1, 11, 2007, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x0, 0x0, 11, 314, -1, 0, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x200001, 0x200001, 11, 2009, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x1, 0x1, 11, 316, -1, 33, 1, 3 },
+ { 0x0, 0x0, 11, 2065, -1, 0, 1, 3 },
+ { 0x1, 0x1, 11, 2066, -1, 12, 1, 3 },
+ { 0x1, 0x1, 11, 2067, -1, 33, 1, 3 },
+ { 0x200001, 0x200001, 11, 2068, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x200001, 0x4200001, 11, 2013, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x1, 0x1, 11, 320, -1, 33, 1, 3 },
+ { 0x0, 0x0, 11, 2073, -1, 0, 1, 3 },
+ { 0x1, 0x1, 11, 2074, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x200001, 0x4200001, 11, 2017, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x1, 0x1, 11, 346, -1, 33, 1, 3 },
+ { 0x0, 0x0, 11, 2099, -1, 0, 1, 3 },
+ { 0x1, 0x1, 11, 2100, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x1, 0x1, 11, 2023, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x0, 0x0, 11, 354, -1, 0, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x200001, 0x200001, 11, 2025, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x1, 0x1, 11, 356, -1, 33, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x1, 0x1, 11, 2027, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x0, 0x0, 11, 358, -1, 0, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x200001, 0x200001, 11, 2029, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x1, 0x1, 11, 360, -1, 33, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x1, 0x1, 11, 2031, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x0, 0x0, 11, 362, -1, 0, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x200001, 0x200001, 11, 2033, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x1, 0x1, 11, 364, -1, 33, 1, 3 },
+ { 0x0, 0x0, 11, 2113, -1, 0, 1, 3 },
+ { 0x1, 0x1, 11, 2114, -1, 12, 1, 3 },
+ { 0x1, 0x1, 11, 2115, -1, 33, 1, 3 },
+ { 0x200001, 0x200001, 11, 2116, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x200001, 0x4200001, 11, 2037, -1, 12, 1, 3 },
+ { 0x2, 0x3, 11, -1, -1, 37, 1, 5 },
+ { 0x1, 0x1, 11, 368, -1, 33, 1, 3 },
+ { 0x0, 0x0, 11, 2121, -1, 0, 1, 3 },
+ { 0x1, 0x1, 11, 2122, -1, 12, 1, 3 },
+ { 0x1, 0x1, 11, -1, -1, 36, 1, 5 },
+ { 0x1, 0x1, 11, -1, -1, 36, 1, 5 },
+ { 0x1, 0x1, 11, -1, -1, 36, 1, 5 },
+ { 0x1, 0x1, 11, -1, -1, 36, 1, 5 },
+ { 0x1, 0x1, 11, 2144, -1, 36, 1, 3 },
+ { 0x1000001, 0x1000001, 11, 2146, -1, 12, 1, 3 },
+ { 0x1, 0x1, 11, 2148, -1, 36, 1, 3 },
+ { 0x1000001, 0x1000001, 11, 2150, -1, 12, 1, 3 },
+ { 0x1, 0x1, 11, -1, -1, 36, 1, 5 },
+ { 0x1, 0x1, 11, -1, -1, 36, 1, 5 },
+ { 0x1, 0x1, 11, -1, -1, 36, 1, 5 },
+ { 0x1, 0x1, 11, -1, -1, 36, 1, 5 },
+ { 0x1, 0x1, 11, 2152, -1, 36, 1, 3 },
+ { 0x1000001, 0x1000001, 11, 2154, -1, 12, 1, 3 },
+ { 0x1, 0x1, 11, 2156, -1, 36, 1, 3 },
+ { 0x1000001, 0x1000001, 11, 2158, -1, 12, 1, 3 },
+ { 0x0, 0x0, 12, -1, -1, 0, 1, 14 },
+ { 0x0, 0x0, 12, -1, -1, 0, 1, 14 },
+ { 0x0, 0x0, 12, -1, -1, 0, 1, 14 },
+ { 0x1, 0x1, 13, 270, 1434, 34, 1, 124 },
+ { 0x1, 0x1, 13, 272, 1443, 34, 1, 124 },
+ { 0x1, 0x1, 13, 274, 1452, 34, 1, 124 },
+ { 0x1, 0x1, 13, 278, 1465, 34, 1, 124 },
+ { 0x1, 0x1, 13, 280, 1474, 34, 1, 124 },
+ { 0x1, 0x1, 13, 282, 1483, 34, 1, 124 },
+ { 0x1, 0x1, 13, 284, 1492, 34, 1, 124 },
+ { 0x1, 0x1, 13, 286, 1501, 34, 1, 124 },
+ { 0x1, 0x1, 13, 288, 1510, 34, 1, 124 },
+ { 0x1, 0x1, 13, 290, 1519, 34, 1, 124 },
+ { 0x1, 0x1, 13, 292, 1529, 34, 1, 124 },
+ { 0x1, 0x1, 13, 294, 1539, 34, 1, 124 },
+ { 0x0, 0x0, 19, -1, 777, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 778, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 779, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 780, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 781, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 782, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 783, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 784, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 785, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 786, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 787, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 788, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 789, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 790, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 791, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 792, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 793, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 794, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 795, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 796, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 797, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 798, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 799, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 800, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 801, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 802, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 803, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 804, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 805, 0, 0, -1 },
+ { 0x0, 0x0, 19, -1, 806, 0, 0, -1 },
+ { 0x0, 0x0, 20, -1, 2793, 0, 0, -1 },
+ { 0x0, 0x0, 20, -1, 2794, 0, 0, -1 },
+ { 0x0, 0x0, 20, -1, 2809, 0, 0, -1 },
+ { 0x0, 0x0, 20, -1, 2810, 0, 0, -1 },
+ { 0x0, 0x0, 20, -1, 2815, 0, 0, -1 },
+ { 0x0, 0x0, 20, -1, 2816, 0, 0, -1 },
+ { 0x0, 0x0, 21, 813, 2805, 0, 0, -1 },
+ { 0x0, 0x0, 21, 814, 2807, 0, 0, -1 },
+ { 0x0, 0x0, 23, -1, 2803, 0, 0, -1 },
+ { 0x0, 0x0, 23, -1, 2804, 0, 0, -1 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, 1254, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 7 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 7 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 7 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 7 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 7 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 7 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 7 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 7 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 6 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 7 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 7 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 7 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 7 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 8 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 8 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 8 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 8 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 8 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 8 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 8 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 8 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 8 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 8 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 8 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 8 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 15 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 15 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 15 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 15 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 15 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 15 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 15 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 15 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 15 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 15 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 15 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 15 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, 1275, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 18 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 19 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 19 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 19 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 19 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 19 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 19 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 19 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 19 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 19 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 19 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 19 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 19 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 20 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, 1308, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 17 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 35, 1, 21 },
+ { 0x1, 0x1, 24, -1, -1, 33, 1, 76 },
+ { 0x1, 0x1, 24, -1, -1, 33, 1, 76 },
+ { 0x1, 0x1, 24, 1324, 1437, 35, 1, 130 },
+ { 0x1, 0x1, 24, 1325, 1446, 35, 1, 130 },
+ { 0x1, 0x1, 24, 1326, 1455, 35, 1, 130 },
+ { 0x1, 0x1, 24, 1327, 1468, 35, 1, 130 },
+ { 0x1, 0x1, 24, 1328, 1477, 35, 1, 130 },
+ { 0x1, 0x1, 24, 1329, 1486, 35, 1, 130 },
+ { 0x1, 0x1, 24, 1330, 1495, 35, 1, 130 },
+ { 0x1, 0x1, 24, 1331, 1504, 35, 1, 130 },
+ { 0x1, 0x1, 24, 1332, 1513, 35, 1, 130 },
+ { 0x1, 0x1, 24, 1333, 1523, 35, 1, 130 },
+ { 0x1, 0x1, 24, 1334, 1533, 35, 1, 130 },
+ { 0x1, 0x1, 24, 1335, 1543, 35, 1, 130 },
+ { 0x1, 0x1, 24, 1336, 1552, 35, 1, 144 },
+ { 0x1, 0x1, 24, 1337, 1558, 35, 1, 149 },
+ { 0x1, 0x1, 24, 1338, 1564, 35, 1, 149 },
+ { 0x1, 0x1, 24, 1339, 1570, 35, 1, 144 },
+ { 0x1, 0x1, 24, 1340, 1576, 35, 1, 149 },
+ { 0x1, 0x1, 24, 1341, 1582, 35, 1, 149 },
+ { 0x1, 0x1, 24, 1342, 1588, 35, 1, 144 },
+ { 0x1, 0x1, 24, 1343, 1594, 35, 1, 149 },
+ { 0x1, 0x1, 24, 1344, 1600, 35, 1, 149 },
+ { 0x1, 0x1, 24, 1345, 1606, 35, 1, 144 },
+ { 0x1, 0x1, 24, 1346, 1612, 35, 1, 149 },
+ { 0x1, 0x1, 24, 1347, 1618, 35, 1, 144 },
+ { 0x1, 0x1, 24, 1348, 1624, 35, 1, 149 },
+ { 0x1, 0x1, 24, 1349, 1630, 35, 1, 144 },
+ { 0x1, 0x1, 24, 1350, 1636, 35, 1, 149 },
+ { 0x1, 0x1, 24, 1351, 1642, 35, 1, 144 },
+ { 0x1, 0x1, 24, 1352, 1648, 35, 1, 149 },
+ { 0x1, 0x1, 24, 1353, 1654, 35, 1, 149 },
+ { 0x0, 0x0, 33, 2787, 2785, 0, 0, -1 },
+ { 0x0, 0x0, 33, 2790, 2788, 0, 0, -1 },
+ { 0x0, 0x0, 33, 2796, 2795, 0, 0, -1 },
+ { 0x0, 0x0, 33, 2798, 2797, 0, 0, -1 },
+ { 0x0, 0x0, 33, 2812, 2811, 0, 0, -1 },
+ { 0x0, 0x0, 33, 2814, 2813, 0, 0, -1 },
+ { 0x0, 0x0, 35, -1, 2806, 0, 0, -1 },
+ { 0x0, 0x0, 35, -1, 2808, 0, 0, -1 },
+ { 0x1, 0x1, 38, -1, 2256, 37, 1, 29 },
+ { 0x1, 0x1, 38, -1, 2315, 37, 1, 29 },
+ { 0x0, 0x0, 38, -1, 2318, 0, 0, -1 },
+ { 0x1, 0x1, 38, -1, -1, 37, 1, 29 },
+ { 0x1, 0x1, 38, -1, 2323, 37, 1, 29 },
+ { 0x0, 0x0, 38, -1, 2326, 0, 0, -1 },
+ { 0x1, 0x1, 38, -1, -1, 37, 1, 29 },
+ { 0x0, 0x0, 38, -1, 2329, 0, 0, -1 },
+ { 0x1, 0x1, 38, -1, -1, 37, 1, 29 },
+ { 0x1, 0x1, 38, -1, 2332, 37, 1, 29 },
+ { 0x1, 0x1, 38, -1, 2335, 37, 1, 29 },
+ { 0x1, 0x1, 38, -1, 2368, 37, 1, 29 },
+ { 0x3, 0x3, 38, -1, -1, 30, 1, 137 },
+ { 0x0, 0x0, 38, 1124, -1, 0, 1, 95 },
+ { 0x0, 0x0, 38, -1, -1, 0, 1, 104 },
+ { 0x0, 0x0, 38, 1130, -1, 0, 1, 116 },
+ { 0x3, 0x3, 38, -1, -1, 30, 1, 155 },
+ { 0x0, 0x0, 38, 1131, -1, 0, 1, 40 },
+ { 0x0, 0x0, 40, -1, 955, 0, 0, -1 },
+ { 0x0, 0x0, 40, -1, 963, 0, 0, -1 },
+ { 0x0, 0x0, 40, 1133, 959, 0, 0, -1 },
+ { 0x3, 0x3, 40, -1, 604, 33, 1, 6 },
+ { 0x18000001, 0x18000001, 40, -1, 612, 6, 1, 7 },
+ { 0x3, 0x3, 40, 1134, 608, 33, 1, 6 },
+ { 0x0, 0x0, 40, -1, 967, 0, 0, -1 },
+ { 0x3, 0x3, 40, -1, 624, 33, 1, 8 },
+ { 0x0, 0x0, 40, -1, 971, 0, 0, -1 },
+ { 0x3, 0x3, 40, -1, 636, 33, 1, 15 },
+ { 0x0, 0x0, 40, -1, 976, 0, 0, -1 },
+ { 0x0, 0x0, 40, -1, 980, 0, 0, -1 },
+ { 0x3, 0x3, 40, -1, 659, 33, 1, 17 },
+ { 0x3, 0x3, 40, -1, 663, 33, 1, 17 },
+ { 0x0, 0x0, 40, -1, 984, 0, 0, -1 },
+ { 0x0, 0x0, 40, -1, 988, 0, 0, -1 },
+ { 0x3, 0x3, 40, -1, 683, 33, 1, 18 },
+ { 0x18000001, 0x18000001, 40, -1, 687, 6, 1, 18 },
+ { 0x0, 0x0, 40, -1, 992, 0, 0, -1 },
+ { 0x3, 0x3, 40, -1, 699, 33, 1, 19 },
+ { 0x0, 0x0, 40, -1, 996, 0, 0, -1 },
+ { 0x0, 0x0, 40, -1, 1000, 0, 0, -1 },
+ { 0x3, 0x3, 40, -1, 719, 33, 1, 20 },
+ { 0x18000001, 0x18000001, 40, -1, 723, 6, 1, 20 },
+ { 0x0, 0x0, 40, -1, 1004, 0, 0, -1 },
+ { 0x3, 0x3, 40, -1, 735, 33, 1, 21 },
+ { 0x0, 0x0, 40, -1, 1009, 0, 0, -1 },
+ { 0x0, 0x0, 40, -1, 1013, 0, 0, -1 },
+ { 0x3, 0x3, 40, -1, 758, 33, 1, 17 },
+ { 0x3, 0x3, 40, -1, 762, 33, 1, 17 },
+ { 0x0, 0x0, 40, -1, 1017, 0, 0, -1 },
+ { 0x3, 0x3, 40, -1, 774, 33, 1, 21 },
+ { 0x0, 0x0, 41, 833, 954, 0, 0, -1 },
+ { 0x0, 0x0, 41, 834, 962, 0, 0, -1 },
+ { 0x0, 0x0, 41, 835, 958, 0, 0, -1 },
+ { 0x1, 0x1, 41, 836, 603, 34, 1, 6 },
+ { 0x10000001, 0x10000001, 41, 837, 611, 6, 1, 7 },
+ { 0x1, 0x1, 41, 838, 607, 34, 1, 6 },
+ { 0x0, 0x0, 41, 839, 966, 0, 0, -1 },
+ { 0x1, 0x1, 41, 840, 623, 34, 1, 8 },
+ { 0x0, 0x0, 41, 841, 970, 0, 0, -1 },
+ { 0x1, 0x1, 41, 842, 635, 34, 1, 15 },
+ { 0x0, 0x0, 41, 843, 975, 0, 0, -1 },
+ { 0x0, 0x0, 41, 844, 979, 0, 0, -1 },
+ { 0x1, 0x1, 41, 845, 658, 34, 1, 17 },
+ { 0x1, 0x1, 41, 846, 662, 34, 1, 17 },
+ { 0x0, 0x0, 41, 847, 983, 0, 0, -1 },
+ { 0x0, 0x0, 41, 848, 987, 0, 0, -1 },
+ { 0x1, 0x1, 41, 849, 682, 34, 1, 18 },
+ { 0x10000001, 0x10000001, 41, 850, 686, 6, 1, 18 },
+ { 0x0, 0x0, 41, 851, 991, 0, 0, -1 },
+ { 0x1, 0x1, 41, 852, 698, 34, 1, 19 },
+ { 0x0, 0x0, 41, 853, 995, 0, 0, -1 },
+ { 0x0, 0x0, 41, 854, 999, 0, 0, -1 },
+ { 0x1, 0x1, 41, 855, 718, 34, 1, 20 },
+ { 0x10000001, 0x10000001, 41, 856, 722, 6, 1, 20 },
+ { 0x0, 0x0, 41, 857, 1003, 0, 0, -1 },
+ { 0x1, 0x1, 41, 858, 734, 34, 1, 21 },
+ { 0x0, 0x0, 41, 859, 1008, 0, 0, -1 },
+ { 0x0, 0x0, 41, 860, 1012, 0, 0, -1 },
+ { 0x1, 0x1, 41, 861, 757, 34, 1, 17 },
+ { 0x1, 0x1, 41, 862, 761, 34, 1, 17 },
+ { 0x0, 0x0, 41, 863, 1016, 0, 0, -1 },
+ { 0x1, 0x1, 41, 864, 773, 34, 1, 21 },
+ { 0x800001, 0x800001, 41, -1, 1138, 4, 1, 16 },
+ { 0x1, 0x1, 41, 2202, 1136, 4, 1, 16 },
+ { 0x1, 0x1, 41, 939, 1141, 4, 1, 22 },
+ { 0x2, 0x3, 41, -1, 1146, 20, 1, 67 },
+ { 0x1, 0x1, 41, 2203, 1144, 21, 1, 67 },
+ { 0x0, 0x0, 42, -1, -1, 0, 1, 80 },
+ { 0x0, 0x0, 42, -1, -1, 0, 1, 80 },
+ { 0x0, 0x0, 42, -1, -1, 0, 1, 123 },
+ { 0x1, 0x1, 44, 1354, 295, 38, 1, 1 },
+ { 0x1, 0x1, 44, 1355, 297, 38, 1, 1 },
+ { 0x0, 0x0, 44, -1, 300, 0, 0, -1 },
+ { 0x0, 0x0, 44, -1, 414, 0, 0, -1 },
+ { 0x1, 0x1, 44, 1359, 317, 38, 1, 1 },
+ { 0x1, 0x1, 44, 1360, 319, 38, 1, 1 },
+ { 0x0, 0x0, 44, -1, 322, 0, 0, -1 },
+ { 0x0, 0x0, 44, -1, 454, 0, 0, -1 },
+ { 0x0, 0x0, 44, -1, 324, 0, 0, -1 },
+ { 0x0, 0x0, 44, -1, 342, 0, 0, -1 },
+ { 0x1, 0x1, 44, 1366, 343, 38, 1, 1 },
+ { 0x1, 0x1, 44, 1367, 345, 38, 1, 1 },
+ { 0x0, 0x0, 44, -1, 348, 0, 0, -1 },
+ { 0x0, 0x0, 44, -1, 462, 0, 0, -1 },
+ { 0x1, 0x1, 44, 1371, 365, 38, 1, 1 },
+ { 0x1, 0x1, 44, 1372, 367, 38, 1, 1 },
+ { 0x0, 0x0, 44, -1, 370, 0, 0, -1 },
+ { 0x0, 0x0, 44, -1, 502, 0, 0, -1 },
+ { 0x0, 0x0, 44, -1, 372, 0, 0, -1 },
+ { 0x0, 0x0, 44, -1, 390, 0, 0, -1 },
+ { 0x0, 0x0, 44, 1230, 2263, 0, 0, -1 },
+ { 0x0, 0x0, 44, 1231, 2271, 0, 1, 54 },
+ { 0x0, 0x0, 44, 1232, 2938, 0, 1, 54 },
+ { 0x0, 0x0, 44, 1233, 2339, 0, 0, -1 },
+ { 0x0, 0x0, 44, 1234, -1, 0, 1, 49 },
+ { 0x0, 0x0, 44, 1102, -1, 0, 1, 0 },
+ { 0x0, 0x0, 44, 1103, -1, 0, 1, 0 },
+ { 0x0, 0x0, 44, 1104, -1, 0, 1, 0 },
+ { 0x1, 0x1, 45, -1, 1658, 30, 1, 152 },
+ { 0x1, 0x1, 45, 945, 1657, 30, 1, 151 },
+ { 0x1, 0x1, 45, -1, 1662, 30, 1, 154 },
+ { 0x1, 0x1, 45, 946, 1661, 30, 1, 153 },
+ { 0x1, 0x1, 45, -1, 1666, 30, 1, 154 },
+ { 0x1, 0x1, 45, 947, 1665, 30, 1, 153 },
+ { 0x3, 0x3, 46, -1, 1142, 3, 1, 22 },
+ { 0x1, 0x1, 47, 2223, -1, 30, 1, 137 },
+ { 0x1, 0x1, 47, 2254, -1, 30, 1, 155 },
+ { 0x0, 0x0, 49, -1, -1, 0, 1, 40 },
+ { 0x0, 0x0, 49, -1, -1, 0, 1, 40 },
+ { 0x0, 0x0, 49, -1, -1, 0, 1, 40 },
+ { 0x1, 0x1, 56, -1, 1659, 31, 1, 152 },
+ { 0x1, 0x1, 56, -1, 1663, 31, 1, 154 },
+ { 0x1, 0x1, 56, -1, 1667, 31, 1, 154 },
+ { 0x0, 0x0, 56, -1, -1, 0, 1, 94 },
+ { 0x2, 0x3, 56, -1, -1, 27, 1, 94 },
+ { 0x1, 0x1, 56, -1, -1, 28, 1, 94 },
+ { 0x0, 0x0, 65, 14, 574, 0, 1, 6 },
+ { 0x0, 0x0, 65, 1255, 577, 0, 1, 6 },
+ { 0x1, 0x1, 65, 1256, 579, 33, 1, 6 },
+ { 0x1, 0x1, 65, 1257, 581, 34, 1, 6 },
+ { 0x3, 0x3, 65, 1258, 583, 33, 1, 6 },
+ { 0x0, 0x0, 65, 1259, 585, 0, 1, 6 },
+ { 0x1, 0x1, 65, 1260, 587, 33, 1, 6 },
+ { 0x1, 0x1, 65, 1261, 589, 34, 1, 6 },
+ { 0x3, 0x3, 65, 1262, 591, 33, 1, 6 },
+ { 0x1, 0x1, 65, 1263, 593, 6, 1, 7 },
+ { 0x8000001, 0x8000001, 65, 1264, 595, 6, 1, 7 },
+ { 0x10000001, 0x10000001, 65, 1265, 597, 6, 1, 7 },
+ { 0x18000001, 0x18000001, 65, 1266, 599, 6, 1, 7 },
+ { 0x0, 0x0, 65, 1267, 613, 0, 1, 8 },
+ { 0x1, 0x1, 65, 1268, 615, 33, 1, 8 },
+ { 0x1, 0x1, 65, 1269, 617, 34, 1, 8 },
+ { 0x3, 0x3, 65, 1270, 619, 33, 1, 8 },
+ { 0x0, 0x0, 65, 1271, 625, 0, 1, 15 },
+ { 0x1, 0x1, 65, 1272, 627, 33, 1, 15 },
+ { 0x1, 0x1, 65, 1273, 629, 34, 1, 15 },
+ { 0x3, 0x3, 65, 1274, 631, 33, 1, 15 },
+ { 0x0, 0x0, 65, 15, 637, 0, 1, 17 },
+ { 0x0, 0x0, 65, 1276, 640, 0, 1, 17 },
+ { 0x1, 0x1, 65, 1277, 642, 33, 1, 17 },
+ { 0x1, 0x1, 65, 1278, 644, 34, 1, 17 },
+ { 0x3, 0x3, 65, 1279, 646, 33, 1, 17 },
+ { 0x0, 0x0, 65, 1280, 648, 0, 1, 17 },
+ { 0x1, 0x1, 65, 1281, 650, 33, 1, 17 },
+ { 0x1, 0x1, 65, 1282, 652, 34, 1, 17 },
+ { 0x3, 0x3, 65, 1283, 654, 33, 1, 17 },
+ { 0x0, 0x0, 65, 1284, 664, 0, 1, 18 },
+ { 0x1, 0x1, 65, 1285, 666, 33, 1, 18 },
+ { 0x1, 0x1, 65, 1286, 668, 34, 1, 18 },
+ { 0x3, 0x3, 65, 1287, 670, 33, 1, 18 },
+ { 0x1, 0x1, 65, 1288, 672, 6, 1, 18 },
+ { 0x8000001, 0x8000001, 65, 1289, 674, 6, 1, 18 },
+ { 0x10000001, 0x10000001, 65, 1290, 676, 6, 1, 18 },
+ { 0x18000001, 0x18000001, 65, 1291, 678, 6, 1, 18 },
+ { 0x0, 0x0, 65, 1292, 688, 0, 1, 19 },
+ { 0x1, 0x1, 65, 1293, 690, 33, 1, 19 },
+ { 0x1, 0x1, 65, 1294, 692, 34, 1, 19 },
+ { 0x3, 0x3, 65, 1295, 694, 33, 1, 19 },
+ { 0x0, 0x0, 65, 1296, 700, 0, 1, 20 },
+ { 0x1, 0x1, 65, 1297, 702, 33, 1, 20 },
+ { 0x1, 0x1, 65, 1298, 704, 34, 1, 20 },
+ { 0x3, 0x3, 65, 1299, 706, 33, 1, 20 },
+ { 0x1, 0x1, 65, 1300, 708, 6, 1, 20 },
+ { 0x8000001, 0x8000001, 65, 1301, 710, 6, 1, 20 },
+ { 0x10000001, 0x10000001, 65, 1302, 712, 6, 1, 20 },
+ { 0x18000001, 0x18000001, 65, 1303, 714, 6, 1, 20 },
+ { 0x0, 0x0, 65, 1304, 724, 0, 1, 21 },
+ { 0x1, 0x1, 65, 1305, 726, 33, 1, 21 },
+ { 0x1, 0x1, 65, 1306, 728, 34, 1, 21 },
+ { 0x3, 0x3, 65, 1307, 730, 33, 1, 21 },
+ { 0x0, 0x0, 65, 17, 736, 0, 1, 17 },
+ { 0x0, 0x0, 65, 1309, 739, 0, 1, 17 },
+ { 0x1, 0x1, 65, 1310, 741, 33, 1, 17 },
+ { 0x1, 0x1, 65, 1311, 743, 34, 1, 17 },
+ { 0x3, 0x3, 65, 1312, 745, 33, 1, 17 },
+ { 0x0, 0x0, 65, 1313, 747, 0, 1, 17 },
+ { 0x1, 0x1, 65, 1314, 749, 33, 1, 17 },
+ { 0x1, 0x1, 65, 1315, 751, 34, 1, 17 },
+ { 0x3, 0x3, 65, 1316, 753, 33, 1, 17 },
+ { 0x0, 0x0, 65, 1317, 763, 0, 1, 21 },
+ { 0x1, 0x1, 65, 1318, 765, 33, 1, 21 },
+ { 0x1, 0x1, 65, 1319, 767, 34, 1, 21 },
+ { 0x3, 0x3, 65, 1320, 769, 33, 1, 21 },
+ { 0x3, 0x3, 66, 543, 1521, 33, 1, 129 },
+ { 0x3, 0x3, 66, 544, 1531, 33, 1, 129 },
+ { 0x3, 0x3, 66, 545, 1541, 33, 1, 129 },
+ { 0x0, 0x0, 66, -1, 1546, 0, 1, 140 },
+ { 0x0, 0x0, 66, -1, 1547, 0, 1, 145 },
+ { 0x0, 0x0, 66, -1, 1548, 0, 1, 145 },
+ { 0x0, 0x0, 107, 1028, 2311, 0, 0, -1 },
+ { 0x0, 0x0, 107, 1029, 2830, 0, 1, 29 },
+ { 0x0, 0x0, 107, 1030, 2352, 0, 0, -1 },
+ { 0x0, 0x0, 107, 1031, 2834, 0, 1, 29 },
+ { 0x0, 0x0, 109, -1, 2313, 0, 0, -1 },
+ { 0x1, 0x1, 109, -1, 2831, 27, 1, 29 },
+ { 0x0, 0x0, 109, -1, 2354, 0, 0, -1 },
+ { 0x1, 0x1, 109, -1, 2835, 27, 1, 29 },
+ { 0x0, 0x0, 110, 1033, -1, 0, 1, 115 },
+ { 0x1, 0x1, 111, -1, -1, 27, 1, 115 },
+ { 0x0, 0x0, 112, 1064, 2860, 0, 1, 1 },
+ { 0x0, 0x0, 112, 1065, 2863, 0, 1, 1 },
+ { 0x0, 0x0, 112, 1206, 303, 0, 0, -1 },
+ { 0x0, 0x0, 112, 1207, 307, 0, 0, -1 },
+ { 0x0, 0x0, 112, 1167, 430, 0, 0, -1 },
+ { 0x0, 0x0, 112, 1168, 438, 0, 0, -1 },
+ { 0x0, 0x0, 112, -1, 446, 0, 0, -1 },
+ { 0x0, 0x0, 112, 1066, 2876, 0, 1, 1 },
+ { 0x0, 0x0, 112, 1067, 2879, 0, 1, 1 },
+ { 0x0, 0x0, 112, -1, 328, 0, 0, -1 },
+ { 0x0, 0x0, 112, -1, 332, 0, 0, -1 },
+ { 0x0, 0x0, 112, 1215, 333, 0, 0, -1 },
+ { 0x0, 0x0, 112, 1216, 337, 0, 0, -1 },
+ { 0x0, 0x0, 112, 1068, 2900, 0, 1, 1 },
+ { 0x0, 0x0, 112, 1069, 2903, 0, 1, 1 },
+ { 0x0, 0x0, 112, 1219, 351, 0, 0, -1 },
+ { 0x0, 0x0, 112, 1220, 355, 0, 0, -1 },
+ { 0x0, 0x0, 112, 1180, 478, 0, 0, -1 },
+ { 0x0, 0x0, 112, 1181, 486, 0, 0, -1 },
+ { 0x0, 0x0, 112, -1, 494, 0, 0, -1 },
+ { 0x0, 0x0, 112, 1373, 2914, 0, 1, 1 },
+ { 0x0, 0x0, 112, 1374, 2916, 0, 1, 1 },
+ { 0x0, 0x0, 112, -1, 376, 0, 0, -1 },
+ { 0x0, 0x0, 112, -1, 380, 0, 0, -1 },
+ { 0x0, 0x0, 112, 1228, 381, 0, 0, -1 },
+ { 0x0, 0x0, 112, 1229, 385, 0, 0, -1 },
+ { 0x0, 0x0, 112, -1, 2281, 0, 0, -1 },
+ { 0x1, 0x9, 112, -1, 2285, 33, 1, 54 },
+ { 0x1, 0x9, 112, -1, 2947, 33, 1, 54 },
+ { 0x2, 0x3, 112, 1390, 2348, 27, 1, 49 },
+ { 0x1, 0x1, 114, 1356, 2861, 37, 1, 1 },
+ { 0x1, 0x1, 114, 1357, 2864, 37, 1, 1 },
+ { 0x1, 0x1, 114, 1361, 2877, 37, 1, 1 },
+ { 0x1, 0x1, 114, 1362, 2880, 37, 1, 1 },
+ { 0x1, 0x1, 114, 1368, 2901, 37, 1, 1 },
+ { 0x1, 0x1, 114, 1369, 2904, 37, 1, 1 },
+ { 0x0, 0x0, 114, -1, 2924, 0, 1, 1 },
+ { 0x0, 0x0, 114, -1, 2925, 0, 1, 1 },
+ { 0x0, 0x0, 115, 1105, 2856, 0, 1, 1 },
+ { 0x0, 0x0, 115, 1106, 2858, 0, 1, 1 },
+ { 0x0, 0x0, 115, 1165, 301, 0, 0, -1 },
+ { 0x0, 0x0, 115, 1166, 305, 0, 0, -1 },
+ { 0x0, 0x0, 115, -1, 434, 0, 0, -1 },
+ { 0x0, 0x0, 115, -1, 442, 0, 0, -1 },
+ { 0x0, 0x0, 115, 1210, 444, 0, 0, -1 },
+ { 0x0, 0x0, 115, -1, 2874, 0, 1, 1 },
+ { 0x0, 0x0, 115, -1, 2875, 0, 1, 1 },
+ { 0x0, 0x0, 115, 1213, 326, 0, 0, -1 },
+ { 0x0, 0x0, 115, 1214, 330, 0, 0, -1 },
+ { 0x0, 0x0, 115, 1174, 335, 0, 0, -1 },
+ { 0x0, 0x0, 115, 1175, 339, 0, 0, -1 },
+ { 0x0, 0x0, 115, 1109, 2896, 0, 1, 1 },
+ { 0x0, 0x0, 115, 1110, 2898, 0, 1, 1 },
+ { 0x0, 0x0, 115, 1178, 349, 0, 0, -1 },
+ { 0x0, 0x0, 115, 1179, 353, 0, 0, -1 },
+ { 0x0, 0x0, 115, -1, 482, 0, 0, -1 },
+ { 0x0, 0x0, 115, -1, 490, 0, 0, -1 },
+ { 0x0, 0x0, 115, 1223, 492, 0, 0, -1 },
+ { 0x0, 0x0, 115, -1, 2912, 0, 1, 1 },
+ { 0x0, 0x0, 115, -1, 2913, 0, 1, 1 },
+ { 0x0, 0x0, 115, 1226, 374, 0, 0, -1 },
+ { 0x0, 0x0, 115, 1227, 378, 0, 0, -1 },
+ { 0x0, 0x0, 115, 1187, 383, 0, 0, -1 },
+ { 0x0, 0x0, 115, 1188, 387, 0, 0, -1 },
+ { 0x0, 0x0, 115, 1060, 2279, 0, 0, -1 },
+ { 0x0, 0x0, 115, 1061, 2283, 0, 1, 54 },
+ { 0x0, 0x0, 115, 1062, 2946, 0, 1, 54 },
+ { 0x0, 0x0, 115, 1063, 2347, 0, 1, 49 },
+ { 0x1, 0x1, 115, -1, -1, 27, 1, 0 },
+ { 0x1, 0x1, 115, -1, -1, 27, 1, 0 },
+ { 0x1, 0x1, 115, -1, -1, 27, 1, 0 },
+ { 0x1, 0x1, 116, -1, 2857, 37, 1, 1 },
+ { 0x1, 0x1, 116, -1, 2859, 37, 1, 1 },
+ { 0x0, 0x0, 116, -1, 2884, 0, 1, 1 },
+ { 0x0, 0x0, 116, -1, 2885, 0, 1, 1 },
+ { 0x1, 0x1, 116, -1, 2897, 37, 1, 1 },
+ { 0x1, 0x1, 116, -1, 2899, 37, 1, 1 },
+ { 0x0, 0x0, 116, -1, 2922, 0, 1, 1 },
+ { 0x0, 0x0, 116, -1, 2923, 0, 1, 1 },
+ { 0x0, 0x0, 117, 1158, -1, 0, 1, 0 },
+ { 0x0, 0x0, 117, 1159, -1, 0, 1, 0 },
+ { 0x0, 0x0, 117, 1160, -1, 0, 1, 0 },
+ { 0x3, 0x3, 117, 1118, -1, 34, 1, 33 },
+ { 0x3, 0x3, 117, 1119, -1, 34, 1, 40 },
+ { 0x1, 0x1, 119, -1, -1, 35, 1, 33 },
+ { 0x1, 0x1, 119, -1, -1, 35, 1, 40 },
+ { 0x0, 0x0, 120, -1, -1, 0, 1, 40 },
+ { 0x0, 0x0, 120, -1, -1, 0, 1, 66 },
+ { 0x1, 0x1, 120, -1, -1, 36, 1, 122 },
+ { 0x0, 0x0, 120, -1, -1, 0, 1, 40 },
+ { 0x1, 0x1, 120, -1, -1, 27, 1, 96 },
+ { 0x0, 0x0, 120, -1, -1, 0, 1, 105 },
+ { 0x0, 0x0, 120, -1, -1, 0, 1, 73 },
+ { 0x0, 0x0, 120, -1, -1, 0, 1, 73 },
+ { 0x0, 0x0, 120, -1, -1, 0, 1, 74 },
+ { 0x0, 0x0, 120, -1, -1, 0, 1, 40 },
+ { 0x1, 0x1, 120, -1, -1, 27, 1, 117 },
+ { 0x1, 0x1, 120, -1, -1, 27, 1, 40 },
+ { 0x0, 0x0, 120, -1, -1, 0, 1, 40 },
+ { 0x0, 0x0, 121, -1, 2786, 0, 0, -1 },
+ { 0x0, 0x0, 121, -1, 2789, 0, 0, -1 },
+ { 0x1, 0x1, 122, -1, -1, 35, 1, 16 },
+ { 0x1, 0x1, 122, -1, -1, 35, 1, 16 },
+ { 0x1, 0x1, 122, -1, -1, 35, 1, 16 },
+ { 0x1, 0x1, 122, -1, -1, 35, 1, 16 },
+ { 0x1, 0x1, 122, -1, -1, 35, 1, 22 },
+ { 0x1, 0x1, 122, -1, -1, 35, 1, 22 },
+ { 0x1, 0x1, 122, -1, -1, 35, 1, 22 },
+ { 0x1, 0x1, 122, -1, -1, 35, 1, 22 },
+ { 0x1, 0x1, 122, -1, -1, 23, 1, 67 },
+ { 0x1, 0x1, 122, -1, -1, 23, 1, 67 },
+ { 0x1, 0x1, 122, -1, -1, 23, 1, 67 },
+ { 0x1, 0x1, 122, -1, -1, 23, 1, 67 },
+ { 0x1, 0x1, 122, 900, -1, 23, 1, 67 },
+ { 0x9, 0x9, 122, 901, -1, 20, 1, 67 },
+ { 0x0, 0x0, 126, 2165, -1, 0, 1, 0 },
+ { 0x0, 0x0, 126, 2166, -1, 0, 1, 0 },
+ { 0x1, 0x1, 126, -1, -1, 28, 1, 33 },
+ { 0x1, 0x1, 126, -1, -1, 27, 1, 33 },
+ { 0x1, 0x1, 126, -1, -1, 29, 1, 0 },
+ { 0x1, 0x1, 126, -1, -1, 29, 1, 0 },
+ { 0x1, 0x1, 126, -1, -1, 29, 1, 0 },
+ { 0x1, 0x1, 126, -1, -1, 29, 1, 0 },
+ { 0x0, 0x0, 126, -1, -1, 0, 1, 114 },
+ { 0x1, 0x1, 126, -1, -1, 29, 1, 0 },
+ { 0x1, 0x1, 126, -1, -1, 29, 1, 0 },
+ { 0x1, 0x1, 126, -1, -1, 29, 1, 0 },
+ { 0x0, 0x0, 126, 1116, -1, 0, 1, 33 },
+ { 0x0, 0x0, 126, 1244, -1, 0, 1, 40 },
+ { 0x0, 0x0, 140, 1194, 2852, 0, 1, 1 },
+ { 0x0, 0x0, 140, 1195, 2854, 0, 1, 1 },
+ { 0x0, 0x0, 140, 1036, 302, 0, 0, -1 },
+ { 0x0, 0x0, 140, 1037, 422, 0, 0, -1 },
+ { 0x0, 0x0, 140, 1076, 311, 0, 0, -1 },
+ { 0x0, 0x0, 140, 1077, 315, 0, 0, -1 },
+ { 0x0, 0x0, 140, 1078, 443, 0, 0, -1 },
+ { 0x0, 0x0, 140, -1, 2872, 0, 1, 1 },
+ { 0x0, 0x0, 140, -1, 2873, 0, 1, 1 },
+ { 0x0, 0x0, 140, 1081, 325, 0, 0, -1 },
+ { 0x0, 0x0, 140, 1082, 329, 0, 0, -1 },
+ { 0x0, 0x0, 140, -1, 336, 0, 0, -1 },
+ { 0x0, 0x0, 140, -1, 340, 0, 0, -1 },
+ { 0x0, 0x0, 140, 1198, 2892, 0, 1, 1 },
+ { 0x0, 0x0, 140, 1199, 2894, 0, 1, 1 },
+ { 0x0, 0x0, 140, 1049, 350, 0, 0, -1 },
+ { 0x0, 0x0, 140, 1050, 470, 0, 0, -1 },
+ { 0x0, 0x0, 140, 1089, 359, 0, 0, -1 },
+ { 0x0, 0x0, 140, 1090, 363, 0, 0, -1 },
+ { 0x0, 0x0, 140, 1091, 491, 0, 0, -1 },
+ { 0x0, 0x0, 140, -1, 2910, 0, 1, 1 },
+ { 0x0, 0x0, 140, -1, 2911, 0, 1, 1 },
+ { 0x0, 0x0, 140, 1094, 373, 0, 0, -1 },
+ { 0x0, 0x0, 140, 1095, 377, 0, 0, -1 },
+ { 0x0, 0x0, 140, -1, 384, 0, 0, -1 },
+ { 0x0, 0x0, 140, -1, 388, 0, 0, -1 },
+ { 0x0, 0x0, 140, 2974, 2267, 0, 0, -1 },
+ { 0x1, 0x1, 140, 2975, 2275, 33, 1, 54 },
+ { 0x1, 0x1, 140, 2976, 2940, 33, 1, 54 },
+ { 0x0, 0x0, 140, 2977, 2341, 0, 0, -1 },
+ { 0x1, 0x1, 140, 2978, -1, 28, 1, 49 },
+ { 0x1, 0x1, 141, -1, 2853, 37, 1, 1 },
+ { 0x1, 0x1, 141, -1, 2855, 37, 1, 1 },
+ { 0x0, 0x0, 141, -1, 2882, 0, 1, 1 },
+ { 0x0, 0x0, 141, -1, 2883, 0, 1, 1 },
+ { 0x1, 0x1, 141, -1, 2893, 37, 1, 1 },
+ { 0x1, 0x1, 141, -1, 2895, 37, 1, 1 },
+ { 0x0, 0x0, 141, -1, 2920, 0, 1, 1 },
+ { 0x0, 0x0, 141, -1, 2921, 0, 1, 1 },
+ { 0x1, 0x1, 144, 899, 1140, 3, 1, 22 },
+ { 0x0, 0x0, 145, 2167, -1, 0, 1, 33 },
+ { 0x0, 0x0, 146, 905, 2846, 0, 1, 1 },
+ { 0x0, 0x0, 146, 906, 2849, 0, 1, 1 },
+ { 0x0, 0x0, 146, -1, 304, 0, 0, -1 },
+ { 0x0, 0x0, 146, -1, 426, 0, 0, -1 },
+ { 0x0, 0x0, 146, 1038, 309, 0, 0, -1 },
+ { 0x0, 0x0, 146, 1039, 313, 0, 0, -1 },
+ { 0x0, 0x0, 146, 1040, 445, 0, 0, -1 },
+ { 0x0, 0x0, 146, 909, 2866, 0, 1, 1 },
+ { 0x0, 0x0, 146, 910, 2869, 0, 1, 1 },
+ { 0x0, 0x0, 146, 1043, 327, 0, 0, -1 },
+ { 0x0, 0x0, 146, 1044, 331, 0, 0, -1 },
+ { 0x0, 0x0, 146, 1083, 334, 0, 0, -1 },
+ { 0x0, 0x0, 146, 1084, 338, 0, 0, -1 },
+ { 0x0, 0x0, 146, 915, 2886, 0, 1, 1 },
+ { 0x0, 0x0, 146, 916, 2889, 0, 1, 1 },
+ { 0x0, 0x0, 146, -1, 352, 0, 0, -1 },
+ { 0x0, 0x0, 146, -1, 474, 0, 0, -1 },
+ { 0x0, 0x0, 146, 1051, 357, 0, 0, -1 },
+ { 0x0, 0x0, 146, 1052, 361, 0, 0, -1 },
+ { 0x0, 0x0, 146, 1053, 493, 0, 0, -1 },
+ { 0x0, 0x0, 146, 919, 2906, 0, 1, 1 },
+ { 0x0, 0x0, 146, 920, 2908, 0, 1, 1 },
+ { 0x0, 0x0, 146, 1056, 375, 0, 0, -1 },
+ { 0x0, 0x0, 146, 1057, 379, 0, 0, -1 },
+ { 0x0, 0x0, 146, 1096, 382, 0, 0, -1 },
+ { 0x0, 0x0, 146, 1097, 386, 0, 0, -1 },
+ { 0x0, 0x0, 146, 1189, 2265, 0, 0, -1 },
+ { 0x1, 0x1, 146, 1190, 2273, 36, 1, 54 },
+ { 0x1, 0x1, 146, 1191, 2939, 36, 1, 54 },
+ { 0x0, 0x0, 146, 1192, 2340, 0, 0, -1 },
+ { 0x1, 0x1, 146, 1193, -1, 27, 1, 49 },
+ { 0x1, 0x1, 147, -1, 2848, 37, 1, 1 },
+ { 0x1, 0x1, 147, -1, 2851, 37, 1, 1 },
+ { 0x1, 0x1, 147, -1, 2868, 37, 1, 1 },
+ { 0x1, 0x1, 147, -1, 2871, 37, 1, 1 },
+ { 0x1, 0x1, 147, -1, 2888, 37, 1, 1 },
+ { 0x1, 0x1, 147, -1, 2891, 37, 1, 1 },
+ { 0x0, 0x0, 147, -1, 2918, 0, 1, 1 },
+ { 0x0, 0x0, 147, -1, 2919, 0, 1, 1 },
+ { 0x0, 0x0, 148, -1, -1, 0, 1, 33 },
+ { 0x0, 0x0, 148, 1117, -1, 0, 1, 40 },
+ { 0x0, 0x0, 149, -1, -1, 0, 1, 40 },
+ { 0x0, 0x0, 149, -1, -1, 0, 1, 66 },
+ { 0x0, 0x0, 149, -1, 2926, 0, 1, 63 },
+ { 0x0, 0x0, 149, -1, 2927, 0, 1, 63 },
+ { 0x0, 0x0, 149, -1, -1, 0, 1, 40 },
+ { 0x0, 0x0, 149, -1, -1, 0, 1, 81 },
+ { 0x0, 0x0, 149, -1, -1, 0, 1, 81 },
+ { 0x0, 0x0, 149, -1, -1, 0, 1, 85 },
+ { 0x0, 0x0, 149, -1, -1, 0, 1, 40 },
+ { 0x1, 0x1, 150, -1, 575, 12, 1, 6 },
+ { 0x1, 0x1, 150, -1, 578, 12, 1, 6 },
+ { 0x200001, 0x200001, 150, -1, 580, 12, 1, 6 },
+ { 0x400001, 0x400001, 150, -1, 582, 12, 1, 6 },
+ { 0x600001, 0x600001, 150, -1, 584, 12, 1, 6 },
+ { 0x1, 0x1, 150, -1, 586, 12, 1, 6 },
+ { 0x200001, 0x200001, 150, -1, 588, 12, 1, 6 },
+ { 0x400001, 0x400001, 150, -1, 590, 12, 1, 6 },
+ { 0x600001, 0x600001, 150, -1, 592, 12, 1, 6 },
+ { 0x41, 0x41, 150, -1, 594, 6, 1, 7 },
+ { 0x8000041, 0x8000041, 150, -1, 596, 6, 1, 7 },
+ { 0x10000041, 0x10000041, 150, -1, 598, 6, 1, 7 },
+ { 0x18000041, 0x18000041, 150, -1, 600, 6, 1, 7 },
+ { 0x1, 0x1, 150, -1, 614, 12, 1, 8 },
+ { 0x200001, 0x200001, 150, -1, 616, 12, 1, 8 },
+ { 0x400001, 0x400001, 150, -1, 618, 12, 1, 8 },
+ { 0x600001, 0x600001, 150, -1, 620, 12, 1, 8 },
+ { 0x1, 0x1, 150, -1, 626, 12, 1, 15 },
+ { 0x200001, 0x200001, 150, -1, 628, 12, 1, 15 },
+ { 0x400001, 0x400001, 150, -1, 630, 12, 1, 15 },
+ { 0x600001, 0x600001, 150, -1, 632, 12, 1, 15 },
+ { 0x1, 0x1, 150, -1, 638, 12, 1, 17 },
+ { 0x1, 0x1, 150, -1, 641, 12, 1, 17 },
+ { 0x200001, 0x200001, 150, -1, 643, 12, 1, 17 },
+ { 0x400001, 0x400001, 150, -1, 645, 12, 1, 17 },
+ { 0x600001, 0x600001, 150, -1, 647, 12, 1, 17 },
+ { 0x1, 0x1, 150, -1, 649, 12, 1, 17 },
+ { 0x200001, 0x200001, 150, -1, 651, 12, 1, 17 },
+ { 0x400001, 0x400001, 150, -1, 653, 12, 1, 17 },
+ { 0x600001, 0x600001, 150, -1, 655, 12, 1, 17 },
+ { 0x1, 0x1, 150, -1, 665, 12, 1, 18 },
+ { 0x200001, 0x200001, 150, -1, 667, 12, 1, 18 },
+ { 0x400001, 0x400001, 150, -1, 669, 12, 1, 18 },
+ { 0x600001, 0x600001, 150, -1, 671, 12, 1, 18 },
+ { 0x41, 0x41, 150, -1, 673, 6, 1, 18 },
+ { 0x8000041, 0x8000041, 150, -1, 675, 6, 1, 18 },
+ { 0x10000041, 0x10000041, 150, -1, 677, 6, 1, 18 },
+ { 0x18000041, 0x18000041, 150, -1, 679, 6, 1, 18 },
+ { 0x1, 0x1, 150, -1, 689, 12, 1, 19 },
+ { 0x200001, 0x200001, 150, -1, 691, 12, 1, 19 },
+ { 0x400001, 0x400001, 150, -1, 693, 12, 1, 19 },
+ { 0x600001, 0x600001, 150, -1, 695, 12, 1, 19 },
+ { 0x1, 0x1, 150, -1, 701, 12, 1, 20 },
+ { 0x200001, 0x200001, 150, -1, 703, 12, 1, 20 },
+ { 0x400001, 0x400001, 150, -1, 705, 12, 1, 20 },
+ { 0x600001, 0x600001, 150, -1, 707, 12, 1, 20 },
+ { 0x41, 0x41, 150, -1, 709, 6, 1, 20 },
+ { 0x8000041, 0x8000041, 150, -1, 711, 6, 1, 20 },
+ { 0x10000041, 0x10000041, 150, -1, 713, 6, 1, 20 },
+ { 0x18000041, 0x18000041, 150, -1, 715, 6, 1, 20 },
+ { 0x1, 0x1, 150, -1, 725, 12, 1, 21 },
+ { 0x200001, 0x200001, 150, -1, 727, 12, 1, 21 },
+ { 0x400001, 0x400001, 150, -1, 729, 12, 1, 21 },
+ { 0x600001, 0x600001, 150, -1, 731, 12, 1, 21 },
+ { 0x1, 0x1, 150, -1, 737, 12, 1, 17 },
+ { 0x1, 0x1, 150, -1, 740, 12, 1, 17 },
+ { 0x200001, 0x200001, 150, -1, 742, 12, 1, 17 },
+ { 0x400001, 0x400001, 150, -1, 744, 12, 1, 17 },
+ { 0x600001, 0x600001, 150, -1, 746, 12, 1, 17 },
+ { 0x1, 0x1, 150, -1, 748, 12, 1, 17 },
+ { 0x200001, 0x200001, 150, -1, 750, 12, 1, 17 },
+ { 0x400001, 0x400001, 150, -1, 752, 12, 1, 17 },
+ { 0x600001, 0x600001, 150, -1, 754, 12, 1, 17 },
+ { 0x1, 0x1, 150, -1, 764, 12, 1, 21 },
+ { 0x200001, 0x200001, 150, -1, 766, 12, 1, 21 },
+ { 0x400001, 0x400001, 150, -1, 768, 12, 1, 21 },
+ { 0x600001, 0x600001, 150, -1, 770, 12, 1, 21 },
+ { 0x0, 0x0, 155, -1, -1, 0, 1, 124 },
+ { 0x0, 0x0, 159, 775, -1, 0, 1, 75 },
+ { 0x0, 0x0, 159, 776, -1, 0, 1, 75 },
+ { 0x9, 0x9, 159, -1, 1438, 32, 1, 130 },
+ { 0x9, 0x9, 159, -1, 1447, 32, 1, 130 },
+ { 0x9, 0x9, 159, -1, 1456, 32, 1, 130 },
+ { 0x9, 0x9, 159, -1, 1469, 32, 1, 130 },
+ { 0x9, 0x9, 159, -1, 1478, 32, 1, 130 },
+ { 0x9, 0x9, 159, -1, 1487, 32, 1, 130 },
+ { 0x9, 0x9, 159, -1, 1496, 32, 1, 130 },
+ { 0x9, 0x9, 159, -1, 1505, 32, 1, 130 },
+ { 0x9, 0x9, 159, -1, 1514, 32, 1, 130 },
+ { 0x9, 0x9, 159, -1, 1524, 32, 1, 130 },
+ { 0x9, 0x9, 159, -1, 1534, 32, 1, 130 },
+ { 0x9, 0x9, 159, -1, 1544, 32, 1, 130 },
+ { 0x9, 0x9, 159, -1, 1553, 32, 1, 144 },
+ { 0x9, 0x9, 159, -1, 1559, 32, 1, 149 },
+ { 0x9, 0x9, 159, -1, 1565, 32, 1, 149 },
+ { 0x9, 0x9, 159, -1, 1571, 32, 1, 144 },
+ { 0x9, 0x9, 159, -1, 1577, 32, 1, 149 },
+ { 0x9, 0x9, 159, -1, 1583, 32, 1, 149 },
+ { 0x9, 0x9, 159, -1, 1589, 32, 1, 144 },
+ { 0x9, 0x9, 159, -1, 1595, 32, 1, 149 },
+ { 0x9, 0x9, 159, -1, 1601, 32, 1, 149 },
+ { 0x9, 0x9, 159, -1, 1607, 32, 1, 144 },
+ { 0x9, 0x9, 159, -1, 1613, 32, 1, 149 },
+ { 0x9, 0x9, 159, -1, 1619, 32, 1, 144 },
+ { 0x9, 0x9, 159, -1, 1625, 32, 1, 149 },
+ { 0x9, 0x9, 159, -1, 1631, 32, 1, 144 },
+ { 0x9, 0x9, 159, -1, 1637, 32, 1, 149 },
+ { 0x9, 0x9, 159, -1, 1643, 32, 1, 144 },
+ { 0x9, 0x9, 159, -1, 1649, 32, 1, 149 },
+ { 0x9, 0x9, 159, -1, 1655, 32, 1, 149 },
+ { 0x0, 0x0, 160, 1235, 296, 0, 0, -1 },
+ { 0x0, 0x0, 160, 1236, 412, 0, 0, -1 },
+ { 0x1, 0x1, 160, -1, 2862, 38, 1, 1 },
+ { 0x1, 0x1, 160, 907, 2865, 38, 1, 1 },
+ { 0x0, 0x0, 160, 908, 413, 0, 0, -1 },
+ { 0x0, 0x0, 160, 1237, 318, 0, 0, -1 },
+ { 0x0, 0x0, 160, 1238, 452, 0, 0, -1 },
+ { 0x1, 0x1, 160, -1, 2878, 38, 1, 1 },
+ { 0x1, 0x1, 160, 911, 2881, 38, 1, 1 },
+ { 0x0, 0x0, 160, 912, 453, 0, 0, -1 },
+ { 0x0, 0x0, 160, 913, 323, 0, 0, -1 },
+ { 0x0, 0x0, 160, 914, 341, 0, 0, -1 },
+ { 0x0, 0x0, 160, 1239, 344, 0, 0, -1 },
+ { 0x0, 0x0, 160, 1240, 460, 0, 0, -1 },
+ { 0x1, 0x1, 160, -1, 2902, 38, 1, 1 },
+ { 0x1, 0x1, 160, 917, 2905, 38, 1, 1 },
+ { 0x0, 0x0, 160, 918, 461, 0, 0, -1 },
+ { 0x0, 0x0, 160, -1, 366, 0, 0, -1 },
+ { 0x0, 0x0, 160, -1, 500, 0, 0, -1 },
+ { 0x1, 0x1, 160, -1, 2915, 38, 1, 1 },
+ { 0x1, 0x1, 160, 921, 2917, 38, 1, 1 },
+ { 0x0, 0x0, 160, 922, 501, 0, 0, -1 },
+ { 0x0, 0x0, 160, 923, 371, 0, 0, -1 },
+ { 0x0, 0x0, 160, 924, 389, 0, 0, -1 },
+ { 0x0, 0x0, 161, 1397, 2287, 0, 0, -1 },
+ { 0x0, 0x0, 161, 1398, 2295, 0, 1, 54 },
+ { 0x0, 0x0, 161, 1399, 2956, 0, 1, 54 },
+ { 0x0, 0x0, 161, 1400, 2343, 0, 0, -1 },
+ { 0x1, 0x1, 161, 1401, -1, 29, 1, 49 },
+ { 0x0, 0x0, 162, -1, 2305, 0, 0, -1 },
+ { 0x1, 0x9, 162, -1, 2309, 33, 1, 54 },
+ { 0x1, 0x9, 162, -1, 2965, 33, 1, 54 },
+ { 0x6, 0x7, 162, -1, 2350, 27, 1, 49 },
+ { 0x0, 0x0, 163, 1383, 2303, 0, 0, -1 },
+ { 0x0, 0x0, 163, 1384, 2307, 0, 1, 54 },
+ { 0x0, 0x0, 163, 1385, 2964, 0, 1, 54 },
+ { 0x1, 0x1, 163, 1386, 2349, 29, 1, 49 },
+ { 0x1, 0x1, 164, 1404, -1, 27, 1, 33 },
+ { 0x0, 0x0, 165, 2159, 2291, 0, 0, -1 },
+ { 0x1, 0x1, 165, 2160, 2299, 33, 1, 54 },
+ { 0x1, 0x1, 165, 2161, 2958, 33, 1, 54 },
+ { 0x0, 0x0, 165, 2162, 2345, 0, 0, -1 },
+ { 0x3, 0x3, 165, 2163, -1, 28, 1, 49 },
+ { 0x0, 0x0, 166, 1392, 2289, 0, 0, -1 },
+ { 0x1, 0x1, 166, 1393, 2297, 36, 1, 54 },
+ { 0x1, 0x1, 166, 1394, 2957, 36, 1, 54 },
+ { 0x0, 0x0, 166, 1395, 2344, 0, 0, -1 },
+ { 0x5, 0x5, 166, 1396, -1, 27, 1, 49 },
+ { 0x0, 0x0, 167, -1, 2928, 0, 1, 63 },
+ { 0x0, 0x0, 167, -1, 2929, 0, 1, 63 },
+ { 0x1, 0x1, 169, -1, -1, 28, 1, 33 },
+ { 0x1, 0x1, 170, 2745, -1, 27, 1, 33 },
+ { 0x1, 0x1, 170, 2746, -1, 27, 1, 33 },
+ { 0x1, 0x1, 171, 1685, -1, 28, 1, 135 },
+ { 0x1, 0x1, 171, 1686, -1, 28, 1, 135 },
+ { 0x1, 0x1, 171, 1687, -1, 28, 1, 135 },
+ { 0x1, 0x1, 171, 1688, -1, 28, 1, 135 },
+ { 0x1, 0x1, 171, 1689, -1, 28, 1, 134 },
+ { 0x1, 0x1, 171, 1690, -1, 28, 1, 134 },
+ { 0x1, 0x1, 171, 1691, -1, 28, 1, 134 },
+ { 0x1, 0x1, 171, 1692, -1, 28, 1, 134 },
+ { 0x1, 0x1, 171, 1693, -1, 28, 1, 134 },
+ { 0x1, 0x1, 171, 1694, -1, 28, 1, 134 },
+ { 0x1, 0x1, 171, 1695, -1, 28, 1, 134 },
+ { 0x1, 0x1, 171, 1696, -1, 28, 1, 134 },
+ { 0x1, 0x1, 171, 1697, -1, 28, 1, 134 },
+ { 0x1, 0x1, 171, 1698, -1, 28, 1, 134 },
+ { 0x1, 0x1, 171, 1699, -1, 28, 1, 134 },
+ { 0x1, 0x1, 171, 1700, -1, 28, 1, 134 },
+ { 0x1, 0x1, 171, 1701, -1, 28, 1, 134 },
+ { 0x1, 0x1, 171, 1702, -1, 28, 1, 134 },
+ { 0x1, 0x1, 171, 1703, -1, 28, 1, 134 },
+ { 0x1, 0x1, 171, 1704, -1, 28, 1, 134 },
+ { 0x1, 0x1, 171, 1705, -1, 28, 1, 136 },
+ { 0x1, 0x1, 171, 1706, -1, 28, 1, 136 },
+ { 0x1, 0x1, 171, 1707, -1, 28, 1, 136 },
+ { 0x1, 0x1, 171, 1708, -1, 28, 1, 136 },
+ { 0x1, 0x1, 171, 1709, -1, 28, 1, 126 },
+ { 0x1, 0x1, 171, 1710, -1, 28, 1, 127 },
+ { 0x1, 0x1, 171, 1711, -1, 28, 1, 128 },
+ { 0x1, 0x1, 171, 1712, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1713, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1714, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1715, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1716, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1717, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1718, -1, 28, 1, 126 },
+ { 0x1, 0x1, 171, 1719, -1, 28, 1, 127 },
+ { 0x1, 0x1, 171, 1720, -1, 28, 1, 128 },
+ { 0x1, 0x1, 171, 1721, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1722, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1723, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1724, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1725, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1726, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1727, -1, 28, 1, 126 },
+ { 0x1, 0x1, 171, 1728, -1, 28, 1, 127 },
+ { 0x1, 0x1, 171, 1729, -1, 28, 1, 128 },
+ { 0x1, 0x1, 171, 1730, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1731, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1732, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1733, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1734, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1735, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1736, -1, 28, 1, 125 },
+ { 0x1, 0x1, 171, 1737, -1, 28, 1, 125 },
+ { 0x1, 0x1, 171, 1738, -1, 28, 1, 125 },
+ { 0x1, 0x1, 171, 1739, -1, 28, 1, 125 },
+ { 0x1, 0x1, 171, 1740, -1, 28, 1, 126 },
+ { 0x1, 0x1, 171, 1741, -1, 28, 1, 127 },
+ { 0x1, 0x1, 171, 1742, -1, 28, 1, 128 },
+ { 0x1, 0x1, 171, 1743, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1744, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1745, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1746, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1747, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1748, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1749, -1, 28, 1, 126 },
+ { 0x1, 0x1, 171, 1750, -1, 28, 1, 127 },
+ { 0x1, 0x1, 171, 1751, -1, 28, 1, 128 },
+ { 0x1, 0x1, 171, 1752, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1753, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1754, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1755, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1756, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1757, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1758, -1, 28, 1, 126 },
+ { 0x1, 0x1, 171, 1759, -1, 28, 1, 127 },
+ { 0x1, 0x1, 171, 1760, -1, 28, 1, 128 },
+ { 0x1, 0x1, 171, 1761, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1762, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1763, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1764, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1765, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1766, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1767, -1, 28, 1, 126 },
+ { 0x1, 0x1, 171, 1768, -1, 28, 1, 127 },
+ { 0x1, 0x1, 171, 1769, -1, 28, 1, 128 },
+ { 0x1, 0x1, 171, 1770, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1771, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1772, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1773, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1774, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1775, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1776, -1, 28, 1, 126 },
+ { 0x1, 0x1, 171, 1777, -1, 28, 1, 127 },
+ { 0x1, 0x1, 171, 1778, -1, 28, 1, 128 },
+ { 0x1, 0x1, 171, 1779, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1780, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1781, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1782, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1783, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1784, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1785, -1, 28, 1, 126 },
+ { 0x1, 0x1, 171, 1786, -1, 28, 1, 127 },
+ { 0x1, 0x1, 171, 1787, -1, 28, 1, 128 },
+ { 0x1, 0x1, 171, 1788, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1789, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1790, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1791, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1792, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1793, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1794, -1, 28, 1, 126 },
+ { 0x1, 0x1, 171, 1795, -1, 28, 1, 127 },
+ { 0x1, 0x1, 171, 1796, -1, 28, 1, 128 },
+ { 0x1, 0x1, 171, 1797, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1798, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1799, -1, 28, 1, 129 },
+ { 0x1, 0x1, 171, 1800, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1801, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1802, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1803, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1804, -1, 28, 1, 126 },
+ { 0x1, 0x1, 171, 1805, -1, 28, 1, 127 },
+ { 0x1, 0x1, 171, 1806, -1, 28, 1, 128 },
+ { 0x1, 0x1, 171, 1807, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1808, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1809, -1, 28, 1, 129 },
+ { 0x1, 0x1, 171, 1810, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1811, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1812, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1813, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1814, -1, 28, 1, 126 },
+ { 0x1, 0x1, 171, 1815, -1, 28, 1, 127 },
+ { 0x1, 0x1, 171, 1816, -1, 28, 1, 128 },
+ { 0x1, 0x1, 171, 1817, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1818, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1819, -1, 28, 1, 129 },
+ { 0x1, 0x1, 171, 1820, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1821, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1822, -1, 28, 1, 130 },
+ { 0x1, 0x1, 171, 1823, -1, 28, 1, 124 },
+ { 0x1, 0x1, 171, 1824, -1, 28, 1, 140 },
+ { 0x1, 0x1, 171, 1825, -1, 28, 1, 145 },
+ { 0x1, 0x1, 171, 1826, -1, 28, 1, 145 },
+ { 0x1, 0x1, 171, 1827, -1, 28, 1, 141 },
+ { 0x1, 0x1, 171, 1828, -1, 28, 1, 142 },
+ { 0x1, 0x1, 171, 1829, -1, 28, 1, 143 },
+ { 0x1, 0x1, 171, 1830, -1, 28, 1, 144 },
+ { 0x1, 0x1, 171, 1831, -1, 28, 1, 144 },
+ { 0x1, 0x1, 171, 1832, -1, 28, 1, 140 },
+ { 0x1, 0x1, 171, 1833, -1, 28, 1, 146 },
+ { 0x1, 0x1, 171, 1834, -1, 28, 1, 147 },
+ { 0x1, 0x1, 171, 1835, -1, 28, 1, 148 },
+ { 0x1, 0x1, 171, 1836, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1837, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1838, -1, 28, 1, 145 },
+ { 0x1, 0x1, 171, 1839, -1, 28, 1, 146 },
+ { 0x1, 0x1, 171, 1840, -1, 28, 1, 147 },
+ { 0x1, 0x1, 171, 1841, -1, 28, 1, 148 },
+ { 0x1, 0x1, 171, 1842, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1843, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1844, -1, 28, 1, 145 },
+ { 0x1, 0x1, 171, 1845, -1, 28, 1, 141 },
+ { 0x1, 0x1, 171, 1846, -1, 28, 1, 142 },
+ { 0x1, 0x1, 171, 1847, -1, 28, 1, 143 },
+ { 0x1, 0x1, 171, 1848, -1, 28, 1, 144 },
+ { 0x1, 0x1, 171, 1849, -1, 28, 1, 144 },
+ { 0x1, 0x1, 171, 1850, -1, 28, 1, 140 },
+ { 0x1, 0x1, 171, 1851, -1, 28, 1, 146 },
+ { 0x1, 0x1, 171, 1852, -1, 28, 1, 147 },
+ { 0x1, 0x1, 171, 1853, -1, 28, 1, 148 },
+ { 0x1, 0x1, 171, 1854, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1855, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1856, -1, 28, 1, 145 },
+ { 0x1, 0x1, 171, 1857, -1, 28, 1, 146 },
+ { 0x1, 0x1, 171, 1858, -1, 28, 1, 147 },
+ { 0x1, 0x1, 171, 1859, -1, 28, 1, 148 },
+ { 0x1, 0x1, 171, 1860, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1861, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1862, -1, 28, 1, 145 },
+ { 0x1, 0x1, 171, 1863, -1, 28, 1, 141 },
+ { 0x1, 0x1, 171, 1864, -1, 28, 1, 142 },
+ { 0x1, 0x1, 171, 1865, -1, 28, 1, 143 },
+ { 0x1, 0x1, 171, 1866, -1, 28, 1, 144 },
+ { 0x1, 0x1, 171, 1867, -1, 28, 1, 144 },
+ { 0x1, 0x1, 171, 1868, -1, 28, 1, 140 },
+ { 0x1, 0x1, 171, 1869, -1, 28, 1, 146 },
+ { 0x1, 0x1, 171, 1870, -1, 28, 1, 147 },
+ { 0x1, 0x1, 171, 1871, -1, 28, 1, 148 },
+ { 0x1, 0x1, 171, 1872, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1873, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1874, -1, 28, 1, 145 },
+ { 0x1, 0x1, 171, 1875, -1, 28, 1, 146 },
+ { 0x1, 0x1, 171, 1876, -1, 28, 1, 147 },
+ { 0x1, 0x1, 171, 1877, -1, 28, 1, 148 },
+ { 0x1, 0x1, 171, 1878, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1879, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1880, -1, 28, 1, 145 },
+ { 0x1, 0x1, 171, 1881, -1, 28, 1, 141 },
+ { 0x1, 0x1, 171, 1882, -1, 28, 1, 142 },
+ { 0x1, 0x1, 171, 1883, -1, 28, 1, 143 },
+ { 0x1, 0x1, 171, 1884, -1, 28, 1, 144 },
+ { 0x1, 0x1, 171, 1885, -1, 28, 1, 144 },
+ { 0x1, 0x1, 171, 1886, -1, 28, 1, 140 },
+ { 0x1, 0x1, 171, 1887, -1, 28, 1, 146 },
+ { 0x1, 0x1, 171, 1888, -1, 28, 1, 147 },
+ { 0x1, 0x1, 171, 1889, -1, 28, 1, 148 },
+ { 0x1, 0x1, 171, 1890, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1891, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1892, -1, 28, 1, 145 },
+ { 0x1, 0x1, 171, 1893, -1, 28, 1, 141 },
+ { 0x1, 0x1, 171, 1894, -1, 28, 1, 142 },
+ { 0x1, 0x1, 171, 1895, -1, 28, 1, 143 },
+ { 0x1, 0x1, 171, 1896, -1, 28, 1, 144 },
+ { 0x1, 0x1, 171, 1897, -1, 28, 1, 144 },
+ { 0x1, 0x1, 171, 1898, -1, 28, 1, 140 },
+ { 0x1, 0x1, 171, 1899, -1, 28, 1, 146 },
+ { 0x1, 0x1, 171, 1900, -1, 28, 1, 147 },
+ { 0x1, 0x1, 171, 1901, -1, 28, 1, 148 },
+ { 0x1, 0x1, 171, 1902, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1903, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1904, -1, 28, 1, 145 },
+ { 0x1, 0x1, 171, 1905, -1, 28, 1, 141 },
+ { 0x1, 0x1, 171, 1906, -1, 28, 1, 142 },
+ { 0x1, 0x1, 171, 1907, -1, 28, 1, 143 },
+ { 0x1, 0x1, 171, 1908, -1, 28, 1, 144 },
+ { 0x1, 0x1, 171, 1909, -1, 28, 1, 144 },
+ { 0x1, 0x1, 171, 1910, -1, 28, 1, 140 },
+ { 0x1, 0x1, 171, 1911, -1, 28, 1, 146 },
+ { 0x1, 0x1, 171, 1912, -1, 28, 1, 147 },
+ { 0x1, 0x1, 171, 1913, -1, 28, 1, 148 },
+ { 0x1, 0x1, 171, 1914, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1915, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1916, -1, 28, 1, 145 },
+ { 0x1, 0x1, 171, 1917, -1, 28, 1, 141 },
+ { 0x1, 0x1, 171, 1918, -1, 28, 1, 142 },
+ { 0x1, 0x1, 171, 1919, -1, 28, 1, 143 },
+ { 0x1, 0x1, 171, 1920, -1, 28, 1, 144 },
+ { 0x1, 0x1, 171, 1921, -1, 28, 1, 144 },
+ { 0x1, 0x1, 171, 1922, -1, 28, 1, 140 },
+ { 0x1, 0x1, 171, 1923, -1, 28, 1, 146 },
+ { 0x1, 0x1, 171, 1924, -1, 28, 1, 147 },
+ { 0x1, 0x1, 171, 1925, -1, 28, 1, 148 },
+ { 0x1, 0x1, 171, 1926, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1927, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1928, -1, 28, 1, 145 },
+ { 0x1, 0x1, 171, 1929, -1, 28, 1, 146 },
+ { 0x1, 0x1, 171, 1930, -1, 28, 1, 147 },
+ { 0x1, 0x1, 171, 1931, -1, 28, 1, 148 },
+ { 0x1, 0x1, 171, 1932, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1933, -1, 28, 1, 149 },
+ { 0x1, 0x1, 171, 1934, -1, 28, 1, 145 },
+ { 0x1, 0x1, 171, 1673, -1, 28, 1, 151 },
+ { 0x1, 0x1, 171, 1674, -1, 28, 1, 152 },
+ { 0x1, 0x1, 171, 1675, -1, 28, 1, 152 },
+ { 0x1, 0x1, 171, 1676, -1, 28, 1, 151 },
+ { 0x1, 0x1, 171, 1677, -1, 28, 1, 153 },
+ { 0x1, 0x1, 171, 1678, -1, 28, 1, 154 },
+ { 0x1, 0x1, 171, 1679, -1, 28, 1, 154 },
+ { 0x1, 0x1, 171, 1680, -1, 28, 1, 153 },
+ { 0x1, 0x1, 171, 1681, -1, 28, 1, 153 },
+ { 0x1, 0x1, 171, 1682, -1, 28, 1, 154 },
+ { 0x1, 0x1, 171, 1683, -1, 28, 1, 154 },
+ { 0x1, 0x1, 171, 1684, -1, 28, 1, 153 },
+ { 0x1, 0x1, 171, 1979, -1, 28, 1, 136 },
+ { 0x1, 0x1, 171, 1980, -1, 28, 1, 136 },
+ { 0x1, 0x1, 171, 1981, -1, 28, 1, 136 },
+ { 0x1, 0x1, 171, 1982, -1, 28, 1, 136 },
+ { 0x1, 0x1, 172, 1935, -1, 29, 1, 151 },
+ { 0x1, 0x1, 172, 1936, -1, 29, 1, 152 },
+ { 0x1, 0x1, 172, 1937, -1, 29, 1, 152 },
+ { 0x1, 0x1, 172, 1938, -1, 29, 1, 151 },
+ { 0x1, 0x1, 172, 1939, -1, 29, 1, 153 },
+ { 0x1, 0x1, 172, 1940, -1, 29, 1, 154 },
+ { 0x1, 0x1, 172, 1941, -1, 29, 1, 154 },
+ { 0x1, 0x1, 172, 1942, -1, 29, 1, 153 },
+ { 0x1, 0x1, 172, 1943, -1, 29, 1, 153 },
+ { 0x1, 0x1, 172, 1944, -1, 29, 1, 154 },
+ { 0x1, 0x1, 172, 1945, -1, 29, 1, 154 },
+ { 0x1, 0x1, 172, 1946, -1, 29, 1, 153 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 135 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 135 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 135 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 135 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 134 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 134 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 134 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 134 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 134 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 134 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 134 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 134 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 134 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 134 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 134 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 134 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 134 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 134 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 134 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 134 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 136 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 136 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 136 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 136 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 126 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 127 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 128 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 269, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 2224, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 126 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 127 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 128 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 271, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 2225, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 126 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 127 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 128 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 273, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 2226, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 125 },
+ { 0x3, 0x3, 173, 275, -1, 28, 1, 125 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 125 },
+ { 0x3, 0x3, 173, 276, -1, 28, 1, 125 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 126 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 127 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 128 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 277, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 2227, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 126 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 127 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 128 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 279, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 2228, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 126 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 127 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 128 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 281, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 2229, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 126 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 127 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 128 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 283, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 2230, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 126 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 127 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 128 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 285, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 2231, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 126 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 127 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 128 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 287, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 2232, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 126 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 127 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 128 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 129 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 289, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 2233, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 126 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 127 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 128 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 129 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 291, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 2234, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 126 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 127 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 128 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 129 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 293, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 130 },
+ { 0x3, 0x3, 173, 2235, -1, 28, 1, 124 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 140 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 145 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 145 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 141 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 142 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 143 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 144 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 144 },
+ { 0x3, 0x3, 173, 2236, -1, 28, 1, 140 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 146 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 147 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 148 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, 2237, -1, 28, 1, 145 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 146 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 147 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 148 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, 2238, -1, 28, 1, 145 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 141 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 142 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 143 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 144 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 144 },
+ { 0x3, 0x3, 173, 2239, -1, 28, 1, 140 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 146 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 147 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 148 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, 2240, -1, 28, 1, 145 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 146 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 147 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 148 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, 2241, -1, 28, 1, 145 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 141 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 142 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 143 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 144 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 144 },
+ { 0x3, 0x3, 173, 2242, -1, 28, 1, 140 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 146 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 147 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 148 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, 2243, -1, 28, 1, 145 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 146 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 147 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 148 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, 2244, -1, 28, 1, 145 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 141 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 142 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 143 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 144 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 144 },
+ { 0x3, 0x3, 173, 2245, -1, 28, 1, 140 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 146 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 147 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 148 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, 2246, -1, 28, 1, 145 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 141 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 142 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 143 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 144 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 144 },
+ { 0x3, 0x3, 173, 2247, -1, 28, 1, 140 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 146 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 147 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 148 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, 2248, -1, 28, 1, 145 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 141 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 142 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 143 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 144 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 144 },
+ { 0x3, 0x3, 173, 2249, -1, 28, 1, 140 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 146 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 147 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 148 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, 2250, -1, 28, 1, 145 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 141 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 142 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 143 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 144 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 144 },
+ { 0x3, 0x3, 173, 2251, -1, 28, 1, 140 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 146 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 147 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 148 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, 2252, -1, 28, 1, 145 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 146 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 147 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 148 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 149 },
+ { 0x3, 0x3, 173, 2253, -1, 28, 1, 145 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 151 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 152 },
+ { 0x3, 0x3, 173, 933, -1, 28, 1, 152 },
+ { 0x3, 0x3, 173, 934, -1, 28, 1, 151 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 153 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 154 },
+ { 0x3, 0x3, 173, 935, -1, 28, 1, 154 },
+ { 0x3, 0x3, 173, 936, -1, 28, 1, 153 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 153 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 154 },
+ { 0x3, 0x3, 173, 937, -1, 28, 1, 154 },
+ { 0x3, 0x3, 173, 938, -1, 28, 1, 153 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 131 },
+ { 0x3, 0x3, 173, 2190, -1, 28, 1, 131 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 138 },
+ { 0x3, 0x3, 173, 2191, -1, 28, 1, 138 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 132 },
+ { 0x3, 0x3, 173, 2192, -1, 28, 1, 132 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 132 },
+ { 0x3, 0x3, 173, 2193, -1, 28, 1, 132 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 131 },
+ { 0x3, 0x3, 173, 2194, -1, 28, 1, 131 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 138 },
+ { 0x3, 0x3, 173, 2195, -1, 28, 1, 138 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 131 },
+ { 0x3, 0x3, 173, 2196, -1, 28, 1, 131 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 138 },
+ { 0x3, 0x3, 173, 2197, -1, 28, 1, 138 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 131 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 133 },
+ { 0x3, 0x3, 173, 2198, -1, 28, 1, 131 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 138 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 139 },
+ { 0x3, 0x3, 173, 2199, -1, 28, 1, 138 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 150 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 156 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 150 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 156 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 150 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 156 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 150 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 156 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 150 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 156 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 136 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 136 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 136 },
+ { 0x3, 0x3, 173, -1, -1, 28, 1, 136 },
+ { 0x0, 0x0, 174, -1, 392, 0, 0, -1 },
+ { 0x0, 0x0, 174, -1, 394, 0, 0, -1 },
+ { 0x0, 0x0, 174, 3004, 2968, 0, 1, 1 },
+ { 0x0, 0x0, 174, 3005, 2969, 0, 1, 1 },
+ { 0x0, 0x0, 174, -1, 400, 0, 0, -1 },
+ { 0x0, 0x0, 174, -1, 402, 0, 0, -1 },
+ { 0x0, 0x0, 174, 3008, 2972, 0, 1, 1 },
+ { 0x0, 0x0, 174, 3009, 2973, 0, 1, 1 },
+ { 0x11, 0x31, 175, 2847, 407, 33, 1, 4 },
+ { 0x2200001, 0x2200001, 175, -1, 408, 12, 1, 4 },
+ { 0x11, 0x31, 175, 2047, 409, 33, 1, 4 },
+ { 0x2200001, 0x2200001, 175, -1, 411, 12, 1, 4 },
+ { 0x1, 0x1, 175, -1, 415, 37, 1, 4 },
+ { 0x2000001, 0x2000001, 175, -1, 416, 12, 1, 4 },
+ { 0x11, 0x11, 175, -1, 417, 33, 1, 4 },
+ { 0x2200001, 0x2200001, 175, -1, 418, 12, 1, 4 },
+ { 0x1, 0x1, 175, 2053, 419, 37, 1, 4 },
+ { 0x2000001, 0x2000001, 175, -1, 421, 12, 1, 4 },
+ { 0x11, 0x11, 175, 2055, 423, 33, 1, 4 },
+ { 0x2200001, 0x2200001, 175, -1, 425, 12, 1, 4 },
+ { 0x1, 0x1, 175, 2057, 427, 37, 1, 4 },
+ { 0x2000001, 0x2000001, 175, -1, 429, 12, 1, 4 },
+ { 0x11, 0x11, 175, 2059, 431, 33, 1, 4 },
+ { 0x2200001, 0x2200001, 175, -1, 433, 12, 1, 4 },
+ { 0x1, 0x1, 175, 2061, 435, 37, 1, 4 },
+ { 0x2000001, 0x2000001, 175, -1, 437, 12, 1, 4 },
+ { 0x11, 0x11, 175, 2063, 439, 33, 1, 4 },
+ { 0x2200001, 0x2200001, 175, -1, 441, 12, 1, 4 },
+ { 0x11, 0x31, 175, 2867, 447, 33, 1, 4 },
+ { 0x2200001, 0x2200001, 175, -1, 448, 12, 1, 4 },
+ { 0x11, 0x31, 175, 2069, 449, 33, 1, 4 },
+ { 0x2200001, 0x2200001, 175, -1, 451, 12, 1, 4 },
+ { 0x11, 0x31, 175, 2887, 455, 33, 1, 4 },
+ { 0x2200001, 0x2200001, 175, -1, 456, 12, 1, 4 },
+ { 0x11, 0x31, 175, 2095, 457, 33, 1, 4 },
+ { 0x2200001, 0x2200001, 175, -1, 459, 12, 1, 4 },
+ { 0x1, 0x1, 175, -1, 463, 37, 1, 4 },
+ { 0x2000001, 0x2000001, 175, -1, 464, 12, 1, 4 },
+ { 0x11, 0x11, 175, -1, 465, 33, 1, 4 },
+ { 0x2200001, 0x2200001, 175, -1, 466, 12, 1, 4 },
+ { 0x1, 0x1, 175, 2101, 467, 37, 1, 4 },
+ { 0x2000001, 0x2000001, 175, -1, 469, 12, 1, 4 },
+ { 0x11, 0x11, 175, 2103, 471, 33, 1, 4 },
+ { 0x2200001, 0x2200001, 175, -1, 473, 12, 1, 4 },
+ { 0x1, 0x1, 175, 2105, 475, 37, 1, 4 },
+ { 0x2000001, 0x2000001, 175, -1, 477, 12, 1, 4 },
+ { 0x11, 0x11, 175, 2107, 479, 33, 1, 4 },
+ { 0x2200001, 0x2200001, 175, -1, 481, 12, 1, 4 },
+ { 0x1, 0x1, 175, 2109, 483, 37, 1, 4 },
+ { 0x2000001, 0x2000001, 175, -1, 485, 12, 1, 4 },
+ { 0x11, 0x11, 175, 2111, 487, 33, 1, 4 },
+ { 0x2200001, 0x2200001, 175, -1, 489, 12, 1, 4 },
+ { 0x11, 0x31, 175, 2907, 495, 33, 1, 4 },
+ { 0x2200001, 0x2200001, 175, -1, 496, 12, 1, 4 },
+ { 0x11, 0x31, 175, 2117, 497, 33, 1, 4 },
+ { 0x2200001, 0x2200001, 175, -1, 499, 12, 1, 4 },
+ { 0x1, 0x1, 175, -1, 503, 33, 1, 4 },
+ { 0x200001, 0x200001, 175, -1, 504, 12, 1, 4 },
+ { 0x1, 0x1, 175, -1, 505, 33, 1, 4 },
+ { 0x200001, 0x200001, 175, -1, 506, 12, 1, 4 },
+ { 0x1, 0x1, 175, -1, 511, 33, 1, 4 },
+ { 0x200001, 0x200001, 175, -1, 512, 12, 1, 4 },
+ { 0x1, 0x1, 175, -1, 513, 33, 1, 4 },
+ { 0x200001, 0x200001, 175, -1, 514, 12, 1, 4 },
+ { 0x2200001, 0x6200001, 176, 2850, -1, 12, 1, 4 },
+ { 0x11, 0x11, 176, 1994, -1, 33, 1, 4 },
+ { 0x1, 0x1, 176, -1, -1, 33, 1, 5 },
+ { 0x4200001, 0x4200001, 176, -1, -1, 12, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 37, 1, 4 },
+ { 0x2000001, 0x2000001, 176, -1, -1, 12, 1, 4 },
+ { 0x2000001, 0x2000001, 176, -1, -1, 12, 1, 4 },
+ { 0x1, 0x1, 176, 2000, -1, 37, 1, 4 },
+ { 0x2200001, 0x2200001, 176, -1, -1, 12, 1, 4 },
+ { 0x11, 0x11, 176, 2002, -1, 33, 1, 4 },
+ { 0x2000001, 0x2000001, 176, -1, -1, 12, 1, 4 },
+ { 0x1, 0x1, 176, 2004, -1, 37, 1, 4 },
+ { 0x2200001, 0x2200001, 176, -1, -1, 12, 1, 4 },
+ { 0x11, 0x11, 176, 2006, -1, 33, 1, 4 },
+ { 0x2000001, 0x2000001, 176, -1, -1, 12, 1, 4 },
+ { 0x1, 0x1, 176, 2008, -1, 37, 1, 4 },
+ { 0x2200001, 0x2200001, 176, -1, -1, 12, 1, 4 },
+ { 0x11, 0x11, 176, 2010, -1, 33, 1, 4 },
+ { 0x1, 0x1, 176, -1, -1, 37, 1, 4 },
+ { 0x2000001, 0x2000001, 176, -1, -1, 12, 1, 4 },
+ { 0x11, 0x11, 176, -1, -1, 33, 1, 4 },
+ { 0x2200001, 0x2200001, 176, -1, -1, 12, 1, 4 },
+ { 0x2200001, 0x6200001, 176, 2870, -1, 12, 1, 4 },
+ { 0x11, 0x11, 176, 2014, -1, 33, 1, 4 },
+ { 0x1, 0x1, 176, -1, -1, 33, 1, 5 },
+ { 0x4200001, 0x4200001, 176, -1, -1, 12, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 37, 1, 4 },
+ { 0x2000001, 0x2000001, 176, -1, -1, 12, 1, 4 },
+ { 0x0, 0x0, 176, -1, -1, 0, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 12, 1, 5 },
+ { 0x0, 0x0, 176, -1, -1, 0, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 12, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 33, 1, 5 },
+ { 0x200001, 0x200001, 176, -1, -1, 12, 1, 5 },
+ { 0x0, 0x0, 176, -1, -1, 0, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 12, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 33, 1, 5 },
+ { 0x200001, 0x200001, 176, -1, -1, 12, 1, 5 },
+ { 0x0, 0x0, 176, -1, -1, 0, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 12, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 33, 1, 5 },
+ { 0x200001, 0x200001, 176, -1, -1, 12, 1, 5 },
+ { 0x0, 0x0, 176, -1, -1, 0, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 12, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 33, 1, 5 },
+ { 0x200001, 0x200001, 176, -1, -1, 12, 1, 5 },
+ { 0x0, 0x0, 176, -1, -1, 0, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 12, 1, 5 },
+ { 0x2200001, 0x6200001, 176, 2890, -1, 12, 1, 4 },
+ { 0x11, 0x11, 176, 2018, -1, 33, 1, 4 },
+ { 0x1, 0x1, 176, -1, -1, 33, 1, 5 },
+ { 0x4200001, 0x4200001, 176, -1, -1, 12, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 37, 1, 4 },
+ { 0x2000001, 0x2000001, 176, -1, -1, 12, 1, 4 },
+ { 0x2000001, 0x2000001, 176, -1, -1, 12, 1, 4 },
+ { 0x1, 0x1, 176, 2024, -1, 37, 1, 4 },
+ { 0x2200001, 0x2200001, 176, -1, -1, 12, 1, 4 },
+ { 0x11, 0x11, 176, 2026, -1, 33, 1, 4 },
+ { 0x2000001, 0x2000001, 176, -1, -1, 12, 1, 4 },
+ { 0x1, 0x1, 176, 2028, -1, 37, 1, 4 },
+ { 0x2200001, 0x2200001, 176, -1, -1, 12, 1, 4 },
+ { 0x11, 0x11, 176, 2030, -1, 33, 1, 4 },
+ { 0x2000001, 0x2000001, 176, -1, -1, 12, 1, 4 },
+ { 0x1, 0x1, 176, 2032, -1, 37, 1, 4 },
+ { 0x2200001, 0x2200001, 176, -1, -1, 12, 1, 4 },
+ { 0x11, 0x11, 176, 2034, -1, 33, 1, 4 },
+ { 0x1, 0x1, 176, -1, -1, 37, 1, 4 },
+ { 0x2000001, 0x2000001, 176, -1, -1, 12, 1, 4 },
+ { 0x11, 0x11, 176, -1, -1, 33, 1, 4 },
+ { 0x2200001, 0x2200001, 176, -1, -1, 12, 1, 4 },
+ { 0x2200001, 0x6200001, 176, 2909, -1, 12, 1, 4 },
+ { 0x11, 0x11, 176, 2038, -1, 33, 1, 4 },
+ { 0x1, 0x1, 176, -1, -1, 33, 1, 5 },
+ { 0x4200001, 0x4200001, 176, -1, -1, 12, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 37, 1, 4 },
+ { 0x2000001, 0x2000001, 176, -1, -1, 12, 1, 4 },
+ { 0x0, 0x0, 176, -1, -1, 0, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 12, 1, 5 },
+ { 0x0, 0x0, 176, -1, -1, 0, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 12, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 33, 1, 5 },
+ { 0x200001, 0x200001, 176, -1, -1, 12, 1, 5 },
+ { 0x0, 0x0, 176, -1, -1, 0, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 12, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 33, 1, 5 },
+ { 0x200001, 0x200001, 176, -1, -1, 12, 1, 5 },
+ { 0x0, 0x0, 176, -1, -1, 0, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 12, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 33, 1, 5 },
+ { 0x200001, 0x200001, 176, -1, -1, 12, 1, 5 },
+ { 0x0, 0x0, 176, -1, -1, 0, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 12, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 33, 1, 5 },
+ { 0x200001, 0x200001, 176, -1, -1, 12, 1, 5 },
+ { 0x0, 0x0, 176, -1, -1, 0, 1, 5 },
+ { 0x1, 0x1, 176, -1, -1, 12, 1, 5 },
+ { 0x9, 0x9, 176, -1, -1, 33, 1, 5 },
+ { 0x1, 0x1, 176, 395, -1, 33, 1, 4 },
+ { 0x1200001, 0x1200001, 176, -1, -1, 12, 1, 5 },
+ { 0x200001, 0x200001, 176, 396, -1, 12, 1, 4 },
+ { 0x9, 0x9, 176, -1, -1, 33, 1, 5 },
+ { 0x1, 0x1, 176, 397, -1, 33, 1, 4 },
+ { 0x1200001, 0x1200001, 176, -1, -1, 12, 1, 5 },
+ { 0x200001, 0x200001, 176, 398, -1, 12, 1, 4 },
+ { 0x9, 0x9, 176, -1, -1, 33, 1, 5 },
+ { 0x1, 0x1, 176, 403, -1, 33, 1, 4 },
+ { 0x1200001, 0x1200001, 176, -1, -1, 12, 1, 5 },
+ { 0x200001, 0x200001, 176, 404, -1, 12, 1, 4 },
+ { 0x9, 0x9, 176, -1, -1, 33, 1, 5 },
+ { 0x1, 0x1, 176, 405, -1, 33, 1, 4 },
+ { 0x1200001, 0x1200001, 176, -1, -1, 12, 1, 5 },
+ { 0x200001, 0x200001, 176, 406, -1, 12, 1, 4 },
+ { 0x0, 0x0, 177, -1, 2293, 0, 0, -1 },
+ { 0x9, 0x9, 177, -1, 2301, 33, 1, 49 },
+ { 0x9, 0x9, 177, -1, 2959, 33, 1, 49 },
+ { 0x0, 0x0, 177, -1, 2346, 0, 0, -1 },
+ { 0x7, 0x7, 177, -1, -1, 27, 1, 49 },
+ { 0x1, 0x1, 197, -1, -1, 27, 1, 10 },
+ { 0x1, 0x1, 211, -1, -1, 29, 1, 0 },
+ { 0x1, 0x1, 211, -1, -1, 29, 1, 0 },
+ { 0x2, 0x3, 211, 1151, -1, 27, 1, 33 },
+ { 0x0, 0x0, 211, 1152, -1, 0, 1, 33 },
+ { 0x0, 0x0, 211, 1153, -1, 0, 1, 0 },
+ { 0x0, 0x0, 211, 1154, -1, 0, 1, 0 },
+ { 0x0, 0x0, 211, 1155, -1, 0, 1, 0 },
+ { 0x0, 0x0, 211, 1156, -1, 0, 1, 0 },
+ { 0x0, 0x0, 211, 2988, -1, 0, 1, 93 },
+ { 0x0, 0x0, 211, 2989, -1, 0, 1, 93 },
+ { 0x0, 0x0, 211, 2990, 949, 0, 0, -1 },
+ { 0x1, 0x1, 212, -1, -1, 27, 1, 0 },
+ { 0x1, 0x1, 212, -1, -1, 27, 1, 0 },
+ { 0x1, 0x1, 213, -1, 1408, 32, 1, 135 },
+ { 0x1, 0x1, 213, -1, 1410, 32, 1, 135 },
+ { 0x1, 0x1, 213, -1, 1412, 32, 1, 134 },
+ { 0x1, 0x1, 213, -1, 1414, 32, 1, 134 },
+ { 0x1, 0x1, 213, -1, 1416, 32, 1, 134 },
+ { 0x1, 0x1, 213, -1, 1418, 32, 1, 134 },
+ { 0x1, 0x1, 213, -1, 1420, 32, 1, 134 },
+ { 0x1, 0x1, 213, -1, 1422, 32, 1, 134 },
+ { 0x1, 0x1, 213, -1, 1424, 32, 1, 134 },
+ { 0x1, 0x1, 213, -1, 1426, 32, 1, 134 },
+ { 0x1, 0x1, 213, -1, 1428, 32, 1, 136 },
+ { 0x1, 0x1, 213, -1, 1430, 32, 1, 136 },
+ { 0x1, 0x1, 213, -1, 1947, 32, 1, 131 },
+ { 0x1, 0x1, 213, -1, 1949, 32, 1, 138 },
+ { 0x1, 0x1, 213, -1, 1951, 32, 1, 132 },
+ { 0x1, 0x1, 213, -1, 1953, 32, 1, 132 },
+ { 0x1, 0x1, 213, -1, 1955, 32, 1, 131 },
+ { 0x1, 0x1, 213, -1, 1957, 32, 1, 138 },
+ { 0x1, 0x1, 213, -1, 1959, 32, 1, 131 },
+ { 0x1, 0x1, 213, -1, 1961, 32, 1, 138 },
+ { 0x1, 0x1, 213, 2749, 1963, 32, 1, 131 },
+ { 0x1, 0x1, 213, 2750, 1966, 32, 1, 138 },
+ { 0x0, 0x0, 214, -1, 2791, 0, 0, -1 },
+ { 0x0, 0x0, 214, -1, 2792, 0, 0, -1 },
+ { 0x0, 0x0, 214, -1, 2817, 0, 0, -1 },
+ { 0x5, 0x5, 214, -1, 2820, 20, 1, 67 },
+ { 0x0, 0x0, 218, 2175, 948, 0, 0, -1 },
+ { 0x0, 0x0, 219, -1, 1121, 0, 0, -1 },
+ { 0x0, 0x0, 219, -1, 1246, 0, 0, -1 },
+ { 0x0, 0x0, 219, -1, -1, 0, 1, 121 },
+ { 0x0, 0x0, 219, -1, -1, 0, 1, 66 },
+ { 0x1, 0x1, 219, 815, 2255, 36, 1, 65 },
+ { 0x1, 0x1, 219, 816, 2314, 36, 1, 65 },
+ { 0x0, 0x0, 219, 817, 2317, 0, 0, -1 },
+ { 0x1, 0x1, 219, 818, -1, 36, 1, 65 },
+ { 0x0, 0x0, 219, 1405, -1, 0, 1, 33 },
+ { 0x1, 0x1, 219, 819, 2322, 36, 1, 65 },
+ { 0x0, 0x0, 219, 820, 2325, 0, 0, -1 },
+ { 0x1, 0x1, 219, 821, -1, 36, 1, 65 },
+ { 0x0, 0x0, 219, 822, 2328, 0, 0, -1 },
+ { 0x1, 0x1, 219, 823, -1, 36, 1, 65 },
+ { 0x1, 0x1, 219, 824, 2331, 36, 1, 65 },
+ { 0x1, 0x1, 219, 825, 2334, 36, 1, 65 },
+ { 0x0, 0x0, 219, 1406, -1, 0, 1, 33 },
+ { 0x1, 0x1, 219, 826, 2367, 36, 1, 65 },
+ { 0x1, 0x1, 219, 827, -1, 31, 1, 137 },
+ { 0x1, 0x1, 219, 226, 1431, 32, 1, 126 },
+ { 0x1, 0x1, 219, 227, 1440, 32, 1, 126 },
+ { 0x1, 0x1, 219, 228, 1449, 32, 1, 126 },
+ { 0x1, 0x1, 219, 229, 1462, 32, 1, 126 },
+ { 0x1, 0x1, 219, 230, 1471, 32, 1, 126 },
+ { 0x1, 0x1, 219, 231, 1480, 32, 1, 126 },
+ { 0x1, 0x1, 219, 232, 1489, 32, 1, 126 },
+ { 0x1, 0x1, 219, 233, 1498, 32, 1, 126 },
+ { 0x1, 0x1, 219, 234, 1507, 32, 1, 126 },
+ { 0x1, 0x1, 219, 235, 1516, 32, 1, 126 },
+ { 0x1, 0x1, 219, 236, 1526, 32, 1, 126 },
+ { 0x1, 0x1, 219, 237, 1536, 32, 1, 126 },
+ { 0x1, 0x1, 219, 238, 1549, 32, 1, 141 },
+ { 0x1, 0x1, 219, 239, 1555, 32, 1, 146 },
+ { 0x1, 0x1, 219, 240, 1561, 32, 1, 146 },
+ { 0x1, 0x1, 219, 241, 1567, 32, 1, 141 },
+ { 0x1, 0x1, 219, 242, 1573, 32, 1, 146 },
+ { 0x1, 0x1, 219, 243, 1579, 32, 1, 146 },
+ { 0x1, 0x1, 219, 244, 1585, 32, 1, 141 },
+ { 0x1, 0x1, 219, 245, 1591, 32, 1, 146 },
+ { 0x1, 0x1, 219, 246, 1597, 32, 1, 146 },
+ { 0x1, 0x1, 219, 247, 1603, 32, 1, 141 },
+ { 0x1, 0x1, 219, 248, 1609, 32, 1, 146 },
+ { 0x1, 0x1, 219, 249, 1615, 32, 1, 141 },
+ { 0x1, 0x1, 219, 250, 1621, 32, 1, 146 },
+ { 0x1, 0x1, 219, 251, 1627, 32, 1, 141 },
+ { 0x1, 0x1, 219, 252, 1633, 32, 1, 146 },
+ { 0x1, 0x1, 219, 253, 1639, 32, 1, 141 },
+ { 0x1, 0x1, 219, 254, 1645, 32, 1, 146 },
+ { 0x1, 0x1, 219, 255, 1651, 32, 1, 146 },
+ { 0x1, 0x1, 219, 831, -1, 31, 1, 155 },
+ { 0x0, 0x0, 220, 2370, -1, 0, 1, 65 },
+ { 0x0, 0x0, 220, 2371, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 25, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 2373, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 2374, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 2375, -1, 0, 1, 44 },
+ { 0x0, 0x0, 220, 2376, -1, 0, 1, 39 },
+ { 0x1, 0x1, 220, 2377, -1, 12, 1, 58 },
+ { 0x0, 0x0, 220, 2378, -1, 0, 1, 53 },
+ { 0x1000001, 0x1000001, 220, 2379, -1, 12, 1, 58 },
+ { 0x1, 0x1, 220, 2380, -1, 36, 1, 53 },
+ { 0x200001, 0x200001, 220, 2381, -1, 12, 1, 58 },
+ { 0x1, 0x1, 220, 2382, -1, 33, 1, 53 },
+ { 0x1200001, 0x1200001, 220, 2383, -1, 12, 1, 48 },
+ { 0x9, 0x9, 220, 2384, -1, 33, 1, 48 },
+ { 0x0, 0x0, 220, 2385, -1, 0, 1, 58 },
+ { 0x0, 0x0, 220, 2386, -1, 0, 1, 53 },
+ { 0x0, 0x0, 220, 2387, -1, 0, 1, 58 },
+ { 0x0, 0x0, 220, 2388, -1, 0, 1, 53 },
+ { 0x0, 0x0, 220, 2389, -1, 0, 1, 58 },
+ { 0x0, 0x0, 220, 2390, -1, 0, 1, 53 },
+ { 0x0, 0x0, 220, 2391, -1, 0, 1, 48 },
+ { 0x0, 0x0, 220, 2392, -1, 0, 1, 48 },
+ { 0x1, 0x1, 220, 2393, -1, 12, 1, 58 },
+ { 0x0, 0x0, 220, 2394, -1, 0, 1, 53 },
+ { 0x200001, 0x1200001, 220, 2395, -1, 12, 1, 58 },
+ { 0x1, 0x9, 220, 2396, -1, 33, 1, 53 },
+ { 0x0, 0x0, 220, 2397, -1, 0, 1, 58 },
+ { 0x0, 0x0, 220, 2398, -1, 0, 1, 53 },
+ { 0x0, 0x0, 220, 2399, -1, 0, 1, 58 },
+ { 0x0, 0x0, 220, 2400, -1, 0, 1, 53 },
+ { 0x1, 0x1, 220, 2401, -1, 12, 1, 58 },
+ { 0x0, 0x0, 220, 2402, -1, 0, 1, 53 },
+ { 0x1000001, 0x1000001, 220, 2403, -1, 12, 1, 58 },
+ { 0x1, 0x1, 220, 2404, -1, 36, 1, 53 },
+ { 0x200001, 0x200001, 220, 2405, -1, 12, 1, 58 },
+ { 0x1, 0x1, 220, 2406, -1, 33, 1, 53 },
+ { 0x1200001, 0x1200001, 220, 2407, -1, 12, 1, 48 },
+ { 0x9, 0x9, 220, 2408, -1, 33, 1, 48 },
+ { 0x0, 0x0, 220, 2409, -1, 0, 1, 58 },
+ { 0x0, 0x0, 220, 2410, -1, 0, 1, 53 },
+ { 0x0, 0x0, 220, 2411, -1, 0, 1, 58 },
+ { 0x0, 0x0, 220, 2412, -1, 0, 1, 53 },
+ { 0x0, 0x0, 220, 2413, -1, 0, 1, 58 },
+ { 0x0, 0x0, 220, 2414, -1, 0, 1, 53 },
+ { 0x0, 0x0, 220, 2415, -1, 0, 1, 48 },
+ { 0x0, 0x0, 220, 2416, -1, 0, 1, 48 },
+ { 0x1, 0x1, 220, 2417, -1, 12, 1, 58 },
+ { 0x0, 0x0, 220, 2418, -1, 0, 1, 53 },
+ { 0x200001, 0x1200001, 220, 2419, -1, 12, 1, 58 },
+ { 0x1, 0x9, 220, 2420, -1, 33, 1, 53 },
+ { 0x0, 0x0, 220, 2421, -1, 0, 1, 58 },
+ { 0x0, 0x0, 220, 2422, -1, 0, 1, 53 },
+ { 0x0, 0x0, 220, 2423, -1, 0, 1, 58 },
+ { 0x0, 0x0, 220, 2424, -1, 0, 1, 53 },
+ { 0x1, 0x1, 220, 2425, -1, 28, 1, 28 },
+ { 0x0, 0x0, 220, 2426, -1, 0, 1, 28 },
+ { 0x3, 0x3, 220, 2427, -1, 27, 1, 28 },
+ { 0x1, 0x1, 220, 2428, -1, 27, 1, 28 },
+ { 0x0, 0x0, 220, 2429, -1, 0, 1, 65 },
+ { 0x0, 0x0, 220, 2430, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 2431, -1, 0, 1, 28 },
+ { 0x1, 0x1, 220, 2432, -1, 36, 1, 65 },
+ { 0x1, 0x1, 220, 2433, -1, 37, 1, 28 },
+ { 0x0, 0x0, 220, 2434, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 2435, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 2436, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 2437, -1, 0, 1, 65 },
+ { 0x0, 0x0, 220, 2438, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 37, -1, 0, 1, 28 },
+ { 0x1, 0x1, 220, 2440, -1, 36, 1, 65 },
+ { 0x1, 0x1, 220, 2441, -1, 37, 1, 28 },
+ { 0x0, 0x0, 220, 2442, -1, 0, 1, 28 },
+ { 0x1, 0x1, 220, 2443, -1, 36, 1, 65 },
+ { 0x1, 0x1, 220, 2444, -1, 37, 1, 28 },
+ { 0x0, 0x0, 220, 2445, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 2446, -1, 0, 1, 65 },
+ { 0x0, 0x0, 220, 2447, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 42, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 2449, -1, 0, 1, 65 },
+ { 0x0, 0x0, 220, 2450, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 43, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 2452, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 2453, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 2454, -1, 0, 1, 48 },
+ { 0x1, 0x1, 220, 2455, -1, 27, 1, 48 },
+ { 0x1, 0x1, 220, 2456, -1, 28, 1, 48 },
+ { 0x3, 0x3, 220, 2457, -1, 27, 1, 48 },
+ { 0x1, 0x1, 220, 2458, -1, 29, 1, 48 },
+ { 0x5, 0x5, 220, 2459, -1, 27, 1, 48 },
+ { 0x3, 0x3, 220, 2460, -1, 28, 1, 48 },
+ { 0x7, 0x7, 220, 2461, -1, 27, 1, 48 },
+ { 0x0, 0x0, 220, 2462, -1, 0, 1, 48 },
+ { 0x0, 0x0, 220, 2463, -1, 0, 1, 48 },
+ { 0x0, 0x0, 220, 2464, -1, 0, 1, 48 },
+ { 0x0, 0x0, 220, 2465, -1, 0, 1, 48 },
+ { 0x1, 0x1, 220, 2466, -1, 28, 1, 28 },
+ { 0x0, 0x0, 220, 2467, -1, 0, 1, 28 },
+ { 0x3, 0x3, 220, 2468, -1, 27, 1, 28 },
+ { 0x1, 0x1, 220, 2469, -1, 27, 1, 28 },
+ { 0x0, 0x0, 220, 2470, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 2471, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 2472, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 52, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 2474, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 2475, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 57, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 2477, -1, 0, 1, 23 },
+ { 0x0, 0x0, 220, 2478, -1, 0, 1, 23 },
+ { 0x0, 0x0, 220, 2479, -1, 0, 1, 23 },
+ { 0x0, 0x0, 220, 2480, -1, 0, 1, 23 },
+ { 0x0, 0x0, 220, 2481, -1, 0, 1, 34 },
+ { 0x0, 0x0, 220, 2482, -1, 0, 1, 65 },
+ { 0x0, 0x0, 220, 2483, -1, 0, 1, 28 },
+ { 0x0, 0x0, 220, 64, -1, 0, 1, 28 },
+ { 0x1, 0x1, 221, 2485, -1, 34, 1, 65 },
+ { 0x1, 0x1, 221, 2486, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2487, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2488, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2489, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2490, -1, 34, 1, 45 },
+ { 0x1, 0x1, 221, 2491, -1, 34, 1, 41 },
+ { 0x400001, 0x400001, 221, 2492, -1, 12, 1, 60 },
+ { 0x1, 0x1, 221, 2493, -1, 34, 1, 55 },
+ { 0x1400001, 0x1400001, 221, 2494, -1, 12, 1, 60 },
+ { 0x5, 0x5, 221, 2495, -1, 34, 1, 55 },
+ { 0x600001, 0x600001, 221, 2496, -1, 12, 1, 60 },
+ { 0x3, 0x3, 221, 2497, -1, 33, 1, 55 },
+ { 0x1600001, 0x1600001, 221, 2498, -1, 12, 1, 50 },
+ { 0xb, 0xb, 221, 2499, -1, 33, 1, 50 },
+ { 0x1, 0x1, 221, 2500, -1, 34, 1, 60 },
+ { 0x1, 0x1, 221, 2501, -1, 34, 1, 55 },
+ { 0x1, 0x1, 221, 2502, -1, 34, 1, 60 },
+ { 0x1, 0x1, 221, 2503, -1, 34, 1, 55 },
+ { 0x1, 0x1, 221, 2504, -1, 34, 1, 60 },
+ { 0x1, 0x1, 221, 2505, -1, 34, 1, 55 },
+ { 0x1, 0x1, 221, 2506, -1, 34, 1, 50 },
+ { 0x1, 0x1, 221, 2507, -1, 34, 1, 50 },
+ { 0x400001, 0x400001, 221, 2508, -1, 12, 1, 60 },
+ { 0x1, 0x1, 221, 2509, -1, 34, 1, 55 },
+ { 0x600001, 0x1600001, 221, 2510, -1, 12, 1, 60 },
+ { 0x3, 0xb, 221, 2511, -1, 33, 1, 55 },
+ { 0x1, 0x1, 221, 2512, -1, 34, 1, 60 },
+ { 0x1, 0x1, 221, 2513, -1, 34, 1, 55 },
+ { 0x1, 0x1, 221, 2514, -1, 34, 1, 60 },
+ { 0x1, 0x1, 221, 2515, -1, 34, 1, 55 },
+ { 0x400001, 0x400001, 221, 2516, -1, 12, 1, 60 },
+ { 0x1, 0x1, 221, 2517, -1, 34, 1, 55 },
+ { 0x1400001, 0x1400001, 221, 2518, -1, 12, 1, 60 },
+ { 0x5, 0x5, 221, 2519, -1, 34, 1, 55 },
+ { 0x600001, 0x600001, 221, 2520, -1, 12, 1, 60 },
+ { 0x3, 0x3, 221, 2521, -1, 33, 1, 55 },
+ { 0x1600001, 0x1600001, 221, 2522, -1, 12, 1, 50 },
+ { 0xb, 0xb, 221, 2523, -1, 33, 1, 50 },
+ { 0x1, 0x1, 221, 2524, -1, 34, 1, 60 },
+ { 0x1, 0x1, 221, 2525, -1, 34, 1, 55 },
+ { 0x1, 0x1, 221, 2526, -1, 34, 1, 60 },
+ { 0x1, 0x1, 221, 2527, -1, 34, 1, 55 },
+ { 0x1, 0x1, 221, 2528, -1, 34, 1, 60 },
+ { 0x1, 0x1, 221, 2529, -1, 34, 1, 55 },
+ { 0x1, 0x1, 221, 2530, -1, 34, 1, 50 },
+ { 0x1, 0x1, 221, 2531, -1, 34, 1, 50 },
+ { 0x400001, 0x400001, 221, 2532, -1, 12, 1, 60 },
+ { 0x1, 0x1, 221, 2533, -1, 34, 1, 55 },
+ { 0x600001, 0x1600001, 221, 2534, -1, 12, 1, 60 },
+ { 0x3, 0xb, 221, 2535, -1, 33, 1, 55 },
+ { 0x1, 0x1, 221, 2536, -1, 34, 1, 60 },
+ { 0x1, 0x1, 221, 2537, -1, 34, 1, 55 },
+ { 0x1, 0x1, 221, 2538, -1, 34, 1, 60 },
+ { 0x1, 0x1, 221, 2539, -1, 34, 1, 55 },
+ { 0x41, 0x41, 221, 2540, -1, 28, 1, 30 },
+ { 0x1, 0x1, 221, 2541, -1, 34, 1, 30 },
+ { 0x83, 0x83, 221, 2542, -1, 27, 1, 30 },
+ { 0x81, 0x81, 221, 2543, -1, 27, 1, 30 },
+ { 0x1, 0x1, 221, 2544, -1, 34, 1, 65 },
+ { 0x1, 0x1, 221, 2545, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2546, -1, 34, 1, 30 },
+ { 0x5, 0x5, 221, 2547, -1, 34, 1, 65 },
+ { 0x9, 0x9, 221, 2548, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2549, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2550, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2551, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2552, -1, 34, 1, 65 },
+ { 0x1, 0x1, 221, 2553, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2554, -1, 34, 1, 30 },
+ { 0x5, 0x5, 221, 2555, -1, 34, 1, 65 },
+ { 0x9, 0x9, 221, 2556, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2557, -1, 34, 1, 30 },
+ { 0x5, 0x5, 221, 2558, -1, 34, 1, 65 },
+ { 0x9, 0x9, 221, 2559, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2560, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2561, -1, 34, 1, 65 },
+ { 0x1, 0x1, 221, 2562, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2563, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2564, -1, 34, 1, 65 },
+ { 0x1, 0x1, 221, 2565, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2566, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2567, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2568, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2569, -1, 34, 1, 50 },
+ { 0x81, 0x81, 221, 2570, -1, 27, 1, 50 },
+ { 0x41, 0x41, 221, 2571, -1, 28, 1, 50 },
+ { 0x83, 0x83, 221, 2572, -1, 27, 1, 50 },
+ { 0x21, 0x21, 221, 2573, -1, 29, 1, 50 },
+ { 0x85, 0x85, 221, 2574, -1, 27, 1, 50 },
+ { 0x43, 0x43, 221, 2575, -1, 28, 1, 50 },
+ { 0x87, 0x87, 221, 2576, -1, 27, 1, 50 },
+ { 0x1, 0x1, 221, 2577, -1, 34, 1, 50 },
+ { 0x1, 0x1, 221, 2578, -1, 34, 1, 50 },
+ { 0x1, 0x1, 221, 2579, -1, 34, 1, 50 },
+ { 0x1, 0x1, 221, 2580, -1, 34, 1, 50 },
+ { 0x41, 0x41, 221, 2581, -1, 28, 1, 30 },
+ { 0x1, 0x1, 221, 2582, -1, 34, 1, 30 },
+ { 0x83, 0x83, 221, 2583, -1, 27, 1, 30 },
+ { 0x81, 0x81, 221, 2584, -1, 27, 1, 30 },
+ { 0x1, 0x1, 221, 2585, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2586, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2587, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2588, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2589, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2590, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2591, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2592, -1, 34, 1, 25 },
+ { 0x1, 0x1, 221, 2593, -1, 34, 1, 25 },
+ { 0x1, 0x1, 221, 2594, -1, 34, 1, 25 },
+ { 0x1, 0x1, 221, 2595, -1, 34, 1, 25 },
+ { 0x1, 0x1, 221, 2596, -1, 34, 1, 36 },
+ { 0x1, 0x1, 221, 2597, -1, 34, 1, 65 },
+ { 0x1, 0x1, 221, 2598, -1, 34, 1, 30 },
+ { 0x1, 0x1, 221, 2599, -1, 34, 1, 30 },
+ { 0x1, 0x1, 222, 2600, -1, 35, 1, 65 },
+ { 0x1, 0x1, 222, 2601, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2602, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2603, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2604, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2605, -1, 35, 1, 46 },
+ { 0x1, 0x1, 222, 2606, -1, 35, 1, 42 },
+ { 0x800001, 0x800001, 222, 2607, -1, 12, 1, 61 },
+ { 0x1, 0x1, 222, 2608, -1, 35, 1, 56 },
+ { 0x1800001, 0x1800001, 222, 2609, -1, 12, 1, 61 },
+ { 0x3, 0x3, 222, 2610, -1, 35, 1, 56 },
+ { 0xa00001, 0xa00001, 222, 2611, -1, 12, 1, 61 },
+ { 0x5, 0x5, 222, 2612, -1, 33, 1, 56 },
+ { 0x1a00001, 0x1a00001, 222, 2613, -1, 12, 1, 51 },
+ { 0xd, 0xd, 222, 2614, -1, 33, 1, 51 },
+ { 0x1, 0x1, 222, 2615, -1, 35, 1, 61 },
+ { 0x1, 0x1, 222, 2616, -1, 35, 1, 56 },
+ { 0x1, 0x1, 222, 2617, -1, 35, 1, 61 },
+ { 0x1, 0x1, 222, 2618, -1, 35, 1, 56 },
+ { 0x1, 0x1, 222, 2619, -1, 35, 1, 61 },
+ { 0x1, 0x1, 222, 2620, -1, 35, 1, 56 },
+ { 0x1, 0x1, 222, 2621, -1, 35, 1, 51 },
+ { 0x1, 0x1, 222, 2622, -1, 35, 1, 51 },
+ { 0x800001, 0x800001, 222, 2623, -1, 12, 1, 61 },
+ { 0x1, 0x1, 222, 2624, -1, 35, 1, 56 },
+ { 0xa00001, 0x1a00001, 222, 2625, -1, 12, 1, 61 },
+ { 0x5, 0xd, 222, 2626, -1, 33, 1, 56 },
+ { 0x1, 0x1, 222, 2627, -1, 35, 1, 61 },
+ { 0x1, 0x1, 222, 2628, -1, 35, 1, 56 },
+ { 0x1, 0x1, 222, 2629, -1, 35, 1, 61 },
+ { 0x1, 0x1, 222, 2630, -1, 35, 1, 56 },
+ { 0x800001, 0x800001, 222, 2631, -1, 12, 1, 61 },
+ { 0x1, 0x1, 222, 2632, -1, 35, 1, 56 },
+ { 0x1800001, 0x1800001, 222, 2633, -1, 12, 1, 61 },
+ { 0x3, 0x3, 222, 2634, -1, 35, 1, 56 },
+ { 0xa00001, 0xa00001, 222, 2635, -1, 12, 1, 61 },
+ { 0x5, 0x5, 222, 2636, -1, 33, 1, 56 },
+ { 0x1a00001, 0x1a00001, 222, 2637, -1, 12, 1, 51 },
+ { 0xd, 0xd, 222, 2638, -1, 33, 1, 51 },
+ { 0x1, 0x1, 222, 2639, -1, 35, 1, 61 },
+ { 0x1, 0x1, 222, 2640, -1, 35, 1, 56 },
+ { 0x1, 0x1, 222, 2641, -1, 35, 1, 61 },
+ { 0x1, 0x1, 222, 2642, -1, 35, 1, 56 },
+ { 0x1, 0x1, 222, 2643, -1, 35, 1, 61 },
+ { 0x1, 0x1, 222, 2644, -1, 35, 1, 56 },
+ { 0x1, 0x1, 222, 2645, -1, 35, 1, 51 },
+ { 0x1, 0x1, 222, 2646, -1, 35, 1, 51 },
+ { 0x800001, 0x800001, 222, 2647, -1, 12, 1, 61 },
+ { 0x1, 0x1, 222, 2648, -1, 35, 1, 56 },
+ { 0xa00001, 0x1a00001, 222, 2649, -1, 12, 1, 61 },
+ { 0x5, 0xd, 222, 2650, -1, 33, 1, 56 },
+ { 0x1, 0x1, 222, 2651, -1, 35, 1, 61 },
+ { 0x1, 0x1, 222, 2652, -1, 35, 1, 56 },
+ { 0x1, 0x1, 222, 2653, -1, 35, 1, 61 },
+ { 0x1, 0x1, 222, 2654, -1, 35, 1, 56 },
+ { 0x81, 0x81, 222, 2655, -1, 28, 1, 31 },
+ { 0x1, 0x1, 222, 2656, -1, 35, 1, 31 },
+ { 0x103, 0x103, 222, 2657, -1, 27, 1, 31 },
+ { 0x101, 0x101, 222, 2658, -1, 27, 1, 31 },
+ { 0x1, 0x1, 222, 2659, -1, 35, 1, 65 },
+ { 0x1, 0x1, 222, 2660, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2661, -1, 35, 1, 31 },
+ { 0x3, 0x3, 222, 2662, -1, 35, 1, 65 },
+ { 0x5, 0x5, 222, 2663, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2664, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2665, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2666, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2667, -1, 35, 1, 65 },
+ { 0x1, 0x1, 222, 2668, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2669, -1, 35, 1, 31 },
+ { 0x3, 0x3, 222, 2670, -1, 35, 1, 65 },
+ { 0x5, 0x5, 222, 2671, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2672, -1, 35, 1, 31 },
+ { 0x3, 0x3, 222, 2673, -1, 35, 1, 65 },
+ { 0x5, 0x5, 222, 2674, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2675, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2676, -1, 35, 1, 65 },
+ { 0x1, 0x1, 222, 2677, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2678, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2679, -1, 35, 1, 65 },
+ { 0x1, 0x1, 222, 2680, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2681, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2682, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2683, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2684, -1, 35, 1, 51 },
+ { 0x101, 0x101, 222, 2685, -1, 27, 1, 51 },
+ { 0x81, 0x81, 222, 2686, -1, 28, 1, 51 },
+ { 0x103, 0x103, 222, 2687, -1, 27, 1, 51 },
+ { 0x41, 0x41, 222, 2688, -1, 29, 1, 51 },
+ { 0x105, 0x105, 222, 2689, -1, 27, 1, 51 },
+ { 0x83, 0x83, 222, 2690, -1, 28, 1, 51 },
+ { 0x107, 0x107, 222, 2691, -1, 27, 1, 51 },
+ { 0x1, 0x1, 222, 2692, -1, 35, 1, 51 },
+ { 0x1, 0x1, 222, 2693, -1, 35, 1, 51 },
+ { 0x1, 0x1, 222, 2694, -1, 35, 1, 51 },
+ { 0x1, 0x1, 222, 2695, -1, 35, 1, 51 },
+ { 0x81, 0x81, 222, 2696, -1, 28, 1, 31 },
+ { 0x1, 0x1, 222, 2697, -1, 35, 1, 31 },
+ { 0x103, 0x103, 222, 2698, -1, 27, 1, 31 },
+ { 0x101, 0x101, 222, 2699, -1, 27, 1, 31 },
+ { 0x1, 0x1, 222, 2700, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2701, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2702, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2703, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2704, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2705, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2706, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2707, -1, 35, 1, 26 },
+ { 0x1, 0x1, 222, 2708, -1, 35, 1, 26 },
+ { 0x1, 0x1, 222, 2709, -1, 35, 1, 26 },
+ { 0x1, 0x1, 222, 2710, -1, 35, 1, 26 },
+ { 0x1, 0x1, 222, 2711, -1, 35, 1, 37 },
+ { 0x1, 0x1, 222, 2712, -1, 35, 1, 65 },
+ { 0x1, 0x1, 222, 2713, -1, 35, 1, 31 },
+ { 0x1, 0x1, 222, 2714, -1, 35, 1, 31 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 65 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, 2209, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 47 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 43 },
+ { 0xc00001, 0xc00001, 223, -1, -1, 12, 1, 62 },
+ { 0x3, 0x3, 223, 2930, -1, 34, 1, 57 },
+ { 0x1c00001, 0x1c00001, 223, -1, -1, 12, 1, 62 },
+ { 0x7, 0x7, 223, 2931, -1, 34, 1, 57 },
+ { 0xe00001, 0xe00001, 223, -1, -1, 12, 1, 62 },
+ { 0x7, 0x7, 223, 2932, -1, 33, 1, 57 },
+ { 0x1e00001, 0x1e00001, 223, -1, -1, 12, 1, 52 },
+ { 0xf, 0xf, 223, 2933, -1, 33, 1, 52 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 62 },
+ { 0x3, 0x3, 223, 2934, -1, 34, 1, 57 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 62 },
+ { 0x3, 0x3, 223, 2935, -1, 34, 1, 57 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 62 },
+ { 0x3, 0x3, 223, 2936, -1, 34, 1, 57 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 52 },
+ { 0x3, 0x3, 223, 2937, -1, 34, 1, 52 },
+ { 0xc00001, 0xc00001, 223, -1, -1, 12, 1, 62 },
+ { 0x3, 0x3, 223, 2942, -1, 34, 1, 57 },
+ { 0xe00001, 0x1e00001, 223, -1, -1, 12, 1, 62 },
+ { 0x7, 0xf, 223, 2943, -1, 33, 1, 57 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 62 },
+ { 0x3, 0x3, 223, 2944, -1, 34, 1, 57 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 62 },
+ { 0x3, 0x3, 223, 2945, -1, 34, 1, 57 },
+ { 0xc00001, 0xc00001, 223, -1, -1, 12, 1, 62 },
+ { 0x3, 0x3, 223, 2948, -1, 34, 1, 57 },
+ { 0x1c00001, 0x1c00001, 223, -1, -1, 12, 1, 62 },
+ { 0x7, 0x7, 223, 2949, -1, 34, 1, 57 },
+ { 0xe00001, 0xe00001, 223, -1, -1, 12, 1, 62 },
+ { 0x7, 0x7, 223, 2950, -1, 33, 1, 57 },
+ { 0x1e00001, 0x1e00001, 223, -1, -1, 12, 1, 52 },
+ { 0xf, 0xf, 223, 2951, -1, 33, 1, 52 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 62 },
+ { 0x3, 0x3, 223, 2952, -1, 34, 1, 57 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 62 },
+ { 0x3, 0x3, 223, 2953, -1, 34, 1, 57 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 62 },
+ { 0x3, 0x3, 223, 2954, -1, 34, 1, 57 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 52 },
+ { 0x3, 0x3, 223, 2955, -1, 34, 1, 52 },
+ { 0xc00001, 0xc00001, 223, -1, -1, 12, 1, 62 },
+ { 0x3, 0x3, 223, 2960, -1, 34, 1, 57 },
+ { 0xe00001, 0x1e00001, 223, -1, -1, 12, 1, 62 },
+ { 0x7, 0xf, 223, 2961, -1, 33, 1, 57 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 62 },
+ { 0x3, 0x3, 223, 2962, -1, 34, 1, 57 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 62 },
+ { 0x3, 0x3, 223, 2963, -1, 34, 1, 57 },
+ { 0xc1, 0xc1, 223, -1, -1, 28, 1, 32 },
+ { 0x3, 0x3, 223, 2828, -1, 34, 1, 32 },
+ { 0x183, 0x183, 223, -1, -1, 27, 1, 32 },
+ { 0x181, 0x181, 223, 2829, -1, 27, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 65 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, 2210, -1, 34, 1, 32 },
+ { 0x7, 0x7, 223, -1, -1, 34, 1, 65 },
+ { 0xb, 0xb, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, 2211, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 65 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, 2214, -1, 34, 1, 32 },
+ { 0x7, 0x7, 223, -1, -1, 34, 1, 65 },
+ { 0xb, 0xb, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, 2215, -1, 34, 1, 32 },
+ { 0x7, 0x7, 223, -1, -1, 34, 1, 65 },
+ { 0xb, 0xb, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, 2217, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 65 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, 2219, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 65 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, 2220, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 52 },
+ { 0x181, 0x181, 223, -1, -1, 27, 1, 52 },
+ { 0xc1, 0xc1, 223, -1, -1, 28, 1, 52 },
+ { 0x183, 0x183, 223, -1, -1, 27, 1, 52 },
+ { 0x61, 0x61, 223, -1, -1, 29, 1, 52 },
+ { 0x185, 0x185, 223, -1, -1, 27, 1, 52 },
+ { 0xc3, 0xc3, 223, -1, -1, 28, 1, 52 },
+ { 0x187, 0x187, 223, -1, -1, 27, 1, 52 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 52 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 52 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 52 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 52 },
+ { 0xc1, 0xc1, 223, -1, -1, 28, 1, 32 },
+ { 0x3, 0x3, 223, 2832, -1, 34, 1, 32 },
+ { 0x183, 0x183, 223, -1, -1, 27, 1, 32 },
+ { 0x181, 0x181, 223, 2833, -1, 27, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 27 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 27 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 27 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 27 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 38 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 65 },
+ { 0x3, 0x3, 223, -1, -1, 34, 1, 32 },
+ { 0x3, 0x3, 223, 2222, -1, 34, 1, 32 },
+ { 0x3, 0x3, 224, 522, 1433, 32, 1, 128 },
+ { 0x3, 0x3, 224, 523, 1442, 32, 1, 128 },
+ { 0x3, 0x3, 224, 524, 1451, 32, 1, 128 },
+ { 0x3, 0x3, 224, 525, 1464, 32, 1, 128 },
+ { 0x3, 0x3, 224, 526, 1473, 32, 1, 128 },
+ { 0x3, 0x3, 224, 527, 1482, 32, 1, 128 },
+ { 0x3, 0x3, 224, 528, 1491, 32, 1, 128 },
+ { 0x3, 0x3, 224, 529, 1500, 32, 1, 128 },
+ { 0x3, 0x3, 224, 530, 1509, 32, 1, 128 },
+ { 0x3, 0x3, 224, 531, 1518, 32, 1, 128 },
+ { 0x3, 0x3, 224, 532, 1528, 32, 1, 128 },
+ { 0x3, 0x3, 224, 533, 1538, 32, 1, 128 },
+ { 0x3, 0x3, 224, 546, 1551, 32, 1, 143 },
+ { 0x3, 0x3, 224, 547, 1557, 32, 1, 148 },
+ { 0x3, 0x3, 224, 548, 1563, 32, 1, 148 },
+ { 0x3, 0x3, 224, 549, 1569, 32, 1, 143 },
+ { 0x3, 0x3, 224, 550, 1575, 32, 1, 148 },
+ { 0x3, 0x3, 224, 551, 1581, 32, 1, 148 },
+ { 0x3, 0x3, 224, 552, 1587, 32, 1, 143 },
+ { 0x3, 0x3, 224, 553, 1593, 32, 1, 148 },
+ { 0x3, 0x3, 224, 554, 1599, 32, 1, 148 },
+ { 0x3, 0x3, 224, 555, 1605, 32, 1, 143 },
+ { 0x3, 0x3, 224, 556, 1611, 32, 1, 148 },
+ { 0x3, 0x3, 224, 557, 1617, 32, 1, 143 },
+ { 0x3, 0x3, 224, 558, 1623, 32, 1, 148 },
+ { 0x3, 0x3, 224, 559, 1629, 32, 1, 143 },
+ { 0x3, 0x3, 224, 560, 1635, 32, 1, 148 },
+ { 0x3, 0x3, 224, 561, 1641, 32, 1, 143 },
+ { 0x3, 0x3, 224, 562, 1647, 32, 1, 148 },
+ { 0x3, 0x3, 224, 563, 1653, 32, 1, 148 },
+ { 0x1, 0x1, 225, -1, -1, 28, 1, 33 },
+ { 0x1, 0x1, 225, -1, -1, 28, 1, 33 },
+ { 0x0, 0x0, 232, 940, -1, 0, 1, 137 },
+ { 0x0, 0x0, 232, 941, -1, 0, 1, 155 },
+ { 0x1, 0x1, 233, -1, 1964, 33, 1, 133 },
+ { 0x1, 0x1, 233, -1, 1967, 33, 1, 139 },
+ { 0x0, 0x0, 233, -1, 1969, 0, 1, 150 },
+ { 0x0, 0x0, 233, -1, 1970, 0, 1, 156 },
+ { 0x0, 0x0, 234, 865, 953, 0, 0, -1 },
+ { 0x0, 0x0, 234, 866, 961, 0, 0, -1 },
+ { 0x0, 0x0, 234, 867, 957, 0, 0, -1 },
+ { 0x1, 0x1, 234, 868, 602, 33, 1, 6 },
+ { 0x8000001, 0x8000001, 234, 869, 610, 6, 1, 7 },
+ { 0x1, 0x1, 234, 870, 606, 33, 1, 6 },
+ { 0x0, 0x0, 234, 871, 965, 0, 0, -1 },
+ { 0x1, 0x1, 234, 872, 622, 33, 1, 8 },
+ { 0x0, 0x0, 234, 873, 969, 0, 0, -1 },
+ { 0x1, 0x1, 234, 874, 634, 33, 1, 15 },
+ { 0x0, 0x0, 234, 875, 974, 0, 0, -1 },
+ { 0x0, 0x0, 234, 876, 978, 0, 0, -1 },
+ { 0x1, 0x1, 234, 877, 657, 33, 1, 17 },
+ { 0x1, 0x1, 234, 878, 661, 33, 1, 17 },
+ { 0x0, 0x0, 234, 879, 982, 0, 0, -1 },
+ { 0x0, 0x0, 234, 880, 986, 0, 0, -1 },
+ { 0x1, 0x1, 234, 881, 681, 33, 1, 18 },
+ { 0x8000001, 0x8000001, 234, 882, 685, 6, 1, 18 },
+ { 0x0, 0x0, 234, 883, 990, 0, 0, -1 },
+ { 0x1, 0x1, 234, 884, 697, 33, 1, 19 },
+ { 0x0, 0x0, 234, 885, 994, 0, 0, -1 },
+ { 0x0, 0x0, 234, 886, 998, 0, 0, -1 },
+ { 0x1, 0x1, 234, 887, 717, 33, 1, 20 },
+ { 0x8000001, 0x8000001, 234, 888, 721, 6, 1, 20 },
+ { 0x0, 0x0, 234, 889, 1002, 0, 0, -1 },
+ { 0x1, 0x1, 234, 890, 733, 33, 1, 21 },
+ { 0x0, 0x0, 234, 891, 1007, 0, 0, -1 },
+ { 0x0, 0x0, 234, 892, 1011, 0, 0, -1 },
+ { 0x1, 0x1, 234, 893, 756, 33, 1, 17 },
+ { 0x1, 0x1, 234, 894, 760, 33, 1, 17 },
+ { 0x0, 0x0, 234, 895, 1015, 0, 0, -1 },
+ { 0x1, 0x1, 234, 896, 772, 33, 1, 21 },
+ { 0x0, 0x0, 235, 2753, 952, 0, 0, -1 },
+ { 0x0, 0x0, 235, 2754, 960, 0, 0, -1 },
+ { 0x0, 0x0, 235, 2755, 956, 0, 0, -1 },
+ { 0x0, 0x0, 235, 2756, 601, 0, 1, 6 },
+ { 0x1, 0x1, 235, 2757, 609, 6, 1, 7 },
+ { 0x0, 0x0, 235, 2758, 605, 0, 1, 6 },
+ { 0x0, 0x0, 235, 2759, 964, 0, 0, -1 },
+ { 0x0, 0x0, 235, 2760, 621, 0, 1, 8 },
+ { 0x0, 0x0, 235, 2761, 968, 0, 0, -1 },
+ { 0x0, 0x0, 235, 2762, 633, 0, 1, 15 },
+ { 0x0, 0x0, 235, 2763, 973, 0, 0, -1 },
+ { 0x0, 0x0, 235, 2764, 977, 0, 0, -1 },
+ { 0x0, 0x0, 235, 2765, 656, 0, 1, 17 },
+ { 0x0, 0x0, 235, 2766, 660, 0, 1, 17 },
+ { 0x0, 0x0, 235, 2767, 981, 0, 0, -1 },
+ { 0x0, 0x0, 235, 2768, 985, 0, 0, -1 },
+ { 0x0, 0x0, 235, 2769, 680, 0, 1, 18 },
+ { 0x1, 0x1, 235, 2770, 684, 6, 1, 18 },
+ { 0x0, 0x0, 235, 2771, 989, 0, 0, -1 },
+ { 0x0, 0x0, 235, 2772, 696, 0, 1, 19 },
+ { 0x0, 0x0, 235, 2773, 993, 0, 0, -1 },
+ { 0x0, 0x0, 235, 2774, 997, 0, 0, -1 },
+ { 0x0, 0x0, 235, 2775, 716, 0, 1, 20 },
+ { 0x1, 0x1, 235, 2776, 720, 6, 1, 20 },
+ { 0x0, 0x0, 235, 2777, 1001, 0, 0, -1 },
+ { 0x0, 0x0, 235, 2778, 732, 0, 1, 21 },
+ { 0x0, 0x0, 235, 2779, 1006, 0, 0, -1 },
+ { 0x0, 0x0, 235, 2780, 1010, 0, 0, -1 },
+ { 0x0, 0x0, 235, 2781, 755, 0, 1, 17 },
+ { 0x0, 0x0, 235, 2782, 759, 0, 1, 17 },
+ { 0x0, 0x0, 235, 2783, 1014, 0, 0, -1 },
+ { 0x0, 0x0, 235, 2784, 771, 0, 1, 21 },
+ { 0x1, 0x1, 235, 897, 1137, 27, 1, 16 },
+ { 0x0, 0x0, 235, 898, 1135, 0, 1, 16 },
+ { 0x0, 0x0, 235, 1202, 1139, 0, 1, 22 },
+ { 0x0, 0x1, 235, 1147, 1145, 20, 1, 67 },
+ { 0x0, 0x0, 235, 111, 1143, 0, 1, 67 },
+ { 0x1, 0x1, 238, -1, -1, 29, 1, 0 },
+ { 0x0, 0x0, 238, -1, -1, 0, 1, 0 },
+ { 0x1, 0x1, 238, 2984, -1, 27, 1, 0 },
+ { 0x1, 0x1, 238, 2985, -1, 27, 1, 0 },
+ { 0x1, 0x1, 238, 2986, -1, 27, 1, 0 },
+ { 0x1, 0x1, 238, 2987, -1, 27, 1, 0 },
+ { 0x0, 0x0, 260, -1, 2310, 0, 0, -1 },
+ { 0x0, 0x0, 260, -1, 2312, 0, 0, -1 },
+ { 0x1, 0x1, 260, -1, -1, 28, 1, 29 },
+ { 0x1, 0x1, 260, -1, -1, 28, 1, 29 },
+ { 0x0, 0x0, 260, -1, 2351, 0, 0, -1 },
+ { 0x0, 0x0, 260, -1, 2353, 0, 0, -1 },
+ { 0x1, 0x1, 260, -1, -1, 28, 1, 29 },
+ { 0x1, 0x1, 260, -1, -1, 28, 1, 29 },
+ { 0x0, 0x0, 262, 23, -1, 0, 1, 0 },
+ { 0x0, 0x0, 262, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 262, -1, -1, 0, 1, 0 },
+ { 0x0, 0x1, 262, -1, -1, 29, 1, 0 },
+ { 0x0, 0x1, 262, -1, -1, 29, 1, 0 },
+ { 0x0, 0x1, 262, -1, -1, 29, 1, 0 },
+ { 0x0, 0x1, 262, -1, -1, 29, 1, 0 },
+ { 0x0, 0x1, 262, -1, -1, 29, 1, 0 },
+ { 0x0, 0x0, 262, 180, -1, 0, 1, 0 },
+ { 0x0, 0x1, 262, -1, -1, 29, 1, 0 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, 299, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, 321, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, 347, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, 369, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 64 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 64 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 64 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 64 },
+ { 0x0, 0x0, 263, -1, 2262, 0, 0, -1 },
+ { 0x0, 0x0, 263, -1, 2264, 0, 0, -1 },
+ { 0x0, 0x0, 263, -1, 2266, 0, 0, -1 },
+ { 0x0, 0x0, 263, -1, 2268, 0, 0, -1 },
+ { 0x1, 0x1, 263, -1, 2270, 12, 1, 59 },
+ { 0x1, 0x1, 263, -1, 2272, 12, 1, 59 },
+ { 0x1, 0x1, 263, -1, 2274, 12, 1, 59 },
+ { 0x1, 0x1, 263, -1, 2276, 12, 1, 49 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 59 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 59 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 59 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 49 },
+ { 0x0, 0x0, 263, -1, 2278, 0, 0, -1 },
+ { 0x0, 0x0, 263, -1, 2280, 0, 0, -1 },
+ { 0x1, 0x1, 263, -1, 2282, 12, 1, 59 },
+ { 0x1, 0x1, 263, -1, 2284, 12, 1, 59 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 59 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 59 },
+ { 0x0, 0x0, 263, -1, 2286, 0, 0, -1 },
+ { 0x0, 0x0, 263, -1, 2288, 0, 0, -1 },
+ { 0x0, 0x0, 263, -1, 2290, 0, 0, -1 },
+ { 0x0, 0x0, 263, -1, 2292, 0, 0, -1 },
+ { 0x1, 0x1, 263, -1, 2294, 12, 1, 59 },
+ { 0x1, 0x1, 263, -1, 2296, 12, 1, 59 },
+ { 0x1, 0x1, 263, -1, 2298, 12, 1, 59 },
+ { 0x1, 0x1, 263, -1, 2300, 12, 1, 49 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 59 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 59 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 59 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 49 },
+ { 0x0, 0x0, 263, -1, 2302, 0, 0, -1 },
+ { 0x0, 0x0, 263, -1, 2304, 0, 0, -1 },
+ { 0x1, 0x1, 263, -1, 2306, 12, 1, 59 },
+ { 0x1, 0x1, 263, -1, 2308, 12, 1, 59 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 59 },
+ { 0x1, 0x1, 263, -1, -1, 12, 1, 59 },
+ { 0x1, 0x1, 263, 391, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, 393, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, 507, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, 509, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, 399, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, 401, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, 515, -1, 12, 1, 2 },
+ { 0x1, 0x1, 263, 517, -1, 12, 1, 2 },
+ { 0x0, 0x0, 264, -1, 2269, 0, 0, -1 },
+ { 0x9, 0x9, 264, -1, 2277, 33, 1, 49 },
+ { 0x9, 0x9, 264, -1, 2941, 33, 1, 49 },
+ { 0x0, 0x0, 264, 1381, 2342, 0, 0, -1 },
+ { 0x3, 0x3, 264, 1382, -1, 27, 1, 49 },
+ { 0x0, 0x0, 268, 2822, -1, 0, 1, 0 },
+ { 0x3, 0x3, 269, -1, -1, 27, 1, 0 },
+ { 0x3, 0x3, 269, -1, -1, 27, 1, 0 },
+ { 0x3, 0x3, 269, -1, -1, 27, 1, 0 },
+ { 0x3, 0x3, 269, -1, -1, 27, 1, 0 },
+ { 0x1, 0x1, 270, 2980, -1, 28, 1, 0 },
+ { 0x1, 0x1, 270, 2981, -1, 28, 1, 0 },
+ { 0x1, 0x1, 270, 2982, -1, 28, 1, 0 },
+ { 0x1, 0x1, 270, 2983, -1, 28, 1, 0 },
+ { 0x1, 0x1, 271, -1, -1, 27, 1, 93 },
+ { 0x1, 0x1, 271, -1, -1, 27, 1, 93 },
+ { 0x0, 0x0, 271, -1, 950, 0, 0, -1 },
+ { 0x0, 0x0, 272, 2993, 2799, 0, 0, -1 },
+ { 0x0, 0x0, 272, 2994, 2801, 0, 0, -1 },
+ { 0x0, 0x0, 273, -1, 2800, 0, 0, -1 },
+ { 0x0, 0x0, 273, -1, 2802, 0, 0, -1 },
+ { 0x0, 0x0, 274, -1, -1, 0, 1, 40 },
+ { 0x0, 0x0, 274, -1, -1, 0, 1, 40 },
+ { 0x0, 0x0, 274, -1, -1, 0, 1, 40 },
+ { 0x0, 0x0, 279, -1, -1, 0, 1, 33 },
+ { 0x0, 0x0, 283, -1, 2316, 0, 1, 29 },
+ { 0x0, 0x0, 284, -1, -1, 0, 1, 0 },
+ { 0x0, 0x0, 284, -1, -1, 0, 1, 71 },
+ { 0x0, 0x0, 284, 1983, 2966, 0, 1, 1 },
+ { 0x0, 0x0, 284, 1984, 2967, 0, 1, 1 },
+ { 0x0, 0x0, 284, -1, 508, 0, 0, -1 },
+ { 0x0, 0x0, 284, -1, 510, 0, 0, -1 },
+ { 0x0, 0x0, 284, 1987, 2970, 0, 1, 1 },
+ { 0x0, 0x0, 284, 1988, 2971, 0, 1, 1 },
+ { 0x0, 0x0, 284, -1, 516, 0, 0, -1 },
+ { 0x0, 0x0, 284, -1, 518, 0, 0, -1 },
+};
+
+static const struct ia64_main_table
+main_table[] = {
+ { 5, 1, 1, 0x0000010000000000ull, 0x000001eff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 0, },
+ { 5, 1, 1, 0x0000010008000000ull, 0x000001eff8000000ull, { 24, 25, 26, 4, 0 }, 0x0, 1, },
+ { 5, 7, 1, 0x0000000000000000ull, 0x0000000000000000ull, { 24, 66, 27, 0, 0 }, 0x0, 2, },
+ { 5, 7, 1, 0x0000000000000000ull, 0x0000000000000000ull, { 24, 63, 26, 0, 0 }, 0x0, 3, },
+ { 6, 1, 1, 0x0000012000000000ull, 0x000001e000000000ull, { 24, 66, 27, 0, 0 }, 0x0, 4, },
+ { 7, 1, 1, 0x0000010040000000ull, 0x000001eff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 5, },
+ { 7, 1, 1, 0x0000010c00000000ull, 0x000001ee00000000ull, { 24, 63, 26, 0, 0 }, 0x0, 6, },
+ { 8, 1, 1, 0x0000010800000000ull, 0x000001ee00000000ull, { 24, 63, 26, 0, 0 }, 0x0, 7, },
+ { 9, 3, 1, 0x0000002c00000000ull, 0x000001ee00000000ull, { 24, 3, 52, 53, 54 }, 0x221, 8, },
+ { 9, 3, 1, 0x0000002c00000000ull, 0x000001ee00000000ull, { 24, 52, 53, 54, 0 }, 0x261, 9, },
+ { 10, 1, 1, 0x0000010060000000ull, 0x000001eff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 10, },
+ { 10, 1, 1, 0x0000010160000000ull, 0x000001eff8000000ull, { 24, 55, 26, 0, 0 }, 0x0, 11, },
+ { 11, 1, 1, 0x0000010068000000ull, 0x000001eff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 12, },
+ { 11, 1, 1, 0x0000010168000000ull, 0x000001eff8000000ull, { 24, 55, 26, 0, 0 }, 0x0, 13, },
+ { 14, 4, 0, 0x0000000100000000ull, 0x000001eff80011ffull, { 16, 0, 0, 0, 0 }, 0x40, 951, },
+ { 14, 4, 0, 0x0000000100000000ull, 0x000001eff80011c0ull, { 16, 0, 0, 0, 0 }, 0x0, 807, },
+ { 14, 4, 0, 0x0000000100000000ull, 0x000001eff80011c0ull, { 16, 0, 0, 0, 0 }, 0x40, 808, },
+ { 14, 4, 0, 0x0000000108000100ull, 0x000001eff80011c0ull, { 16, 0, 0, 0, 0 }, 0x200, 2200, },
+ { 14, 4, 0, 0x0000000108000100ull, 0x000001eff80011c0ull, { 16, 0, 0, 0, 0 }, 0x240, 2201, },
+ { 14, 4, 1, 0x0000002100000000ull, 0x000001ef00001000ull, { 15, 16, 0, 0, 0 }, 0x0, 564, },
+ { 14, 4, 1, 0x0000002100000000ull, 0x000001ef00001000ull, { 15, 16, 0, 0, 0 }, 0x40, 565, },
+ { 14, 4, 0, 0x0000008000000000ull, 0x000001ee000011ffull, { 81, 0, 0, 0, 0 }, 0x40, 972, },
+ { 14, 4, 0, 0x0000008000000000ull, 0x000001ee000011c0ull, { 81, 0, 0, 0, 0 }, 0x0, 809, },
+ { 14, 4, 0, 0x0000008000000000ull, 0x000001ee000011c0ull, { 81, 0, 0, 0, 0 }, 0x40, 810, },
+ { 14, 4, 0, 0x0000008000000080ull, 0x000001ee000011c0ull, { 81, 0, 0, 0, 0 }, 0x210, 2991, },
+ { 14, 4, 0, 0x0000008000000080ull, 0x000001ee000011c0ull, { 81, 0, 0, 0, 0 }, 0x250, 2992, },
+ { 14, 4, 0, 0x0000008000000140ull, 0x000001ee000011c0ull, { 81, 0, 0, 0, 0 }, 0x30, 572, },
+ { 14, 4, 0, 0x0000008000000140ull, 0x000001ee000011c0ull, { 81, 0, 0, 0, 0 }, 0x70, 573, },
+ { 14, 4, 0, 0x0000008000000180ull, 0x000001ee000011c0ull, { 81, 0, 0, 0, 0 }, 0x230, 570, },
+ { 14, 4, 0, 0x0000008000000180ull, 0x000001ee000011c0ull, { 81, 0, 0, 0, 0 }, 0x270, 571, },
+ { 14, 4, 1, 0x000000a000000000ull, 0x000001ee00001000ull, { 15, 81, 0, 0, 0 }, 0x0, 566, },
+ { 14, 4, 1, 0x000000a000000000ull, 0x000001ee00001000ull, { 15, 81, 0, 0, 0 }, 0x40, 567, },
+ { 15, 4, 0, 0x0000000000000000ull, 0x000001e1f8000000ull, { 65, 0, 0, 0, 0 }, 0x0, 519, },
+ { 15, 5, 0, 0x0000000000000000ull, 0x000001e3f8000000ull, { 65, 0, 0, 0, 0 }, 0x0, 942, },
+ { 15, 2, 0, 0x0000000000000000ull, 0x000001eff8000000ull, { 65, 0, 0, 0, 0 }, 0x2, 1120, },
+ { 15, 3, 0, 0x0000000000000000ull, 0x000001eff8000000ull, { 65, 0, 0, 0, 0 }, 0x0, 1245, },
+ { 15, 6, 0, 0x0000000000000000ull, 0x000001eff8000000ull, { 69, 0, 0, 0, 0 }, 0x0, 2995, },
+ { 15, 7, 0, 0x0000000000000000ull, 0x0000000000000000ull, { 65, 0, 0, 0, 0 }, 0x0, 16, },
+ { 16, 6, 0, 0x0000018000000000ull, 0x000001ee000011ffull, { 82, 0, 0, 0, 0 }, 0x40, 1005, },
+ { 16, 6, 0, 0x0000018000000000ull, 0x000001ee000011c0ull, { 82, 0, 0, 0, 0 }, 0x0, 811, },
+ { 16, 6, 0, 0x0000018000000000ull, 0x000001ee000011c0ull, { 82, 0, 0, 0, 0 }, 0x40, 812, },
+ { 16, 6, 1, 0x000001a000000000ull, 0x000001ee00001000ull, { 15, 82, 0, 0, 0 }, 0x0, 568, },
+ { 16, 6, 1, 0x000001a000000000ull, 0x000001ee00001000ull, { 15, 82, 0, 0, 0 }, 0x40, 569, },
+ { 17, 4, 0, 0x0000004080000000ull, 0x000001e9f8000018ull, { 16, 77, 0, 0, 0 }, 0x20, 2818, },
+ { 17, 4, 0, 0x000000e000000000ull, 0x000001e800000018ull, { 81, 77, 0, 0, 0 }, 0x20, 2819, },
+ { 18, 4, 0, 0x0000000060000000ull, 0x000001e1f8000000ull, { 0, 0, 0, 0, 0 }, 0x2c, 222, },
+ { 22, 2, 0, 0x0000000200000000ull, 0x000001ee00000000ull, { 25, 80, 0, 0, 0 }, 0x0, 2205, },
+ { 22, 3, 0, 0x0000000800000000ull, 0x000001ee00000000ull, { 24, 81, 0, 0, 0 }, 0x0, 224, },
+ { 22, 3, 0, 0x0000000c00000000ull, 0x000001ee00000000ull, { 18, 81, 0, 0, 0 }, 0x0, 225, },
+ { 22, 3, 0, 0x0000002200000000ull, 0x000001ee00000000ull, { 25, 80, 0, 0, 0 }, 0x0, 2206, },
+ { 22, 3, 0, 0x0000002600000000ull, 0x000001ee00000000ull, { 19, 80, 0, 0, 0 }, 0x0, 2207, },
+ { 22, 7, 0, 0x0000000000000000ull, 0x0000000000000000ull, { 25, 80, 0, 0, 0 }, 0x0, 2208, },
+ { 25, 4, 0, 0x0000000020000000ull, 0x000001e1f8000000ull, { 0, 0, 0, 0, 0 }, 0x224, 18, },
+ { 26, 1, 2, 0x0000018000000000ull, 0x000001fe00001000ull, { 22, 23, 25, 26, 0 }, 0x0, 1204, },
+ { 26, 1, 1, 0x0000018000000000ull, 0x000001fe00001000ull, { 22, 25, 26, 0, 0 }, 0x40, 1205, },
+ { 26, 1, 2, 0x0000018000000000ull, 0x000001fe00001000ull, { 23, 22, 26, 25, 0 }, 0x0, 1163, },
+ { 26, 1, 1, 0x0000018000000000ull, 0x000001fe00001000ull, { 23, 26, 25, 0, 0 }, 0x40, 1164, },
+ { 26, 1, 2, 0x0000018000000000ull, 0x000001fe00001000ull, { 22, 23, 26, 25, 0 }, 0x0, 1072, },
+ { 26, 1, 1, 0x0000018000000000ull, 0x000001fe00001000ull, { 22, 26, 25, 0, 0 }, 0x40, 1073, },
+ { 26, 1, 2, 0x0000018000000000ull, 0x000001fe00001000ull, { 23, 22, 25, 26, 0 }, 0x0, 1034, },
+ { 26, 1, 1, 0x0000018000000000ull, 0x000001fe00001000ull, { 23, 25, 26, 0, 0 }, 0x40, 1035, },
+ { 26, 1, 2, 0x0000018200000000ull, 0x000001fe00001000ull, { 22, 23, 25, 26, 0 }, 0x40, 1358, },
+ { 26, 1, 2, 0x0000019000000000ull, 0x000001fe00001000ull, { 22, 23, 7, 26, 0 }, 0x0, 1074, },
+ { 26, 1, 1, 0x0000019000000000ull, 0x000001fe00001000ull, { 22, 7, 26, 0, 0 }, 0x40, 1075, },
+ { 26, 1, 2, 0x0000019000000000ull, 0x000001fe00001000ull, { 22, 23, 26, 7, 0 }, 0x40, 1208, },
+ { 26, 1, 1, 0x0000019000000000ull, 0x000001fe00001000ull, { 22, 26, 7, 0, 0 }, 0x40, 1209, },
+ { 26, 1, 2, 0x0000019000000000ull, 0x000001fe00001000ull, { 22, 23, 7, 26, 0 }, 0x40, 1169, },
+ { 26, 1, 2, 0x0000018800000000ull, 0x000001ee00001000ull, { 22, 23, 55, 26, 0 }, 0x0, 1211, },
+ { 26, 1, 1, 0x0000018800000000ull, 0x000001ee00001000ull, { 22, 55, 26, 0, 0 }, 0x40, 1212, },
+ { 26, 1, 2, 0x0000018800000000ull, 0x000001ee00001000ull, { 22, 23, 57, 26, 0 }, 0x0, 1170, },
+ { 26, 1, 1, 0x0000018800000000ull, 0x000001ee00001000ull, { 22, 57, 26, 0, 0 }, 0x40, 1171, },
+ { 26, 1, 2, 0x0000018800000000ull, 0x000001ee00001000ull, { 23, 22, 57, 26, 0 }, 0x0, 1079, },
+ { 26, 1, 1, 0x0000018800000000ull, 0x000001ee00001000ull, { 23, 57, 26, 0, 0 }, 0x40, 1080, },
+ { 26, 1, 2, 0x0000018800000000ull, 0x000001ee00001000ull, { 23, 22, 55, 26, 0 }, 0x0, 1041, },
+ { 26, 1, 1, 0x0000018800000000ull, 0x000001ee00001000ull, { 23, 55, 26, 0, 0 }, 0x40, 1042, },
+ { 26, 1, 2, 0x0000018a00000000ull, 0x000001ee00001000ull, { 22, 23, 55, 26, 0 }, 0x40, 1363, },
+ { 26, 1, 2, 0x000001a800000000ull, 0x000001ee00001000ull, { 22, 23, 59, 26, 0 }, 0x0, 1196, },
+ { 26, 1, 1, 0x000001a800000000ull, 0x000001ee00001000ull, { 22, 59, 26, 0, 0 }, 0x40, 1197, },
+ { 26, 1, 2, 0x000001a800000000ull, 0x000001ee00001000ull, { 23, 22, 59, 26, 0 }, 0x0, 1107, },
+ { 26, 1, 1, 0x000001a800000000ull, 0x000001ee00001000ull, { 23, 59, 26, 0, 0 }, 0x40, 1108, },
+ { 26, 1, 2, 0x000001c200000000ull, 0x000001fe00001000ull, { 23, 22, 25, 26, 0 }, 0x40, 1364, },
+ { 26, 1, 2, 0x000001d000000000ull, 0x000001fe00001000ull, { 23, 22, 7, 26, 0 }, 0x40, 1172, },
+ { 26, 1, 1, 0x000001d000000000ull, 0x000001fe00001000ull, { 23, 7, 26, 0, 0 }, 0x40, 1173, },
+ { 26, 1, 2, 0x000001d000000000ull, 0x000001fe00001000ull, { 23, 22, 26, 7, 0 }, 0x40, 1045, },
+ { 26, 1, 1, 0x000001d000000000ull, 0x000001fe00001000ull, { 23, 26, 7, 0, 0 }, 0x40, 1046, },
+ { 26, 1, 2, 0x000001ca00000000ull, 0x000001ee00001000ull, { 23, 22, 55, 26, 0 }, 0x40, 1365, },
+ { 27, 1, 2, 0x0000018400000000ull, 0x000001fe00001000ull, { 22, 23, 25, 26, 0 }, 0x0, 1217, },
+ { 27, 1, 1, 0x0000018400000000ull, 0x000001fe00001000ull, { 22, 25, 26, 0, 0 }, 0x40, 1218, },
+ { 27, 1, 2, 0x0000018400000000ull, 0x000001fe00001000ull, { 23, 22, 26, 25, 0 }, 0x0, 1176, },
+ { 27, 1, 1, 0x0000018400000000ull, 0x000001fe00001000ull, { 23, 26, 25, 0, 0 }, 0x40, 1177, },
+ { 27, 1, 2, 0x0000018400000000ull, 0x000001fe00001000ull, { 22, 23, 26, 25, 0 }, 0x0, 1085, },
+ { 27, 1, 1, 0x0000018400000000ull, 0x000001fe00001000ull, { 22, 26, 25, 0, 0 }, 0x40, 1086, },
+ { 27, 1, 2, 0x0000018400000000ull, 0x000001fe00001000ull, { 23, 22, 25, 26, 0 }, 0x0, 1047, },
+ { 27, 1, 1, 0x0000018400000000ull, 0x000001fe00001000ull, { 23, 25, 26, 0, 0 }, 0x40, 1048, },
+ { 27, 1, 2, 0x0000018600000000ull, 0x000001fe00001000ull, { 22, 23, 25, 26, 0 }, 0x40, 1370, },
+ { 27, 1, 2, 0x0000019400000000ull, 0x000001fe00001000ull, { 22, 23, 7, 26, 0 }, 0x0, 1087, },
+ { 27, 1, 1, 0x0000019400000000ull, 0x000001fe00001000ull, { 22, 7, 26, 0, 0 }, 0x40, 1088, },
+ { 27, 1, 2, 0x0000019400000000ull, 0x000001fe00001000ull, { 22, 23, 26, 7, 0 }, 0x40, 1221, },
+ { 27, 1, 1, 0x0000019400000000ull, 0x000001fe00001000ull, { 22, 26, 7, 0, 0 }, 0x40, 1222, },
+ { 27, 1, 2, 0x0000019400000000ull, 0x000001fe00001000ull, { 22, 23, 7, 26, 0 }, 0x40, 1182, },
+ { 27, 1, 2, 0x0000018c00000000ull, 0x000001ee00001000ull, { 22, 23, 55, 26, 0 }, 0x0, 1224, },
+ { 27, 1, 1, 0x0000018c00000000ull, 0x000001ee00001000ull, { 22, 55, 26, 0, 0 }, 0x40, 1225, },
+ { 27, 1, 2, 0x0000018c00000000ull, 0x000001ee00001000ull, { 22, 23, 57, 26, 0 }, 0x0, 1183, },
+ { 27, 1, 1, 0x0000018c00000000ull, 0x000001ee00001000ull, { 22, 57, 26, 0, 0 }, 0x40, 1184, },
+ { 27, 1, 2, 0x0000018c00000000ull, 0x000001ee00001000ull, { 23, 22, 57, 26, 0 }, 0x0, 1092, },
+ { 27, 1, 1, 0x0000018c00000000ull, 0x000001ee00001000ull, { 23, 57, 26, 0, 0 }, 0x40, 1093, },
+ { 27, 1, 2, 0x0000018c00000000ull, 0x000001ee00001000ull, { 23, 22, 55, 26, 0 }, 0x0, 1054, },
+ { 27, 1, 1, 0x0000018c00000000ull, 0x000001ee00001000ull, { 23, 55, 26, 0, 0 }, 0x40, 1055, },
+ { 27, 1, 2, 0x0000018e00000000ull, 0x000001ee00001000ull, { 22, 23, 55, 26, 0 }, 0x40, 1375, },
+ { 27, 1, 2, 0x000001ac00000000ull, 0x000001ee00001000ull, { 22, 23, 56, 26, 0 }, 0x0, 1241, },
+ { 27, 1, 1, 0x000001ac00000000ull, 0x000001ee00001000ull, { 22, 56, 26, 0, 0 }, 0x40, 1242, },
+ { 27, 1, 2, 0x000001ac00000000ull, 0x000001ee00001000ull, { 22, 23, 58, 26, 0 }, 0x0, 1200, },
+ { 27, 1, 1, 0x000001ac00000000ull, 0x000001ee00001000ull, { 22, 58, 26, 0, 0 }, 0x40, 1201, },
+ { 27, 1, 2, 0x000001ac00000000ull, 0x000001ee00001000ull, { 23, 22, 58, 26, 0 }, 0x0, 1111, },
+ { 27, 1, 1, 0x000001ac00000000ull, 0x000001ee00001000ull, { 23, 58, 26, 0, 0 }, 0x40, 1112, },
+ { 27, 1, 2, 0x000001ac00000000ull, 0x000001ee00001000ull, { 23, 22, 56, 26, 0 }, 0x0, 1070, },
+ { 27, 1, 1, 0x000001ac00000000ull, 0x000001ee00001000ull, { 23, 56, 26, 0, 0 }, 0x40, 1071, },
+ { 27, 1, 2, 0x000001c600000000ull, 0x000001fe00001000ull, { 23, 22, 25, 26, 0 }, 0x40, 1376, },
+ { 27, 1, 2, 0x000001d400000000ull, 0x000001fe00001000ull, { 23, 22, 7, 26, 0 }, 0x40, 1185, },
+ { 27, 1, 1, 0x000001d400000000ull, 0x000001fe00001000ull, { 23, 7, 26, 0, 0 }, 0x40, 1186, },
+ { 27, 1, 2, 0x000001d400000000ull, 0x000001fe00001000ull, { 23, 22, 26, 7, 0 }, 0x40, 1058, },
+ { 27, 1, 1, 0x000001d400000000ull, 0x000001fe00001000ull, { 23, 26, 7, 0, 0 }, 0x40, 1059, },
+ { 27, 1, 2, 0x000001ce00000000ull, 0x000001ee00001000ull, { 23, 22, 55, 26, 0 }, 0x40, 1377, },
+ { 28, 3, 1, 0x0000008808000000ull, 0x000001fff8000000ull, { 24, 33, 25, 1, 2 }, 0x0, 257, },
+ { 28, 3, 1, 0x0000008808000000ull, 0x000001fff8000000ull, { 24, 33, 25, 0, 0 }, 0x40, 258, },
+ { 29, 3, 1, 0x0000008008000000ull, 0x000001fff8000000ull, { 24, 33, 25, 2, 0 }, 0x0, 259, },
+ { 29, 3, 1, 0x0000008008000000ull, 0x000001fff8000000ull, { 24, 33, 25, 0, 0 }, 0x40, 260, },
+ { 30, 3, 1, 0x0000008048000000ull, 0x000001fff8000000ull, { 24, 33, 25, 2, 0 }, 0x0, 261, },
+ { 30, 3, 1, 0x0000008048000000ull, 0x000001fff8000000ull, { 24, 33, 25, 0, 0 }, 0x40, 262, },
+ { 31, 3, 1, 0x0000008088000000ull, 0x000001fff8000000ull, { 24, 33, 25, 2, 0 }, 0x0, 263, },
+ { 31, 3, 1, 0x0000008088000000ull, 0x000001fff8000000ull, { 24, 33, 25, 0, 0 }, 0x40, 264, },
+ { 32, 3, 1, 0x00000080c8000000ull, 0x000001fff8000000ull, { 24, 33, 25, 2, 0 }, 0x0, 265, },
+ { 32, 3, 1, 0x00000080c8000000ull, 0x000001fff8000000ull, { 24, 33, 25, 0, 0 }, 0x40, 266, },
+ { 34, 4, 0, 0x0000000010000000ull, 0x000001e1f8000000ull, { 0, 0, 0, 0, 0 }, 0x224, 19, },
+ { 36, 2, 1, 0x00000000c0000000ull, 0x000001eff8000000ull, { 24, 26, 0, 0, 0 }, 0x0, 1149, },
+ { 37, 2, 1, 0x00000000c8000000ull, 0x000001eff8000000ull, { 24, 26, 0, 0, 0 }, 0x0, 1150, },
+ { 39, 2, 1, 0x0000008000000000ull, 0x000001e000000000ull, { 24, 25, 26, 47, 72 }, 0x0, 20, },
+ { 39, 2, 1, 0x000000a600000000ull, 0x000001ee04000000ull, { 24, 25, 45, 73, 0 }, 0x0, 3000, },
+ { 39, 2, 1, 0x000000a604000000ull, 0x000001ee04000000ull, { 24, 55, 45, 73, 0 }, 0x0, 3001, },
+ { 39, 2, 1, 0x000000ae00000000ull, 0x000001ee00000000ull, { 24, 48, 26, 46, 73 }, 0x0, 21, },
+ { 43, 4, 0, 0x0000000080000000ull, 0x000001e1f8000000ull, { 0, 0, 0, 0, 0 }, 0x20, 22, },
+ { 48, 2, 1, 0x000000a400000000ull, 0x000001ee00002000ull, { 24, 26, 76, 73, 0 }, 0x0, 2836, },
+ { 50, 5, 1, 0x0000000080000000ull, 0x000001e3f80fe000ull, { 18, 20, 0, 0, 0 }, 0x40, 24, },
+ { 51, 5, 1, 0x0000010008000000ull, 0x000001fff8000000ull, { 18, 20, 19, 0, 0 }, 0x40, 2257, },
+ { 52, 5, 1, 0x00000000b8000000ull, 0x000001eff8000000ull, { 18, 19, 20, 0, 0 }, 0x0, 2258, },
+ { 52, 5, 1, 0x00000000b8000000ull, 0x000001eff8000000ull, { 18, 19, 20, 0, 0 }, 0x40, 26, },
+ { 53, 5, 1, 0x00000000b0000000ull, 0x000001eff8000000ull, { 18, 19, 20, 0, 0 }, 0x0, 2259, },
+ { 53, 5, 1, 0x00000000b0000000ull, 0x000001eff8000000ull, { 18, 19, 20, 0, 0 }, 0x40, 27, },
+ { 54, 5, 1, 0x0000000160000000ull, 0x000001e3f8000000ull, { 18, 19, 20, 0, 0 }, 0x0, 28, },
+ { 55, 5, 1, 0x0000000168000000ull, 0x000001e3f8000000ull, { 18, 19, 20, 0, 0 }, 0x0, 29, },
+ { 57, 3, 0, 0x0000002180000000ull, 0x000001fff8000000ull, { 26, 0, 0, 0, 0 }, 0x0, 30, },
+ { 58, 5, 0, 0x0000000040000000ull, 0x000001eff8000000ull, { 79, 0, 0, 0, 0 }, 0x0, 2260, },
+ { 58, 5, 0, 0x0000000040000000ull, 0x000001eff8000000ull, { 79, 0, 0, 0, 0 }, 0x40, 31, },
+ { 59, 5, 2, 0x000000a000000000ull, 0x000001e000001000ull, { 22, 23, 19, 60, 0 }, 0x0, 1247, },
+ { 59, 5, 1, 0x000000a000000000ull, 0x000001e000001000ull, { 22, 19, 60, 0, 0 }, 0x40, 1248, },
+ { 59, 5, 2, 0x000000a000000000ull, 0x000001e000001000ull, { 23, 22, 19, 60, 0 }, 0x40, 1402, },
+ { 59, 5, 1, 0x000000a000000000ull, 0x000001e000001000ull, { 23, 19, 60, 0, 0 }, 0x40, 1403, },
+ { 60, 5, 0, 0x0000000028000000ull, 0x000001eff8000000ull, { 0, 0, 0, 0, 0 }, 0x0, 2261, },
+ { 60, 5, 0, 0x0000000028000000ull, 0x000001eff8000000ull, { 0, 0, 0, 0, 0 }, 0x40, 32, },
+ { 61, 5, 2, 0x0000008000000000ull, 0x000001fe00001000ull, { 22, 23, 19, 20, 0 }, 0x0, 925, },
+ { 61, 5, 1, 0x0000008000000000ull, 0x000001fe00001000ull, { 22, 19, 20, 0, 0 }, 0x40, 926, },
+ { 61, 5, 2, 0x0000008000000000ull, 0x000001fe00001000ull, { 22, 23, 19, 20, 0 }, 0x40, 927, },
+ { 61, 5, 2, 0x0000009000000000ull, 0x000001fe00001000ull, { 22, 23, 20, 19, 0 }, 0x0, 1098, },
+ { 61, 5, 1, 0x0000009000000000ull, 0x000001fe00001000ull, { 22, 20, 19, 0, 0 }, 0x40, 1099, },
+ { 61, 5, 2, 0x0000009000000000ull, 0x000001fe00001000ull, { 22, 23, 20, 19, 0 }, 0x40, 1100, },
+ { 61, 5, 2, 0x0000008000000000ull, 0x000001fe00001000ull, { 23, 22, 19, 20, 0 }, 0x0, 1378, },
+ { 61, 5, 1, 0x0000008000000000ull, 0x000001fe00001000ull, { 23, 19, 20, 0, 0 }, 0x40, 1379, },
+ { 61, 5, 2, 0x0000008000000000ull, 0x000001fe00001000ull, { 23, 22, 19, 20, 0 }, 0x40, 1380, },
+ { 61, 5, 2, 0x0000009000000000ull, 0x000001fe00001000ull, { 23, 22, 20, 19, 0 }, 0x0, 1387, },
+ { 61, 5, 1, 0x0000009000000000ull, 0x000001fe00001000ull, { 23, 20, 19, 0, 0 }, 0x40, 1388, },
+ { 61, 5, 2, 0x0000009000000000ull, 0x000001fe00001000ull, { 23, 22, 20, 19, 0 }, 0x40, 1389, },
+ { 62, 5, 1, 0x00000000c0000000ull, 0x000001eff8000000ull, { 18, 19, 0, 0, 0 }, 0x0, 1024, },
+ { 62, 5, 1, 0x00000000c0000000ull, 0x000001eff8000000ull, { 18, 19, 0, 0, 0 }, 0x40, 1025, },
+ { 62, 5, 1, 0x00000000e0000000ull, 0x000001e3f8000000ull, { 18, 19, 0, 0, 0 }, 0x0, 2998, },
+ { 62, 5, 1, 0x0000010008000000ull, 0x000001fff80fe000ull, { 18, 20, 0, 0, 0 }, 0x40, 2999, },
+ { 63, 3, 1, 0x0000008488000000ull, 0x000001fff8000000ull, { 24, 33, 71, 0, 0 }, 0x0, 267, },
+ { 64, 3, 1, 0x00000084c8000000ull, 0x000001fff8000000ull, { 24, 33, 71, 0, 0 }, 0x0, 268, },
+ { 67, 3, 0, 0x0000000060000000ull, 0x000001eff8000000ull, { 0, 0, 0, 0, 0 }, 0x21, 33, },
+ { 68, 5, 1, 0x0000010000000000ull, 0x000001fc00000000ull, { 18, 20, 21, 19, 0 }, 0x0, 2319, },
+ { 68, 5, 1, 0x0000010000000000ull, 0x000001fc00000000ull, { 18, 20, 21, 19, 0 }, 0x40, 34, },
+ { 69, 5, 1, 0x00000000a8000000ull, 0x000001eff8000000ull, { 18, 19, 20, 0, 0 }, 0x0, 2320, },
+ { 69, 5, 1, 0x00000000a8000000ull, 0x000001eff8000000ull, { 18, 19, 20, 0, 0 }, 0x40, 35, },
+ { 70, 5, 1, 0x0000000080000000ull, 0x000001e3f8000000ull, { 18, 19, 20, 0, 0 }, 0x0, 2213, },
+ { 71, 5, 1, 0x00000000a0000000ull, 0x000001eff8000000ull, { 18, 19, 20, 0, 0 }, 0x0, 2321, },
+ { 71, 5, 1, 0x00000000a0000000ull, 0x000001eff8000000ull, { 18, 19, 20, 0, 0 }, 0x40, 36, },
+ { 72, 5, 1, 0x00000001c8000000ull, 0x000001e3f8000000ull, { 18, 19, 20, 0, 0 }, 0x0, 1203, },
+ { 73, 5, 1, 0x0000010000000000ull, 0x000001fc000fe000ull, { 18, 20, 21, 0, 0 }, 0x40, 2324, },
+ { 74, 5, 1, 0x0000014000000000ull, 0x000001fc00000000ull, { 18, 20, 21, 19, 0 }, 0x0, 2327, },
+ { 74, 5, 1, 0x0000014000000000ull, 0x000001fc00000000ull, { 18, 20, 21, 19, 0 }, 0x40, 38, },
+ { 75, 5, 1, 0x0000000088000000ull, 0x000001e3f8000000ull, { 18, 20, 0, 0, 0 }, 0xc0, 39, },
+ { 76, 5, 1, 0x0000000088000000ull, 0x000001e3f80fe000ull, { 18, 20, 0, 0, 0 }, 0x40, 40, },
+ { 77, 5, 1, 0x0000018000000000ull, 0x000001fc00000000ull, { 18, 20, 21, 19, 0 }, 0x0, 2330, },
+ { 77, 5, 1, 0x0000018000000000ull, 0x000001fc00000000ull, { 18, 20, 21, 19, 0 }, 0x40, 41, },
+ { 78, 5, 1, 0x0000018000000000ull, 0x000001fc000fe000ull, { 18, 20, 21, 0, 0 }, 0x40, 2333, },
+ { 79, 5, 1, 0x0000010008000000ull, 0x000001fff80fe000ull, { 18, 20, 0, 0, 0 }, 0x40, 2336, },
+ { 80, 5, 1, 0x0000000170000000ull, 0x000001e3f8000000ull, { 18, 19, 20, 0, 0 }, 0x0, 44, },
+ { 81, 5, 1, 0x0000002080000000ull, 0x000001e3f80fe000ull, { 18, 20, 0, 0, 0 }, 0x40, 45, },
+ { 82, 5, 1, 0x0000000140000000ull, 0x000001e3f8000000ull, { 18, 19, 20, 0, 0 }, 0x0, 46, },
+ { 83, 5, 1, 0x00000020b8000000ull, 0x000001eff8000000ull, { 18, 19, 20, 0, 0 }, 0x0, 2337, },
+ { 83, 5, 1, 0x00000020b8000000ull, 0x000001eff8000000ull, { 18, 19, 20, 0, 0 }, 0x40, 47, },
+ { 84, 5, 1, 0x00000020b0000000ull, 0x000001eff8000000ull, { 18, 19, 20, 0, 0 }, 0x0, 2338, },
+ { 84, 5, 1, 0x00000020b0000000ull, 0x000001eff8000000ull, { 18, 19, 20, 0, 0 }, 0x40, 48, },
+ { 85, 5, 1, 0x0000002180000000ull, 0x000001eff8000000ull, { 18, 19, 20, 0, 0 }, 0x0, 928, },
+ { 85, 5, 1, 0x0000002180000000ull, 0x000001eff8000000ull, { 18, 19, 20, 0, 0 }, 0x40, 929, },
+ { 85, 5, 1, 0x0000002188000000ull, 0x000001eff8000000ull, { 18, 20, 19, 0, 0 }, 0x40, 1101, },
+ { 86, 5, 1, 0x00000020c0000000ull, 0x000001eff8000000ull, { 18, 19, 0, 0, 0 }, 0x0, 1026, },
+ { 86, 5, 1, 0x00000020c0000000ull, 0x000001eff8000000ull, { 18, 19, 0, 0, 0 }, 0x40, 1027, },
+ { 87, 5, 1, 0x0000013000000000ull, 0x000001fc00000000ull, { 18, 20, 21, 19, 0 }, 0x0, 2355, },
+ { 87, 5, 1, 0x0000013000000000ull, 0x000001fc00000000ull, { 18, 20, 21, 19, 0 }, 0x40, 49, },
+ { 88, 5, 1, 0x00000020a8000000ull, 0x000001eff8000000ull, { 18, 19, 20, 0, 0 }, 0x0, 2356, },
+ { 88, 5, 1, 0x00000020a8000000ull, 0x000001eff8000000ull, { 18, 19, 20, 0, 0 }, 0x40, 50, },
+ { 89, 5, 1, 0x0000002080000000ull, 0x000001e3f8000000ull, { 18, 19, 20, 0, 0 }, 0x0, 2221, },
+ { 90, 5, 1, 0x00000020a0000000ull, 0x000001eff8000000ull, { 18, 19, 20, 0, 0 }, 0x0, 2357, },
+ { 90, 5, 1, 0x00000020a0000000ull, 0x000001eff8000000ull, { 18, 19, 20, 0, 0 }, 0x40, 51, },
+ { 91, 5, 1, 0x0000013000000000ull, 0x000001fc000fe000ull, { 18, 20, 21, 0, 0 }, 0x40, 2358, },
+ { 92, 5, 1, 0x0000017000000000ull, 0x000001fc00000000ull, { 18, 20, 21, 19, 0 }, 0x0, 2359, },
+ { 92, 5, 1, 0x0000017000000000ull, 0x000001fc00000000ull, { 18, 20, 21, 19, 0 }, 0x40, 53, },
+ { 93, 5, 1, 0x0000002088000000ull, 0x000001e3f8000000ull, { 18, 20, 0, 0, 0 }, 0xc0, 54, },
+ { 94, 5, 1, 0x0000002088000000ull, 0x000001e3f80fe000ull, { 18, 20, 0, 0, 0 }, 0x40, 55, },
+ { 95, 5, 1, 0x000001b000000000ull, 0x000001fc00000000ull, { 18, 20, 21, 19, 0 }, 0x0, 2360, },
+ { 95, 5, 1, 0x000001b000000000ull, 0x000001fc00000000ull, { 18, 20, 21, 19, 0 }, 0x40, 56, },
+ { 96, 5, 1, 0x000001b000000000ull, 0x000001fc000fe000ull, { 18, 20, 21, 0, 0 }, 0x40, 2361, },
+ { 97, 5, 2, 0x0000002200000000ull, 0x000001fe00000000ull, { 18, 23, 19, 20, 0 }, 0x0, 2362, },
+ { 97, 5, 2, 0x0000002200000000ull, 0x000001fe00000000ull, { 18, 23, 19, 20, 0 }, 0x40, 58, },
+ { 98, 5, 2, 0x0000003200000000ull, 0x000001fe00000000ull, { 18, 23, 20, 0, 0 }, 0x0, 2363, },
+ { 98, 5, 2, 0x0000003200000000ull, 0x000001fe00000000ull, { 18, 23, 20, 0, 0 }, 0x40, 59, },
+ { 99, 5, 2, 0x0000000200000000ull, 0x000001fe00000000ull, { 18, 23, 19, 20, 0 }, 0x0, 2364, },
+ { 99, 5, 2, 0x0000000200000000ull, 0x000001fe00000000ull, { 18, 23, 19, 20, 0 }, 0x40, 60, },
+ { 100, 5, 2, 0x0000001200000000ull, 0x000001fe00000000ull, { 18, 23, 20, 0, 0 }, 0x0, 2365, },
+ { 100, 5, 2, 0x0000001200000000ull, 0x000001fe00000000ull, { 18, 23, 20, 0, 0 }, 0x40, 61, },
+ { 101, 5, 1, 0x000001c000000000ull, 0x000001f000000000ull, { 18, 20, 21, 19, 0 }, 0x0, 62, },
+ { 102, 5, 0, 0x0000000020000000ull, 0x000001eff8000000ull, { 50, 51, 0, 0, 0 }, 0x0, 2366, },
+ { 102, 5, 0, 0x0000000020000000ull, 0x000001eff8000000ull, { 50, 51, 0, 0, 0 }, 0x40, 63, },
+ { 103, 5, 1, 0x0000014008000000ull, 0x000001fff8000000ull, { 18, 20, 19, 0, 0 }, 0x40, 2369, },
+ { 104, 5, 1, 0x00000001a0000000ull, 0x000001e3f8000000ull, { 18, 19, 20, 0, 0 }, 0x0, 65, },
+ { 105, 5, 1, 0x00000001e0000000ull, 0x000001e3f8000000ull, { 18, 19, 20, 0, 0 }, 0x0, 2168, },
+ { 106, 3, 0, 0x0000000100000000ull, 0x000001eff8000000ull, { 0, 0, 0, 0, 0 }, 0x0, 66, },
+ { 108, 5, 1, 0x0000000178000000ull, 0x000001e3f8000000ull, { 18, 19, 20, 0, 0 }, 0x0, 67, },
+ { 113, 3, 1, 0x0000008708000000ull, 0x000001ffc8000000ull, { 24, 19, 0, 0, 0 }, 0x0, 2747, },
+ { 118, 4, 0, 0x0000004008000000ull, 0x000001e1f8000000ull, { 65, 0, 0, 0, 0 }, 0x0, 520, },
+ { 118, 5, 0, 0x000000000c000000ull, 0x000001e3fc000000ull, { 65, 0, 0, 0, 0 }, 0x0, 943, },
+ { 118, 2, 0, 0x000000000c000000ull, 0x000001effc000000ull, { 65, 0, 0, 0, 0 }, 0x2, 1123, },
+ { 118, 3, 0, 0x000000000c000000ull, 0x000001effc000000ull, { 65, 0, 0, 0, 0 }, 0x0, 1249, },
+ { 118, 6, 0, 0x000000000c000000ull, 0x000001effc000000ull, { 69, 0, 0, 0, 0 }, 0x0, 2996, },
+ { 118, 7, 0, 0x0000000000000000ull, 0x0000000000000000ull, { 65, 0, 0, 0, 0 }, 0x0, 68, },
+ { 123, 3, 0, 0x0000000080000000ull, 0x000001eff8000000ull, { 0, 0, 0, 0, 0 }, 0x0, 69, },
+ { 123, 3, 0, 0x0000000090000000ull, 0x000001eff8000000ull, { 24, 0, 0, 0, 0 }, 0x0, 902, },
+ { 123, 3, 0, 0x0000000098000000ull, 0x000001eff8000000ull, { 18, 0, 0, 0, 0 }, 0x0, 903, },
+ { 124, 3, 0, 0x0000002170000000ull, 0x000001eff8000000ull, { 25, 0, 0, 0, 0 }, 0xc, 828, },
+ { 125, 3, 1, 0x0000002070000000ull, 0x000001eff8000000ull, { 30, 25, 0, 0, 0 }, 0x8, 829, },
+ { 125, 3, 1, 0x0000002078000000ull, 0x000001eff8000000ull, { 31, 25, 0, 0, 0 }, 0x8, 1125, },
+ { 127, 3, 1, 0x0000008000000000ull, 0x000001fff8000000ull, { 24, 33, 0, 0, 0 }, 0x0, 70, },
+ { 127, 3, 1, 0x0000009000000000ull, 0x000001fff8000000ull, { 24, 33, 25, 0, 0 }, 0x400, 71, },
+ { 127, 3, 1, 0x000000a000000000ull, 0x000001eff0000000ull, { 24, 33, 62, 0, 0 }, 0x400, 72, },
+ { 128, 3, 2, 0x0000008a08000000ull, 0x000001fff8000000ull, { 24, 1, 33, 0, 0 }, 0x0, 73, },
+ { 128, 3, 1, 0x0000008a08000000ull, 0x000001fff8000000ull, { 24, 33, 0, 0, 0 }, 0x40, 74, },
+ { 129, 3, 1, 0x0000008040000000ull, 0x000001fff8000000ull, { 24, 33, 0, 0, 0 }, 0x0, 75, },
+ { 129, 3, 1, 0x0000009040000000ull, 0x000001fff8000000ull, { 24, 33, 25, 0, 0 }, 0x400, 76, },
+ { 129, 3, 1, 0x000000a040000000ull, 0x000001eff0000000ull, { 24, 33, 62, 0, 0 }, 0x400, 77, },
+ { 130, 3, 1, 0x0000008080000000ull, 0x000001fff8000000ull, { 24, 33, 0, 0, 0 }, 0x0, 78, },
+ { 130, 3, 1, 0x0000009080000000ull, 0x000001fff8000000ull, { 24, 33, 25, 0, 0 }, 0x400, 79, },
+ { 130, 3, 1, 0x000000a080000000ull, 0x000001eff0000000ull, { 24, 33, 62, 0, 0 }, 0x400, 80, },
+ { 131, 3, 1, 0x00000080c0000000ull, 0x000001fff8000000ull, { 24, 33, 0, 0, 0 }, 0x0, 81, },
+ { 131, 3, 1, 0x00000080c0000000ull, 0x000001fff8000000ull, { 24, 33, 83, 0, 0 }, 0x0, 1321, },
+ { 131, 3, 1, 0x00000090c0000000ull, 0x000001fff8000000ull, { 24, 33, 25, 0, 0 }, 0x400, 82, },
+ { 131, 3, 1, 0x000000a0c0000000ull, 0x000001eff0000000ull, { 24, 33, 62, 0, 0 }, 0x400, 83, },
+ { 132, 3, 1, 0x000000c6c0000000ull, 0x000001fff8000000ull, { 18, 33, 0, 0, 0 }, 0x0, 1021, },
+ { 132, 3, 1, 0x000000d6c0000000ull, 0x000001fff8000000ull, { 18, 33, 25, 0, 0 }, 0x400, 1022, },
+ { 132, 3, 1, 0x000000e6c0000000ull, 0x000001eff0000000ull, { 18, 33, 62, 0, 0 }, 0x400, 1023, },
+ { 133, 3, 1, 0x000000c040000000ull, 0x000001fff8000000ull, { 18, 33, 0, 0, 0 }, 0x0, 84, },
+ { 133, 3, 1, 0x000000d040000000ull, 0x000001fff8000000ull, { 18, 33, 25, 0, 0 }, 0x400, 85, },
+ { 133, 3, 1, 0x000000e040000000ull, 0x000001eff0000000ull, { 18, 33, 62, 0, 0 }, 0x400, 86, },
+ { 134, 3, 1, 0x000000c0c0000000ull, 0x000001fff8000000ull, { 18, 33, 0, 0, 0 }, 0x0, 87, },
+ { 134, 3, 1, 0x000000d0c0000000ull, 0x000001fff8000000ull, { 18, 33, 25, 0, 0 }, 0x400, 88, },
+ { 134, 3, 1, 0x000000e0c0000000ull, 0x000001eff0000000ull, { 18, 33, 62, 0, 0 }, 0x400, 89, },
+ { 135, 3, 1, 0x000000c000000000ull, 0x000001fff8000000ull, { 18, 33, 0, 0, 0 }, 0x0, 90, },
+ { 135, 3, 1, 0x000000d000000000ull, 0x000001fff8000000ull, { 18, 33, 25, 0, 0 }, 0x400, 91, },
+ { 135, 3, 1, 0x000000e000000000ull, 0x000001eff0000000ull, { 18, 33, 62, 0, 0 }, 0x400, 92, },
+ { 136, 3, 2, 0x000000c048000000ull, 0x000001fff8000000ull, { 18, 19, 33, 0, 0 }, 0x0, 93, },
+ { 136, 3, 2, 0x000000d048000000ull, 0x000001fff8000000ull, { 18, 19, 33, 6, 0 }, 0x400, 94, },
+ { 137, 3, 2, 0x000000c0c8000000ull, 0x000001fff8000000ull, { 18, 19, 33, 0, 0 }, 0x0, 95, },
+ { 137, 3, 2, 0x000000d0c8000000ull, 0x000001fff8000000ull, { 18, 19, 33, 6, 0 }, 0x400, 96, },
+ { 138, 3, 2, 0x000000c088000000ull, 0x000001fff8000000ull, { 18, 19, 33, 0, 0 }, 0x0, 97, },
+ { 138, 3, 2, 0x000000d088000000ull, 0x000001fff8000000ull, { 18, 19, 33, 5, 0 }, 0x400, 98, },
+ { 139, 3, 1, 0x000000c080000000ull, 0x000001fff8000000ull, { 18, 33, 0, 0, 0 }, 0x0, 99, },
+ { 139, 3, 1, 0x000000d080000000ull, 0x000001fff8000000ull, { 18, 33, 25, 0, 0 }, 0x400, 100, },
+ { 139, 3, 1, 0x000000e080000000ull, 0x000001eff0000000ull, { 18, 33, 62, 0, 0 }, 0x400, 101, },
+ { 142, 3, 0, 0x000000cb00000000ull, 0x000001fff8000000ull, { 33, 0, 0, 0, 0 }, 0x0, 102, },
+ { 142, 3, 0, 0x000000db00000000ull, 0x000001fff8000000ull, { 33, 25, 0, 0, 0 }, 0x400, 103, },
+ { 142, 3, 0, 0x000000eb00000000ull, 0x000001eff0000000ull, { 33, 62, 0, 0, 0 }, 0x400, 104, },
+ { 143, 3, 0, 0x0000000050000000ull, 0x000001eff8000000ull, { 0, 0, 0, 0, 0 }, 0x21, 105, },
+ { 151, 3, 0, 0x0000000110000000ull, 0x000001eff8000000ull, { 0, 0, 0, 0, 0 }, 0x0, 106, },
+ { 152, 2, 1, 0x000000e880000000ull, 0x000001fff0000000ull, { 24, 25, 26, 0, 0 }, 0x0, 2169, },
+ { 153, 2, 1, 0x000000ea80000000ull, 0x000001fff0000000ull, { 24, 25, 26, 0, 0 }, 0x0, 2170, },
+ { 154, 2, 1, 0x000000f880000000ull, 0x000001fff0000000ull, { 24, 25, 26, 0, 0 }, 0x0, 2171, },
+ { 155, 1, 1, 0x0000010800000000ull, 0x000001fff80fe000ull, { 24, 26, 0, 0, 0 }, 0x0, 107, },
+ { 155, 1, 1, 0x0000012000000000ull, 0x000001e000300000ull, { 24, 66, 0, 0, 0 }, 0x40, 108, },
+ { 155, 5, 1, 0x0000000080000000ull, 0x000001e3f8000000ull, { 18, 20, 0, 0, 0 }, 0xc0, 109, },
+ { 155, 2, 1, 0x0000000e00100000ull, 0x000001ee00f00000ull, { 15, 25, 0, 0, 0 }, 0x40, 110, },
+ { 155, 2, 1, 0x0000000e00000000ull, 0x000001ee00f00000ull, { 15, 25, 78, 0, 0 }, 0x0, 2821, },
+ { 155, 2, 1, 0x0000000188000000ull, 0x000001eff8000000ull, { 24, 16, 0, 0, 0 }, 0x0, 112, },
+ { 155, 2, 1, 0x0000000600000000ull, 0x000001ee00000000ull, { 9, 25, 64, 0, 0 }, 0x0, 113, },
+ { 155, 2, 1, 0x00000016ff001fc0ull, 0x000001feff001fc0ull, { 9, 25, 0, 0, 0 }, 0x40, 114, },
+ { 155, 2, 1, 0x0000000400000000ull, 0x000001ee00000000ull, { 10, 68, 0, 0, 0 }, 0x0, 115, },
+ { 155, 2, 1, 0x0000000180000000ull, 0x000001eff8000000ull, { 24, 8, 0, 0, 0 }, 0x0, 116, },
+ { 155, 2, 1, 0x0000000198000000ull, 0x000001eff8000000ull, { 24, 9, 0, 0, 0 }, 0x0, 117, },
+ { 155, 2, 1, 0x0000000150000000ull, 0x000001eff8000000ull, { 14, 25, 0, 0, 0 }, 0x0, 1126, },
+ { 155, 2, 1, 0x0000000050000000ull, 0x000001eff8000000ull, { 14, 55, 0, 0, 0 }, 0x0, 1127, },
+ { 155, 2, 1, 0x0000000190000000ull, 0x000001eff8000000ull, { 24, 14, 0, 0, 0 }, 0x0, 1128, },
+ { 155, 3, 1, 0x0000000140000000ull, 0x000001eff8000000ull, { 14, 55, 0, 0, 0 }, 0x0, 1250, },
+ { 155, 3, 1, 0x0000002150000000ull, 0x000001eff8000000ull, { 14, 25, 0, 0, 0 }, 0x0, 1251, },
+ { 155, 3, 1, 0x0000002110000000ull, 0x000001eff8000000ull, { 24, 14, 0, 0, 0 }, 0x0, 1252, },
+ { 155, 3, 1, 0x0000002160000000ull, 0x000001eff8000000ull, { 17, 25, 0, 0, 0 }, 0x8, 118, },
+ { 155, 3, 1, 0x0000002120000000ull, 0x000001eff8000000ull, { 24, 17, 0, 0, 0 }, 0x8, 119, },
+ { 155, 3, 1, 0x0000002168000000ull, 0x000001eff8000000ull, { 12, 25, 0, 0, 0 }, 0x8, 120, },
+ { 155, 3, 1, 0x0000002148000000ull, 0x000001eff8000000ull, { 13, 25, 0, 0, 0 }, 0x0, 121, },
+ { 155, 3, 1, 0x0000002128000000ull, 0x000001eff8000000ull, { 24, 11, 0, 0, 0 }, 0x8, 122, },
+ { 155, 3, 1, 0x0000002108000000ull, 0x000001eff8000000ull, { 24, 13, 0, 0, 0 }, 0x0, 123, },
+ { 155, 3, 1, 0x0000002000000000ull, 0x000001eff8000000ull, { 38, 25, 0, 0, 0 }, 0x8, 124, },
+ { 155, 3, 1, 0x0000002008000000ull, 0x000001eff8000000ull, { 29, 25, 0, 0, 0 }, 0x8, 125, },
+ { 155, 3, 1, 0x0000002010000000ull, 0x000001eff8000000ull, { 32, 25, 0, 0, 0 }, 0x8, 126, },
+ { 155, 3, 1, 0x0000002018000000ull, 0x000001eff8000000ull, { 35, 25, 0, 0, 0 }, 0x8, 127, },
+ { 155, 3, 1, 0x0000002020000000ull, 0x000001eff8000000ull, { 36, 25, 0, 0, 0 }, 0x8, 128, },
+ { 155, 3, 1, 0x0000002028000000ull, 0x000001eff8000000ull, { 37, 25, 0, 0, 0 }, 0x8, 129, },
+ { 155, 3, 1, 0x0000002030000000ull, 0x000001eff8000000ull, { 34, 25, 0, 0, 0 }, 0x8, 130, },
+ { 155, 3, 1, 0x0000002080000000ull, 0x000001eff8000000ull, { 24, 38, 0, 0, 0 }, 0x8, 131, },
+ { 155, 3, 1, 0x0000002088000000ull, 0x000001eff8000000ull, { 24, 29, 0, 0, 0 }, 0x8, 132, },
+ { 155, 3, 1, 0x0000002090000000ull, 0x000001eff8000000ull, { 24, 32, 0, 0, 0 }, 0x8, 133, },
+ { 155, 3, 1, 0x0000002098000000ull, 0x000001eff8000000ull, { 24, 35, 0, 0, 0 }, 0x8, 134, },
+ { 155, 3, 1, 0x00000020a0000000ull, 0x000001eff8000000ull, { 24, 36, 0, 0, 0 }, 0x8, 135, },
+ { 155, 3, 1, 0x00000020a8000000ull, 0x000001eff8000000ull, { 24, 37, 0, 0, 0 }, 0x0, 136, },
+ { 155, 3, 1, 0x00000020b0000000ull, 0x000001eff8000000ull, { 24, 34, 0, 0, 0 }, 0x8, 137, },
+ { 155, 3, 1, 0x00000020b8000000ull, 0x000001eff8000000ull, { 24, 28, 0, 0, 0 }, 0x0, 138, },
+ { 155, 7, 1, 0x0000000000000000ull, 0x0000000000000000ull, { 24, 14, 0, 0, 0 }, 0x0, 139, },
+ { 155, 7, 1, 0x0000000000000000ull, 0x0000000000000000ull, { 14, 55, 0, 0, 0 }, 0x0, 140, },
+ { 155, 7, 1, 0x0000000000000000ull, 0x0000000000000000ull, { 14, 25, 0, 0, 0 }, 0x0, 141, },
+ { 156, 6, 1, 0x000000c000000000ull, 0x000001e000100000ull, { 24, 70, 0, 0, 0 }, 0x0, 142, },
+ { 157, 2, 1, 0x000000eca0000000ull, 0x000001fff0000000ull, { 24, 25, 74, 0, 0 }, 0x0, 143, },
+ { 158, 2, 1, 0x000000eea0000000ull, 0x000001fff0000000ull, { 24, 25, 75, 0, 0 }, 0x0, 144, },
+ { 168, 4, 0, 0x0000004000000000ull, 0x000001e1f8000000ull, { 65, 0, 0, 0, 0 }, 0x0, 521, },
+ { 168, 5, 0, 0x0000000008000000ull, 0x000001e3fc000000ull, { 65, 0, 0, 0, 0 }, 0x0, 944, },
+ { 168, 2, 0, 0x0000000008000000ull, 0x000001effc000000ull, { 65, 0, 0, 0, 0 }, 0x2, 1129, },
+ { 168, 3, 0, 0x0000000008000000ull, 0x000001effc000000ull, { 65, 0, 0, 0, 0 }, 0x0, 1253, },
+ { 168, 6, 0, 0x0000000008000000ull, 0x000001effc000000ull, { 69, 0, 0, 0, 0 }, 0x0, 2997, },
+ { 168, 7, 0, 0x0000000000000000ull, 0x0000000000000000ull, { 65, 0, 0, 0, 0 }, 0x0, 145, },
+ { 175, 1, 1, 0x0000010070000000ull, 0x000001eff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 146, },
+ { 175, 1, 1, 0x0000010170000000ull, 0x000001eff8000000ull, { 24, 55, 26, 0, 0 }, 0x0, 147, },
+ { 178, 2, 1, 0x000000ea00000000ull, 0x000001fff0000000ull, { 24, 25, 26, 0, 0 }, 0x0, 2979, },
+ { 179, 2, 1, 0x000000f820000000ull, 0x000001fff0000000ull, { 24, 25, 26, 0, 0 }, 0x0, 2823, },
+ { 180, 1, 1, 0x0000010400000000ull, 0x000001fff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 148, },
+ { 181, 1, 1, 0x0000010600000000ull, 0x000001fff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 149, },
+ { 182, 1, 1, 0x0000011400000000ull, 0x000001fff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 150, },
+ { 183, 1, 1, 0x0000010450000000ull, 0x000001fff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 151, },
+ { 184, 1, 1, 0x0000010650000000ull, 0x000001fff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 152, },
+ { 185, 1, 1, 0x0000010470000000ull, 0x000001fff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 153, },
+ { 186, 1, 1, 0x0000010670000000ull, 0x000001fff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 154, },
+ { 187, 1, 1, 0x0000010520000000ull, 0x000001fff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 930, },
+ { 188, 1, 1, 0x0000010720000000ull, 0x000001fff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 931, },
+ { 189, 1, 1, 0x0000011520000000ull, 0x000001fff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 932, },
+ { 190, 2, 1, 0x000000e850000000ull, 0x000001fff0000000ull, { 24, 25, 26, 0, 0 }, 0x0, 2837, },
+ { 191, 2, 1, 0x000000ea70000000ull, 0x000001fff0000000ull, { 24, 25, 26, 0, 0 }, 0x0, 155, },
+ { 192, 2, 1, 0x000000e810000000ull, 0x000001fff0000000ull, { 24, 25, 26, 0, 0 }, 0x0, 2838, },
+ { 193, 2, 1, 0x000000ea30000000ull, 0x000001fff0000000ull, { 24, 25, 26, 0, 0 }, 0x0, 156, },
+ { 194, 2, 1, 0x000000ead0000000ull, 0x000001fff0000000ull, { 24, 25, 26, 0, 0 }, 0x0, 2172, },
+ { 195, 2, 1, 0x000000e230000000ull, 0x000001ff30000000ull, { 24, 25, 26, 42, 0 }, 0x0, 157, },
+ { 196, 2, 1, 0x000000e690000000ull, 0x000001fff0000000ull, { 24, 26, 0, 0, 0 }, 0x0, 158, },
+ { 198, 3, 1, 0x00000021c0000000ull, 0x000001eff8000000ull, { 24, 26, 25, 0, 0 }, 0x0, 2173, },
+ { 198, 3, 1, 0x00000020c0000000ull, 0x000001eff8000000ull, { 24, 26, 49, 0, 0 }, 0x0, 2174, },
+ { 198, 3, 0, 0x0000002188000000ull, 0x000001eff8000000ull, { 26, 49, 0, 0, 0 }, 0x0, 2204, },
+ { 199, 2, 1, 0x000000e8b0000000ull, 0x000001fff0000000ull, { 24, 25, 26, 0, 0 }, 0x0, 159, },
+ { 200, 2, 1, 0x000000e240000000ull, 0x000001fff0000000ull, { 24, 25, 26, 0, 0 }, 0x0, 160, },
+ { 200, 2, 1, 0x000000ee50000000ull, 0x000001fff0000000ull, { 24, 25, 39, 0, 0 }, 0x0, 161, },
+ { 201, 2, 1, 0x000000f040000000ull, 0x000001fff0000000ull, { 24, 25, 26, 0, 0 }, 0x0, 162, },
+ { 201, 2, 1, 0x000000fc50000000ull, 0x000001fff0000000ull, { 24, 25, 39, 0, 0 }, 0x0, 163, },
+ { 202, 1, 1, 0x0000010680000000ull, 0x000001ffe0000000ull, { 24, 25, 41, 26, 0 }, 0x0, 164, },
+ { 203, 2, 1, 0x000000e220000000ull, 0x000001fff0000000ull, { 24, 26, 25, 0, 0 }, 0x0, 165, },
+ { 203, 2, 1, 0x000000e630000000ull, 0x000001fff0000000ull, { 24, 26, 43, 0, 0 }, 0x0, 166, },
+ { 204, 2, 1, 0x000000f020000000ull, 0x000001fff0000000ull, { 24, 26, 25, 0, 0 }, 0x0, 167, },
+ { 204, 2, 1, 0x000000f430000000ull, 0x000001fff0000000ull, { 24, 26, 43, 0, 0 }, 0x0, 168, },
+ { 205, 1, 1, 0x00000106c0000000ull, 0x000001ffe0000000ull, { 24, 25, 41, 26, 0 }, 0x0, 169, },
+ { 206, 1, 1, 0x0000010420000000ull, 0x000001fff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 170, },
+ { 207, 1, 1, 0x0000010620000000ull, 0x000001fff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 171, },
+ { 208, 1, 1, 0x0000011420000000ull, 0x000001fff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 172, },
+ { 209, 3, 0, 0x0000002048000000ull, 0x000001eff8000000ull, { 26, 25, 0, 0, 0 }, 0x8, 1157, },
+ { 209, 3, 0, 0x0000002050000000ull, 0x000001eff8000000ull, { 26, 25, 0, 0, 0 }, 0xc, 1032, },
+ { 209, 3, 0, 0x00000021a0000000ull, 0x000001eff8000000ull, { 26, 0, 0, 0, 0 }, 0x8, 904, },
+ { 210, 3, 0, 0x0000002060000000ull, 0x000001eff8000000ull, { 26, 25, 0, 0, 0 }, 0x8, 830, },
+ { 215, 4, 0, 0x0000000040000000ull, 0x000001e1f8000000ull, { 0, 0, 0, 0, 0 }, 0x22c, 173, },
+ { 216, 3, 0, 0x0000000038000000ull, 0x000001ee78000000ull, { 67, 0, 0, 0, 0 }, 0x8, 174, },
+ { 217, 3, 0, 0x0000000028000000ull, 0x000001ee78000000ull, { 67, 0, 0, 0, 0 }, 0x0, 175, },
+ { 226, 3, 1, 0x000000c708000000ull, 0x000001ffc8000000ull, { 18, 25, 0, 0, 0 }, 0x0, 2748, },
+ { 227, 2, 1, 0x000000a600000000ull, 0x000001ee04000000ull, { 24, 25, 45, 0, 0 }, 0x140, 176, },
+ { 227, 2, 1, 0x000000f240000000ull, 0x000001fff0000000ull, { 24, 25, 26, 0, 0 }, 0x0, 177, },
+ { 228, 1, 1, 0x0000010080000000ull, 0x000001efe0000000ull, { 24, 25, 40, 26, 0 }, 0x0, 178, },
+ { 229, 1, 1, 0x00000100c0000000ull, 0x000001efe0000000ull, { 24, 25, 40, 26, 0 }, 0x0, 179, },
+ { 230, 2, 1, 0x000000a400000000ull, 0x000001ee00002000ull, { 24, 26, 76, 0, 0 }, 0x140, 2844, },
+ { 230, 2, 1, 0x000000f220000000ull, 0x000001fff0000000ull, { 24, 26, 25, 0, 0 }, 0x0, 181, },
+ { 231, 2, 1, 0x000000ac00000000ull, 0x000001ee00000000ull, { 24, 25, 26, 44, 0 }, 0x0, 182, },
+ { 236, 3, 0, 0x0000000180000000ull, 0x000001eff8000000ull, { 0, 0, 0, 0, 0 }, 0x0, 832, },
+ { 237, 3, 0, 0x0000000030000000ull, 0x000001ee78000000ull, { 67, 0, 0, 0, 0 }, 0x8, 183, },
+ { 239, 3, 1, 0x0000008c00000000ull, 0x000001fff8000000ull, { 33, 25, 0, 0, 0 }, 0x0, 184, },
+ { 239, 3, 1, 0x000000ac00000000ull, 0x000001eff0000000ull, { 33, 25, 61, 0, 0 }, 0x400, 185, },
+ { 240, 3, 1, 0x0000008c08000000ull, 0x000001fff8000000ull, { 33, 25, 1, 0, 0 }, 0x0, 186, },
+ { 240, 3, 1, 0x0000008c08000000ull, 0x000001fff8000000ull, { 33, 25, 0, 0, 0 }, 0x40, 187, },
+ { 241, 3, 1, 0x0000008c40000000ull, 0x000001fff8000000ull, { 33, 25, 0, 0, 0 }, 0x0, 188, },
+ { 241, 3, 1, 0x000000ac40000000ull, 0x000001eff0000000ull, { 33, 25, 61, 0, 0 }, 0x400, 189, },
+ { 242, 3, 1, 0x0000008c80000000ull, 0x000001fff8000000ull, { 33, 25, 0, 0, 0 }, 0x0, 190, },
+ { 242, 3, 1, 0x000000ac80000000ull, 0x000001eff0000000ull, { 33, 25, 61, 0, 0 }, 0x400, 191, },
+ { 243, 3, 1, 0x0000008cc0000000ull, 0x000001fff8000000ull, { 33, 25, 0, 0, 0 }, 0x0, 192, },
+ { 243, 3, 1, 0x000000acc0000000ull, 0x000001eff0000000ull, { 33, 25, 61, 0, 0 }, 0x400, 193, },
+ { 244, 3, 1, 0x000000cec0000000ull, 0x000001fff8000000ull, { 33, 19, 0, 0, 0 }, 0x0, 2751, },
+ { 244, 3, 1, 0x000000eec0000000ull, 0x000001eff0000000ull, { 33, 19, 61, 0, 0 }, 0x400, 2752, },
+ { 245, 3, 1, 0x000000cc40000000ull, 0x000001fff8000000ull, { 33, 19, 0, 0, 0 }, 0x0, 194, },
+ { 245, 3, 1, 0x000000ec40000000ull, 0x000001eff0000000ull, { 33, 19, 61, 0, 0 }, 0x400, 195, },
+ { 246, 3, 1, 0x000000ccc0000000ull, 0x000001fff8000000ull, { 33, 19, 0, 0, 0 }, 0x0, 196, },
+ { 246, 3, 1, 0x000000ecc0000000ull, 0x000001eff0000000ull, { 33, 19, 61, 0, 0 }, 0x400, 197, },
+ { 247, 3, 1, 0x000000cc00000000ull, 0x000001fff8000000ull, { 33, 19, 0, 0, 0 }, 0x0, 198, },
+ { 247, 3, 1, 0x000000ec00000000ull, 0x000001eff0000000ull, { 33, 19, 61, 0, 0 }, 0x400, 199, },
+ { 248, 3, 1, 0x000000cc80000000ull, 0x000001fff8000000ull, { 33, 19, 0, 0, 0 }, 0x0, 200, },
+ { 248, 3, 1, 0x000000ec80000000ull, 0x000001eff0000000ull, { 33, 19, 61, 0, 0 }, 0x400, 201, },
+ { 249, 1, 1, 0x0000010028000000ull, 0x000001eff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 202, },
+ { 249, 1, 1, 0x0000010020000000ull, 0x000001eff8000000ull, { 24, 25, 26, 4, 0 }, 0x0, 203, },
+ { 249, 1, 1, 0x0000010128000000ull, 0x000001eff8000000ull, { 24, 55, 26, 0, 0 }, 0x0, 204, },
+ { 250, 3, 0, 0x0000000020000000ull, 0x000001ee78000000ull, { 67, 0, 0, 0, 0 }, 0x0, 205, },
+ { 251, 2, 1, 0x00000000a0000000ull, 0x000001eff8000000ull, { 24, 26, 0, 0, 0 }, 0x0, 206, },
+ { 252, 2, 1, 0x00000000a8000000ull, 0x000001eff8000000ull, { 24, 26, 0, 0, 0 }, 0x0, 207, },
+ { 253, 2, 1, 0x00000000b0000000ull, 0x000001eff8000000ull, { 24, 26, 0, 0, 0 }, 0x0, 208, },
+ { 254, 3, 0, 0x0000000198000000ull, 0x000001eff8000000ull, { 0, 0, 0, 0, 0 }, 0x0, 1132, },
+ { 255, 3, 1, 0x00000020f8000000ull, 0x000001eff8000000ull, { 24, 26, 0, 0, 0 }, 0x8, 209, },
+ { 256, 2, 2, 0x000000a000000000ull, 0x000001fe00003000ull, { 22, 23, 26, 76, 0 }, 0x0, 3002, },
+ { 256, 2, 1, 0x000000a000000000ull, 0x000001fe00003000ull, { 22, 26, 76, 0, 0 }, 0x40, 3003, },
+ { 256, 2, 2, 0x000000a000000000ull, 0x000001fe00003000ull, { 23, 22, 26, 76, 0 }, 0x40, 1985, },
+ { 256, 2, 1, 0x000000a000000000ull, 0x000001fe00003000ull, { 23, 26, 76, 0, 0 }, 0x40, 1986, },
+ { 257, 3, 1, 0x00000020d0000000ull, 0x000001eff8000000ull, { 24, 26, 0, 0, 0 }, 0x0, 210, },
+ { 258, 2, 2, 0x000000a000002000ull, 0x000001fe00003000ull, { 22, 23, 26, 0, 0 }, 0x0, 3006, },
+ { 258, 2, 1, 0x000000a000002000ull, 0x000001fe00003000ull, { 22, 26, 0, 0, 0 }, 0x40, 3007, },
+ { 258, 2, 2, 0x000000a000002000ull, 0x000001fe00003000ull, { 23, 22, 26, 0, 0 }, 0x40, 1989, },
+ { 258, 2, 1, 0x000000a000002000ull, 0x000001fe00003000ull, { 23, 26, 0, 0, 0 }, 0x40, 1990, },
+ { 259, 3, 1, 0x00000020f0000000ull, 0x000001eff8000000ull, { 24, 26, 0, 0, 0 }, 0x8, 211, },
+ { 261, 3, 1, 0x00000020d8000000ull, 0x000001eff8000000ull, { 24, 26, 0, 0, 0 }, 0x0, 212, },
+ { 265, 2, 1, 0x000000e840000000ull, 0x000001fff0000000ull, { 24, 25, 26, 0, 0 }, 0x0, 1113, },
+ { 266, 2, 1, 0x000000ea40000000ull, 0x000001fff0000000ull, { 24, 25, 26, 0, 0 }, 0x0, 1114, },
+ { 267, 2, 1, 0x000000f840000000ull, 0x000001fff0000000ull, { 24, 25, 26, 0, 0 }, 0x0, 1115, },
+ { 275, 3, 1, 0x0000008208000000ull, 0x000001fff8000000ull, { 24, 33, 25, 0, 0 }, 0x0, 213, },
+ { 276, 3, 1, 0x0000008248000000ull, 0x000001fff8000000ull, { 24, 33, 25, 0, 0 }, 0x0, 214, },
+ { 277, 3, 1, 0x0000008288000000ull, 0x000001fff8000000ull, { 24, 33, 25, 0, 0 }, 0x0, 215, },
+ { 278, 3, 1, 0x00000082c8000000ull, 0x000001fff8000000ull, { 24, 33, 25, 0, 0 }, 0x0, 216, },
+ { 280, 5, 1, 0x000001d000000000ull, 0x000001fc00000000ull, { 18, 20, 21, 19, 0 }, 0x0, 1161, },
+ { 280, 5, 1, 0x000001d000000000ull, 0x000001fc00000000ull, { 18, 20, 21, 19, 0 }, 0x40, 1243, },
+ { 281, 5, 1, 0x000001d000000000ull, 0x000001fc000fe000ull, { 18, 20, 21, 0, 0 }, 0x40, 1162, },
+ { 282, 1, 1, 0x0000010078000000ull, 0x000001eff8000000ull, { 24, 25, 26, 0, 0 }, 0x0, 217, },
+ { 282, 1, 1, 0x0000010178000000ull, 0x000001eff8000000ull, { 24, 55, 26, 0, 0 }, 0x0, 218, },
+ { 285, 2, 1, 0x0000000080000000ull, 0x000001eff8000000ull, { 24, 26, 0, 0, 0 }, 0x0, 219, },
+ { 286, 2, 1, 0x0000000088000000ull, 0x000001eff8000000ull, { 24, 26, 0, 0, 0 }, 0x0, 220, },
+ { 287, 2, 1, 0x0000000090000000ull, 0x000001eff8000000ull, { 24, 26, 0, 0, 0 }, 0x0, 221, },
+};
+
+static const char dis_table[] = {
+0xa0, 0xc5, 0xe8, 0xa0, 0x2e, 0x98, 0xa0, 0x2c, 0x80, 0xa0, 0x1b, 0xc0,
+0x98, 0xb0, 0x02, 0x50, 0x90, 0x50, 0x90, 0x28, 0x24, 0x38, 0x28, 0x24,
+0x38, 0x20, 0x90, 0x28, 0x24, 0x38, 0x18, 0x24, 0x38, 0x10, 0x91, 0x60,
+0x90, 0x28, 0x24, 0x38, 0x00, 0x10, 0x10, 0x58, 0x41, 0x61, 0xbf, 0xc0,
+0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+0x10, 0x10, 0x52, 0xc0, 0xc0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+0x10, 0x10, 0x10, 0x24, 0x23, 0x70, 0x90, 0x28, 0x24, 0x37, 0xf0, 0x24,
+0x37, 0xe8, 0xa8, 0x0b, 0x48, 0x15, 0x20, 0x97, 0x20, 0x95, 0xc8, 0x9a,
+0xb8, 0x05, 0x38, 0x91, 0x18, 0x90, 0xa0, 0x90, 0x60, 0x80, 0x90, 0x20,
+0x34, 0x86, 0xa4, 0x24, 0x00, 0x34, 0x83, 0x80, 0xa4, 0x35, 0xa0, 0x36,
+0xb9, 0x90, 0x50, 0x90, 0x28, 0x80, 0x36, 0xaf, 0x80, 0x34, 0x66, 0x81,
+0x33, 0xe2, 0x90, 0xe0, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x23, 0x10, 0x34,
+0x63, 0xa4, 0x1f, 0x08, 0x34, 0x60, 0x90, 0x38, 0xa4, 0x37, 0xa0, 0x36,
+0xfa, 0xa4, 0x37, 0x48, 0x36, 0xee, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x36,
+0x20, 0x36, 0xcf, 0xa4, 0x35, 0xf8, 0x36, 0xca, 0x80, 0xa4, 0x22, 0xf0,
+0x34, 0x5f, 0x92, 0x18, 0x91, 0xc0, 0x80, 0x91, 0x80, 0x90, 0xf8, 0xdb,
+0x84, 0x60, 0xf9, 0x40, 0xc0, 0xc0, 0x80, 0xa4, 0x41, 0x58, 0x8c, 0x42,
+0xb8, 0x84, 0x38, 0x61, 0xc0, 0xc0, 0x80, 0xa4, 0x41, 0x48, 0x8c, 0x42,
+0x98, 0x84, 0x38, 0x5f, 0xd3, 0x82, 0x40, 0x50, 0xc0, 0xc0, 0x81, 0x38,
+0x13, 0x50, 0xc0, 0xc0, 0x81, 0x38, 0x11, 0xa4, 0x1f, 0x18, 0x33, 0xe4,
+0x80, 0x90, 0x28, 0x80, 0x33, 0xe0, 0x80, 0x34, 0x68, 0x81, 0x90, 0x38,
+0xa4, 0x23, 0x80, 0x34, 0x6b, 0xa4, 0x23, 0x48, 0x34, 0x65, 0xc0, 0x40,
+0x10, 0x10, 0x90, 0x38, 0xa4, 0x1e, 0xf0, 0x33, 0xdf, 0xa4, 0x1e, 0xe0,
+0x33, 0xdd, 0x18, 0x24, 0x23, 0xf8, 0x83, 0x90, 0xa8, 0xd3, 0x82, 0xc0,
+0xc0, 0xc0, 0x80, 0xa4, 0x41, 0x28, 0x38, 0x4b, 0xc0, 0xc0, 0x80, 0xa4,
+0x41, 0x18, 0x38, 0x47, 0xd3, 0x82, 0x40, 0x50, 0xc0, 0xc0, 0x81, 0x38,
+0x0d, 0x50, 0xc0, 0xc0, 0x81, 0x38, 0x0b, 0x92, 0xb8, 0x99, 0x84, 0x23,
+0x68, 0x90, 0x78, 0x90, 0x50, 0x10, 0x10, 0x80, 0xa4, 0x35, 0x98, 0x36,
+0xb8, 0x82, 0x36, 0xae, 0x90, 0x80, 0x10, 0x10, 0x90, 0x38, 0xa4, 0x37,
+0x98, 0x36, 0xf9, 0xa4, 0x37, 0x40, 0x36, 0xed, 0x80, 0x90, 0x38, 0xa4,
+0x36, 0x18, 0x36, 0xce, 0xa4, 0x35, 0xf0, 0x36, 0xc9, 0x83, 0x90, 0xa8,
+0xd3, 0x82, 0xc0, 0xc0, 0xc0, 0x80, 0xa4, 0x40, 0xf8, 0x38, 0x3f, 0xc0,
+0xc0, 0x80, 0xa4, 0x40, 0xe8, 0x38, 0x3b, 0xd3, 0x82, 0x40, 0x50, 0xc0,
+0xc0, 0x81, 0x38, 0x07, 0x50, 0xc0, 0xc0, 0x81, 0x38, 0x05, 0x18, 0x24,
+0x23, 0x78, 0x83, 0x90, 0xa8, 0xd3, 0x82, 0xc0, 0xc0, 0xc0, 0x80, 0xa4,
+0x40, 0xc8, 0x38, 0x33, 0xc0, 0xc0, 0x80, 0xa4, 0x40, 0xb8, 0x38, 0x2f,
+0xd3, 0x82, 0x40, 0x50, 0xc0, 0xc0, 0x81, 0x38, 0x01, 0x50, 0xc0, 0xc0,
+0x81, 0x37, 0xff, 0x94, 0x50, 0x92, 0xf8, 0x99, 0x84, 0x1f, 0x48, 0x90,
+0x78, 0x90, 0x50, 0x10, 0x10, 0x80, 0xa4, 0x35, 0x90, 0x36, 0xb7, 0x82,
+0x36, 0xad, 0x90, 0x80, 0x10, 0x10, 0x90, 0x38, 0xa4, 0x37, 0x90, 0x36,
+0xf8, 0xa4, 0x37, 0x38, 0x36, 0xec, 0x80, 0x90, 0x38, 0xa4, 0x36, 0x10,
+0x36, 0xcd, 0xa4, 0x35, 0xe8, 0x36, 0xc8, 0x83, 0x90, 0xe8, 0xd3, 0x83,
+0xc0, 0xc0, 0xc0, 0x80, 0xa4, 0x41, 0x68, 0x8c, 0x42, 0xd8, 0x84, 0x38,
+0x63, 0xc0, 0xc0, 0x80, 0xa4, 0x41, 0x50, 0x8c, 0x42, 0xa8, 0x84, 0x38,
+0x60, 0xd3, 0x82, 0x40, 0x50, 0xc0, 0xc0, 0x81, 0x38, 0x15, 0x50, 0xc0,
+0xc0, 0x81, 0x38, 0x12, 0x18, 0x24, 0x1f, 0x40, 0x83, 0x90, 0xa8, 0xd3,
+0x82, 0xc0, 0xc0, 0xc0, 0x80, 0xa4, 0x41, 0x38, 0x38, 0x4f, 0xc0, 0xc0,
+0x80, 0xa4, 0x41, 0x20, 0x38, 0x49, 0xd3, 0x82, 0x40, 0x50, 0xc0, 0xc0,
+0x81, 0x38, 0x0f, 0x50, 0xc0, 0xc0, 0x81, 0x38, 0x0c, 0x92, 0xb8, 0x99,
+0x84, 0x1f, 0x38, 0x90, 0x78, 0x90, 0x50, 0x10, 0x10, 0x80, 0xa4, 0x35,
+0x88, 0x36, 0xb6, 0x82, 0x36, 0xac, 0x90, 0x80, 0x10, 0x10, 0x90, 0x38,
+0xa4, 0x37, 0x88, 0x36, 0xf7, 0xa4, 0x37, 0x30, 0x36, 0xeb, 0x80, 0x90,
+0x38, 0xa4, 0x36, 0x08, 0x36, 0xcc, 0xa4, 0x35, 0xe0, 0x36, 0xc7, 0x83,
+0x90, 0xa8, 0xd3, 0x82, 0xc0, 0xc0, 0xc0, 0x80, 0xa4, 0x41, 0x08, 0x38,
+0x43, 0xc0, 0xc0, 0x80, 0xa4, 0x40, 0xf0, 0x38, 0x3d, 0xd3, 0x82, 0x40,
+0x50, 0xc0, 0xc0, 0x81, 0x38, 0x09, 0x50, 0xc0, 0xc0, 0x81, 0x38, 0x06,
+0x18, 0x20, 0x01, 0x48, 0x83, 0x90, 0xa8, 0xd3, 0x82, 0xc0, 0xc0, 0xc0,
+0x80, 0xa4, 0x40, 0xd8, 0x38, 0x37, 0xc0, 0xc0, 0x80, 0xa4, 0x40, 0xc0,
+0x38, 0x31, 0xd3, 0x82, 0x40, 0x50, 0xc0, 0xc0, 0x81, 0x38, 0x03, 0x50,
+0xc0, 0xc0, 0x81, 0x38, 0x00, 0xda, 0x06, 0xe0, 0xf9, 0x80, 0x90, 0x60,
+0x90, 0x38, 0xa4, 0x23, 0xe8, 0x34, 0x7b, 0x80, 0x34, 0x78, 0x90, 0x38,
+0xa4, 0x23, 0x90, 0x34, 0x76, 0x80, 0x34, 0x73, 0x90, 0x60, 0x90, 0x38,
+0xa4, 0x23, 0xd0, 0x34, 0x7c, 0x80, 0x34, 0x79, 0x90, 0x38, 0xa4, 0x23,
+0xa8, 0x34, 0x77, 0x80, 0x34, 0x74, 0xc8, 0x40, 0x19, 0x00, 0x91, 0x58,
+0x90, 0x60, 0x82, 0x90, 0x20, 0x36, 0xab, 0xa4, 0x35, 0x48, 0x36, 0xaa,
+0x90, 0xc0, 0x80, 0x90, 0x90, 0x90, 0x48, 0xc9, 0xe1, 0xb9, 0x00, 0x85,
+0x36, 0xe3, 0xc9, 0xe1, 0xb8, 0x40, 0x85, 0x36, 0xe0, 0x80, 0x36, 0xdf,
+0x10, 0x10, 0x81, 0x36, 0xbb, 0x90, 0xa8, 0x10, 0x10, 0x90, 0x28, 0x81,
+0x36, 0xd9, 0x90, 0x38, 0xa4, 0x36, 0xa0, 0x36, 0xd5, 0xa4, 0x36, 0x90,
+0x36, 0xd3, 0x90, 0x70, 0x10, 0x10, 0x90, 0x38, 0xa4, 0x36, 0xb8, 0x36,
+0xd8, 0x80, 0x36, 0xd6, 0x90, 0x60, 0x90, 0x28, 0x24, 0x36, 0xf0, 0xa4,
+0x36, 0xe0, 0x36, 0xdd, 0x80, 0xa4, 0x36, 0xd0, 0x36, 0xdb, 0x80, 0x90,
+0xf8, 0x90, 0x90, 0x90, 0x50, 0x90, 0x28, 0x80, 0x37, 0xf7, 0x80, 0x37,
+0xfe, 0x80, 0xa4, 0x3f, 0xe0, 0x37, 0xfd, 0x90, 0x28, 0x81, 0x37, 0xfb,
+0x80, 0xa4, 0x3f, 0xc8, 0x37, 0xfa, 0x83, 0x37, 0xf8, 0x98, 0xe8, 0x01,
+0xb0, 0x90, 0x88, 0x90, 0x60, 0xa4, 0x35, 0x38, 0x10, 0x10, 0x10, 0x10,
+0x83, 0x33, 0xb7, 0x24, 0x35, 0x30, 0x90, 0x28, 0x24, 0x35, 0x28, 0x24,
+0x35, 0x20, 0x90, 0x88, 0x90, 0x60, 0xa4, 0x35, 0x10, 0x10, 0x10, 0x10,
+0x10, 0x83, 0x33, 0xb6, 0x24, 0x35, 0x08, 0x90, 0x28, 0x24, 0x35, 0x00,
+0x24, 0x34, 0xf8, 0xa8, 0x09, 0x00, 0x0e, 0x20, 0x96, 0x48, 0x95, 0xe8,
+0x93, 0x38, 0x91, 0xa0, 0x90, 0xd0, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x1e,
+0x60, 0x33, 0xcd, 0xa4, 0x1e, 0x50, 0x33, 0xcb, 0x90, 0x38, 0xa4, 0x1e,
+0x40, 0x33, 0xc9, 0x80, 0x33, 0xc7, 0x90, 0x60, 0x90, 0x28, 0x24, 0x1e,
+0x00, 0xa4, 0x1d, 0xf0, 0x33, 0xbf, 0x90, 0x38, 0xa4, 0x1d, 0xe0, 0x33,
+0xbd, 0xa4, 0x1e, 0x28, 0x33, 0xc6, 0x90, 0xe0, 0x90, 0x70, 0x90, 0x38,
+0xa4, 0x1e, 0x18, 0x33, 0xc4, 0xa4, 0x1e, 0x08, 0x33, 0xc2, 0x90, 0x38,
+0xa4, 0x34, 0xb0, 0x36, 0x9c, 0xa4, 0x34, 0x50, 0x36, 0x90, 0x90, 0x70,
+0x90, 0x38, 0xa4, 0x31, 0x90, 0x36, 0x3e, 0xa4, 0x31, 0x60, 0x36, 0x38,
+0x10, 0x10, 0xa4, 0x1d, 0xd0, 0x33, 0xbb, 0x99, 0x60, 0x02, 0x70, 0x90,
+0x90, 0x90, 0x50, 0x90, 0x28, 0x24, 0x1e, 0x90, 0x80, 0x33, 0xda, 0x80,
+0xa4, 0x1e, 0x98, 0x33, 0xd8, 0x90, 0x50, 0x90, 0x28, 0x24, 0x1e, 0xa0,
+0x80, 0x33, 0xdb, 0x90, 0x38, 0xa4, 0x1e, 0xa8, 0x33, 0xd9, 0xa4, 0x1e,
+0x70, 0x33, 0xcf, 0x90, 0xe0, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x33, 0xe8,
+0x36, 0x85, 0xa4, 0x33, 0x48, 0x36, 0x72, 0x90, 0x38, 0xa4, 0x32, 0xe0,
+0x36, 0x63, 0xa4, 0x32, 0x50, 0x36, 0x52, 0x81, 0xa4, 0x1e, 0x80, 0x33,
+0xd1, 0xe4, 0xa1, 0xfc, 0x40, 0x37, 0xf3, 0x18, 0x24, 0x1d, 0xc8, 0xe4,
+0xe1, 0xfa, 0xc0, 0x37, 0xed, 0x92, 0x40, 0x91, 0x08, 0x10, 0x10, 0x90,
+0x80, 0x10, 0x10, 0x90, 0x38, 0xa4, 0x34, 0xa8, 0x36, 0x9b, 0xa4, 0x34,
+0x48, 0x36, 0x8f, 0x80, 0x90, 0x38, 0xa4, 0x31, 0x88, 0x36, 0x3d, 0xa4,
+0x31, 0x58, 0x36, 0x37, 0x18, 0x20, 0x00, 0xf8, 0x80, 0x90, 0x70, 0x90,
+0x38, 0xa4, 0x33, 0xd8, 0x36, 0x84, 0xa4, 0x33, 0x40, 0x36, 0x70, 0x90,
+0x38, 0xa4, 0x32, 0xd0, 0x36, 0x62, 0xa4, 0x32, 0x48, 0x36, 0x50, 0xe4,
+0xa1, 0xf9, 0x40, 0x37, 0xe7, 0x18, 0x24, 0x1d, 0xc0, 0xe4, 0xe1, 0xf7,
+0xc0, 0x37, 0xe1, 0x92, 0x90, 0x92, 0x40, 0x91, 0x08, 0x10, 0x10, 0x90,
+0x80, 0x10, 0x10, 0x90, 0x38, 0xa4, 0x34, 0xa0, 0x36, 0x9a, 0xa4, 0x34,
+0x40, 0x36, 0x8e, 0x80, 0x90, 0x38, 0xa4, 0x31, 0x80, 0x36, 0x3c, 0xa4,
+0x31, 0x50, 0x36, 0x36, 0x18, 0x20, 0x00, 0xf8, 0x80, 0x90, 0x70, 0x90,
+0x38, 0xa4, 0x33, 0xc8, 0x36, 0x83, 0xa4, 0x33, 0x38, 0x36, 0x6e, 0x90,
+0x38, 0xa4, 0x32, 0xc0, 0x36, 0x61, 0xa4, 0x32, 0x40, 0x36, 0x4e, 0xe4,
+0xa1, 0xfc, 0x80, 0x37, 0xf5, 0x10, 0x10, 0xe4, 0xe1, 0xfb, 0x00, 0x37,
+0xef, 0x92, 0x50, 0x99, 0x1c, 0x1e, 0xb0, 0x10, 0x10, 0x90, 0x80, 0x10,
+0x10, 0x90, 0x38, 0xa4, 0x34, 0x98, 0x36, 0x99, 0xa4, 0x34, 0x38, 0x36,
+0x8d, 0x80, 0x90, 0x38, 0xa4, 0x31, 0x78, 0x36, 0x3b, 0xa4, 0x31, 0x48,
+0x36, 0x35, 0x18, 0x20, 0x00, 0xf8, 0x80, 0x90, 0x70, 0x90, 0x38, 0xa4,
+0x33, 0xb8, 0x36, 0x82, 0xa4, 0x33, 0x30, 0x36, 0x6c, 0x90, 0x38, 0xa4,
+0x32, 0xb0, 0x36, 0x60, 0xa4, 0x32, 0x38, 0x36, 0x4c, 0xe4, 0xa1, 0xf9,
+0x80, 0x37, 0xe9, 0x10, 0x10, 0xe4, 0xe1, 0xf8, 0x00, 0x37, 0xe3, 0xc0,
+0x40, 0x80, 0x10, 0x10, 0x81, 0x90, 0x90, 0x90, 0x48, 0xc9, 0xe1, 0x90,
+0x80, 0x85, 0x36, 0x46, 0xc9, 0xe1, 0x91, 0x00, 0x85, 0x36, 0x43, 0x80,
+0x36, 0x41, 0x80, 0xd8, 0x47, 0x80, 0x0d, 0xc0, 0xc0, 0x80, 0x10, 0x10,
+0x82, 0x90, 0x58, 0xd5, 0x81, 0x80, 0x80, 0x37, 0xdd, 0x80, 0x37, 0xdb,
+0xd5, 0x81, 0x80, 0x80, 0x37, 0xd9, 0x80, 0x37, 0xd7, 0xc0, 0x80, 0x10,
+0x10, 0x82, 0x90, 0x58, 0xd5, 0x81, 0x80, 0x80, 0x37, 0xde, 0x80, 0x37,
+0xdc, 0xd5, 0x81, 0x80, 0x80, 0x37, 0xda, 0x80, 0x37, 0xd8, 0xc0, 0x80,
+0x83, 0xa4, 0x3e, 0xa8, 0x37, 0xd6, 0xa0, 0x57, 0xc0, 0xa0, 0x41, 0xe0,
+0xa8, 0x1e, 0xb0, 0x34, 0x88, 0xa0, 0x12, 0x38, 0xa0, 0x0b, 0x48, 0x96,
+0x00, 0x9a, 0xf0, 0x05, 0xc0, 0x91, 0x70, 0x90, 0xb8, 0x90, 0x70, 0x90,
+0x38, 0xa4, 0x15, 0x58, 0x33, 0xb5, 0xa4, 0x15, 0x78, 0x33, 0xb4, 0x10,
+0x10, 0xa4, 0x15, 0x68, 0x33, 0xb3, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x14,
+0xf8, 0x33, 0x9a, 0xa4, 0x15, 0x18, 0x33, 0x99, 0x10, 0x10, 0xa4, 0x15,
+0x08, 0x33, 0x98, 0x90, 0xb8, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x14, 0x98,
+0x33, 0x7f, 0xa4, 0x14, 0xb8, 0x33, 0x7e, 0x10, 0x10, 0xa4, 0x14, 0xa8,
+0x33, 0x7d, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x14, 0x38, 0x33, 0x63, 0xa4,
+0x14, 0x58, 0x33, 0x62, 0x10, 0x10, 0xa4, 0x14, 0x48, 0x33, 0x61, 0x91,
+0x70, 0x90, 0xb8, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x15, 0x28, 0x33, 0xb0,
+0xa4, 0x15, 0x48, 0x33, 0xb2, 0x10, 0x10, 0xa4, 0x15, 0x38, 0x33, 0xb1,
+0x90, 0x70, 0x90, 0x38, 0xa4, 0x14, 0xc8, 0x33, 0x95, 0xa4, 0x14, 0xe8,
+0x33, 0x97, 0x10, 0x10, 0xa4, 0x14, 0xd8, 0x33, 0x96, 0x90, 0xb8, 0x90,
+0x70, 0x90, 0x38, 0xa4, 0x14, 0x68, 0x33, 0x7a, 0xa4, 0x14, 0x88, 0x33,
+0x7c, 0x10, 0x10, 0xa4, 0x14, 0x78, 0x33, 0x7b, 0x90, 0x70, 0x90, 0x38,
+0xa4, 0x14, 0x08, 0x33, 0x5e, 0xa4, 0x14, 0x28, 0x33, 0x60, 0x10, 0x10,
+0xa4, 0x14, 0x18, 0x33, 0x5f, 0xe4, 0xe1, 0x83, 0x40, 0x36, 0x21, 0x9a,
+0xf0, 0x05, 0x00, 0x91, 0x70, 0x90, 0xb8, 0x90, 0x70, 0x90, 0x38, 0xa4,
+0x13, 0xa0, 0x33, 0xad, 0xa4, 0x13, 0x98, 0x33, 0xaf, 0x10, 0x10, 0xa4,
+0x13, 0x90, 0x33, 0xae, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x13, 0x88, 0x33,
+0x92, 0xa4, 0x13, 0x80, 0x33, 0x94, 0x10, 0x10, 0xa4, 0x13, 0x78, 0x33,
+0x93, 0x90, 0xb8, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x13, 0x70, 0x33, 0x77,
+0xa4, 0x13, 0x68, 0x33, 0x79, 0x10, 0x10, 0xa4, 0x13, 0x60, 0x33, 0x78,
+0x90, 0x70, 0x90, 0x38, 0xa4, 0x13, 0x58, 0x33, 0x5b, 0xa4, 0x13, 0x50,
+0x33, 0x5d, 0x10, 0x10, 0xa4, 0x13, 0x48, 0x33, 0x5c, 0x91, 0x10, 0x90,
+0x88, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0xaa, 0x80, 0x33, 0xac, 0x10,
+0x10, 0x80, 0x33, 0xab, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0x8f, 0x80,
+0x33, 0x91, 0x10, 0x10, 0x80, 0x33, 0x90, 0x90, 0x88, 0x90, 0x50, 0x90,
+0x28, 0x80, 0x33, 0x74, 0x80, 0x33, 0x76, 0x10, 0x10, 0x80, 0x33, 0x75,
+0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0x58, 0x80, 0x33, 0x5a, 0x10, 0x10,
+0x80, 0x33, 0x59, 0xe4, 0xe1, 0x5e, 0x40, 0x35, 0xa1, 0x95, 0x40, 0x9a,
+0x90, 0x05, 0x00, 0x91, 0x10, 0x90, 0x88, 0x90, 0x50, 0x90, 0x28, 0x80,
+0x33, 0xa7, 0x80, 0x33, 0xa9, 0x10, 0x10, 0x80, 0x33, 0xa8, 0x90, 0x50,
+0x90, 0x28, 0x80, 0x33, 0x8c, 0x80, 0x33, 0x8e, 0x10, 0x10, 0x80, 0x33,
+0x8d, 0x90, 0xb8, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x13, 0x30, 0x33, 0x71,
+0xa4, 0x13, 0x40, 0x33, 0x73, 0x10, 0x10, 0xa4, 0x13, 0x38, 0x33, 0x72,
+0x90, 0x70, 0x90, 0x38, 0xa4, 0x13, 0x00, 0x33, 0x55, 0xa4, 0x13, 0x10,
+0x33, 0x57, 0x10, 0x10, 0xa4, 0x13, 0x08, 0x33, 0x56, 0x91, 0x10, 0x90,
+0x88, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0xa4, 0x80, 0x33, 0xa6, 0x10,
+0x10, 0x80, 0x33, 0xa5, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0x89, 0x80,
+0x33, 0x8b, 0x10, 0x10, 0x80, 0x33, 0x8a, 0x90, 0xb8, 0x90, 0x70, 0x90,
+0x38, 0xa4, 0x13, 0x18, 0x33, 0x6e, 0xa4, 0x13, 0x28, 0x33, 0x70, 0x10,
+0x10, 0xa4, 0x13, 0x20, 0x33, 0x6f, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x12,
+0xe8, 0x33, 0x52, 0xa4, 0x12, 0xf8, 0x33, 0x54, 0x10, 0x10, 0xa4, 0x12,
+0xf0, 0x33, 0x53, 0xe4, 0xe1, 0x82, 0x40, 0x36, 0x1d, 0x98, 0xb8, 0x01,
+0x68, 0x10, 0x10, 0x10, 0x10, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0x4f,
+0x80, 0x33, 0x51, 0x10, 0x10, 0x80, 0x33, 0x50, 0x90, 0x60, 0x90, 0x30,
+0x60, 0xa0, 0x97, 0x00, 0x60, 0xa0, 0x96, 0xc0, 0x90, 0x30, 0x60, 0xa0,
+0x96, 0x80, 0x60, 0xa0, 0x96, 0x40, 0xe4, 0xe1, 0x5c, 0x40, 0x35, 0x99,
+0xa0, 0x08, 0x08, 0x94, 0xe0, 0x9a, 0x60, 0x04, 0xa0, 0x91, 0x40, 0x90,
+0xb8, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x13, 0xd8, 0x33, 0x9e, 0xa4, 0x13,
+0xf8, 0x33, 0xa3, 0x10, 0x10, 0xa4, 0x13, 0xe8, 0x33, 0xa2, 0x90, 0x50,
+0x90, 0x28, 0x80, 0x33, 0x83, 0x80, 0x33, 0x88, 0x10, 0x10, 0x80, 0x33,
+0x87, 0x90, 0x88, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0x68, 0x80, 0x33,
+0x6d, 0x10, 0x10, 0x80, 0x33, 0x6c, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33,
+0x49, 0x80, 0x33, 0x4e, 0x10, 0x10, 0x80, 0x33, 0x4d, 0x91, 0x40, 0x90,
+0xb8, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x13, 0xa8, 0x33, 0x9b, 0xa4, 0x13,
+0xc8, 0x33, 0x9d, 0x10, 0x10, 0xa4, 0x13, 0xb8, 0x33, 0x9c, 0x90, 0x50,
+0x90, 0x28, 0x80, 0x33, 0x80, 0x80, 0x33, 0x82, 0x10, 0x10, 0x80, 0x33,
+0x81, 0x90, 0x88, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0x65, 0x80, 0x33,
+0x67, 0x10, 0x10, 0x80, 0x33, 0x66, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33,
+0x46, 0x80, 0x33, 0x48, 0x10, 0x10, 0x80, 0x33, 0x47, 0xe4, 0xe1, 0x81,
+0x40, 0x36, 0x19, 0x9a, 0x60, 0x02, 0xe0, 0x91, 0x40, 0x90, 0xb8, 0x90,
+0x70, 0x90, 0x38, 0xa4, 0x1a, 0x20, 0x33, 0x9f, 0xa4, 0x1a, 0x10, 0x33,
+0xa1, 0x10, 0x10, 0xa4, 0x1a, 0x00, 0x33, 0xa0, 0x90, 0x50, 0x90, 0x28,
+0x80, 0x33, 0x84, 0x80, 0x33, 0x86, 0x10, 0x10, 0x80, 0x33, 0x85, 0x90,
+0x88, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0x69, 0x80, 0x33, 0x6b, 0x10,
+0x10, 0x80, 0x33, 0x6a, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0x4a, 0x80,
+0x33, 0x4c, 0x10, 0x10, 0x80, 0x33, 0x4b, 0x81, 0x90, 0x50, 0x90, 0x28,
+0x24, 0x19, 0xd0, 0x24, 0x19, 0xf0, 0x10, 0x10, 0x24, 0x19, 0xe0, 0xe4,
+0xe1, 0x5a, 0x40, 0x35, 0x91, 0x93, 0x90, 0x99, 0xb8, 0x03, 0x50, 0x90,
+0xe8, 0x90, 0x88, 0x90, 0x40, 0x80, 0xa4, 0x15, 0xb8, 0x32, 0xca, 0x10,
+0x10, 0xa4, 0x15, 0xa8, 0x32, 0xc9, 0x90, 0x28, 0x81, 0x32, 0xc6, 0x10,
+0x10, 0x80, 0x32, 0xc5, 0x90, 0x60, 0x90, 0x28, 0x81, 0x32, 0xc2, 0x10,
+0x10, 0x80, 0x32, 0xc1, 0x90, 0x28, 0x81, 0x32, 0xbe, 0x10, 0x10, 0x80,
+0x32, 0xbd, 0x90, 0xe8, 0x90, 0x88, 0x90, 0x40, 0x80, 0xa4, 0x15, 0x88,
+0x32, 0xc7, 0x10, 0x10, 0xa4, 0x15, 0x98, 0x32, 0xc8, 0x90, 0x28, 0x81,
+0x32, 0xc3, 0x10, 0x10, 0x80, 0x32, 0xc4, 0x90, 0x60, 0x90, 0x28, 0x81,
+0x32, 0xbf, 0x10, 0x10, 0x80, 0x32, 0xc0, 0x90, 0x28, 0x81, 0x32, 0xbb,
+0x10, 0x10, 0x80, 0x32, 0xbc, 0xe4, 0xe1, 0x80, 0x40, 0x36, 0x15, 0x88,
+0x00, 0x88, 0x10, 0x10, 0x10, 0x10, 0x90, 0x28, 0x81, 0x32, 0xb9, 0x10,
+0x10, 0x80, 0x32, 0xba, 0xe4, 0xe1, 0x58, 0x40, 0x35, 0x89, 0xa0, 0x0e,
+0x80, 0xa0, 0x09, 0x08, 0x94, 0x80, 0x9a, 0x30, 0x04, 0x40, 0x91, 0x10,
+0x90, 0x88, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0x39, 0x80, 0x33, 0x38,
+0x10, 0x10, 0x80, 0x33, 0x37, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0x1e,
+0x80, 0x33, 0x1d, 0x10, 0x10, 0x80, 0x33, 0x1c, 0x90, 0x88, 0x90, 0x50,
+0x90, 0x28, 0x80, 0x33, 0x03, 0x80, 0x33, 0x02, 0x10, 0x10, 0x80, 0x33,
+0x01, 0x90, 0x50, 0x90, 0x28, 0x80, 0x32, 0xe8, 0x80, 0x32, 0xe7, 0x10,
+0x10, 0x80, 0x32, 0xe6, 0x91, 0x10, 0x90, 0x88, 0x90, 0x50, 0x90, 0x28,
+0x80, 0x33, 0x34, 0x80, 0x33, 0x36, 0x10, 0x10, 0x80, 0x33, 0x35, 0x90,
+0x50, 0x90, 0x28, 0x80, 0x33, 0x19, 0x80, 0x33, 0x1b, 0x10, 0x10, 0x80,
+0x33, 0x1a, 0x90, 0x88, 0x90, 0x50, 0x90, 0x28, 0x80, 0x32, 0xfe, 0x80,
+0x33, 0x00, 0x10, 0x10, 0x80, 0x32, 0xff, 0x90, 0x50, 0x90, 0x28, 0x80,
+0x32, 0xe3, 0x80, 0x32, 0xe5, 0x10, 0x10, 0x80, 0x32, 0xe4, 0xe4, 0xe1,
+0x72, 0x40, 0x35, 0xf1, 0x9a, 0x30, 0x04, 0x40, 0x91, 0x10, 0x90, 0x88,
+0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0x31, 0x80, 0x33, 0x33, 0x10, 0x10,
+0x80, 0x33, 0x32, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0x16, 0x80, 0x33,
+0x18, 0x10, 0x10, 0x80, 0x33, 0x17, 0x90, 0x88, 0x90, 0x50, 0x90, 0x28,
+0x80, 0x32, 0xfb, 0x80, 0x32, 0xfd, 0x10, 0x10, 0x80, 0x32, 0xfc, 0x90,
+0x50, 0x90, 0x28, 0x80, 0x32, 0xe0, 0x80, 0x32, 0xe2, 0x10, 0x10, 0x80,
+0x32, 0xe1, 0x91, 0x10, 0x90, 0x88, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33,
+0x2e, 0x80, 0x33, 0x30, 0x10, 0x10, 0x80, 0x33, 0x2f, 0x90, 0x50, 0x90,
+0x28, 0x80, 0x33, 0x13, 0x80, 0x33, 0x15, 0x10, 0x10, 0x80, 0x33, 0x14,
+0x90, 0x88, 0x90, 0x50, 0x90, 0x28, 0x80, 0x32, 0xf8, 0x80, 0x32, 0xfa,
+0x10, 0x10, 0x80, 0x32, 0xf9, 0x90, 0x50, 0x90, 0x28, 0x80, 0x32, 0xdd,
+0x80, 0x32, 0xdf, 0x10, 0x10, 0x80, 0x32, 0xde, 0xe4, 0xe1, 0x51, 0x40,
+0x35, 0x59, 0x94, 0x80, 0x9a, 0x30, 0x04, 0x40, 0x91, 0x10, 0x90, 0x88,
+0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0x2b, 0x80, 0x33, 0x2d, 0x10, 0x10,
+0x80, 0x33, 0x2c, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0x10, 0x80, 0x33,
+0x12, 0x10, 0x10, 0x80, 0x33, 0x11, 0x90, 0x88, 0x90, 0x50, 0x90, 0x28,
+0x80, 0x32, 0xf5, 0x80, 0x32, 0xf7, 0x10, 0x10, 0x80, 0x32, 0xf6, 0x90,
+0x50, 0x90, 0x28, 0x80, 0x32, 0xda, 0x80, 0x32, 0xdc, 0x10, 0x10, 0x80,
+0x32, 0xdb, 0x91, 0x10, 0x90, 0x88, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33,
+0x28, 0x80, 0x33, 0x2a, 0x10, 0x10, 0x80, 0x33, 0x29, 0x90, 0x50, 0x90,
+0x28, 0x80, 0x33, 0x0d, 0x80, 0x33, 0x0f, 0x10, 0x10, 0x80, 0x33, 0x0e,
+0x90, 0x88, 0x90, 0x50, 0x90, 0x28, 0x80, 0x32, 0xf2, 0x80, 0x32, 0xf4,
+0x10, 0x10, 0x80, 0x32, 0xf3, 0x90, 0x50, 0x90, 0x28, 0x80, 0x32, 0xd7,
+0x80, 0x32, 0xd9, 0x10, 0x10, 0x80, 0x32, 0xd8, 0xe4, 0xe1, 0x70, 0x40,
+0x35, 0xe9, 0x88, 0x00, 0xb0, 0x10, 0x10, 0x10, 0x10, 0x90, 0x50, 0x90,
+0x28, 0x80, 0x32, 0xd4, 0x80, 0x32, 0xd6, 0x10, 0x10, 0x80, 0x32, 0xd5,
+0xe4, 0xe1, 0x50, 0x40, 0x35, 0x55, 0x96, 0xe8, 0x94, 0x80, 0x9a, 0x30,
+0x04, 0x40, 0x91, 0x10, 0x90, 0x88, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33,
+0x22, 0x80, 0x33, 0x27, 0x10, 0x10, 0x80, 0x33, 0x26, 0x90, 0x50, 0x90,
+0x28, 0x80, 0x33, 0x07, 0x80, 0x33, 0x0c, 0x10, 0x10, 0x80, 0x33, 0x0b,
+0x90, 0x88, 0x90, 0x50, 0x90, 0x28, 0x80, 0x32, 0xec, 0x80, 0x32, 0xf1,
+0x10, 0x10, 0x80, 0x32, 0xf0, 0x90, 0x50, 0x90, 0x28, 0x80, 0x32, 0xce,
+0x80, 0x32, 0xd3, 0x10, 0x10, 0x80, 0x32, 0xd2, 0x91, 0x10, 0x90, 0x88,
+0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0x1f, 0x80, 0x33, 0x21, 0x10, 0x10,
+0x80, 0x33, 0x20, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0x04, 0x80, 0x33,
+0x06, 0x10, 0x10, 0x80, 0x33, 0x05, 0x90, 0x88, 0x90, 0x50, 0x90, 0x28,
+0x80, 0x32, 0xe9, 0x80, 0x32, 0xeb, 0x10, 0x10, 0x80, 0x32, 0xea, 0x90,
+0x50, 0x90, 0x28, 0x80, 0x32, 0xcb, 0x80, 0x32, 0xcd, 0x10, 0x10, 0x80,
+0x32, 0xcc, 0xe4, 0xe1, 0x6e, 0x40, 0x35, 0xe1, 0x88, 0x02, 0x28, 0x91,
+0x10, 0x90, 0x88, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0x23, 0x80, 0x33,
+0x25, 0x10, 0x10, 0x80, 0x33, 0x24, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33,
+0x08, 0x80, 0x33, 0x0a, 0x10, 0x10, 0x80, 0x33, 0x09, 0x90, 0x88, 0x90,
+0x50, 0x90, 0x28, 0x80, 0x32, 0xed, 0x80, 0x32, 0xef, 0x10, 0x10, 0x80,
+0x32, 0xee, 0x90, 0x50, 0x90, 0x28, 0x80, 0x32, 0xcf, 0x80, 0x32, 0xd1,
+0x10, 0x10, 0x80, 0x32, 0xd0, 0xe4, 0xe1, 0x4f, 0x40, 0x35, 0x51, 0x90,
+0x40, 0xe5, 0x21, 0x6c, 0x40, 0x35, 0xd9, 0xe5, 0x21, 0x4e, 0x40, 0x35,
+0x4d, 0x9e, 0xb4, 0x22, 0xe8, 0x93, 0x70, 0x91, 0xd8, 0xd5, 0x07, 0x80,
+0xd0, 0xc4, 0x40, 0x90, 0x48, 0x80, 0x8c, 0x3e, 0x38, 0x84, 0x37, 0xd1,
+0xa4, 0x3c, 0x18, 0x37, 0x9b, 0x90, 0x28, 0x24, 0x3b, 0x58, 0xa4, 0x39,
+0xd8, 0x37, 0x53, 0xd0, 0xc4, 0x40, 0x90, 0x48, 0x80, 0x8c, 0x3e, 0x18,
+0x84, 0x37, 0xcf, 0xa4, 0x3c, 0x08, 0x37, 0x99, 0x90, 0x28, 0x24, 0x3b,
+0x48, 0xa4, 0x39, 0xc8, 0x37, 0x51, 0xd5, 0x06, 0x80, 0xd0, 0xc3, 0x40,
+0x90, 0x28, 0x80, 0x37, 0xbb, 0xa4, 0x3b, 0xe8, 0x37, 0x95, 0x90, 0x28,
+0x24, 0x3b, 0x28, 0xa4, 0x39, 0xa8, 0x37, 0x4d, 0xd0, 0xc3, 0x40, 0x90,
+0x28, 0x80, 0x37, 0xb7, 0xa4, 0x3b, 0xd8, 0x37, 0x93, 0x90, 0x28, 0x24,
+0x3b, 0x18, 0xa4, 0x39, 0x98, 0x37, 0x4b, 0x91, 0x98, 0xd5, 0x06, 0x80,
+0xd0, 0xc3, 0x40, 0x90, 0x28, 0x80, 0x37, 0xaf, 0xa4, 0x3b, 0xb8, 0x37,
+0x8f, 0x90, 0x28, 0x24, 0x3a, 0xf8, 0xa4, 0x39, 0x78, 0x37, 0x47, 0xd0,
+0xc3, 0x40, 0x90, 0x28, 0x80, 0x37, 0xab, 0xa4, 0x3b, 0xa8, 0x37, 0x8d,
+0x90, 0x28, 0x24, 0x3a, 0xe8, 0xa4, 0x39, 0x68, 0x37, 0x45, 0xd5, 0x06,
+0x80, 0xd0, 0xc3, 0x40, 0x90, 0x28, 0x80, 0x37, 0xa3, 0xa4, 0x3b, 0x88,
+0x37, 0x89, 0x90, 0x28, 0x24, 0x3a, 0xc8, 0xa4, 0x39, 0x48, 0x37, 0x41,
+0xd0, 0xc3, 0x40, 0x90, 0x28, 0x80, 0x37, 0x9f, 0xa4, 0x3b, 0x78, 0x37,
+0x87, 0x90, 0x28, 0x24, 0x3a, 0xb8, 0xa4, 0x39, 0x38, 0x37, 0x3f, 0x93,
+0x70, 0x91, 0xd8, 0xd5, 0x07, 0x80, 0xd0, 0xc4, 0x40, 0x90, 0x48, 0x80,
+0x8c, 0x3e, 0x58, 0x84, 0x37, 0xd3, 0xa4, 0x3c, 0x28, 0x37, 0x9d, 0x90,
+0x28, 0x24, 0x3b, 0x68, 0xa4, 0x39, 0xe8, 0x37, 0x55, 0xd0, 0xc4, 0x40,
+0x90, 0x48, 0x80, 0x8c, 0x3e, 0x28, 0x84, 0x37, 0xd0, 0xa4, 0x3c, 0x10,
+0x37, 0x9a, 0x90, 0x28, 0x24, 0x3b, 0x50, 0xa4, 0x39, 0xd0, 0x37, 0x52,
+0xd5, 0x06, 0x80, 0xd0, 0xc3, 0x40, 0x90, 0x28, 0x80, 0x37, 0xbf, 0xa4,
+0x3b, 0xf8, 0x37, 0x97, 0x90, 0x28, 0x24, 0x3b, 0x38, 0xa4, 0x39, 0xb8,
+0x37, 0x4f, 0xd0, 0xc3, 0x40, 0x90, 0x28, 0x80, 0x37, 0xb9, 0xa4, 0x3b,
+0xe0, 0x37, 0x94, 0x90, 0x28, 0x24, 0x3b, 0x20, 0xa4, 0x39, 0xa0, 0x37,
+0x4c, 0x91, 0x98, 0xd5, 0x06, 0x80, 0xd0, 0xc3, 0x40, 0x90, 0x28, 0x80,
+0x37, 0xb3, 0xa4, 0x3b, 0xc8, 0x37, 0x91, 0x90, 0x28, 0x24, 0x3b, 0x08,
+0xa4, 0x39, 0x88, 0x37, 0x49, 0xd0, 0xc3, 0x40, 0x90, 0x28, 0x80, 0x37,
+0xad, 0xa4, 0x3b, 0xb0, 0x37, 0x8e, 0x90, 0x28, 0x24, 0x3a, 0xf0, 0xa4,
+0x39, 0x70, 0x37, 0x46, 0xd5, 0x06, 0x80, 0xd0, 0xc3, 0x40, 0x90, 0x28,
+0x80, 0x37, 0xa7, 0xa4, 0x3b, 0x98, 0x37, 0x8b, 0x90, 0x28, 0x24, 0x3a,
+0xd8, 0xa4, 0x39, 0x58, 0x37, 0x43, 0xd0, 0xc3, 0x40, 0x90, 0x28, 0x80,
+0x37, 0xa1, 0xa4, 0x3b, 0x80, 0x37, 0x88, 0x90, 0x28, 0x24, 0x3a, 0xc0,
+0xa4, 0x39, 0x40, 0x37, 0x40, 0x99, 0x08, 0x01, 0xf0, 0x81, 0x90, 0x78,
+0xd4, 0xc2, 0x00, 0xa4, 0x22, 0x80, 0x34, 0x40, 0xa4, 0x21, 0x80, 0x34,
+0x20, 0xd4, 0xc2, 0x00, 0xa4, 0x21, 0xa0, 0x34, 0x44, 0xa4, 0x20, 0xa0,
+0x34, 0x24, 0x81, 0x90, 0x78, 0xd4, 0xc2, 0x00, 0xa4, 0x21, 0xe0, 0x34,
+0x4c, 0xa4, 0x20, 0xe0, 0x34, 0x2c, 0xd4, 0xc2, 0x00, 0xa4, 0x21, 0xc0,
+0x34, 0x48, 0xa4, 0x20, 0xc0, 0x34, 0x28, 0xa8, 0x0b, 0x18, 0x13, 0xa8,
+0x96, 0x80, 0x93, 0x40, 0x99, 0x90, 0x03, 0x00, 0x90, 0xc0, 0x90, 0x60,
+0x90, 0x38, 0xa4, 0x12, 0xb8, 0x32, 0x58, 0x24, 0x12, 0xb0, 0x90, 0x38,
+0xa4, 0x11, 0xe0, 0x32, 0x3d, 0x24, 0x11, 0xd8, 0x90, 0x60, 0x90, 0x38,
+0xa4, 0x11, 0x08, 0x32, 0x22, 0x24, 0x11, 0x00, 0x90, 0x38, 0xa4, 0x10,
+0x30, 0x32, 0x07, 0x24, 0x10, 0x28, 0x90, 0xc0, 0x90, 0x60, 0x90, 0x38,
+0xa4, 0x12, 0xa8, 0x32, 0x53, 0x24, 0x12, 0xa0, 0x90, 0x38, 0xa4, 0x11,
+0xd0, 0x32, 0x38, 0x24, 0x11, 0xc8, 0x90, 0x60, 0x90, 0x38, 0xa4, 0x10,
+0xf8, 0x32, 0x1d, 0x24, 0x10, 0xf0, 0x90, 0x38, 0xa4, 0x10, 0x20, 0x32,
+0x02, 0x24, 0x10, 0x18, 0xe4, 0xe1, 0xc8, 0x40, 0x37, 0x23, 0x99, 0x90,
+0x03, 0x00, 0x90, 0xc0, 0x90, 0x60, 0x90, 0x38, 0xa4, 0x12, 0x90, 0x32,
+0x50, 0x24, 0x12, 0x88, 0x90, 0x38, 0xa4, 0x11, 0xb8, 0x32, 0x35, 0x24,
+0x11, 0xb0, 0x90, 0x60, 0x90, 0x38, 0xa4, 0x10, 0xe0, 0x32, 0x1a, 0x24,
+0x10, 0xd8, 0x90, 0x38, 0xa4, 0x10, 0x08, 0x31, 0xff, 0x24, 0x10, 0x00,
+0x90, 0xc0, 0x90, 0x60, 0x90, 0x38, 0xa4, 0x12, 0x78, 0x32, 0x4d, 0x24,
+0x12, 0x70, 0x90, 0x38, 0xa4, 0x11, 0xa0, 0x32, 0x32, 0x24, 0x11, 0x98,
+0x90, 0x60, 0x90, 0x38, 0xa4, 0x10, 0xc8, 0x32, 0x17, 0x24, 0x10, 0xc0,
+0x90, 0x38, 0xa4, 0x0f, 0xf0, 0x31, 0xfc, 0x24, 0x0f, 0xe8, 0xe4, 0xe1,
+0xc6, 0xc0, 0x37, 0x1d, 0x93, 0x78, 0x99, 0x90, 0x03, 0x00, 0x90, 0xc0,
+0x90, 0x60, 0x90, 0x38, 0xa4, 0x12, 0x60, 0x32, 0x4a, 0x24, 0x12, 0x58,
+0x90, 0x38, 0xa4, 0x11, 0x88, 0x32, 0x2f, 0x24, 0x11, 0x80, 0x90, 0x60,
+0x90, 0x38, 0xa4, 0x10, 0xb0, 0x32, 0x14, 0x24, 0x10, 0xa8, 0x90, 0x38,
+0xa4, 0x0f, 0xd8, 0x31, 0xf9, 0x24, 0x0f, 0xd0, 0x90, 0xc0, 0x90, 0x60,
+0x90, 0x38, 0xa4, 0x12, 0x48, 0x32, 0x47, 0x24, 0x12, 0x40, 0x90, 0x38,
+0xa4, 0x11, 0x70, 0x32, 0x2c, 0x24, 0x11, 0x68, 0x90, 0x60, 0x90, 0x38,
+0xa4, 0x10, 0x98, 0x32, 0x11, 0x24, 0x10, 0x90, 0x90, 0x38, 0xa4, 0x0f,
+0xc0, 0x31, 0xf6, 0x24, 0x0f, 0xb8, 0xec, 0xa1, 0x16, 0x00, 0x02, 0x00,
+0x34, 0x5a, 0xa4, 0x38, 0xa8, 0x37, 0x17, 0x88, 0x00, 0x88, 0x10, 0x10,
+0x10, 0x10, 0x90, 0x38, 0xa4, 0x0f, 0xa8, 0x31, 0xf3, 0x24, 0x0f, 0xa0,
+0xe9, 0x61, 0x15, 0x40, 0x02, 0x00, 0x34, 0x56, 0xe3, 0x61, 0xc3, 0xc0,
+0x37, 0x11, 0x95, 0x08, 0x93, 0x40, 0x99, 0x90, 0x03, 0x00, 0x90, 0xc0,
+0x90, 0x60, 0x90, 0x38, 0xa4, 0x12, 0x30, 0x32, 0x41, 0x24, 0x12, 0x28,
+0x90, 0x38, 0xa4, 0x11, 0x58, 0x32, 0x26, 0x24, 0x11, 0x50, 0x90, 0x60,
+0x90, 0x38, 0xa4, 0x10, 0x80, 0x32, 0x0b, 0x24, 0x10, 0x78, 0x90, 0x38,
+0xa4, 0x0f, 0x90, 0x31, 0xed, 0x24, 0x0f, 0x88, 0x90, 0xc0, 0x90, 0x60,
+0x90, 0x38, 0xa4, 0x12, 0x00, 0x32, 0x3e, 0x24, 0x11, 0xf8, 0x90, 0x38,
+0xa4, 0x11, 0x28, 0x32, 0x23, 0x24, 0x11, 0x20, 0x90, 0x60, 0x90, 0x38,
+0xa4, 0x10, 0x50, 0x32, 0x08, 0x24, 0x10, 0x48, 0x90, 0x38, 0xa4, 0x0f,
+0x60, 0x31, 0xea, 0x24, 0x0f, 0x58, 0xe4, 0xe1, 0xc8, 0x80, 0x37, 0x25,
+0x88, 0x01, 0x88, 0x90, 0xc0, 0x90, 0x60, 0x90, 0x38, 0xa4, 0x12, 0x20,
+0x32, 0x42, 0x24, 0x12, 0x18, 0x90, 0x38, 0xa4, 0x11, 0x48, 0x32, 0x27,
+0x24, 0x11, 0x40, 0x90, 0x60, 0x90, 0x38, 0xa4, 0x10, 0x70, 0x32, 0x0c,
+0x24, 0x10, 0x68, 0x90, 0x38, 0xa4, 0x0f, 0x80, 0x31, 0xee, 0x24, 0x0f,
+0x78, 0xe4, 0xe1, 0xc7, 0x00, 0x37, 0x1f, 0x92, 0xd0, 0x99, 0x50, 0x02,
+0x80, 0x90, 0xa0, 0x90, 0x50, 0x90, 0x28, 0x80, 0x31, 0xe9, 0x24, 0x0f,
+0x40, 0x90, 0x28, 0x80, 0x31, 0xe5, 0x24, 0x0f, 0x20, 0x90, 0x50, 0x90,
+0x28, 0x80, 0x31, 0xe1, 0x24, 0x0f, 0x00, 0x90, 0x28, 0x80, 0x31, 0xdd,
+0x24, 0x0e, 0xe0, 0x90, 0xa0, 0x90, 0x50, 0x90, 0x28, 0x80, 0x31, 0xe6,
+0x24, 0x0f, 0x38, 0x90, 0x28, 0x80, 0x31, 0xe2, 0x24, 0x0f, 0x18, 0x90,
+0x50, 0x90, 0x28, 0x80, 0x31, 0xde, 0x24, 0x0e, 0xf8, 0x90, 0x28, 0x80,
+0x31, 0xda, 0x24, 0x0e, 0xd8, 0xec, 0xe1, 0xc5, 0xa1, 0x17, 0x00, 0x37,
+0x19, 0x88, 0x00, 0x78, 0x10, 0x10, 0x10, 0x10, 0x90, 0x28, 0x80, 0x31,
+0xd8, 0x24, 0x0e, 0xc8, 0xec, 0xe1, 0xc4, 0x21, 0x15, 0x00, 0x37, 0x13,
+0xe5, 0xa1, 0x4d, 0x40, 0x35, 0x31, 0xa0, 0x2a, 0x10, 0xa8, 0x16, 0x60,
+0x29, 0xd8, 0xa0, 0x0c, 0x48, 0xa0, 0x0a, 0xc8, 0x95, 0x60, 0x92, 0xb0,
+0x91, 0x40, 0x90, 0x88, 0x90, 0x50, 0x90, 0x28, 0x80, 0x31, 0xa1, 0x80,
+0x31, 0xa0, 0x10, 0x10, 0x80, 0x31, 0x9f, 0x90, 0x70, 0x90, 0x38, 0xa4,
+0x08, 0x98, 0x31, 0xb3, 0xa4, 0x08, 0x90, 0x31, 0xb2, 0x10, 0x10, 0xa4,
+0x08, 0x88, 0x31, 0xb1, 0x90, 0xb8, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x09,
+0xb8, 0x31, 0xd7, 0xa4, 0x09, 0xb0, 0x31, 0xd6, 0x10, 0x10, 0xa4, 0x09,
+0xa8, 0x31, 0xd5, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x09, 0x28, 0x31, 0xc5,
+0xa4, 0x09, 0x20, 0x31, 0xc4, 0x10, 0x10, 0xa4, 0x09, 0x18, 0x31, 0xc3,
+0x91, 0x40, 0x90, 0x88, 0x90, 0x50, 0x90, 0x28, 0x80, 0x31, 0x9c, 0x80,
+0x31, 0x9e, 0x10, 0x10, 0x80, 0x31, 0x9d, 0x90, 0x70, 0x90, 0x38, 0xa4,
+0x08, 0x70, 0x31, 0xae, 0xa4, 0x08, 0x80, 0x31, 0xb0, 0x10, 0x10, 0xa4,
+0x08, 0x78, 0x31, 0xaf, 0x90, 0xb8, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x09,
+0x90, 0x31, 0xd2, 0xa4, 0x09, 0xa0, 0x31, 0xd4, 0x10, 0x10, 0xa4, 0x09,
+0x98, 0x31, 0xd3, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x09, 0x00, 0x31, 0xc0,
+0xa4, 0x09, 0x10, 0x31, 0xc2, 0x10, 0x10, 0xa4, 0x09, 0x08, 0x31, 0xc1,
+0x92, 0xb0, 0x91, 0x40, 0x90, 0x88, 0x90, 0x50, 0x90, 0x28, 0x80, 0x31,
+0x99, 0x80, 0x31, 0x9b, 0x10, 0x10, 0x80, 0x31, 0x9a, 0x90, 0x70, 0x90,
+0x38, 0xa4, 0x08, 0x58, 0x31, 0xab, 0xa4, 0x08, 0x68, 0x31, 0xad, 0x10,
+0x10, 0xa4, 0x08, 0x60, 0x31, 0xac, 0x90, 0xb8, 0x90, 0x70, 0x90, 0x38,
+0xa4, 0x09, 0x78, 0x31, 0xcf, 0xa4, 0x09, 0x88, 0x31, 0xd1, 0x10, 0x10,
+0xa4, 0x09, 0x80, 0x31, 0xd0, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x08, 0xe8,
+0x31, 0xbd, 0xa4, 0x08, 0xf8, 0x31, 0xbf, 0x10, 0x10, 0xa4, 0x08, 0xf0,
+0x31, 0xbe, 0x91, 0x40, 0x90, 0x88, 0x90, 0x50, 0x90, 0x28, 0x80, 0x31,
+0x96, 0x80, 0x31, 0x98, 0x10, 0x10, 0x80, 0x31, 0x97, 0x90, 0x70, 0x90,
+0x38, 0xa4, 0x08, 0x40, 0x31, 0xa8, 0xa4, 0x08, 0x50, 0x31, 0xaa, 0x10,
+0x10, 0xa4, 0x08, 0x48, 0x31, 0xa9, 0x90, 0xb8, 0x90, 0x70, 0x90, 0x38,
+0xa4, 0x09, 0x60, 0x31, 0xcc, 0xa4, 0x09, 0x70, 0x31, 0xce, 0x10, 0x10,
+0xa4, 0x09, 0x68, 0x31, 0xcd, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x08, 0xd0,
+0x31, 0xba, 0xa4, 0x08, 0xe0, 0x31, 0xbc, 0x10, 0x10, 0xa4, 0x08, 0xd8,
+0x31, 0xbb, 0x10, 0x10, 0x90, 0xa8, 0x10, 0x10, 0x10, 0x10, 0x90, 0x50,
+0x90, 0x28, 0x80, 0x31, 0x8d, 0x80, 0x31, 0x8f, 0x10, 0x10, 0x80, 0x31,
+0x8e, 0x90, 0x60, 0x90, 0x30, 0x60, 0xa0, 0x2a, 0xc0, 0x60, 0xa0, 0x2a,
+0x80, 0x90, 0x30, 0x60, 0xa0, 0x2a, 0x40, 0x60, 0xa0, 0x2a, 0x00, 0x97,
+0xf0, 0x95, 0x60, 0x92, 0xb0, 0x91, 0x40, 0x90, 0x88, 0x90, 0x50, 0x90,
+0x28, 0x80, 0x31, 0x93, 0x80, 0x31, 0x95, 0x10, 0x10, 0x80, 0x31, 0x94,
+0x90, 0x70, 0x90, 0x38, 0xa4, 0x08, 0x28, 0x31, 0xa5, 0xa4, 0x08, 0x38,
+0x31, 0xa7, 0x10, 0x10, 0xa4, 0x08, 0x30, 0x31, 0xa6, 0x90, 0xb8, 0x90,
+0x70, 0x90, 0x38, 0xa4, 0x09, 0x48, 0x31, 0xc9, 0xa4, 0x09, 0x58, 0x31,
+0xcb, 0x10, 0x10, 0xa4, 0x09, 0x50, 0x31, 0xca, 0x90, 0x70, 0x90, 0x38,
+0xa4, 0x08, 0xb8, 0x31, 0xb7, 0xa4, 0x08, 0xc8, 0x31, 0xb9, 0x10, 0x10,
+0xa4, 0x08, 0xc0, 0x31, 0xb8, 0x91, 0x40, 0x90, 0x88, 0x90, 0x50, 0x90,
+0x28, 0x80, 0x31, 0x90, 0x80, 0x31, 0x92, 0x10, 0x10, 0x80, 0x31, 0x91,
+0x90, 0x70, 0x90, 0x38, 0xa4, 0x08, 0x10, 0x31, 0xa2, 0xa4, 0x08, 0x20,
+0x31, 0xa4, 0x10, 0x10, 0xa4, 0x08, 0x18, 0x31, 0xa3, 0x90, 0xb8, 0x90,
+0x70, 0x90, 0x38, 0xa4, 0x09, 0x30, 0x31, 0xc6, 0xa4, 0x09, 0x40, 0x31,
+0xc8, 0x10, 0x10, 0xa4, 0x09, 0x38, 0x31, 0xc7, 0x90, 0x70, 0x90, 0x38,
+0xa4, 0x08, 0xa0, 0x31, 0xb4, 0xa4, 0x08, 0xb0, 0x31, 0xb6, 0x10, 0x10,
+0xa4, 0x08, 0xa8, 0x31, 0xb5, 0x10, 0x10, 0x91, 0x40, 0x90, 0xa0, 0x90,
+0x50, 0x90, 0x28, 0x80, 0x30, 0xcb, 0x80, 0x30, 0xca, 0x90, 0x28, 0x80,
+0x30, 0xc9, 0x80, 0x30, 0xc8, 0x90, 0x50, 0x90, 0x28, 0x80, 0x30, 0xc4,
+0x80, 0x30, 0xc7, 0x90, 0x28, 0x80, 0x30, 0xc6, 0x80, 0x30, 0xc5, 0x90,
+0xa0, 0x90, 0x50, 0x90, 0x28, 0x80, 0x30, 0xbc, 0x80, 0x30, 0xc3, 0x90,
+0x28, 0x80, 0x30, 0xc2, 0x80, 0x30, 0xc1, 0x90, 0x50, 0x90, 0x28, 0x80,
+0x30, 0xbd, 0x80, 0x30, 0xc0, 0x90, 0x28, 0x80, 0x30, 0xbf, 0x80, 0x30,
+0xbe, 0x91, 0x88, 0x80, 0x90, 0xc0, 0x90, 0x60, 0x90, 0x28, 0x81, 0x31,
+0x3b, 0x10, 0x10, 0x80, 0x31, 0x3a, 0x90, 0x28, 0x81, 0x31, 0x3d, 0x10,
+0x10, 0x80, 0x31, 0x3c, 0x90, 0x60, 0x90, 0x28, 0x81, 0x31, 0x41, 0x10,
+0x10, 0x80, 0x31, 0x40, 0x90, 0x28, 0x81, 0x31, 0x3f, 0x10, 0x10, 0x80,
+0x31, 0x3e, 0x80, 0x10, 0x10, 0x10, 0x10, 0x90, 0x28, 0x81, 0x31, 0x38,
+0x10, 0x10, 0x80, 0x31, 0x39, 0xa0, 0x0b, 0x90, 0xa0, 0x0a, 0xc8, 0x95,
+0x60, 0x92, 0xb0, 0x91, 0x40, 0x90, 0x88, 0x90, 0x50, 0x90, 0x28, 0x80,
+0x31, 0x56, 0x80, 0x31, 0x55, 0x10, 0x10, 0x80, 0x31, 0x54, 0x90, 0x70,
+0x90, 0x38, 0xa4, 0x06, 0xe8, 0x31, 0x68, 0xa4, 0x06, 0xe0, 0x31, 0x67,
+0x10, 0x10, 0xa4, 0x06, 0xd8, 0x31, 0x66, 0x90, 0xb8, 0x90, 0x70, 0x90,
+0x38, 0xa4, 0x08, 0x08, 0x31, 0x8c, 0xa4, 0x08, 0x00, 0x31, 0x8b, 0x10,
+0x10, 0xa4, 0x07, 0xf8, 0x31, 0x8a, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x07,
+0x78, 0x31, 0x7a, 0xa4, 0x07, 0x70, 0x31, 0x79, 0x10, 0x10, 0xa4, 0x07,
+0x68, 0x31, 0x78, 0x91, 0x40, 0x90, 0x88, 0x90, 0x50, 0x90, 0x28, 0x80,
+0x31, 0x51, 0x80, 0x31, 0x53, 0x10, 0x10, 0x80, 0x31, 0x52, 0x90, 0x70,
+0x90, 0x38, 0xa4, 0x06, 0xc0, 0x31, 0x63, 0xa4, 0x06, 0xd0, 0x31, 0x65,
+0x10, 0x10, 0xa4, 0x06, 0xc8, 0x31, 0x64, 0x90, 0xb8, 0x90, 0x70, 0x90,
+0x38, 0xa4, 0x07, 0xe0, 0x31, 0x87, 0xa4, 0x07, 0xf0, 0x31, 0x89, 0x10,
+0x10, 0xa4, 0x07, 0xe8, 0x31, 0x88, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x07,
+0x50, 0x31, 0x75, 0xa4, 0x07, 0x60, 0x31, 0x77, 0x10, 0x10, 0xa4, 0x07,
+0x58, 0x31, 0x76, 0x92, 0xb0, 0x91, 0x40, 0x90, 0x88, 0x90, 0x50, 0x90,
+0x28, 0x80, 0x31, 0x4e, 0x80, 0x31, 0x50, 0x10, 0x10, 0x80, 0x31, 0x4f,
+0x90, 0x70, 0x90, 0x38, 0xa4, 0x06, 0xa8, 0x31, 0x60, 0xa4, 0x06, 0xb8,
+0x31, 0x62, 0x10, 0x10, 0xa4, 0x06, 0xb0, 0x31, 0x61, 0x90, 0xb8, 0x90,
+0x70, 0x90, 0x38, 0xa4, 0x07, 0xc8, 0x31, 0x84, 0xa4, 0x07, 0xd8, 0x31,
+0x86, 0x10, 0x10, 0xa4, 0x07, 0xd0, 0x31, 0x85, 0x90, 0x70, 0x90, 0x38,
+0xa4, 0x07, 0x38, 0x31, 0x72, 0xa4, 0x07, 0x48, 0x31, 0x74, 0x10, 0x10,
+0xa4, 0x07, 0x40, 0x31, 0x73, 0x91, 0x40, 0x90, 0x88, 0x90, 0x50, 0x90,
+0x28, 0x80, 0x31, 0x4b, 0x80, 0x31, 0x4d, 0x10, 0x10, 0x80, 0x31, 0x4c,
+0x90, 0x70, 0x90, 0x38, 0xa4, 0x06, 0x90, 0x31, 0x5d, 0xa4, 0x06, 0xa0,
+0x31, 0x5f, 0x10, 0x10, 0xa4, 0x06, 0x98, 0x31, 0x5e, 0x90, 0xb8, 0x90,
+0x70, 0x90, 0x38, 0xa4, 0x07, 0xb0, 0x31, 0x81, 0xa4, 0x07, 0xc0, 0x31,
+0x83, 0x10, 0x10, 0xa4, 0x07, 0xb8, 0x31, 0x82, 0x90, 0x70, 0x90, 0x38,
+0xa4, 0x07, 0x20, 0x31, 0x6f, 0xa4, 0x07, 0x30, 0x31, 0x71, 0x10, 0x10,
+0xa4, 0x07, 0x28, 0x31, 0x70, 0x10, 0x10, 0x80, 0x10, 0x10, 0x10, 0x10,
+0x90, 0x50, 0x90, 0x28, 0x80, 0x31, 0x42, 0x80, 0x31, 0x44, 0x10, 0x10,
+0x80, 0x31, 0x43, 0x80, 0x95, 0x60, 0x92, 0xb0, 0x91, 0x40, 0x90, 0x88,
+0x90, 0x50, 0x90, 0x28, 0x80, 0x31, 0x48, 0x80, 0x31, 0x4a, 0x10, 0x10,
+0x80, 0x31, 0x49, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x06, 0x78, 0x31, 0x5a,
+0xa4, 0x06, 0x88, 0x31, 0x5c, 0x10, 0x10, 0xa4, 0x06, 0x80, 0x31, 0x5b,
+0x90, 0xb8, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x07, 0x98, 0x31, 0x7e, 0xa4,
+0x07, 0xa8, 0x31, 0x80, 0x10, 0x10, 0xa4, 0x07, 0xa0, 0x31, 0x7f, 0x90,
+0x70, 0x90, 0x38, 0xa4, 0x07, 0x08, 0x31, 0x6c, 0xa4, 0x07, 0x18, 0x31,
+0x6e, 0x10, 0x10, 0xa4, 0x07, 0x10, 0x31, 0x6d, 0x91, 0x40, 0x90, 0x88,
+0x90, 0x50, 0x90, 0x28, 0x80, 0x31, 0x45, 0x80, 0x31, 0x47, 0x10, 0x10,
+0x80, 0x31, 0x46, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x06, 0x60, 0x31, 0x57,
+0xa4, 0x06, 0x70, 0x31, 0x59, 0x10, 0x10, 0xa4, 0x06, 0x68, 0x31, 0x58,
+0x90, 0xb8, 0x90, 0x70, 0x90, 0x38, 0xa4, 0x07, 0x80, 0x31, 0x7b, 0xa4,
+0x07, 0x90, 0x31, 0x7d, 0x10, 0x10, 0xa4, 0x07, 0x88, 0x31, 0x7c, 0x90,
+0x70, 0x90, 0x38, 0xa4, 0x06, 0xf0, 0x31, 0x69, 0xa4, 0x07, 0x00, 0x31,
+0x6b, 0x10, 0x10, 0xa4, 0x06, 0xf8, 0x31, 0x6a, 0x10, 0x10, 0x91, 0x40,
+0x90, 0xa0, 0x90, 0x50, 0x90, 0x28, 0x80, 0x30, 0xbb, 0x80, 0x30, 0xba,
+0x90, 0x28, 0x80, 0x30, 0xb9, 0x80, 0x30, 0xb8, 0x90, 0x50, 0x90, 0x28,
+0x80, 0x30, 0xb4, 0x80, 0x30, 0xb7, 0x90, 0x28, 0x80, 0x30, 0xb6, 0x80,
+0x30, 0xb5, 0x90, 0xa0, 0x90, 0x50, 0x90, 0x28, 0x80, 0x30, 0xac, 0x80,
+0x30, 0xb3, 0x90, 0x28, 0x80, 0x30, 0xb2, 0x80, 0x30, 0xb1, 0x90, 0x50,
+0x90, 0x28, 0x80, 0x30, 0xad, 0x80, 0x30, 0xb0, 0x90, 0x28, 0x80, 0x30,
+0xaf, 0x80, 0x30, 0xae, 0xc3, 0xc0, 0x30, 0x42, 0x9c, 0xe8, 0x07, 0x60,
+0x91, 0x90, 0x90, 0xf0, 0x10, 0x10, 0x80, 0x88, 0x00, 0x80, 0x90, 0x50,
+0x90, 0x28, 0x80, 0x33, 0xf8, 0x80, 0x33, 0xf9, 0x81, 0x33, 0xef, 0xd0,
+0x41, 0x80, 0x24, 0x20, 0x90, 0x24, 0x20, 0x98, 0x10, 0x10, 0x80, 0x90,
+0x58, 0x80, 0x90, 0x28, 0x24, 0x1f, 0x90, 0x24, 0x1f, 0x98, 0x81, 0x24,
+0x1f, 0x50, 0x92, 0x68, 0x91, 0x00, 0x80, 0x90, 0x90, 0x90, 0x30, 0x80,
+0x24, 0x20, 0x00, 0x90, 0x38, 0xa4, 0x1f, 0xf8, 0x34, 0x06, 0x80, 0x34,
+0x05, 0x80, 0x90, 0x28, 0x80, 0x34, 0x0f, 0xa4, 0x1f, 0xe0, 0x34, 0x0e,
+0x80, 0x90, 0xc0, 0x90, 0x60, 0x90, 0x28, 0x80, 0x34, 0x09, 0xa4, 0x1f,
+0xf0, 0x34, 0x08, 0x90, 0x28, 0x80, 0x34, 0x04, 0xa4, 0x1f, 0xe8, 0x34,
+0x03, 0x90, 0x50, 0x90, 0x28, 0x80, 0x34, 0x0d, 0x80, 0x34, 0x0c, 0x90,
+0x28, 0x24, 0x20, 0x88, 0x24, 0x20, 0x80, 0x90, 0x58, 0x80, 0x10, 0x10,
+0x80, 0x10, 0x10, 0x80, 0x33, 0xfb, 0x80, 0x90, 0x40, 0x10, 0x10, 0x80,
+0x24, 0x1f, 0x60, 0x80, 0x10, 0x10, 0x80, 0x33, 0xfa, 0x91, 0x58, 0x91,
+0x00, 0x90, 0x80, 0x81, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33, 0xf6, 0x80,
+0x33, 0xf7, 0x81, 0x33, 0xee, 0x81, 0x90, 0x50, 0x90, 0x28, 0x80, 0x33,
+0xf4, 0x80, 0x33, 0xf5, 0x81, 0x33, 0xed, 0x83, 0x90, 0x28, 0x24, 0x1f,
+0x80, 0x24, 0x1f, 0x88, 0x90, 0xe8, 0x81, 0x90, 0x88, 0x90, 0x38, 0x10,
+0x10, 0x80, 0x34, 0x07, 0x90, 0x28, 0x80, 0x34, 0x02, 0x80, 0x34, 0x01,
+0x80, 0x90, 0x28, 0x80, 0x34, 0x0b, 0x80, 0x34, 0x0a, 0x82, 0x10, 0x10,
+0x80, 0x24, 0x1f, 0x58, 0x97, 0x10, 0x9e, 0x10, 0x06, 0x98, 0x93, 0x00,
+0x91, 0x80, 0x90, 0xc0, 0x90, 0x60, 0x90, 0x38, 0xa4, 0x03, 0x80, 0x30,
+0x71, 0x24, 0x03, 0x78, 0x90, 0x38, 0xa4, 0x04, 0x10, 0x30, 0x83, 0x24,
+0x04, 0x08, 0x90, 0x60, 0x90, 0x38, 0xa4, 0x05, 0x30, 0x30, 0xa7, 0x24,
+0x05, 0x28, 0x90, 0x38, 0xa4, 0x04, 0xa0, 0x30, 0x95, 0x24, 0x04, 0x98,
+0x90, 0xc0, 0x90, 0x60, 0x90, 0x38, 0xa4, 0x03, 0x70, 0x30, 0x6c, 0x24,
+0x03, 0x68, 0x90, 0x38, 0xa4, 0x04, 0x00, 0x30, 0x7e, 0x24, 0x03, 0xf8,
+0x90, 0x60, 0x90, 0x38, 0xa4, 0x05, 0x20, 0x30, 0xa2, 0x24, 0x05, 0x18,
+0x90, 0x38, 0xa4, 0x04, 0x90, 0x30, 0x90, 0x24, 0x04, 0x88, 0x91, 0x80,
+0x90, 0xc0, 0x90, 0x60, 0x90, 0x38, 0xa4, 0x03, 0x58, 0x30, 0x69, 0x24,
+0x03, 0x50, 0x90, 0x38, 0xa4, 0x03, 0xe8, 0x30, 0x7b, 0x24, 0x03, 0xe0,
+0x90, 0x60, 0x90, 0x38, 0xa4, 0x05, 0x08, 0x30, 0x9f, 0x24, 0x05, 0x00,
+0x90, 0x38, 0xa4, 0x04, 0x78, 0x30, 0x8d, 0x24, 0x04, 0x70, 0x90, 0xc0,
+0x90, 0x60, 0x90, 0x38, 0xa4, 0x03, 0x40, 0x30, 0x66, 0x24, 0x03, 0x38,
+0x90, 0x38, 0xa4, 0x03, 0xd0, 0x30, 0x78, 0x24, 0x03, 0xc8, 0x90, 0x60,
+0x90, 0x38, 0xa4, 0x04, 0xf0, 0x30, 0x9c, 0x24, 0x04, 0xe8, 0x90, 0x38,
+0xa4, 0x04, 0x60, 0x30, 0x8a, 0x24, 0x04, 0x58, 0x10, 0x10, 0x80, 0x10,
+0x10, 0x10, 0x10, 0x90, 0x38, 0xa4, 0x02, 0xf8, 0x30, 0x5d, 0x24, 0x02,
+0xf0, 0xd7, 0x42, 0x00, 0xa4, 0x38, 0x58, 0x37, 0x0d, 0xa4, 0x38, 0x38,
+0x37, 0x09, 0x9c, 0xe0, 0x06, 0x90, 0x93, 0x00, 0x91, 0x80, 0x90, 0xc0,
+0x90, 0x60, 0x90, 0x38, 0xa4, 0x03, 0x28, 0x30, 0x63, 0x24, 0x03, 0x20,
+0x90, 0x38, 0xa4, 0x03, 0xb8, 0x30, 0x75, 0x24, 0x03, 0xb0, 0x90, 0x60,
+0x90, 0x38, 0xa4, 0x04, 0xd8, 0x30, 0x99, 0x24, 0x04, 0xd0, 0x90, 0x38,
+0xa4, 0x04, 0x48, 0x30, 0x87, 0x24, 0x04, 0x40, 0x90, 0xc0, 0x90, 0x60,
+0x90, 0x38, 0xa4, 0x03, 0x10, 0x30, 0x60, 0x24, 0x03, 0x08, 0x90, 0x38,
+0xa4, 0x03, 0xa0, 0x30, 0x72, 0x24, 0x03, 0x98, 0x90, 0x60, 0x90, 0x38,
+0xa4, 0x04, 0xc0, 0x30, 0x96, 0x24, 0x04, 0xb8, 0x90, 0x38, 0xa4, 0x04,
+0x30, 0x30, 0x84, 0x24, 0x04, 0x28, 0x10, 0x10, 0x90, 0xe0, 0x90, 0x70,
+0x90, 0x38, 0xa4, 0x02, 0x88, 0x30, 0x52, 0xa4, 0x02, 0x78, 0x30, 0x50,
+0x90, 0x38, 0xa4, 0x02, 0x70, 0x30, 0x4b, 0xa4, 0x02, 0x60, 0x30, 0x4d,
+0x90, 0x70, 0x90, 0x38, 0xa4, 0x02, 0x50, 0x30, 0x43, 0xa4, 0x02, 0x40,
+0x30, 0x49, 0x90, 0x38, 0xa4, 0x02, 0x38, 0x30, 0x44, 0xa4, 0x02, 0x28,
+0x30, 0x46, 0x91, 0x48, 0x80, 0x90, 0xa0, 0x90, 0x50, 0x90, 0x28, 0x80,
+0x30, 0x56, 0x24, 0x02, 0xa8, 0x90, 0x28, 0x80, 0x30, 0x58, 0x24, 0x02,
+0xb8, 0x90, 0x50, 0x90, 0x28, 0x80, 0x30, 0x5c, 0x24, 0x02, 0xd8, 0x90,
+0x28, 0x80, 0x30, 0x5a, 0x24, 0x02, 0xc8, 0x80, 0x10, 0x10, 0x10, 0x10,
+0x90, 0x28, 0x80, 0x30, 0x53, 0x24, 0x02, 0xa0, 0xd7, 0x42, 0x00, 0xa4,
+0x38, 0x60, 0x37, 0x0e, 0xa4, 0x38, 0x40, 0x37, 0x0a, 0xa0, 0x14, 0x68,
+0xa0, 0x10, 0x90, 0xa0, 0x0c, 0x60, 0x9e, 0x88, 0x09, 0xd0, 0x94, 0xf0,
+0x90, 0xb0, 0x88, 0x00, 0x68, 0x84, 0x10, 0x10, 0xc9, 0xe1, 0x44, 0x40,
+0x85, 0x35, 0x2d, 0xcb, 0x61, 0x3d, 0x00, 0x85, 0x35, 0x03, 0x9a, 0x00,
+0x03, 0xf8, 0x91, 0x98, 0x80, 0x91, 0x10, 0x90, 0xa0, 0x90, 0x68, 0x90,
+0x20, 0x3a, 0x53, 0xc9, 0xe2, 0x94, 0x40, 0x85, 0x35, 0x2b, 0xa4, 0x52,
+0x78, 0x3a, 0x50, 0x90, 0x38, 0xa4, 0x52, 0x40, 0x3a, 0x49, 0xa4, 0x52,
+0x30, 0x3a, 0x47, 0x90, 0x48, 0x10, 0x10, 0xa4, 0x51, 0xf8, 0x3a, 0x40,
+0x10, 0x10, 0x80, 0x3a, 0x3c, 0x81, 0x10, 0x10, 0x80, 0xa4, 0x51, 0xc8,
+0x3a, 0x3a, 0x91, 0xb0, 0x91, 0x60, 0x90, 0xe0, 0x90, 0x70, 0x90, 0x38,
+0xa4, 0x52, 0x68, 0x3a, 0x4e, 0xa4, 0x52, 0x58, 0x3a, 0x4c, 0x90, 0x38,
+0xa4, 0x52, 0x20, 0x3a, 0x45, 0xa4, 0x52, 0x10, 0x3a, 0x43, 0x90, 0x48,
+0x10, 0x10, 0xa4, 0x51, 0xe8, 0x3a, 0x3e, 0x10, 0x10, 0x80, 0x3a, 0x3b,
+0x90, 0x28, 0x80, 0x3a, 0x34, 0x80, 0x3a, 0x33, 0x81, 0x10, 0x10, 0x80,
+0xa4, 0x51, 0xb8, 0x3a, 0x38, 0xcb, 0x61, 0x3c, 0xc0, 0x85, 0x35, 0x02,
+0x90, 0xd8, 0x88, 0x00, 0x90, 0x84, 0x90, 0x38, 0xc1, 0xc0, 0x85, 0x3a,
+0x56, 0xc9, 0xe1, 0x44, 0x00, 0x85, 0x35, 0x29, 0xcb, 0x61, 0x3c, 0x80,
+0x85, 0x35, 0x01, 0x88, 0x00, 0x68, 0x84, 0x10, 0x10, 0xc9, 0xe1, 0x43,
+0xc0, 0x85, 0x35, 0x27, 0xcb, 0x61, 0x3c, 0x40, 0x85, 0x35, 0x00, 0x91,
+0xf8, 0x90, 0xb0, 0x88, 0x00, 0x68, 0x84, 0x10, 0x10, 0xc9, 0xe1, 0x43,
+0x40, 0x85, 0x35, 0x23, 0xcb, 0x61, 0x3b, 0xc0, 0x85, 0x34, 0xfe, 0x88,
+0x01, 0x00, 0x90, 0xa0, 0x81, 0x90, 0x70, 0x80, 0x90, 0x20, 0x3a, 0x4a,
+0xc9, 0xe1, 0x43, 0x00, 0x85, 0x35, 0x21, 0x81, 0x3a, 0x41, 0x81, 0x10,
+0x10, 0x80, 0xa4, 0x51, 0xa8, 0x3a, 0x36, 0xcb, 0x61, 0x3b, 0x80, 0x85,
+0x34, 0xfd, 0x90, 0xb0, 0x88, 0x00, 0x68, 0x84, 0x10, 0x10, 0xc9, 0xe1,
+0x42, 0xc0, 0x85, 0x35, 0x1f, 0xcb, 0x61, 0x3b, 0x40, 0x85, 0x34, 0xfc,
+0x88, 0x00, 0x68, 0x84, 0x10, 0x10, 0xc9, 0xe1, 0x42, 0x80, 0x85, 0x35,
+0x1d, 0xcb, 0x61, 0x3b, 0x00, 0x85, 0x34, 0xfb, 0x92, 0x38, 0x81, 0x91,
+0x68, 0x91, 0x18, 0x90, 0x80, 0x90, 0x40, 0x80, 0xa4, 0x53, 0x28, 0x3a,
+0x66, 0x80, 0xa4, 0x53, 0x20, 0x3a, 0x63, 0x90, 0x28, 0x81, 0x3a, 0x62,
+0x90, 0x38, 0xa4, 0x53, 0x00, 0x3a, 0x61, 0xa4, 0x52, 0xf0, 0x3a, 0x5f,
+0x90, 0x28, 0x80, 0x3a, 0x5d, 0x80, 0x3a, 0x5c, 0x80, 0x90, 0x40, 0x10,
+0x10, 0x80, 0x24, 0x52, 0xd8, 0x10, 0x10, 0x90, 0x38, 0xa4, 0x52, 0xc8,
+0x3a, 0x5a, 0xa4, 0x52, 0xb8, 0x3a, 0x58, 0x90, 0x28, 0x80, 0x3a, 0x55,
+0x80, 0x3a, 0x54, 0x9a, 0xd0, 0x03, 0xe0, 0x91, 0x60, 0x90, 0xb0, 0x88,
+0x00, 0x68, 0x84, 0x10, 0x10, 0xc9, 0xe1, 0x42, 0x00, 0x85, 0x35, 0x19,
+0xcb, 0x61, 0x3a, 0x80, 0x85, 0x34, 0xf9, 0x88, 0x00, 0x68, 0x84, 0x10,
+0x10, 0xc9, 0xe1, 0x41, 0xc0, 0x85, 0x35, 0x17, 0xcb, 0x61, 0x3a, 0x40,
+0x85, 0x34, 0xf8, 0x90, 0xb0, 0x88, 0x00, 0x68, 0x84, 0x10, 0x10, 0xc9,
+0xe1, 0x41, 0x80, 0x85, 0x35, 0x15, 0xcb, 0x61, 0x3a, 0x00, 0x85, 0x34,
+0xf7, 0x88, 0x00, 0x68, 0x84, 0x10, 0x10, 0xc9, 0xe1, 0x41, 0x40, 0x85,
+0x35, 0x13, 0xcb, 0x61, 0x39, 0xc0, 0x85, 0x34, 0xf6, 0x90, 0x90, 0x90,
+0x48, 0xcb, 0xa1, 0x38, 0x00, 0x85, 0x34, 0xe5, 0xcb, 0xa1, 0x37, 0xc0,
+0x85, 0x34, 0xe4, 0x90, 0x48, 0xcb, 0xa1, 0x37, 0x80, 0x85, 0x34, 0xe3,
+0xcb, 0xa1, 0x37, 0x40, 0x85, 0x34, 0xe2, 0xcb, 0xa2, 0x8c, 0x40, 0x80,
+0x3a, 0x32, 0x92, 0x40, 0x91, 0x20, 0x90, 0x90, 0x90, 0x48, 0x8c, 0x26,
+0x60, 0x84, 0x24, 0x26, 0xd8, 0x8c, 0x26, 0x58, 0x84, 0x24, 0x26, 0xd0,
+0x90, 0x48, 0x8c, 0x26, 0x50, 0x84, 0x24, 0x26, 0xc8, 0x8c, 0x26, 0x48,
+0x84, 0x24, 0x26, 0xc0, 0x90, 0x90, 0x90, 0x48, 0x8c, 0x26, 0x38, 0x84,
+0x24, 0x26, 0xb0, 0x8c, 0x26, 0x30, 0x84, 0x24, 0x26, 0xa8, 0x90, 0x48,
+0x8c, 0x26, 0x28, 0x84, 0x24, 0x26, 0xa0, 0x8c, 0x26, 0x20, 0x84, 0x24,
+0x26, 0x98, 0x91, 0x20, 0x90, 0x90, 0x90, 0x48, 0x8c, 0x26, 0x10, 0x84,
+0x24, 0x26, 0x88, 0x8c, 0x26, 0x08, 0x84, 0x24, 0x26, 0x80, 0x90, 0x48,
+0x8c, 0x26, 0x00, 0x84, 0x24, 0x26, 0x78, 0x8c, 0x25, 0xf8, 0x84, 0x24,
+0x26, 0x70, 0x90, 0x38, 0xa4, 0x25, 0xe0, 0x34, 0xbd, 0xa4, 0x25, 0xd0,
+0x34, 0xbb, 0xa0, 0x0f, 0x50, 0xa0, 0x09, 0x08, 0x9a, 0x30, 0x04, 0x40,
+0x91, 0x90, 0x90, 0xc8, 0x98, 0x50, 0x00, 0x80, 0xe5, 0x22, 0x8a, 0x40,
+0x3a, 0x21, 0xe5, 0x22, 0x82, 0x40, 0x3a, 0x1d, 0xcb, 0x61, 0x2a, 0x40,
+0x85, 0x34, 0xb8, 0x98, 0x50, 0x00, 0x80, 0xe5, 0x22, 0x7a, 0x40, 0x39,
+0xe1, 0xe5, 0x22, 0x72, 0x40, 0x39, 0xdd, 0xcb, 0x61, 0x2a, 0x00, 0x85,
+0x34, 0xb7, 0x90, 0x48, 0xcb, 0xa1, 0x29, 0xc0, 0x85, 0x34, 0xb6, 0xcb,
+0xa1, 0x29, 0x80, 0x85, 0x34, 0xb5, 0x91, 0x90, 0x90, 0xc8, 0x98, 0x50,
+0x00, 0x80, 0xe5, 0x22, 0x64, 0x40, 0x39, 0xa9, 0xe5, 0x22, 0x58, 0x40,
+0x39, 0x79, 0xcb, 0x61, 0x29, 0x00, 0x85, 0x34, 0xb3, 0x98, 0x50, 0x00,
+0x80, 0xe5, 0x22, 0x4c, 0x40, 0x39, 0x49, 0xe5, 0x22, 0x40, 0x40, 0x39,
+0x19, 0xcb, 0x61, 0x28, 0xc0, 0x85, 0x34, 0xb2, 0x90, 0x48, 0xcb, 0xa1,
+0x28, 0x80, 0x85, 0x34, 0xb1, 0xcb, 0xa1, 0x28, 0x40, 0x85, 0x34, 0xb0,
+0x92, 0x20, 0x91, 0x30, 0x90, 0xb8, 0xd5, 0x03, 0x00, 0xc0, 0xc0, 0x81,
+0x8c, 0x01, 0xa0, 0x84, 0x30, 0x3e, 0xc0, 0xc0, 0x81, 0x8c, 0x01, 0x80,
+0x84, 0x30, 0x3c, 0xd5, 0x02, 0x00, 0xc0, 0xc0, 0x81, 0x30, 0x28, 0xc0,
+0xc0, 0x81, 0x30, 0x24, 0x90, 0x78, 0xd5, 0x02, 0x00, 0xc0, 0xc0, 0x81,
+0x30, 0x1c, 0xc0, 0xc0, 0x81, 0x30, 0x18, 0xd5, 0x02, 0x00, 0xc0, 0xc0,
+0x81, 0x30, 0x10, 0xc0, 0xc0, 0x81, 0x30, 0x0c, 0x91, 0x70, 0x90, 0xd8,
+0xd5, 0x03, 0x80, 0xc8, 0xe2, 0x38, 0x40, 0x81, 0x8c, 0x01, 0xc0, 0x84,
+0x30, 0x40, 0xc8, 0xe2, 0x3a, 0x40, 0x81, 0x8c, 0x01, 0x90, 0x84, 0x30,
+0x3d, 0xd5, 0x02, 0x80, 0xc8, 0xe2, 0x37, 0x40, 0x81, 0x30, 0x2c, 0xc8,
+0xe2, 0x31, 0xc0, 0x81, 0x30, 0x26, 0x90, 0x98, 0xd5, 0x02, 0x80, 0xc8,
+0xe2, 0x26, 0xc0, 0x81, 0x30, 0x20, 0xc8, 0xe2, 0x28, 0xc0, 0x81, 0x30,
+0x1a, 0xd5, 0x02, 0x80, 0xc8, 0xe2, 0x25, 0xc0, 0x81, 0x30, 0x14, 0xc8,
+0xe2, 0x20, 0x40, 0x81, 0x30, 0x0e, 0x9a, 0x30, 0x04, 0x40, 0x91, 0x90,
+0x90, 0xc8, 0x98, 0x50, 0x00, 0x80, 0xe5, 0x22, 0x7e, 0x40, 0x39, 0xf1,
+0xe5, 0x22, 0x80, 0x40, 0x3a, 0x15, 0xcb, 0x61, 0x27, 0xc0, 0x85, 0x34,
+0xae, 0x98, 0x50, 0x00, 0x80, 0xe5, 0x22, 0x6e, 0x40, 0x39, 0xb1, 0xe5,
+0x22, 0x70, 0x40, 0x39, 0xd5, 0xcb, 0x61, 0x27, 0x80, 0x85, 0x34, 0xad,
+0x90, 0x48, 0xcb, 0xa1, 0x27, 0x40, 0x85, 0x34, 0xac, 0xcb, 0xa1, 0x27,
+0x00, 0x85, 0x34, 0xab, 0x91, 0x90, 0x90, 0xc8, 0x98, 0x50, 0x00, 0x80,
+0xe5, 0x22, 0x60, 0x40, 0x39, 0x99, 0xe5, 0x22, 0x54, 0x40, 0x39, 0x69,
+0xcb, 0x61, 0x25, 0x40, 0x85, 0x34, 0x9a, 0x98, 0x50, 0x00, 0x80, 0xe5,
+0x22, 0x48, 0x40, 0x39, 0x39, 0xe5, 0x22, 0x3c, 0x40, 0x39, 0x09, 0xcb,
+0x61, 0x25, 0x00, 0x85, 0x34, 0x99, 0x90, 0x48, 0xcb, 0xa1, 0x24, 0xc0,
+0x85, 0x34, 0x98, 0xcb, 0xa1, 0x24, 0x80, 0x85, 0x34, 0x97, 0x91, 0x00,
+0x90, 0x80, 0x90, 0x40, 0xe5, 0x20, 0x02, 0x40, 0x30, 0x0a, 0xe5, 0x20,
+0x01, 0x80, 0x30, 0x07, 0x90, 0x40, 0xe5, 0x20, 0x00, 0xc0, 0x30, 0x04,
+0xe5, 0x20, 0x00, 0x00, 0x30, 0x01, 0x90, 0x80, 0x90, 0x40, 0xe5, 0x22,
+0x2d, 0x40, 0x38, 0xab, 0xe5, 0x22, 0x2f, 0x80, 0x38, 0xd3, 0x90, 0x40,
+0xe5, 0x22, 0x1b, 0xc0, 0x38, 0x65, 0xe5, 0x22, 0x1e, 0x00, 0x38, 0x8d,
+0x80, 0x99, 0x28, 0x02, 0xf0, 0x8c, 0x24, 0x48, 0x90, 0x80, 0x90, 0x40,
+0xe5, 0x22, 0x84, 0x40, 0x3a, 0x0d, 0xe5, 0x22, 0x81, 0x40, 0x3a, 0x19,
+0x90, 0x40, 0xe5, 0x22, 0x74, 0x40, 0x39, 0xcd, 0xe5, 0x22, 0x71, 0x40,
+0x39, 0xd9, 0x91, 0x48, 0x90, 0xc8, 0x98, 0x50, 0x00, 0x80, 0xe5, 0x22,
+0x62, 0x40, 0x39, 0xa1, 0xe5, 0x22, 0x56, 0x40, 0x39, 0x71, 0xcb, 0x61,
+0x23, 0x00, 0x85, 0x34, 0x90, 0x90, 0x40, 0xe5, 0x22, 0x4a, 0x40, 0x39,
+0x41, 0xe5, 0x22, 0x3e, 0x40, 0x39, 0x11, 0x90, 0x48, 0xcb, 0xa1, 0x22,
+0x80, 0x85, 0x34, 0x8e, 0xcb, 0xa1, 0x22, 0xc0, 0x85, 0x34, 0x8f, 0x10,
+0x10, 0x90, 0x80, 0x90, 0x40, 0xe5, 0x22, 0x33, 0xc0, 0x38, 0xcb, 0xe5,
+0x22, 0x30, 0xc0, 0x38, 0xd9, 0x90, 0x40, 0xe5, 0x22, 0x22, 0x40, 0x38,
+0x85, 0xe5, 0x22, 0x1f, 0x40, 0x38, 0x93,
+};
+
+static const struct ia64_dis_names ia64_dis_names[] = {
+{ 0x51, 41, 0, 10 },
+{ 0x31, 41, 1, 20 },
+{ 0x11, 42, 0, 19 },
+{ 0x29, 41, 0, 12 },
+{ 0x19, 41, 1, 24 },
+{ 0x9, 42, 0, 23 },
+{ 0x15, 41, 0, 14 },
+{ 0xd, 41, 1, 28 },
+{ 0x5, 42, 0, 27 },
+{ 0xb, 41, 0, 16 },
+{ 0x7, 41, 1, 32 },
+{ 0x3, 42, 0, 31 },
+{ 0x51, 39, 1, 58 },
+{ 0x50, 39, 0, 34 },
+{ 0xd1, 39, 1, 57 },
+{ 0xd0, 39, 0, 33 },
+{ 0x31, 39, 1, 68 },
+{ 0x30, 39, 1, 44 },
+{ 0x11, 40, 1, 67 },
+{ 0x10, 40, 0, 43 },
+{ 0x71, 39, 1, 66 },
+{ 0x70, 39, 1, 42 },
+{ 0x31, 40, 1, 65 },
+{ 0x30, 40, 0, 41 },
+{ 0x29, 39, 1, 60 },
+{ 0x28, 39, 0, 36 },
+{ 0x69, 39, 1, 59 },
+{ 0x68, 39, 0, 35 },
+{ 0x19, 39, 1, 72 },
+{ 0x18, 39, 1, 48 },
+{ 0x9, 40, 1, 71 },
+{ 0x8, 40, 0, 47 },
+{ 0x39, 39, 1, 70 },
+{ 0x38, 39, 1, 46 },
+{ 0x19, 40, 1, 69 },
+{ 0x18, 40, 0, 45 },
+{ 0x15, 39, 1, 62 },
+{ 0x14, 39, 0, 38 },
+{ 0x35, 39, 1, 61 },
+{ 0x34, 39, 0, 37 },
+{ 0xd, 39, 1, 76 },
+{ 0xc, 39, 1, 52 },
+{ 0x5, 40, 1, 75 },
+{ 0x4, 40, 0, 51 },
+{ 0x1d, 39, 1, 74 },
+{ 0x1c, 39, 1, 50 },
+{ 0xd, 40, 1, 73 },
+{ 0xc, 40, 0, 49 },
+{ 0xb, 39, 1, 64 },
+{ 0xa, 39, 0, 40 },
+{ 0x1b, 39, 1, 63 },
+{ 0x1a, 39, 0, 39 },
+{ 0x7, 39, 1, 80 },
+{ 0x6, 39, 1, 56 },
+{ 0x3, 40, 1, 79 },
+{ 0x2, 40, 0, 55 },
+{ 0xf, 39, 1, 78 },
+{ 0xe, 39, 1, 54 },
+{ 0x7, 40, 1, 77 },
+{ 0x6, 40, 0, 53 },
+{ 0x8, 38, 0, 82 },
+{ 0x18, 38, 0, 81 },
+{ 0x1, 38, 1, 86 },
+{ 0x2, 38, 0, 85 },
+{ 0x3, 38, 1, 84 },
+{ 0x4, 38, 0, 83 },
+{ 0x1, 336, 0, 87 },
+{ 0x20, 289, 0, 98 },
+{ 0x220, 289, 0, 94 },
+{ 0x1220, 289, 0, 91 },
+{ 0xa20, 289, 0, 92 },
+{ 0x620, 289, 0, 93 },
+{ 0x120, 289, 0, 95 },
+{ 0xa0, 289, 0, 96 },
+{ 0x60, 289, 0, 97 },
+{ 0x10, 289, 0, 102 },
+{ 0x90, 289, 0, 99 },
+{ 0x50, 289, 0, 100 },
+{ 0x30, 289, 0, 101 },
+{ 0x8, 289, 0, 103 },
+{ 0x4, 289, 0, 104 },
+{ 0x2, 289, 0, 105 },
+{ 0x1, 289, 0, 106 },
+{ 0x1, 411, 0, 108 },
+{ 0x3, 411, 0, 107 },
+{ 0x2, 417, 0, 109 },
+{ 0x1, 417, 0, 110 },
+{ 0x2, 413, 0, 111 },
+{ 0x1, 413, 0, 112 },
+{ 0x2, 415, 0, 113 },
+{ 0x1, 415, 0, 114 },
+{ 0x2, 419, 0, 115 },
+{ 0x1, 419, 0, 116 },
+{ 0x1, 268, 0, 143 },
+{ 0x5, 268, 0, 141 },
+{ 0x3, 268, 0, 142 },
+{ 0x140, 277, 0, 119 },
+{ 0x540, 277, 0, 117 },
+{ 0x340, 277, 0, 118 },
+{ 0xc0, 277, 0, 131 },
+{ 0x2c0, 277, 0, 129 },
+{ 0x1c0, 277, 0, 130 },
+{ 0x20, 277, 0, 146 },
+{ 0xa0, 277, 0, 144 },
+{ 0x60, 277, 0, 145 },
+{ 0x10, 277, 0, 158 },
+{ 0x50, 277, 0, 156 },
+{ 0x30, 277, 0, 157 },
+{ 0x8, 277, 0, 170 },
+{ 0x28, 277, 0, 168 },
+{ 0x18, 277, 0, 169 },
+{ 0x4, 277, 0, 180 },
+{ 0x2, 277, 0, 181 },
+{ 0x1, 277, 0, 182 },
+{ 0x140, 271, 0, 122 },
+{ 0x540, 271, 0, 120 },
+{ 0x340, 271, 0, 121 },
+{ 0xc0, 271, 0, 134 },
+{ 0x2c0, 271, 0, 132 },
+{ 0x1c0, 271, 0, 133 },
+{ 0x20, 271, 0, 149 },
+{ 0xa0, 271, 0, 147 },
+{ 0x60, 271, 0, 148 },
+{ 0x10, 271, 0, 161 },
+{ 0x50, 271, 0, 159 },
+{ 0x30, 271, 0, 160 },
+{ 0x8, 271, 0, 173 },
+{ 0x28, 271, 0, 171 },
+{ 0x18, 271, 0, 172 },
+{ 0x4, 271, 0, 183 },
+{ 0x2, 271, 0, 184 },
+{ 0x1, 271, 0, 185 },
+{ 0x140, 274, 0, 125 },
+{ 0x540, 274, 0, 123 },
+{ 0x340, 274, 0, 124 },
+{ 0xc0, 274, 0, 137 },
+{ 0x2c0, 274, 0, 135 },
+{ 0x1c0, 274, 0, 136 },
+{ 0x20, 274, 0, 152 },
+{ 0xa0, 274, 0, 150 },
+{ 0x60, 274, 0, 151 },
+{ 0x10, 274, 0, 164 },
+{ 0x50, 274, 0, 162 },
+{ 0x30, 274, 0, 163 },
+{ 0x8, 274, 0, 176 },
+{ 0x28, 274, 0, 174 },
+{ 0x18, 274, 0, 175 },
+{ 0x4, 274, 0, 186 },
+{ 0x2, 274, 0, 187 },
+{ 0x1, 274, 0, 188 },
+{ 0x140, 286, 0, 128 },
+{ 0x540, 286, 0, 126 },
+{ 0x340, 286, 0, 127 },
+{ 0xc0, 286, 0, 140 },
+{ 0x2c0, 286, 0, 138 },
+{ 0x1c0, 286, 0, 139 },
+{ 0x20, 286, 0, 155 },
+{ 0xa0, 286, 0, 153 },
+{ 0x60, 286, 0, 154 },
+{ 0x10, 286, 0, 167 },
+{ 0x50, 286, 0, 165 },
+{ 0x30, 286, 0, 166 },
+{ 0x8, 286, 0, 179 },
+{ 0x28, 286, 0, 177 },
+{ 0x18, 286, 0, 178 },
+{ 0x4, 286, 0, 189 },
+{ 0x2, 286, 0, 190 },
+{ 0x1, 286, 0, 191 },
+{ 0x8, 390, 0, 192 },
+{ 0x4, 390, 0, 193 },
+{ 0x2, 390, 0, 194 },
+{ 0x1, 390, 0, 195 },
+{ 0x20, 288, 0, 203 },
+{ 0x220, 288, 0, 199 },
+{ 0x1220, 288, 0, 196 },
+{ 0xa20, 288, 0, 197 },
+{ 0x620, 288, 0, 198 },
+{ 0x120, 288, 0, 200 },
+{ 0xa0, 288, 0, 201 },
+{ 0x60, 288, 0, 202 },
+{ 0x10, 288, 0, 207 },
+{ 0x90, 288, 0, 204 },
+{ 0x50, 288, 0, 205 },
+{ 0x30, 288, 0, 206 },
+{ 0x8, 288, 0, 208 },
+{ 0x4, 288, 0, 209 },
+{ 0x2, 288, 0, 210 },
+{ 0x1, 288, 0, 211 },
+{ 0x20, 287, 0, 219 },
+{ 0x220, 287, 0, 215 },
+{ 0x1220, 287, 0, 212 },
+{ 0xa20, 287, 0, 213 },
+{ 0x620, 287, 0, 214 },
+{ 0x120, 287, 0, 216 },
+{ 0xa0, 287, 0, 217 },
+{ 0x60, 287, 0, 218 },
+{ 0x10, 287, 0, 223 },
+{ 0x90, 287, 0, 220 },
+{ 0x50, 287, 0, 221 },
+{ 0x30, 287, 0, 222 },
+{ 0x8, 287, 0, 224 },
+{ 0x4, 287, 0, 225 },
+{ 0x2, 287, 0, 226 },
+{ 0x1, 287, 0, 227 },
+{ 0x140, 279, 0, 230 },
+{ 0x540, 279, 0, 228 },
+{ 0x340, 279, 0, 229 },
+{ 0xc0, 279, 0, 239 },
+{ 0x2c0, 279, 0, 237 },
+{ 0x1c0, 279, 0, 238 },
+{ 0x20, 279, 0, 248 },
+{ 0xa0, 279, 0, 246 },
+{ 0x60, 279, 0, 247 },
+{ 0x10, 279, 0, 257 },
+{ 0x50, 279, 0, 255 },
+{ 0x30, 279, 0, 256 },
+{ 0x8, 279, 0, 266 },
+{ 0x28, 279, 0, 264 },
+{ 0x18, 279, 0, 265 },
+{ 0x4, 279, 0, 273 },
+{ 0x2, 279, 0, 274 },
+{ 0x1, 279, 0, 275 },
+{ 0x140, 281, 0, 233 },
+{ 0x540, 281, 0, 231 },
+{ 0x340, 281, 0, 232 },
+{ 0xc0, 281, 0, 242 },
+{ 0x2c0, 281, 0, 240 },
+{ 0x1c0, 281, 0, 241 },
+{ 0x20, 281, 0, 251 },
+{ 0xa0, 281, 0, 249 },
+{ 0x60, 281, 0, 250 },
+{ 0x10, 281, 0, 260 },
+{ 0x50, 281, 0, 258 },
+{ 0x30, 281, 0, 259 },
+{ 0x8, 281, 0, 269 },
+{ 0x28, 281, 0, 267 },
+{ 0x18, 281, 0, 268 },
+{ 0x4, 281, 0, 276 },
+{ 0x2, 281, 0, 277 },
+{ 0x1, 281, 0, 278 },
+{ 0x140, 283, 0, 236 },
+{ 0x540, 283, 0, 234 },
+{ 0x340, 283, 0, 235 },
+{ 0xc0, 283, 0, 245 },
+{ 0x2c0, 283, 0, 243 },
+{ 0x1c0, 283, 0, 244 },
+{ 0x20, 283, 0, 254 },
+{ 0xa0, 283, 0, 252 },
+{ 0x60, 283, 0, 253 },
+{ 0x10, 283, 0, 263 },
+{ 0x50, 283, 0, 261 },
+{ 0x30, 283, 0, 262 },
+{ 0x8, 283, 0, 272 },
+{ 0x28, 283, 0, 270 },
+{ 0x18, 283, 0, 271 },
+{ 0x4, 283, 0, 279 },
+{ 0x2, 283, 0, 280 },
+{ 0x1, 283, 0, 281 },
+{ 0x140, 278, 0, 284 },
+{ 0x540, 278, 0, 282 },
+{ 0x340, 278, 0, 283 },
+{ 0xc0, 278, 0, 293 },
+{ 0x2c0, 278, 0, 291 },
+{ 0x1c0, 278, 0, 292 },
+{ 0x20, 278, 0, 302 },
+{ 0xa0, 278, 0, 300 },
+{ 0x60, 278, 0, 301 },
+{ 0x10, 278, 0, 311 },
+{ 0x50, 278, 0, 309 },
+{ 0x30, 278, 0, 310 },
+{ 0x8, 278, 0, 320 },
+{ 0x28, 278, 0, 318 },
+{ 0x18, 278, 0, 319 },
+{ 0x4, 278, 0, 327 },
+{ 0x2, 278, 0, 328 },
+{ 0x1, 278, 0, 329 },
+{ 0x140, 280, 0, 287 },
+{ 0x540, 280, 0, 285 },
+{ 0x340, 280, 0, 286 },
+{ 0xc0, 280, 0, 296 },
+{ 0x2c0, 280, 0, 294 },
+{ 0x1c0, 280, 0, 295 },
+{ 0x20, 280, 0, 305 },
+{ 0xa0, 280, 0, 303 },
+{ 0x60, 280, 0, 304 },
+{ 0x10, 280, 0, 314 },
+{ 0x50, 280, 0, 312 },
+{ 0x30, 280, 0, 313 },
+{ 0x8, 280, 0, 323 },
+{ 0x28, 280, 0, 321 },
+{ 0x18, 280, 0, 322 },
+{ 0x4, 280, 0, 330 },
+{ 0x2, 280, 0, 331 },
+{ 0x1, 280, 0, 332 },
+{ 0x140, 282, 0, 290 },
+{ 0x540, 282, 0, 288 },
+{ 0x340, 282, 0, 289 },
+{ 0xc0, 282, 0, 299 },
+{ 0x2c0, 282, 0, 297 },
+{ 0x1c0, 282, 0, 298 },
+{ 0x20, 282, 0, 308 },
+{ 0xa0, 282, 0, 306 },
+{ 0x60, 282, 0, 307 },
+{ 0x10, 282, 0, 317 },
+{ 0x50, 282, 0, 315 },
+{ 0x30, 282, 0, 316 },
+{ 0x8, 282, 0, 326 },
+{ 0x28, 282, 0, 324 },
+{ 0x18, 282, 0, 325 },
+{ 0x4, 282, 0, 333 },
+{ 0x2, 282, 0, 334 },
+{ 0x1, 282, 0, 335 },
+{ 0x1, 410, 0, 337 },
+{ 0x3, 410, 0, 336 },
+{ 0x2, 416, 0, 338 },
+{ 0x1, 416, 0, 339 },
+{ 0x2, 412, 0, 340 },
+{ 0x1, 412, 0, 341 },
+{ 0x2, 414, 0, 342 },
+{ 0x1, 414, 0, 343 },
+{ 0x2, 418, 0, 344 },
+{ 0x1, 418, 0, 345 },
+{ 0x1, 267, 0, 372 },
+{ 0x5, 267, 0, 370 },
+{ 0x3, 267, 0, 371 },
+{ 0x140, 276, 0, 348 },
+{ 0x540, 276, 0, 346 },
+{ 0x340, 276, 0, 347 },
+{ 0xc0, 276, 0, 360 },
+{ 0x2c0, 276, 0, 358 },
+{ 0x1c0, 276, 0, 359 },
+{ 0x20, 276, 0, 375 },
+{ 0xa0, 276, 0, 373 },
+{ 0x60, 276, 0, 374 },
+{ 0x10, 276, 0, 387 },
+{ 0x50, 276, 0, 385 },
+{ 0x30, 276, 0, 386 },
+{ 0x8, 276, 0, 399 },
+{ 0x28, 276, 0, 397 },
+{ 0x18, 276, 0, 398 },
+{ 0x4, 276, 0, 409 },
+{ 0x2, 276, 0, 410 },
+{ 0x1, 276, 0, 411 },
+{ 0x140, 270, 0, 351 },
+{ 0x540, 270, 0, 349 },
+{ 0x340, 270, 0, 350 },
+{ 0xc0, 270, 0, 363 },
+{ 0x2c0, 270, 0, 361 },
+{ 0x1c0, 270, 0, 362 },
+{ 0x20, 270, 0, 378 },
+{ 0xa0, 270, 0, 376 },
+{ 0x60, 270, 0, 377 },
+{ 0x10, 270, 0, 390 },
+{ 0x50, 270, 0, 388 },
+{ 0x30, 270, 0, 389 },
+{ 0x8, 270, 0, 402 },
+{ 0x28, 270, 0, 400 },
+{ 0x18, 270, 0, 401 },
+{ 0x4, 270, 0, 412 },
+{ 0x2, 270, 0, 413 },
+{ 0x1, 270, 0, 414 },
+{ 0x140, 273, 0, 354 },
+{ 0x540, 273, 0, 352 },
+{ 0x340, 273, 0, 353 },
+{ 0xc0, 273, 0, 366 },
+{ 0x2c0, 273, 0, 364 },
+{ 0x1c0, 273, 0, 365 },
+{ 0x20, 273, 0, 381 },
+{ 0xa0, 273, 0, 379 },
+{ 0x60, 273, 0, 380 },
+{ 0x10, 273, 0, 393 },
+{ 0x50, 273, 0, 391 },
+{ 0x30, 273, 0, 392 },
+{ 0x8, 273, 0, 405 },
+{ 0x28, 273, 0, 403 },
+{ 0x18, 273, 0, 404 },
+{ 0x4, 273, 0, 415 },
+{ 0x2, 273, 0, 416 },
+{ 0x1, 273, 0, 417 },
+{ 0x140, 285, 0, 357 },
+{ 0x540, 285, 0, 355 },
+{ 0x340, 285, 0, 356 },
+{ 0xc0, 285, 0, 369 },
+{ 0x2c0, 285, 0, 367 },
+{ 0x1c0, 285, 0, 368 },
+{ 0x20, 285, 0, 384 },
+{ 0xa0, 285, 0, 382 },
+{ 0x60, 285, 0, 383 },
+{ 0x10, 285, 0, 396 },
+{ 0x50, 285, 0, 394 },
+{ 0x30, 285, 0, 395 },
+{ 0x8, 285, 0, 408 },
+{ 0x28, 285, 0, 406 },
+{ 0x18, 285, 0, 407 },
+{ 0x4, 285, 0, 418 },
+{ 0x2, 285, 0, 419 },
+{ 0x1, 285, 0, 420 },
+{ 0x1, 266, 0, 447 },
+{ 0x5, 266, 0, 445 },
+{ 0x3, 266, 0, 446 },
+{ 0x140, 275, 0, 423 },
+{ 0x540, 275, 0, 421 },
+{ 0x340, 275, 0, 422 },
+{ 0xc0, 275, 0, 435 },
+{ 0x2c0, 275, 0, 433 },
+{ 0x1c0, 275, 0, 434 },
+{ 0x20, 275, 0, 450 },
+{ 0xa0, 275, 0, 448 },
+{ 0x60, 275, 0, 449 },
+{ 0x10, 275, 0, 462 },
+{ 0x50, 275, 0, 460 },
+{ 0x30, 275, 0, 461 },
+{ 0x8, 275, 0, 474 },
+{ 0x28, 275, 0, 472 },
+{ 0x18, 275, 0, 473 },
+{ 0x4, 275, 0, 484 },
+{ 0x2, 275, 0, 485 },
+{ 0x1, 275, 0, 486 },
+{ 0x140, 269, 0, 426 },
+{ 0x540, 269, 0, 424 },
+{ 0x340, 269, 0, 425 },
+{ 0xc0, 269, 0, 438 },
+{ 0x2c0, 269, 0, 436 },
+{ 0x1c0, 269, 0, 437 },
+{ 0x20, 269, 0, 453 },
+{ 0xa0, 269, 0, 451 },
+{ 0x60, 269, 0, 452 },
+{ 0x10, 269, 0, 465 },
+{ 0x50, 269, 0, 463 },
+{ 0x30, 269, 0, 464 },
+{ 0x8, 269, 0, 477 },
+{ 0x28, 269, 0, 475 },
+{ 0x18, 269, 0, 476 },
+{ 0x4, 269, 0, 487 },
+{ 0x2, 269, 0, 488 },
+{ 0x1, 269, 0, 489 },
+{ 0x140, 272, 0, 429 },
+{ 0x540, 272, 0, 427 },
+{ 0x340, 272, 0, 428 },
+{ 0xc0, 272, 0, 441 },
+{ 0x2c0, 272, 0, 439 },
+{ 0x1c0, 272, 0, 440 },
+{ 0x20, 272, 0, 456 },
+{ 0xa0, 272, 0, 454 },
+{ 0x60, 272, 0, 455 },
+{ 0x10, 272, 0, 468 },
+{ 0x50, 272, 0, 466 },
+{ 0x30, 272, 0, 467 },
+{ 0x8, 272, 0, 480 },
+{ 0x28, 272, 0, 478 },
+{ 0x18, 272, 0, 479 },
+{ 0x4, 272, 0, 490 },
+{ 0x2, 272, 0, 491 },
+{ 0x1, 272, 0, 492 },
+{ 0x140, 284, 0, 432 },
+{ 0x540, 284, 0, 430 },
+{ 0x340, 284, 0, 431 },
+{ 0xc0, 284, 0, 444 },
+{ 0x2c0, 284, 0, 442 },
+{ 0x1c0, 284, 0, 443 },
+{ 0x20, 284, 0, 459 },
+{ 0xa0, 284, 0, 457 },
+{ 0x60, 284, 0, 458 },
+{ 0x10, 284, 0, 471 },
+{ 0x50, 284, 0, 469 },
+{ 0x30, 284, 0, 470 },
+{ 0x8, 284, 0, 483 },
+{ 0x28, 284, 0, 481 },
+{ 0x18, 284, 0, 482 },
+{ 0x4, 284, 0, 493 },
+{ 0x2, 284, 0, 494 },
+{ 0x1, 284, 0, 495 },
+{ 0x8, 409, 0, 497 },
+{ 0x18, 409, 0, 496 },
+{ 0x4, 409, 0, 499 },
+{ 0xc, 409, 0, 498 },
+{ 0x2, 409, 0, 506 },
+{ 0x1, 409, 0, 507 },
+{ 0x4, 407, 0, 501 },
+{ 0xc, 407, 0, 500 },
+{ 0x2, 407, 0, 508 },
+{ 0x1, 407, 0, 509 },
+{ 0x4, 405, 0, 503 },
+{ 0xc, 405, 0, 502 },
+{ 0x2, 405, 0, 510 },
+{ 0x1, 405, 0, 511 },
+{ 0x4, 401, 0, 505 },
+{ 0xc, 401, 0, 504 },
+{ 0x2, 401, 0, 512 },
+{ 0x1, 401, 0, 513 },
+{ 0xa00, 265, 0, 528 },
+{ 0x2a00, 265, 0, 526 },
+{ 0x1a00, 265, 0, 527 },
+{ 0x600, 265, 0, 540 },
+{ 0x2600, 265, 0, 516 },
+{ 0xa600, 265, 0, 514 },
+{ 0x6600, 265, 0, 515 },
+{ 0x1600, 265, 0, 538 },
+{ 0xe00, 265, 0, 539 },
+{ 0x100, 265, 0, 552 },
+{ 0x500, 265, 0, 550 },
+{ 0x300, 265, 0, 551 },
+{ 0x80, 265, 0, 555 },
+{ 0x280, 265, 0, 553 },
+{ 0x180, 265, 0, 554 },
+{ 0x40, 265, 0, 567 },
+{ 0x140, 265, 0, 565 },
+{ 0xc0, 265, 0, 566 },
+{ 0x20, 265, 0, 579 },
+{ 0xa0, 265, 0, 577 },
+{ 0x60, 265, 0, 578 },
+{ 0x10, 265, 0, 591 },
+{ 0x50, 265, 0, 589 },
+{ 0x30, 265, 0, 590 },
+{ 0x8, 265, 0, 603 },
+{ 0x28, 265, 0, 601 },
+{ 0x18, 265, 0, 602 },
+{ 0x4, 265, 0, 613 },
+{ 0x2, 265, 0, 614 },
+{ 0x1, 265, 0, 615 },
+{ 0x500, 261, 0, 531 },
+{ 0x1500, 261, 0, 529 },
+{ 0xd00, 261, 0, 530 },
+{ 0x300, 261, 0, 543 },
+{ 0x1300, 261, 0, 519 },
+{ 0x5300, 261, 0, 517 },
+{ 0x3300, 261, 0, 518 },
+{ 0xb00, 261, 0, 541 },
+{ 0x700, 261, 0, 542 },
+{ 0x80, 261, 0, 558 },
+{ 0x280, 261, 0, 556 },
+{ 0x180, 261, 0, 557 },
+{ 0x40, 261, 0, 570 },
+{ 0x140, 261, 0, 568 },
+{ 0xc0, 261, 0, 569 },
+{ 0x20, 261, 0, 582 },
+{ 0xa0, 261, 0, 580 },
+{ 0x60, 261, 0, 581 },
+{ 0x10, 261, 0, 594 },
+{ 0x50, 261, 0, 592 },
+{ 0x30, 261, 0, 593 },
+{ 0x8, 261, 0, 606 },
+{ 0x28, 261, 0, 604 },
+{ 0x18, 261, 0, 605 },
+{ 0x4, 261, 0, 616 },
+{ 0x2, 261, 0, 617 },
+{ 0x1, 261, 0, 618 },
+{ 0x500, 258, 0, 534 },
+{ 0x1500, 258, 0, 532 },
+{ 0xd00, 258, 0, 533 },
+{ 0x300, 258, 0, 546 },
+{ 0x1300, 258, 0, 522 },
+{ 0x5300, 258, 0, 520 },
+{ 0x3300, 258, 0, 521 },
+{ 0xb00, 258, 0, 544 },
+{ 0x700, 258, 0, 545 },
+{ 0x80, 258, 0, 561 },
+{ 0x280, 258, 0, 559 },
+{ 0x180, 258, 0, 560 },
+{ 0x40, 258, 0, 573 },
+{ 0x140, 258, 0, 571 },
+{ 0xc0, 258, 0, 572 },
+{ 0x20, 258, 0, 585 },
+{ 0xa0, 258, 0, 583 },
+{ 0x60, 258, 0, 584 },
+{ 0x10, 258, 0, 597 },
+{ 0x50, 258, 0, 595 },
+{ 0x30, 258, 0, 596 },
+{ 0x8, 258, 0, 609 },
+{ 0x28, 258, 0, 607 },
+{ 0x18, 258, 0, 608 },
+{ 0x4, 258, 0, 619 },
+{ 0x2, 258, 0, 620 },
+{ 0x1, 258, 0, 621 },
+{ 0x500, 253, 0, 537 },
+{ 0x1500, 253, 0, 535 },
+{ 0xd00, 253, 0, 536 },
+{ 0x300, 253, 0, 549 },
+{ 0x1300, 253, 0, 525 },
+{ 0x5300, 253, 0, 523 },
+{ 0x3300, 253, 0, 524 },
+{ 0xb00, 253, 0, 547 },
+{ 0x700, 253, 0, 548 },
+{ 0x80, 253, 0, 564 },
+{ 0x280, 253, 0, 562 },
+{ 0x180, 253, 0, 563 },
+{ 0x40, 253, 0, 576 },
+{ 0x140, 253, 0, 574 },
+{ 0xc0, 253, 0, 575 },
+{ 0x20, 253, 0, 588 },
+{ 0xa0, 253, 0, 586 },
+{ 0x60, 253, 0, 587 },
+{ 0x10, 253, 0, 600 },
+{ 0x50, 253, 0, 598 },
+{ 0x30, 253, 0, 599 },
+{ 0x8, 253, 0, 612 },
+{ 0x28, 253, 0, 610 },
+{ 0x18, 253, 0, 611 },
+{ 0x4, 253, 0, 622 },
+{ 0x2, 253, 0, 623 },
+{ 0x1, 253, 0, 624 },
+{ 0x8, 238, 0, 625 },
+{ 0x4, 238, 0, 626 },
+{ 0x2, 238, 0, 627 },
+{ 0x1, 238, 0, 628 },
+{ 0x2, 176, 0, 631 },
+{ 0xa, 176, 0, 629 },
+{ 0x6, 176, 0, 630 },
+{ 0x1, 176, 0, 637 },
+{ 0x5, 176, 0, 635 },
+{ 0x3, 176, 0, 636 },
+{ 0x2, 175, 0, 634 },
+{ 0xa, 175, 0, 632 },
+{ 0x6, 175, 0, 633 },
+{ 0x1, 175, 0, 640 },
+{ 0x5, 175, 0, 638 },
+{ 0x3, 175, 0, 639 },
+{ 0x4, 446, 0, 641 },
+{ 0x2, 446, 0, 642 },
+{ 0x1, 446, 0, 643 },
+{ 0x4, 445, 0, 644 },
+{ 0x2, 445, 0, 645 },
+{ 0x1, 445, 0, 646 },
+{ 0x4, 444, 0, 647 },
+{ 0x2, 444, 0, 648 },
+{ 0x1, 444, 0, 649 },
+{ 0x4, 443, 0, 650 },
+{ 0x2, 443, 0, 651 },
+{ 0x1, 443, 0, 652 },
+{ 0x2, 123, 1, 658 },
+{ 0x2, 124, 0, 657 },
+{ 0xa, 123, 1, 654 },
+{ 0xa, 124, 0, 653 },
+{ 0x6, 123, 1, 656 },
+{ 0x6, 124, 0, 655 },
+{ 0x1, 123, 1, 688 },
+{ 0x1, 124, 0, 687 },
+{ 0x5, 123, 1, 684 },
+{ 0x5, 124, 0, 683 },
+{ 0x3, 123, 1, 686 },
+{ 0x3, 124, 0, 685 },
+{ 0x2, 131, 1, 664 },
+{ 0x2, 132, 0, 663 },
+{ 0xa, 131, 1, 660 },
+{ 0xa, 132, 0, 659 },
+{ 0x6, 131, 1, 662 },
+{ 0x6, 132, 0, 661 },
+{ 0x1, 131, 1, 694 },
+{ 0x1, 132, 0, 693 },
+{ 0x5, 131, 1, 690 },
+{ 0x5, 132, 0, 689 },
+{ 0x3, 131, 1, 692 },
+{ 0x3, 132, 0, 691 },
+{ 0x2, 129, 1, 670 },
+{ 0x2, 130, 0, 669 },
+{ 0xa, 129, 1, 666 },
+{ 0xa, 130, 0, 665 },
+{ 0x6, 129, 1, 668 },
+{ 0x6, 130, 0, 667 },
+{ 0x1, 129, 1, 700 },
+{ 0x1, 130, 0, 699 },
+{ 0x5, 129, 1, 696 },
+{ 0x5, 130, 0, 695 },
+{ 0x3, 129, 1, 698 },
+{ 0x3, 130, 0, 697 },
+{ 0x2, 127, 1, 676 },
+{ 0x2, 128, 0, 675 },
+{ 0xa, 127, 1, 672 },
+{ 0xa, 128, 0, 671 },
+{ 0x6, 127, 1, 674 },
+{ 0x6, 128, 0, 673 },
+{ 0x1, 127, 1, 706 },
+{ 0x1, 128, 0, 705 },
+{ 0x5, 127, 1, 702 },
+{ 0x5, 128, 0, 701 },
+{ 0x3, 127, 1, 704 },
+{ 0x3, 128, 0, 703 },
+{ 0x2, 125, 1, 682 },
+{ 0x2, 126, 0, 681 },
+{ 0xa, 125, 1, 678 },
+{ 0xa, 126, 0, 677 },
+{ 0x6, 125, 1, 680 },
+{ 0x6, 126, 0, 679 },
+{ 0x1, 125, 1, 712 },
+{ 0x1, 126, 0, 711 },
+{ 0x5, 125, 1, 708 },
+{ 0x5, 126, 0, 707 },
+{ 0x3, 125, 1, 710 },
+{ 0x3, 126, 0, 709 },
+{ 0x4, 402, 1, 718 },
+{ 0x4, 403, 0, 717 },
+{ 0xc, 402, 1, 716 },
+{ 0xc, 403, 0, 715 },
+{ 0x2, 402, 1, 728 },
+{ 0x2, 403, 0, 727 },
+{ 0x1, 402, 1, 730 },
+{ 0x1, 403, 0, 729 },
+{ 0x8, 408, 0, 714 },
+{ 0x18, 408, 0, 713 },
+{ 0x4, 408, 0, 720 },
+{ 0xc, 408, 0, 719 },
+{ 0x2, 408, 0, 731 },
+{ 0x1, 408, 0, 732 },
+{ 0x4, 406, 0, 722 },
+{ 0xc, 406, 0, 721 },
+{ 0x2, 406, 0, 733 },
+{ 0x1, 406, 0, 734 },
+{ 0x4, 404, 0, 724 },
+{ 0xc, 404, 0, 723 },
+{ 0x2, 404, 0, 735 },
+{ 0x1, 404, 0, 736 },
+{ 0x4, 400, 0, 726 },
+{ 0xc, 400, 0, 725 },
+{ 0x2, 400, 0, 737 },
+{ 0x1, 400, 0, 738 },
+{ 0xa00, 264, 0, 753 },
+{ 0x2a00, 264, 0, 751 },
+{ 0x1a00, 264, 0, 752 },
+{ 0x600, 264, 0, 765 },
+{ 0x2600, 264, 0, 741 },
+{ 0xa600, 264, 0, 739 },
+{ 0x6600, 264, 0, 740 },
+{ 0x1600, 264, 0, 763 },
+{ 0xe00, 264, 0, 764 },
+{ 0x100, 264, 0, 777 },
+{ 0x500, 264, 0, 775 },
+{ 0x300, 264, 0, 776 },
+{ 0x80, 264, 0, 780 },
+{ 0x280, 264, 0, 778 },
+{ 0x180, 264, 0, 779 },
+{ 0x40, 264, 0, 792 },
+{ 0x140, 264, 0, 790 },
+{ 0xc0, 264, 0, 791 },
+{ 0x20, 264, 0, 804 },
+{ 0xa0, 264, 0, 802 },
+{ 0x60, 264, 0, 803 },
+{ 0x10, 264, 0, 816 },
+{ 0x50, 264, 0, 814 },
+{ 0x30, 264, 0, 815 },
+{ 0x8, 264, 0, 828 },
+{ 0x28, 264, 0, 826 },
+{ 0x18, 264, 0, 827 },
+{ 0x4, 264, 0, 838 },
+{ 0x2, 264, 0, 839 },
+{ 0x1, 264, 0, 840 },
+{ 0x500, 260, 0, 756 },
+{ 0x1500, 260, 0, 754 },
+{ 0xd00, 260, 0, 755 },
+{ 0x300, 260, 0, 768 },
+{ 0x1300, 260, 0, 744 },
+{ 0x5300, 260, 0, 742 },
+{ 0x3300, 260, 0, 743 },
+{ 0xb00, 260, 0, 766 },
+{ 0x700, 260, 0, 767 },
+{ 0x80, 260, 0, 783 },
+{ 0x280, 260, 0, 781 },
+{ 0x180, 260, 0, 782 },
+{ 0x40, 260, 0, 795 },
+{ 0x140, 260, 0, 793 },
+{ 0xc0, 260, 0, 794 },
+{ 0x20, 260, 0, 807 },
+{ 0xa0, 260, 0, 805 },
+{ 0x60, 260, 0, 806 },
+{ 0x10, 260, 0, 819 },
+{ 0x50, 260, 0, 817 },
+{ 0x30, 260, 0, 818 },
+{ 0x8, 260, 0, 831 },
+{ 0x28, 260, 0, 829 },
+{ 0x18, 260, 0, 830 },
+{ 0x4, 260, 0, 841 },
+{ 0x2, 260, 0, 842 },
+{ 0x1, 260, 0, 843 },
+{ 0x500, 257, 0, 759 },
+{ 0x1500, 257, 0, 757 },
+{ 0xd00, 257, 0, 758 },
+{ 0x300, 257, 0, 771 },
+{ 0x1300, 257, 0, 747 },
+{ 0x5300, 257, 0, 745 },
+{ 0x3300, 257, 0, 746 },
+{ 0xb00, 257, 0, 769 },
+{ 0x700, 257, 0, 770 },
+{ 0x80, 257, 0, 786 },
+{ 0x280, 257, 0, 784 },
+{ 0x180, 257, 0, 785 },
+{ 0x40, 257, 0, 798 },
+{ 0x140, 257, 0, 796 },
+{ 0xc0, 257, 0, 797 },
+{ 0x20, 257, 0, 810 },
+{ 0xa0, 257, 0, 808 },
+{ 0x60, 257, 0, 809 },
+{ 0x10, 257, 0, 822 },
+{ 0x50, 257, 0, 820 },
+{ 0x30, 257, 0, 821 },
+{ 0x8, 257, 0, 834 },
+{ 0x28, 257, 0, 832 },
+{ 0x18, 257, 0, 833 },
+{ 0x4, 257, 0, 844 },
+{ 0x2, 257, 0, 845 },
+{ 0x1, 257, 0, 846 },
+{ 0x500, 252, 0, 762 },
+{ 0x1500, 252, 0, 760 },
+{ 0xd00, 252, 0, 761 },
+{ 0x300, 252, 0, 774 },
+{ 0x1300, 252, 0, 750 },
+{ 0x5300, 252, 0, 748 },
+{ 0x3300, 252, 0, 749 },
+{ 0xb00, 252, 0, 772 },
+{ 0x700, 252, 0, 773 },
+{ 0x80, 252, 0, 789 },
+{ 0x280, 252, 0, 787 },
+{ 0x180, 252, 0, 788 },
+{ 0x40, 252, 0, 801 },
+{ 0x140, 252, 0, 799 },
+{ 0xc0, 252, 0, 800 },
+{ 0x20, 252, 0, 813 },
+{ 0xa0, 252, 0, 811 },
+{ 0x60, 252, 0, 812 },
+{ 0x10, 252, 0, 825 },
+{ 0x50, 252, 0, 823 },
+{ 0x30, 252, 0, 824 },
+{ 0x8, 252, 0, 837 },
+{ 0x28, 252, 0, 835 },
+{ 0x18, 252, 0, 836 },
+{ 0x4, 252, 0, 847 },
+{ 0x2, 252, 0, 848 },
+{ 0x1, 252, 0, 849 },
+{ 0x8, 254, 1, 895 },
+{ 0x8, 255, 0, 894 },
+{ 0x28, 254, 1, 891 },
+{ 0x28, 255, 0, 890 },
+{ 0x18, 254, 1, 893 },
+{ 0x18, 255, 0, 892 },
+{ 0x4, 254, 1, 957 },
+{ 0x4, 255, 0, 956 },
+{ 0x2, 254, 1, 959 },
+{ 0x2, 255, 0, 958 },
+{ 0x1, 254, 1, 961 },
+{ 0x1, 255, 0, 960 },
+{ 0xa00, 262, 0, 865 },
+{ 0x2a00, 262, 0, 863 },
+{ 0x1a00, 262, 0, 864 },
+{ 0x600, 262, 0, 877 },
+{ 0x2600, 262, 0, 853 },
+{ 0xa600, 262, 0, 851 },
+{ 0x6600, 262, 0, 852 },
+{ 0x1600, 262, 0, 875 },
+{ 0xe00, 262, 0, 876 },
+{ 0x100, 262, 0, 889 },
+{ 0x500, 262, 0, 887 },
+{ 0x300, 262, 0, 888 },
+{ 0x80, 262, 0, 898 },
+{ 0x280, 262, 0, 896 },
+{ 0x180, 262, 0, 897 },
+{ 0x40, 262, 0, 910 },
+{ 0x140, 262, 0, 908 },
+{ 0xc0, 262, 0, 909 },
+{ 0x20, 262, 0, 922 },
+{ 0xa0, 262, 0, 920 },
+{ 0x60, 262, 0, 921 },
+{ 0x10, 262, 0, 934 },
+{ 0x50, 262, 0, 932 },
+{ 0x30, 262, 0, 933 },
+{ 0x8, 262, 0, 946 },
+{ 0x28, 262, 0, 944 },
+{ 0x18, 262, 0, 945 },
+{ 0x4, 262, 0, 962 },
+{ 0x2, 262, 0, 963 },
+{ 0x1, 262, 1, 964 },
+{ 0x1, 263, 0, 850 },
+{ 0x500, 259, 0, 868 },
+{ 0x1500, 259, 0, 866 },
+{ 0xd00, 259, 0, 867 },
+{ 0x300, 259, 0, 880 },
+{ 0x1300, 259, 0, 856 },
+{ 0x5300, 259, 0, 854 },
+{ 0x3300, 259, 0, 855 },
+{ 0xb00, 259, 0, 878 },
+{ 0x700, 259, 0, 879 },
+{ 0x80, 259, 0, 901 },
+{ 0x280, 259, 0, 899 },
+{ 0x180, 259, 0, 900 },
+{ 0x40, 259, 0, 913 },
+{ 0x140, 259, 0, 911 },
+{ 0xc0, 259, 0, 912 },
+{ 0x20, 259, 0, 925 },
+{ 0xa0, 259, 0, 923 },
+{ 0x60, 259, 0, 924 },
+{ 0x10, 259, 0, 937 },
+{ 0x50, 259, 0, 935 },
+{ 0x30, 259, 0, 936 },
+{ 0x8, 259, 0, 949 },
+{ 0x28, 259, 0, 947 },
+{ 0x18, 259, 0, 948 },
+{ 0x4, 259, 0, 965 },
+{ 0x2, 259, 0, 966 },
+{ 0x1, 259, 0, 967 },
+{ 0x500, 256, 0, 871 },
+{ 0x1500, 256, 0, 869 },
+{ 0xd00, 256, 0, 870 },
+{ 0x300, 256, 0, 883 },
+{ 0x1300, 256, 0, 859 },
+{ 0x5300, 256, 0, 857 },
+{ 0x3300, 256, 0, 858 },
+{ 0xb00, 256, 0, 881 },
+{ 0x700, 256, 0, 882 },
+{ 0x80, 256, 0, 904 },
+{ 0x280, 256, 0, 902 },
+{ 0x180, 256, 0, 903 },
+{ 0x40, 256, 0, 916 },
+{ 0x140, 256, 0, 914 },
+{ 0xc0, 256, 0, 915 },
+{ 0x20, 256, 0, 928 },
+{ 0xa0, 256, 0, 926 },
+{ 0x60, 256, 0, 927 },
+{ 0x10, 256, 0, 940 },
+{ 0x50, 256, 0, 938 },
+{ 0x30, 256, 0, 939 },
+{ 0x8, 256, 0, 952 },
+{ 0x28, 256, 0, 950 },
+{ 0x18, 256, 0, 951 },
+{ 0x4, 256, 0, 968 },
+{ 0x2, 256, 0, 969 },
+{ 0x1, 256, 0, 970 },
+{ 0x500, 251, 0, 874 },
+{ 0x1500, 251, 0, 872 },
+{ 0xd00, 251, 0, 873 },
+{ 0x300, 251, 0, 886 },
+{ 0x1300, 251, 0, 862 },
+{ 0x5300, 251, 0, 860 },
+{ 0x3300, 251, 0, 861 },
+{ 0xb00, 251, 0, 884 },
+{ 0x700, 251, 0, 885 },
+{ 0x80, 251, 0, 907 },
+{ 0x280, 251, 0, 905 },
+{ 0x180, 251, 0, 906 },
+{ 0x40, 251, 0, 919 },
+{ 0x140, 251, 0, 917 },
+{ 0xc0, 251, 0, 918 },
+{ 0x20, 251, 0, 931 },
+{ 0xa0, 251, 0, 929 },
+{ 0x60, 251, 0, 930 },
+{ 0x10, 251, 0, 943 },
+{ 0x50, 251, 0, 941 },
+{ 0x30, 251, 0, 942 },
+{ 0x8, 251, 0, 955 },
+{ 0x28, 251, 0, 953 },
+{ 0x18, 251, 0, 954 },
+{ 0x4, 251, 0, 971 },
+{ 0x2, 251, 0, 972 },
+{ 0x1, 251, 0, 973 },
+{ 0x2, 150, 0, 975 },
+{ 0x1, 150, 0, 976 },
+{ 0x1, 50, 0, 977 },
+{ 0x3, 49, 0, 978 },
+{ 0x1, 428, 0, 979 },
+{ 0x1, 438, 0, 980 },
+{ 0x2, 386, 0, 983 },
+{ 0x1, 386, 0, 984 },
+{ 0x2, 384, 0, 985 },
+{ 0x1, 384, 0, 986 },
+{ 0x1, 383, 0, 987 },
+{ 0x1, 328, 0, 992 },
+{ 0x1, 327, 0, 993 },
+{ 0x1, 326, 0, 994 },
+{ 0x1, 325, 0, 995 },
+{ 0x1, 250, 0, 996 },
+{ 0x1, 249, 0, 997 },
+{ 0x1, 324, 0, 998 },
+{ 0x1, 323, 0, 999 },
+{ 0x1, 322, 0, 1000 },
+{ 0x1, 321, 0, 1001 },
+{ 0x1, 320, 0, 1002 },
+{ 0x1, 319, 0, 1003 },
+{ 0x1, 318, 0, 1004 },
+{ 0x2, 248, 0, 1005 },
+{ 0x1, 248, 0, 1006 },
+{ 0x2, 366, 0, 1012 },
+{ 0x1, 366, 0, 1013 },
+{ 0x1, 317, 0, 1014 },
+{ 0x1, 316, 0, 1015 },
+{ 0x1, 315, 0, 1016 },
+{ 0x1, 314, 0, 1017 },
+{ 0x1, 8, 1, 1019 },
+{ 0x1, 9, 0, 1018 },
+{ 0x1, 313, 0, 1020 },
+{ 0x1, 312, 0, 1021 },
+{ 0x1, 311, 0, 1022 },
+{ 0x1, 310, 0, 1023 },
+{ 0x1, 388, 0, 1024 },
+{ 0x1, 399, 0, 1025 },
+{ 0x1, 389, 0, 1026 },
+{ 0x1, 423, 0, 1027 },
+{ 0x1, 309, 0, 1031 },
+{ 0x1, 247, 0, 1032 },
+{ 0x1, 177, 0, 1035 },
+{ 0x2, 291, 0, 1039 },
+{ 0x1, 291, 0, 1040 },
+{ 0x1, 236, 0, 1041 },
+{ 0x5, 48, 0, 1043 },
+{ 0x3, 48, 0, 1044 },
+{ 0x5, 47, 0, 1045 },
+{ 0x3, 47, 0, 1046 },
+{ 0x1, 365, 0, 1047 },
+{ 0x1, 373, 0, 1048 },
+{ 0x1, 371, 0, 1049 },
+{ 0x1, 392, 0, 1050 },
+{ 0x1, 372, 0, 1051 },
+{ 0x1, 370, 0, 1052 },
+{ 0x2, 378, 0, 1053 },
+{ 0x1, 378, 0, 1055 },
+{ 0x2, 376, 0, 1054 },
+{ 0x1, 376, 0, 1056 },
+{ 0x2, 396, 0, 1057 },
+{ 0x1, 396, 0, 1060 },
+{ 0x2, 377, 0, 1058 },
+{ 0x1, 377, 0, 1061 },
+{ 0x2, 375, 0, 1059 },
+{ 0x1, 375, 0, 1062 },
+{ 0x1, 338, 0, 1063 },
+{ 0x1, 337, 0, 1064 },
+{ 0x1, 369, 0, 1065 },
+{ 0x1, 360, 0, 1066 },
+{ 0x1, 362, 0, 1067 },
+{ 0x1, 359, 0, 1068 },
+{ 0x1, 361, 0, 1069 },
+{ 0x2, 442, 0, 1070 },
+{ 0x1, 442, 0, 1073 },
+{ 0x2, 441, 0, 1071 },
+{ 0x1, 441, 0, 1074 },
+{ 0x2, 440, 0, 1072 },
+{ 0x1, 440, 0, 1075 },
+{ 0x1, 348, 0, 1076 },
+{ 0x2, 347, 0, 1077 },
+{ 0x1, 347, 0, 1078 },
+{ 0x2, 294, 0, 1079 },
+{ 0x1, 294, 0, 1082 },
+{ 0x2, 293, 0, 1080 },
+{ 0x1, 293, 0, 1083 },
+{ 0x2, 292, 0, 1081 },
+{ 0x1, 292, 0, 1084 },
+{ 0x2, 363, 0, 1085 },
+{ 0x1, 363, 0, 1086 },
+{ 0x2, 364, 0, 1087 },
+{ 0x1, 364, 0, 1088 },
+{ 0xa, 434, 1, 1100 },
+{ 0xa, 435, 1, 1099 },
+{ 0xa, 436, 1, 1098 },
+{ 0xa, 437, 0, 1097 },
+{ 0x1a, 434, 1, 1092 },
+{ 0x1a, 435, 1, 1091 },
+{ 0x32, 436, 1, 1090 },
+{ 0x32, 437, 0, 1089 },
+{ 0x6, 434, 1, 1108 },
+{ 0x6, 435, 1, 1107 },
+{ 0x6, 436, 1, 1106 },
+{ 0x6, 437, 0, 1105 },
+{ 0x1, 434, 1, 1120 },
+{ 0x1, 435, 1, 1119 },
+{ 0x1, 436, 1, 1118 },
+{ 0x1, 437, 0, 1117 },
+{ 0x9, 434, 1, 1104 },
+{ 0x9, 435, 1, 1103 },
+{ 0x9, 436, 1, 1102 },
+{ 0x9, 437, 0, 1101 },
+{ 0x19, 434, 1, 1096 },
+{ 0x19, 435, 1, 1095 },
+{ 0x31, 436, 1, 1094 },
+{ 0x31, 437, 0, 1093 },
+{ 0x5, 434, 1, 1112 },
+{ 0x5, 435, 1, 1111 },
+{ 0x5, 436, 1, 1110 },
+{ 0x5, 437, 0, 1109 },
+{ 0x3, 434, 1, 1116 },
+{ 0x3, 435, 1, 1115 },
+{ 0x3, 436, 1, 1114 },
+{ 0x3, 437, 0, 1113 },
+{ 0xa, 429, 1, 1132 },
+{ 0xa, 430, 1, 1131 },
+{ 0xa, 431, 1, 1130 },
+{ 0xa, 432, 0, 1129 },
+{ 0x1a, 429, 1, 1124 },
+{ 0x1a, 430, 1, 1123 },
+{ 0x32, 431, 1, 1122 },
+{ 0x32, 432, 0, 1121 },
+{ 0x6, 429, 1, 1140 },
+{ 0x6, 430, 1, 1139 },
+{ 0x6, 431, 1, 1138 },
+{ 0x6, 432, 0, 1137 },
+{ 0x1, 429, 1, 1152 },
+{ 0x1, 430, 1, 1151 },
+{ 0x1, 431, 1, 1150 },
+{ 0x1, 432, 0, 1149 },
+{ 0x9, 429, 1, 1136 },
+{ 0x9, 430, 1, 1135 },
+{ 0x9, 431, 1, 1134 },
+{ 0x9, 432, 0, 1133 },
+{ 0x19, 429, 1, 1128 },
+{ 0x19, 430, 1, 1127 },
+{ 0x31, 431, 1, 1126 },
+{ 0x31, 432, 0, 1125 },
+{ 0x5, 429, 1, 1144 },
+{ 0x5, 430, 1, 1143 },
+{ 0x5, 431, 1, 1142 },
+{ 0x5, 432, 0, 1141 },
+{ 0x3, 429, 1, 1148 },
+{ 0x3, 430, 1, 1147 },
+{ 0x3, 431, 1, 1146 },
+{ 0x3, 432, 0, 1145 },
+{ 0x1, 139, 0, 1153 },
+{ 0x1, 138, 0, 1154 },
+{ 0x1, 391, 1, 1156 },
+{ 0x1, 137, 0, 1155 },
+{ 0x2, 395, 1, 1158 },
+{ 0x2, 141, 0, 1157 },
+{ 0x1, 395, 1, 1160 },
+{ 0x1, 141, 0, 1159 },
+{ 0x1, 397, 0, 1161 },
+{ 0x1, 136, 0, 1162 },
+{ 0x2, 135, 0, 1163 },
+{ 0x2, 134, 0, 1164 },
+{ 0x1, 454, 1, 1170 },
+{ 0x1, 246, 0, 1033 },
+{ 0x1, 453, 0, 1171 },
+{ 0x1, 452, 1, 1172 },
+{ 0x1, 245, 0, 1042 },
+{ 0x1, 308, 0, 1173 },
+{ 0x1, 307, 1, 1174 },
+{ 0x1, 290, 0, 1034 },
+{ 0x1, 306, 0, 1175 },
+{ 0x1, 305, 1, 1176 },
+{ 0x1, 427, 0, 1036 },
+{ 0x1, 304, 1, 1177 },
+{ 0x1, 398, 0, 1038 },
+{ 0x1, 303, 0, 1178 },
+{ 0x1, 302, 0, 1179 },
+{ 0x1, 301, 0, 1180 },
+{ 0x1, 300, 1, 1181 },
+{ 0x2, 398, 0, 1037 },
+{ 0x10, 299, 0, 1185 },
+{ 0x90, 299, 0, 1183 },
+{ 0x190, 299, 0, 1182 },
+{ 0x50, 299, 0, 1184 },
+{ 0x30, 299, 0, 1187 },
+{ 0x70, 299, 0, 1186 },
+{ 0x8, 299, 0, 1189 },
+{ 0x18, 299, 0, 1188 },
+{ 0x4, 299, 0, 1190 },
+{ 0x1, 299, 0, 1193 },
+{ 0x3, 299, 0, 1192 },
+{ 0x1, 298, 1, 1194 },
+{ 0x2, 299, 0, 1191 },
+{ 0x3, 46, 0, 1195 },
+{ 0x1, 241, 1, 1196 },
+{ 0x1, 242, 1, 1028 },
+{ 0x1, 243, 0, 88 },
+{ 0x1, 341, 1, 1197 },
+{ 0x1, 342, 1, 1029 },
+{ 0x1, 343, 0, 89 },
+{ 0x1, 34, 1, 1198 },
+{ 0x1, 35, 1, 1030 },
+{ 0x1, 36, 0, 90 },
+{ 0x1, 230, 0, 1199 },
+{ 0x4, 447, 0, 1200 },
+{ 0x2, 447, 0, 1201 },
+{ 0x1, 447, 1, 1203 },
+{ 0x1, 448, 0, 1202 },
+{ 0x8, 449, 0, 1204 },
+{ 0x4, 449, 0, 1205 },
+{ 0x1, 449, 1, 1207 },
+{ 0x2, 449, 0, 1206 },
+{ 0x8, 219, 0, 1208 },
+{ 0x4, 219, 0, 1209 },
+{ 0x2, 219, 0, 1210 },
+{ 0x1, 219, 1, 1212 },
+{ 0x1, 220, 0, 1211 },
+{ 0x10, 221, 0, 1213 },
+{ 0x8, 221, 0, 1214 },
+{ 0x4, 221, 0, 1215 },
+{ 0x1, 221, 1, 1217 },
+{ 0x2, 221, 0, 1216 },
+{ 0x220, 191, 0, 1218 },
+{ 0x120, 191, 0, 1219 },
+{ 0xa0, 191, 0, 1220 },
+{ 0x60, 191, 1, 1222 },
+{ 0x4, 192, 0, 1221 },
+{ 0x110, 191, 0, 1228 },
+{ 0x90, 191, 0, 1229 },
+{ 0x50, 191, 0, 1230 },
+{ 0x30, 191, 1, 1232 },
+{ 0x2, 192, 0, 1231 },
+{ 0x8, 191, 0, 1233 },
+{ 0x4, 191, 0, 1234 },
+{ 0x2, 191, 0, 1235 },
+{ 0x1, 191, 1, 1237 },
+{ 0x1, 192, 0, 1236 },
+{ 0x440, 193, 0, 1223 },
+{ 0x240, 193, 0, 1224 },
+{ 0x140, 193, 0, 1225 },
+{ 0xc0, 193, 1, 1227 },
+{ 0x40, 193, 0, 1226 },
+{ 0x220, 193, 0, 1238 },
+{ 0x120, 193, 0, 1239 },
+{ 0xa0, 193, 0, 1240 },
+{ 0x60, 193, 1, 1242 },
+{ 0x20, 193, 0, 1241 },
+{ 0x10, 193, 0, 1243 },
+{ 0x8, 193, 0, 1244 },
+{ 0x4, 193, 0, 1245 },
+{ 0x1, 193, 1, 1247 },
+{ 0x2, 193, 0, 1246 },
+{ 0x8, 215, 0, 1248 },
+{ 0x4, 215, 0, 1249 },
+{ 0x2, 215, 0, 1250 },
+{ 0x1, 215, 1, 1252 },
+{ 0x1, 216, 0, 1251 },
+{ 0x220, 187, 0, 1253 },
+{ 0x120, 187, 0, 1254 },
+{ 0xa0, 187, 0, 1255 },
+{ 0x60, 187, 1, 1257 },
+{ 0x4, 188, 0, 1256 },
+{ 0x110, 187, 0, 1263 },
+{ 0x90, 187, 0, 1264 },
+{ 0x50, 187, 0, 1265 },
+{ 0x30, 187, 1, 1267 },
+{ 0x2, 188, 0, 1266 },
+{ 0x8, 187, 0, 1268 },
+{ 0x4, 187, 0, 1269 },
+{ 0x2, 187, 0, 1270 },
+{ 0x1, 187, 1, 1272 },
+{ 0x1, 188, 0, 1271 },
+{ 0x440, 233, 0, 1258 },
+{ 0x240, 233, 0, 1259 },
+{ 0x140, 233, 0, 1260 },
+{ 0xc0, 233, 1, 1262 },
+{ 0x40, 233, 0, 1261 },
+{ 0x220, 233, 0, 1273 },
+{ 0x120, 233, 0, 1274 },
+{ 0xa0, 233, 0, 1275 },
+{ 0x60, 233, 1, 1277 },
+{ 0x20, 233, 0, 1276 },
+{ 0x10, 233, 0, 1278 },
+{ 0x8, 233, 0, 1279 },
+{ 0x4, 233, 0, 1280 },
+{ 0x1, 233, 1, 1282 },
+{ 0x2, 233, 0, 1281 },
+{ 0x8, 207, 0, 1283 },
+{ 0x4, 207, 0, 1284 },
+{ 0x2, 207, 0, 1285 },
+{ 0x1, 207, 1, 1287 },
+{ 0x1, 208, 0, 1286 },
+{ 0x10, 214, 0, 1288 },
+{ 0x8, 214, 0, 1289 },
+{ 0x4, 214, 0, 1290 },
+{ 0x1, 214, 1, 1292 },
+{ 0x2, 214, 0, 1291 },
+{ 0x220, 178, 0, 1293 },
+{ 0x120, 178, 0, 1294 },
+{ 0xa0, 178, 0, 1295 },
+{ 0x60, 178, 1, 1297 },
+{ 0x4, 179, 0, 1296 },
+{ 0x110, 178, 0, 1318 },
+{ 0x90, 178, 0, 1319 },
+{ 0x50, 178, 0, 1320 },
+{ 0x30, 178, 1, 1322 },
+{ 0x2, 179, 0, 1321 },
+{ 0x8, 178, 0, 1323 },
+{ 0x4, 178, 0, 1324 },
+{ 0x2, 178, 0, 1325 },
+{ 0x1, 178, 1, 1327 },
+{ 0x1, 179, 0, 1326 },
+{ 0x440, 186, 0, 1298 },
+{ 0x240, 186, 0, 1299 },
+{ 0x140, 186, 0, 1300 },
+{ 0xc0, 186, 1, 1302 },
+{ 0x40, 186, 0, 1301 },
+{ 0x220, 186, 0, 1328 },
+{ 0x120, 186, 0, 1329 },
+{ 0xa0, 186, 0, 1330 },
+{ 0x60, 186, 1, 1332 },
+{ 0x20, 186, 0, 1331 },
+{ 0x10, 186, 0, 1333 },
+{ 0x8, 186, 0, 1334 },
+{ 0x4, 186, 0, 1335 },
+{ 0x1, 186, 1, 1337 },
+{ 0x2, 186, 0, 1336 },
+{ 0x440, 143, 0, 1303 },
+{ 0x240, 143, 0, 1304 },
+{ 0x140, 143, 0, 1305 },
+{ 0xc0, 143, 1, 1307 },
+{ 0x40, 143, 0, 1306 },
+{ 0x220, 143, 0, 1338 },
+{ 0x120, 143, 0, 1339 },
+{ 0xa0, 143, 0, 1340 },
+{ 0x60, 143, 1, 1342 },
+{ 0x20, 143, 0, 1341 },
+{ 0x10, 143, 0, 1343 },
+{ 0x8, 143, 0, 1344 },
+{ 0x1, 143, 1, 1347 },
+{ 0x2, 143, 0, 1346 },
+{ 0x440, 194, 1, 1313 },
+{ 0x441, 174, 0, 1308 },
+{ 0x240, 194, 1, 1314 },
+{ 0x241, 174, 0, 1309 },
+{ 0x140, 194, 1, 1315 },
+{ 0x141, 174, 0, 1310 },
+{ 0xc0, 194, 1, 1317 },
+{ 0x40, 194, 1, 1316 },
+{ 0xc1, 174, 1, 1312 },
+{ 0x41, 174, 0, 1311 },
+{ 0x220, 194, 1, 1358 },
+{ 0x221, 174, 0, 1348 },
+{ 0x120, 194, 1, 1359 },
+{ 0x121, 174, 0, 1349 },
+{ 0xa0, 194, 1, 1360 },
+{ 0xa1, 174, 0, 1350 },
+{ 0x60, 194, 1, 1362 },
+{ 0x20, 194, 1, 1361 },
+{ 0x61, 174, 1, 1352 },
+{ 0x21, 174, 0, 1351 },
+{ 0x10, 194, 1, 1363 },
+{ 0x11, 174, 0, 1353 },
+{ 0x8, 194, 1, 1364 },
+{ 0x9, 174, 0, 1354 },
+{ 0x4, 194, 1, 1365 },
+{ 0x5, 174, 0, 1355 },
+{ 0x1, 194, 1, 1367 },
+{ 0x2, 194, 1, 1366 },
+{ 0x3, 174, 1, 1357 },
+{ 0x1, 174, 0, 1356 },
+{ 0x1, 153, 1, 1375 },
+{ 0x1, 154, 1, 1374 },
+{ 0x1, 155, 1, 1373 },
+{ 0x1, 156, 0, 1372 },
+{ 0x3, 153, 1, 1371 },
+{ 0x3, 154, 1, 1370 },
+{ 0x3, 155, 1, 1369 },
+{ 0x3, 156, 0, 1368 },
+{ 0x1108, 159, 1, 1537 },
+{ 0x1108, 160, 1, 1536 },
+{ 0x1108, 165, 1, 1377 },
+{ 0x1108, 166, 0, 1376 },
+{ 0x908, 159, 1, 1539 },
+{ 0x908, 160, 1, 1538 },
+{ 0x908, 165, 1, 1379 },
+{ 0x908, 166, 0, 1378 },
+{ 0x508, 159, 1, 1541 },
+{ 0x508, 160, 1, 1540 },
+{ 0x508, 165, 1, 1381 },
+{ 0x508, 166, 0, 1380 },
+{ 0x308, 159, 1, 1545 },
+{ 0x308, 160, 1, 1544 },
+{ 0x108, 160, 1, 1542 },
+{ 0x18, 161, 1, 1543 },
+{ 0x308, 165, 1, 1385 },
+{ 0x308, 166, 1, 1384 },
+{ 0x108, 166, 1, 1382 },
+{ 0x18, 167, 0, 1383 },
+{ 0x88, 159, 1, 1577 },
+{ 0x88, 160, 1, 1576 },
+{ 0x88, 165, 1, 1457 },
+{ 0x88, 166, 0, 1456 },
+{ 0x48, 159, 1, 1579 },
+{ 0x48, 160, 1, 1578 },
+{ 0x48, 165, 1, 1459 },
+{ 0x48, 166, 0, 1458 },
+{ 0x28, 159, 1, 1581 },
+{ 0x28, 160, 1, 1580 },
+{ 0x28, 165, 1, 1461 },
+{ 0x28, 166, 0, 1460 },
+{ 0x18, 159, 1, 1585 },
+{ 0x18, 160, 1, 1584 },
+{ 0x8, 160, 1, 1582 },
+{ 0x8, 161, 1, 1583 },
+{ 0x18, 165, 1, 1465 },
+{ 0x18, 166, 1, 1464 },
+{ 0x8, 166, 1, 1462 },
+{ 0x8, 167, 0, 1463 },
+{ 0x884, 159, 1, 1547 },
+{ 0x884, 160, 1, 1546 },
+{ 0x442, 162, 1, 1437 },
+{ 0x442, 163, 1, 1436 },
+{ 0x884, 165, 1, 1407 },
+{ 0x884, 166, 1, 1406 },
+{ 0x442, 168, 1, 1387 },
+{ 0x442, 169, 0, 1386 },
+{ 0x484, 159, 1, 1549 },
+{ 0x484, 160, 1, 1548 },
+{ 0x242, 162, 1, 1439 },
+{ 0x242, 163, 1, 1438 },
+{ 0x484, 165, 1, 1409 },
+{ 0x484, 166, 1, 1408 },
+{ 0x242, 168, 1, 1389 },
+{ 0x242, 169, 0, 1388 },
+{ 0x284, 159, 1, 1551 },
+{ 0x284, 160, 1, 1550 },
+{ 0x142, 162, 1, 1441 },
+{ 0x142, 163, 1, 1440 },
+{ 0x284, 165, 1, 1411 },
+{ 0x284, 166, 1, 1410 },
+{ 0x142, 168, 1, 1391 },
+{ 0x142, 169, 0, 1390 },
+{ 0x184, 159, 1, 1555 },
+{ 0x184, 160, 1, 1554 },
+{ 0x84, 160, 1, 1552 },
+{ 0xc, 161, 1, 1553 },
+{ 0xc2, 162, 1, 1445 },
+{ 0xc2, 163, 1, 1444 },
+{ 0x42, 163, 1, 1442 },
+{ 0x6, 164, 1, 1443 },
+{ 0x184, 165, 1, 1415 },
+{ 0x184, 166, 1, 1414 },
+{ 0x84, 166, 1, 1412 },
+{ 0xc, 167, 1, 1413 },
+{ 0xc2, 168, 1, 1395 },
+{ 0xc2, 169, 1, 1394 },
+{ 0x42, 169, 1, 1392 },
+{ 0x6, 170, 0, 1393 },
+{ 0x44, 159, 1, 1587 },
+{ 0x44, 160, 1, 1586 },
+{ 0x22, 162, 1, 1517 },
+{ 0x22, 163, 1, 1516 },
+{ 0x44, 165, 1, 1487 },
+{ 0x44, 166, 1, 1486 },
+{ 0x22, 168, 1, 1467 },
+{ 0x22, 169, 0, 1466 },
+{ 0x24, 159, 1, 1589 },
+{ 0x24, 160, 1, 1588 },
+{ 0x12, 162, 1, 1519 },
+{ 0x12, 163, 1, 1518 },
+{ 0x24, 165, 1, 1489 },
+{ 0x24, 166, 1, 1488 },
+{ 0x12, 168, 1, 1469 },
+{ 0x12, 169, 0, 1468 },
+{ 0x14, 159, 1, 1591 },
+{ 0x14, 160, 1, 1590 },
+{ 0xa, 162, 1, 1521 },
+{ 0xa, 163, 1, 1520 },
+{ 0x14, 165, 1, 1491 },
+{ 0x14, 166, 1, 1490 },
+{ 0xa, 168, 1, 1471 },
+{ 0xa, 169, 0, 1470 },
+{ 0xc, 159, 1, 1595 },
+{ 0xc, 160, 1, 1594 },
+{ 0x4, 160, 1, 1592 },
+{ 0x4, 161, 1, 1593 },
+{ 0x6, 162, 1, 1525 },
+{ 0x6, 163, 1, 1524 },
+{ 0x2, 163, 1, 1522 },
+{ 0x2, 164, 1, 1523 },
+{ 0xc, 165, 1, 1495 },
+{ 0xc, 166, 1, 1494 },
+{ 0x4, 166, 1, 1492 },
+{ 0x4, 167, 1, 1493 },
+{ 0x6, 168, 1, 1475 },
+{ 0x6, 169, 1, 1474 },
+{ 0x2, 169, 1, 1472 },
+{ 0x2, 170, 0, 1473 },
+{ 0x442, 159, 1, 1557 },
+{ 0x442, 160, 1, 1556 },
+{ 0x221, 162, 1, 1447 },
+{ 0x221, 163, 1, 1446 },
+{ 0x442, 165, 1, 1417 },
+{ 0x442, 166, 1, 1416 },
+{ 0x221, 168, 1, 1397 },
+{ 0x221, 169, 0, 1396 },
+{ 0x242, 159, 1, 1559 },
+{ 0x242, 160, 1, 1558 },
+{ 0x121, 162, 1, 1449 },
+{ 0x121, 163, 1, 1448 },
+{ 0x242, 165, 1, 1419 },
+{ 0x242, 166, 1, 1418 },
+{ 0x121, 168, 1, 1399 },
+{ 0x121, 169, 0, 1398 },
+{ 0x142, 159, 1, 1561 },
+{ 0x142, 160, 1, 1560 },
+{ 0xa1, 162, 1, 1451 },
+{ 0xa1, 163, 1, 1450 },
+{ 0x142, 165, 1, 1421 },
+{ 0x142, 166, 1, 1420 },
+{ 0xa1, 168, 1, 1401 },
+{ 0xa1, 169, 0, 1400 },
+{ 0xc2, 159, 1, 1565 },
+{ 0xc2, 160, 1, 1564 },
+{ 0x42, 160, 1, 1562 },
+{ 0x6, 161, 1, 1563 },
+{ 0x61, 162, 1, 1455 },
+{ 0x61, 163, 1, 1454 },
+{ 0x21, 163, 1, 1452 },
+{ 0x3, 164, 1, 1453 },
+{ 0xc2, 165, 1, 1425 },
+{ 0xc2, 166, 1, 1424 },
+{ 0x42, 166, 1, 1422 },
+{ 0x6, 167, 1, 1423 },
+{ 0x61, 168, 1, 1405 },
+{ 0x61, 169, 1, 1404 },
+{ 0x21, 169, 1, 1402 },
+{ 0x3, 170, 0, 1403 },
+{ 0x22, 159, 1, 1597 },
+{ 0x22, 160, 1, 1596 },
+{ 0x11, 162, 1, 1527 },
+{ 0x11, 163, 1, 1526 },
+{ 0x22, 165, 1, 1497 },
+{ 0x22, 166, 1, 1496 },
+{ 0x11, 168, 1, 1477 },
+{ 0x11, 169, 0, 1476 },
+{ 0x12, 159, 1, 1599 },
+{ 0x12, 160, 1, 1598 },
+{ 0x9, 162, 1, 1529 },
+{ 0x9, 163, 1, 1528 },
+{ 0x12, 165, 1, 1499 },
+{ 0x12, 166, 1, 1498 },
+{ 0x9, 168, 1, 1479 },
+{ 0x9, 169, 0, 1478 },
+{ 0xa, 159, 1, 1601 },
+{ 0xa, 160, 1, 1600 },
+{ 0x5, 162, 1, 1531 },
+{ 0x5, 163, 1, 1530 },
+{ 0xa, 165, 1, 1501 },
+{ 0xa, 166, 1, 1500 },
+{ 0x5, 168, 1, 1481 },
+{ 0x5, 169, 0, 1480 },
+{ 0x6, 159, 1, 1605 },
+{ 0x6, 160, 1, 1604 },
+{ 0x2, 160, 1, 1602 },
+{ 0x2, 161, 1, 1603 },
+{ 0x3, 162, 1, 1535 },
+{ 0x3, 163, 1, 1534 },
+{ 0x1, 163, 1, 1532 },
+{ 0x1, 164, 1, 1533 },
+{ 0x6, 165, 1, 1505 },
+{ 0x6, 166, 1, 1504 },
+{ 0x2, 166, 1, 1502 },
+{ 0x2, 167, 1, 1503 },
+{ 0x3, 168, 1, 1485 },
+{ 0x3, 169, 1, 1484 },
+{ 0x1, 169, 1, 1482 },
+{ 0x1, 170, 0, 1483 },
+{ 0x221, 159, 1, 1567 },
+{ 0x221, 160, 1, 1566 },
+{ 0x221, 165, 1, 1427 },
+{ 0x221, 166, 0, 1426 },
+{ 0x121, 159, 1, 1569 },
+{ 0x121, 160, 1, 1568 },
+{ 0x121, 165, 1, 1429 },
+{ 0x121, 166, 0, 1428 },
+{ 0xa1, 159, 1, 1571 },
+{ 0xa1, 160, 1, 1570 },
+{ 0xa1, 165, 1, 1431 },
+{ 0xa1, 166, 0, 1430 },
+{ 0x61, 159, 1, 1575 },
+{ 0x61, 160, 1, 1574 },
+{ 0x21, 160, 1, 1572 },
+{ 0x3, 161, 1, 1573 },
+{ 0x61, 165, 1, 1435 },
+{ 0x61, 166, 1, 1434 },
+{ 0x21, 166, 1, 1432 },
+{ 0x3, 167, 0, 1433 },
+{ 0x11, 159, 1, 1607 },
+{ 0x11, 160, 1, 1606 },
+{ 0x11, 165, 1, 1507 },
+{ 0x11, 166, 0, 1506 },
+{ 0x9, 159, 1, 1609 },
+{ 0x9, 160, 1, 1608 },
+{ 0x9, 165, 1, 1509 },
+{ 0x9, 166, 0, 1508 },
+{ 0x5, 159, 1, 1611 },
+{ 0x5, 160, 1, 1610 },
+{ 0x5, 165, 1, 1511 },
+{ 0x5, 166, 0, 1510 },
+{ 0x3, 159, 1, 1615 },
+{ 0x3, 160, 1, 1614 },
+{ 0x1, 160, 1, 1612 },
+{ 0x1, 161, 1, 1613 },
+{ 0x3, 165, 1, 1515 },
+{ 0x3, 166, 1, 1514 },
+{ 0x1, 166, 1, 1512 },
+{ 0x1, 167, 0, 1513 },
+{ 0x442, 205, 0, 1616 },
+{ 0x242, 205, 0, 1617 },
+{ 0x142, 205, 0, 1618 },
+{ 0xc2, 205, 1, 1620 },
+{ 0x6, 206, 1, 1619 },
+{ 0x1, 439, 0, 981 },
+{ 0x22, 205, 0, 1626 },
+{ 0x12, 205, 0, 1627 },
+{ 0xa, 205, 0, 1628 },
+{ 0x6, 205, 1, 1630 },
+{ 0x2, 206, 1, 1629 },
+{ 0x2, 367, 0, 1010 },
+{ 0x221, 205, 0, 1621 },
+{ 0x121, 205, 0, 1622 },
+{ 0xa1, 205, 0, 1623 },
+{ 0x61, 205, 1, 1625 },
+{ 0x3, 206, 1, 1624 },
+{ 0x1, 433, 0, 982 },
+{ 0x11, 205, 0, 1631 },
+{ 0x9, 205, 0, 1632 },
+{ 0x5, 205, 0, 1633 },
+{ 0x3, 205, 1, 1635 },
+{ 0x1, 206, 1, 1634 },
+{ 0x1, 367, 0, 1011 },
+{ 0x4, 211, 0, 1636 },
+{ 0x1, 211, 0, 1638 },
+{ 0x1, 218, 0, 1639 },
+{ 0x1, 217, 1, 1640 },
+{ 0x2, 211, 0, 1637 },
+{ 0x1, 196, 0, 1641 },
+{ 0x880, 202, 0, 1642 },
+{ 0x480, 202, 0, 1643 },
+{ 0x280, 202, 0, 1644 },
+{ 0x180, 202, 1, 1646 },
+{ 0x80, 203, 0, 1645 },
+{ 0x440, 202, 1, 1657 },
+{ 0x88, 204, 0, 1647 },
+{ 0x240, 202, 1, 1658 },
+{ 0x48, 204, 0, 1648 },
+{ 0x140, 202, 1, 1659 },
+{ 0x28, 204, 0, 1649 },
+{ 0xc0, 202, 1, 1661 },
+{ 0x40, 203, 1, 1660 },
+{ 0x18, 204, 1, 1651 },
+{ 0x8, 204, 0, 1650 },
+{ 0x220, 202, 1, 1662 },
+{ 0x44, 204, 0, 1652 },
+{ 0x120, 202, 1, 1663 },
+{ 0x24, 204, 0, 1653 },
+{ 0xa0, 202, 1, 1664 },
+{ 0x14, 204, 0, 1654 },
+{ 0x60, 202, 1, 1666 },
+{ 0x20, 203, 1, 1665 },
+{ 0xc, 204, 1, 1656 },
+{ 0x4, 204, 0, 1655 },
+{ 0x110, 202, 0, 1667 },
+{ 0x90, 202, 0, 1668 },
+{ 0x50, 202, 0, 1669 },
+{ 0x30, 202, 1, 1671 },
+{ 0x10, 203, 1, 1670 },
+{ 0x1, 385, 0, 974 },
+{ 0x88, 202, 0, 1672 },
+{ 0x48, 202, 0, 1673 },
+{ 0x28, 202, 0, 1674 },
+{ 0x18, 202, 1, 1676 },
+{ 0x8, 203, 1, 1675 },
+{ 0xc, 368, 0, 1007 },
+{ 0x44, 202, 1, 1687 },
+{ 0x22, 204, 0, 1677 },
+{ 0x24, 202, 1, 1688 },
+{ 0x12, 204, 0, 1678 },
+{ 0x14, 202, 1, 1689 },
+{ 0xa, 204, 0, 1679 },
+{ 0xc, 202, 1, 1691 },
+{ 0x4, 203, 1, 1690 },
+{ 0x6, 204, 1, 1681 },
+{ 0x2, 204, 1, 1680 },
+{ 0x6, 368, 0, 1008 },
+{ 0x22, 202, 1, 1692 },
+{ 0x11, 204, 0, 1682 },
+{ 0x12, 202, 1, 1693 },
+{ 0x9, 204, 0, 1683 },
+{ 0xa, 202, 1, 1694 },
+{ 0x5, 204, 0, 1684 },
+{ 0x6, 202, 1, 1696 },
+{ 0x2, 203, 1, 1695 },
+{ 0x3, 204, 1, 1686 },
+{ 0x1, 204, 1, 1685 },
+{ 0x3, 368, 0, 1009 },
+{ 0x11, 202, 0, 1697 },
+{ 0x9, 202, 0, 1698 },
+{ 0x5, 202, 0, 1699 },
+{ 0x3, 202, 1, 1701 },
+{ 0x1, 203, 0, 1700 },
+{ 0x8, 198, 0, 1702 },
+{ 0x4, 198, 0, 1703 },
+{ 0x2, 198, 0, 1704 },
+{ 0x1, 198, 1, 1706 },
+{ 0x1, 199, 1, 1705 },
+{ 0x1, 332, 0, 988 },
+{ 0x8, 200, 0, 1707 },
+{ 0x4, 200, 0, 1708 },
+{ 0x2, 200, 0, 1709 },
+{ 0x1, 200, 1, 1711 },
+{ 0x1, 201, 1, 1710 },
+{ 0x1, 331, 0, 989 },
+{ 0x8, 209, 0, 1712 },
+{ 0x4, 209, 0, 1713 },
+{ 0x2, 209, 0, 1714 },
+{ 0x1, 209, 1, 1716 },
+{ 0x1, 210, 1, 1715 },
+{ 0x1, 330, 0, 990 },
+{ 0x8, 212, 0, 1717 },
+{ 0x4, 212, 0, 1718 },
+{ 0x2, 212, 0, 1719 },
+{ 0x1, 212, 1, 1721 },
+{ 0x1, 213, 1, 1720 },
+{ 0x1, 329, 0, 991 },
+{ 0x8, 224, 0, 1722 },
+{ 0x4, 224, 0, 1723 },
+{ 0x2, 224, 0, 1724 },
+{ 0x1, 224, 1, 1726 },
+{ 0x1, 225, 0, 1725 },
+{ 0x8, 222, 0, 1727 },
+{ 0x4, 222, 0, 1728 },
+{ 0x2, 222, 0, 1729 },
+{ 0x1, 222, 1, 1731 },
+{ 0x1, 223, 0, 1730 },
+{ 0x1, 240, 0, 1732 },
+{ 0x1, 340, 0, 1733 },
+{ 0x1, 33, 0, 1734 },
+{ 0x8, 151, 0, 1735 },
+{ 0x4, 151, 0, 1736 },
+{ 0x2, 151, 0, 1737 },
+{ 0x1, 151, 1, 1739 },
+{ 0x1, 152, 0, 1738 },
+{ 0x8, 157, 0, 1740 },
+{ 0x4, 157, 0, 1741 },
+{ 0x2, 157, 0, 1742 },
+{ 0x1, 157, 1, 1744 },
+{ 0x1, 158, 0, 1743 },
+{ 0x8, 231, 0, 1745 },
+{ 0x4, 231, 0, 1746 },
+{ 0x2, 231, 0, 1747 },
+{ 0x1, 231, 1, 1749 },
+{ 0x1, 232, 0, 1748 },
+{ 0x1, 173, 0, 1750 },
+{ 0x442, 171, 0, 1751 },
+{ 0x242, 171, 0, 1752 },
+{ 0x142, 171, 0, 1753 },
+{ 0xc2, 171, 1, 1755 },
+{ 0x6, 172, 0, 1754 },
+{ 0x22, 171, 0, 1761 },
+{ 0x12, 171, 0, 1762 },
+{ 0xa, 171, 0, 1763 },
+{ 0x6, 171, 1, 1765 },
+{ 0x2, 172, 1, 1764 },
+{ 0x1, 135, 0, 1165 },
+{ 0x221, 171, 0, 1756 },
+{ 0x121, 171, 0, 1757 },
+{ 0xa1, 171, 0, 1758 },
+{ 0x61, 171, 1, 1760 },
+{ 0x3, 172, 0, 1759 },
+{ 0x11, 171, 0, 1766 },
+{ 0x9, 171, 0, 1767 },
+{ 0x5, 171, 0, 1768 },
+{ 0x3, 171, 1, 1770 },
+{ 0x1, 172, 1, 1769 },
+{ 0x1, 134, 0, 1166 },
+{ 0x1, 237, 0, 1771 },
+{ 0x1, 195, 0, 1772 },
+{ 0x1, 149, 0, 1773 },
+{ 0x1, 148, 0, 1774 },
+{ 0x4, 234, 0, 1775 },
+{ 0x2, 234, 0, 1776 },
+{ 0x1, 234, 0, 1777 },
+{ 0x1, 197, 0, 1778 },
+{ 0x2, 235, 0, 1779 },
+{ 0x1, 235, 0, 1780 },
+{ 0x4, 185, 0, 1781 },
+{ 0x2, 185, 0, 1782 },
+{ 0x1, 185, 0, 1783 },
+{ 0x4, 182, 0, 1784 },
+{ 0x1, 190, 0, 1787 },
+{ 0x1, 189, 1, 1788 },
+{ 0x2, 182, 0, 1785 },
+{ 0x1, 142, 0, 1789 },
+{ 0x1, 297, 1, 1790 },
+{ 0x1, 182, 0, 1786 },
+{ 0x8, 144, 0, 1791 },
+{ 0x4, 144, 0, 1792 },
+{ 0x2, 144, 0, 1793 },
+{ 0x1, 144, 1, 1795 },
+{ 0x1, 145, 0, 1794 },
+{ 0x8, 146, 0, 1796 },
+{ 0x4, 146, 0, 1797 },
+{ 0x2, 146, 0, 1798 },
+{ 0x1, 146, 1, 1800 },
+{ 0x1, 147, 1, 1799 },
+{ 0x1, 426, 0, 1167 },
+{ 0x8, 180, 0, 1801 },
+{ 0x4, 180, 0, 1802 },
+{ 0x2, 180, 0, 1803 },
+{ 0x1, 180, 1, 1805 },
+{ 0x1, 181, 1, 1804 },
+{ 0x1, 425, 0, 1168 },
+{ 0x8, 183, 0, 1806 },
+{ 0x4, 183, 0, 1807 },
+{ 0x2, 183, 0, 1808 },
+{ 0x1, 183, 1, 1810 },
+{ 0x1, 184, 1, 1809 },
+{ 0x1, 424, 0, 1169 },
+{ 0x8, 228, 0, 1811 },
+{ 0x4, 228, 0, 1812 },
+{ 0x2, 228, 0, 1813 },
+{ 0x1, 228, 1, 1815 },
+{ 0x1, 229, 0, 1814 },
+{ 0x8, 226, 0, 1816 },
+{ 0x4, 226, 0, 1817 },
+{ 0x2, 226, 0, 1818 },
+{ 0x1, 226, 1, 1820 },
+{ 0x1, 227, 0, 1819 },
+{ 0x8, 44, 0, 1825 },
+{ 0x18, 44, 0, 1821 },
+{ 0x4, 44, 0, 1826 },
+{ 0xc, 44, 0, 1822 },
+{ 0x2, 44, 0, 1827 },
+{ 0x6, 44, 0, 1823 },
+{ 0x1, 44, 0, 1828 },
+{ 0x3, 44, 0, 1824 },
+{ 0x51, 30, 0, 1830 },
+{ 0xd1, 30, 0, 1829 },
+{ 0x31, 30, 1, 1840 },
+{ 0x11, 31, 0, 1839 },
+{ 0x71, 30, 1, 1838 },
+{ 0x31, 31, 0, 1837 },
+{ 0x29, 30, 0, 1832 },
+{ 0x69, 30, 0, 1831 },
+{ 0x19, 30, 1, 1844 },
+{ 0x9, 31, 0, 1843 },
+{ 0x39, 30, 1, 1842 },
+{ 0x19, 31, 0, 1841 },
+{ 0x15, 30, 0, 1834 },
+{ 0x35, 30, 0, 1833 },
+{ 0xd, 30, 1, 1848 },
+{ 0x5, 31, 0, 1847 },
+{ 0x1d, 30, 1, 1846 },
+{ 0xd, 31, 0, 1845 },
+{ 0xb, 30, 0, 1836 },
+{ 0x1b, 30, 0, 1835 },
+{ 0x7, 30, 1, 1852 },
+{ 0x3, 31, 0, 1851 },
+{ 0xf, 30, 1, 1850 },
+{ 0x7, 31, 0, 1849 },
+{ 0xa2, 28, 0, 1854 },
+{ 0x1a2, 28, 0, 1853 },
+{ 0x62, 28, 1, 1864 },
+{ 0x22, 29, 0, 1863 },
+{ 0xe2, 28, 1, 1862 },
+{ 0x62, 29, 0, 1861 },
+{ 0x52, 28, 0, 1856 },
+{ 0xd2, 28, 0, 1855 },
+{ 0x32, 28, 1, 1868 },
+{ 0x12, 29, 0, 1867 },
+{ 0x72, 28, 1, 1866 },
+{ 0x32, 29, 0, 1865 },
+{ 0x2a, 28, 0, 1858 },
+{ 0x6a, 28, 0, 1857 },
+{ 0x1a, 28, 1, 1872 },
+{ 0xa, 29, 0, 1871 },
+{ 0x3a, 28, 1, 1870 },
+{ 0x1a, 29, 0, 1869 },
+{ 0x16, 28, 0, 1860 },
+{ 0x36, 28, 0, 1859 },
+{ 0xe, 28, 1, 1876 },
+{ 0x6, 29, 0, 1875 },
+{ 0x1e, 28, 1, 1874 },
+{ 0xe, 29, 0, 1873 },
+{ 0x51, 28, 0, 1878 },
+{ 0xd1, 28, 0, 1877 },
+{ 0x31, 28, 1, 1888 },
+{ 0x11, 29, 0, 1887 },
+{ 0x71, 28, 1, 1886 },
+{ 0x31, 29, 0, 1885 },
+{ 0x29, 28, 0, 1880 },
+{ 0x69, 28, 0, 1879 },
+{ 0x19, 28, 1, 1892 },
+{ 0x9, 29, 0, 1891 },
+{ 0x39, 28, 1, 1890 },
+{ 0x19, 29, 0, 1889 },
+{ 0x15, 28, 0, 1882 },
+{ 0x35, 28, 0, 1881 },
+{ 0xd, 28, 1, 1896 },
+{ 0x5, 29, 0, 1895 },
+{ 0x1d, 28, 1, 1894 },
+{ 0xd, 29, 0, 1893 },
+{ 0xb, 28, 0, 1884 },
+{ 0x1b, 28, 0, 1883 },
+{ 0x7, 28, 1, 1900 },
+{ 0x3, 29, 0, 1899 },
+{ 0xf, 28, 1, 1898 },
+{ 0x7, 29, 0, 1897 },
+{ 0x51, 26, 0, 1902 },
+{ 0xd1, 26, 0, 1901 },
+{ 0x31, 26, 1, 1912 },
+{ 0x11, 27, 0, 1911 },
+{ 0x71, 26, 1, 1910 },
+{ 0x31, 27, 0, 1909 },
+{ 0x29, 26, 0, 1904 },
+{ 0x69, 26, 0, 1903 },
+{ 0x19, 26, 1, 1916 },
+{ 0x9, 27, 0, 1915 },
+{ 0x39, 26, 1, 1914 },
+{ 0x19, 27, 0, 1913 },
+{ 0x15, 26, 0, 1906 },
+{ 0x35, 26, 0, 1905 },
+{ 0xd, 26, 1, 1920 },
+{ 0x5, 27, 0, 1919 },
+{ 0x1d, 26, 1, 1918 },
+{ 0xd, 27, 0, 1917 },
+{ 0xb, 26, 0, 1908 },
+{ 0x1b, 26, 0, 1907 },
+{ 0x7, 26, 1, 1924 },
+{ 0x3, 27, 0, 1923 },
+{ 0xf, 26, 1, 1922 },
+{ 0x7, 27, 0, 1921 },
+{ 0xa2, 24, 0, 1926 },
+{ 0x1a2, 24, 0, 1925 },
+{ 0x62, 24, 1, 1936 },
+{ 0x22, 25, 0, 1935 },
+{ 0xe2, 24, 1, 1934 },
+{ 0x62, 25, 0, 1933 },
+{ 0x52, 24, 0, 1928 },
+{ 0xd2, 24, 0, 1927 },
+{ 0x32, 24, 1, 1940 },
+{ 0x12, 25, 0, 1939 },
+{ 0x72, 24, 1, 1938 },
+{ 0x32, 25, 0, 1937 },
+{ 0x2a, 24, 0, 1930 },
+{ 0x6a, 24, 0, 1929 },
+{ 0x1a, 24, 1, 1944 },
+{ 0xa, 25, 0, 1943 },
+{ 0x3a, 24, 1, 1942 },
+{ 0x1a, 25, 0, 1941 },
+{ 0x16, 24, 0, 1932 },
+{ 0x36, 24, 0, 1931 },
+{ 0xe, 24, 1, 1948 },
+{ 0x6, 25, 0, 1947 },
+{ 0x1e, 24, 1, 1946 },
+{ 0xe, 25, 0, 1945 },
+{ 0x51, 24, 0, 1950 },
+{ 0xd1, 24, 0, 1949 },
+{ 0x31, 24, 1, 1960 },
+{ 0x11, 25, 0, 1959 },
+{ 0x71, 24, 1, 1958 },
+{ 0x31, 25, 0, 1957 },
+{ 0x29, 24, 0, 1952 },
+{ 0x69, 24, 0, 1951 },
+{ 0x19, 24, 1, 1964 },
+{ 0x9, 25, 0, 1963 },
+{ 0x39, 24, 1, 1962 },
+{ 0x19, 25, 0, 1961 },
+{ 0x15, 24, 0, 1954 },
+{ 0x35, 24, 0, 1953 },
+{ 0xd, 24, 1, 1968 },
+{ 0x5, 25, 0, 1967 },
+{ 0x1d, 24, 1, 1966 },
+{ 0xd, 25, 0, 1965 },
+{ 0xb, 24, 0, 1956 },
+{ 0x1b, 24, 0, 1955 },
+{ 0x7, 24, 1, 1972 },
+{ 0x3, 25, 0, 1971 },
+{ 0xf, 24, 1, 1970 },
+{ 0x7, 25, 0, 1969 },
+{ 0x51, 22, 1, 1998 },
+{ 0x50, 22, 0, 1974 },
+{ 0xd1, 22, 1, 1997 },
+{ 0xd0, 22, 0, 1973 },
+{ 0x31, 22, 1, 2008 },
+{ 0x30, 22, 1, 1984 },
+{ 0x11, 23, 1, 2007 },
+{ 0x10, 23, 0, 1983 },
+{ 0x71, 22, 1, 2006 },
+{ 0x70, 22, 1, 1982 },
+{ 0x31, 23, 1, 2005 },
+{ 0x30, 23, 0, 1981 },
+{ 0x29, 22, 1, 2000 },
+{ 0x28, 22, 0, 1976 },
+{ 0x69, 22, 1, 1999 },
+{ 0x68, 22, 0, 1975 },
+{ 0x19, 22, 1, 2012 },
+{ 0x18, 22, 1, 1988 },
+{ 0x9, 23, 1, 2011 },
+{ 0x8, 23, 0, 1987 },
+{ 0x39, 22, 1, 2010 },
+{ 0x38, 22, 1, 1986 },
+{ 0x19, 23, 1, 2009 },
+{ 0x18, 23, 0, 1985 },
+{ 0x15, 22, 1, 2002 },
+{ 0x14, 22, 0, 1978 },
+{ 0x35, 22, 1, 2001 },
+{ 0x34, 22, 0, 1977 },
+{ 0xd, 22, 1, 2016 },
+{ 0xc, 22, 1, 1992 },
+{ 0x5, 23, 1, 2015 },
+{ 0x4, 23, 0, 1991 },
+{ 0x1d, 22, 1, 2014 },
+{ 0x1c, 22, 1, 1990 },
+{ 0xd, 23, 1, 2013 },
+{ 0xc, 23, 0, 1989 },
+{ 0xb, 22, 1, 2004 },
+{ 0xa, 22, 0, 1980 },
+{ 0x1b, 22, 1, 2003 },
+{ 0x1a, 22, 0, 1979 },
+{ 0x7, 22, 1, 2020 },
+{ 0x6, 22, 1, 1996 },
+{ 0x3, 23, 1, 2019 },
+{ 0x2, 23, 0, 1995 },
+{ 0xf, 22, 1, 2018 },
+{ 0xe, 22, 1, 1994 },
+{ 0x7, 23, 1, 2017 },
+{ 0x6, 23, 0, 1993 },
+{ 0x8, 21, 0, 2022 },
+{ 0x18, 21, 0, 2021 },
+{ 0x1, 21, 1, 2026 },
+{ 0x2, 21, 0, 2025 },
+{ 0x3, 21, 1, 2024 },
+{ 0x4, 21, 0, 2023 },
+{ 0x1, 239, 0, 2027 },
+{ 0x1, 339, 0, 2028 },
+{ 0x14, 43, 0, 2031 },
+{ 0x34, 43, 0, 2029 },
+{ 0xc, 43, 0, 2032 },
+{ 0x1c, 43, 0, 2030 },
+{ 0x2, 43, 0, 2035 },
+{ 0x6, 43, 0, 2033 },
+{ 0x1, 43, 0, 2036 },
+{ 0x3, 43, 0, 2034 },
+{ 0x51, 19, 0, 2038 },
+{ 0xd1, 19, 0, 2037 },
+{ 0x31, 19, 1, 2048 },
+{ 0x11, 20, 0, 2047 },
+{ 0x71, 19, 1, 2046 },
+{ 0x31, 20, 0, 2045 },
+{ 0x29, 19, 0, 2040 },
+{ 0x69, 19, 0, 2039 },
+{ 0x19, 19, 1, 2052 },
+{ 0x9, 20, 0, 2051 },
+{ 0x39, 19, 1, 2050 },
+{ 0x19, 20, 0, 2049 },
+{ 0x15, 19, 0, 2042 },
+{ 0x35, 19, 0, 2041 },
+{ 0xd, 19, 1, 2056 },
+{ 0x5, 20, 0, 2055 },
+{ 0x1d, 19, 1, 2054 },
+{ 0xd, 20, 0, 2053 },
+{ 0xb, 19, 0, 2044 },
+{ 0x1b, 19, 0, 2043 },
+{ 0x7, 19, 1, 2060 },
+{ 0x3, 20, 0, 2059 },
+{ 0xf, 19, 1, 2058 },
+{ 0x7, 20, 0, 2057 },
+{ 0x1, 32, 0, 2061 },
+{ 0x1, 140, 0, 2062 },
+{ 0x2, 45, 0, 2063 },
+{ 0x1, 45, 0, 2064 },
+{ 0x1, 387, 0, 2065 },
+{ 0x2, 52, 0, 2066 },
+{ 0x1, 52, 0, 2067 },
+{ 0x1, 133, 0, 2068 },
+{ 0x51, 17, 0, 2070 },
+{ 0xd1, 17, 0, 2069 },
+{ 0x31, 17, 1, 2080 },
+{ 0x11, 18, 0, 2079 },
+{ 0x71, 17, 1, 2078 },
+{ 0x31, 18, 0, 2077 },
+{ 0x29, 17, 0, 2072 },
+{ 0x69, 17, 0, 2071 },
+{ 0x19, 17, 1, 2084 },
+{ 0x9, 18, 0, 2083 },
+{ 0x39, 17, 1, 2082 },
+{ 0x19, 18, 0, 2081 },
+{ 0x15, 17, 0, 2074 },
+{ 0x35, 17, 0, 2073 },
+{ 0xd, 17, 1, 2088 },
+{ 0x5, 18, 0, 2087 },
+{ 0x1d, 17, 1, 2086 },
+{ 0xd, 18, 0, 2085 },
+{ 0xb, 17, 0, 2076 },
+{ 0x1b, 17, 0, 2075 },
+{ 0x7, 17, 1, 2092 },
+{ 0x3, 18, 0, 2091 },
+{ 0xf, 17, 1, 2090 },
+{ 0x7, 18, 0, 2089 },
+{ 0xa20, 15, 0, 2094 },
+{ 0x1a20, 15, 0, 2093 },
+{ 0x620, 15, 1, 2104 },
+{ 0x220, 16, 0, 2103 },
+{ 0xe20, 15, 1, 2102 },
+{ 0x620, 16, 0, 2101 },
+{ 0x520, 15, 0, 2096 },
+{ 0xd20, 15, 0, 2095 },
+{ 0x320, 15, 1, 2108 },
+{ 0x120, 16, 0, 2107 },
+{ 0x720, 15, 1, 2106 },
+{ 0x320, 16, 0, 2105 },
+{ 0x2a0, 15, 0, 2098 },
+{ 0x6a0, 15, 0, 2097 },
+{ 0x1a0, 15, 1, 2112 },
+{ 0xa0, 16, 0, 2111 },
+{ 0x3a0, 15, 1, 2110 },
+{ 0x1a0, 16, 0, 2109 },
+{ 0x160, 15, 0, 2100 },
+{ 0x360, 15, 0, 2099 },
+{ 0xe0, 15, 1, 2116 },
+{ 0x60, 16, 0, 2115 },
+{ 0x1e0, 15, 1, 2114 },
+{ 0xe0, 16, 0, 2113 },
+{ 0x51, 15, 1, 2142 },
+{ 0x50, 15, 0, 2118 },
+{ 0xd1, 15, 1, 2141 },
+{ 0xd0, 15, 0, 2117 },
+{ 0x31, 15, 1, 2152 },
+{ 0x30, 15, 1, 2128 },
+{ 0x11, 16, 1, 2151 },
+{ 0x10, 16, 0, 2127 },
+{ 0x71, 15, 1, 2150 },
+{ 0x70, 15, 1, 2126 },
+{ 0x31, 16, 1, 2149 },
+{ 0x30, 16, 0, 2125 },
+{ 0x29, 15, 1, 2144 },
+{ 0x28, 15, 0, 2120 },
+{ 0x69, 15, 1, 2143 },
+{ 0x68, 15, 0, 2119 },
+{ 0x19, 15, 1, 2156 },
+{ 0x18, 15, 1, 2132 },
+{ 0x9, 16, 1, 2155 },
+{ 0x8, 16, 0, 2131 },
+{ 0x39, 15, 1, 2154 },
+{ 0x38, 15, 1, 2130 },
+{ 0x19, 16, 1, 2153 },
+{ 0x18, 16, 0, 2129 },
+{ 0x15, 15, 1, 2146 },
+{ 0x14, 15, 0, 2122 },
+{ 0x35, 15, 1, 2145 },
+{ 0x34, 15, 0, 2121 },
+{ 0xd, 15, 1, 2160 },
+{ 0xc, 15, 1, 2136 },
+{ 0x5, 16, 1, 2159 },
+{ 0x4, 16, 0, 2135 },
+{ 0x1d, 15, 1, 2158 },
+{ 0x1c, 15, 1, 2134 },
+{ 0xd, 16, 1, 2157 },
+{ 0xc, 16, 0, 2133 },
+{ 0xb, 15, 1, 2148 },
+{ 0xa, 15, 0, 2124 },
+{ 0x1b, 15, 1, 2147 },
+{ 0x1a, 15, 0, 2123 },
+{ 0x7, 15, 1, 2164 },
+{ 0x6, 15, 1, 2140 },
+{ 0x3, 16, 1, 2163 },
+{ 0x2, 16, 0, 2139 },
+{ 0xf, 15, 1, 2162 },
+{ 0xe, 15, 1, 2138 },
+{ 0x7, 16, 1, 2161 },
+{ 0x6, 16, 0, 2137 },
+{ 0x8, 14, 0, 2166 },
+{ 0x18, 14, 0, 2165 },
+{ 0x1, 14, 1, 2170 },
+{ 0x2, 14, 0, 2169 },
+{ 0x3, 14, 1, 2168 },
+{ 0x4, 14, 0, 2167 },
+{ 0x1, 109, 1, 2322 },
+{ 0x1, 110, 1, 2321 },
+{ 0x1, 111, 1, 2320 },
+{ 0x1, 112, 1, 2319 },
+{ 0x1, 113, 1, 2318 },
+{ 0x1, 114, 1, 2317 },
+{ 0x1, 115, 1, 2316 },
+{ 0x1, 116, 1, 2315 },
+{ 0x39, 41, 1, 22 },
+{ 0x19, 42, 0, 21 },
+{ 0x3, 109, 1, 2314 },
+{ 0x3, 110, 1, 2313 },
+{ 0x3, 111, 1, 2312 },
+{ 0x3, 112, 1, 2311 },
+{ 0x3, 113, 1, 2310 },
+{ 0x3, 114, 1, 2309 },
+{ 0x3, 115, 1, 2308 },
+{ 0x3, 116, 1, 2307 },
+{ 0x69, 41, 0, 11 },
+{ 0x14, 100, 1, 2302 },
+{ 0x22, 101, 1, 2299 },
+{ 0x44, 101, 1, 2301 },
+{ 0xa, 108, 1, 2300 },
+{ 0xd1, 41, 0, 9 },
+{ 0x34, 100, 1, 2174 },
+{ 0xc4, 101, 1, 2173 },
+{ 0x1c, 107, 1, 2171 },
+{ 0xe, 122, 0, 2172 },
+{ 0xc, 100, 1, 2462 },
+{ 0xa, 101, 1, 2459 },
+{ 0x14, 101, 1, 2461 },
+{ 0x6, 108, 0, 2460 },
+{ 0x2, 100, 1, 2186 },
+{ 0x2, 101, 1, 2185 },
+{ 0x2, 106, 1, 2184 },
+{ 0x2, 107, 0, 2183 },
+{ 0x12, 100, 1, 2182 },
+{ 0x42, 101, 1, 2181 },
+{ 0x6, 106, 1, 2180 },
+{ 0x6, 107, 0, 2179 },
+{ 0xa, 100, 1, 2306 },
+{ 0x12, 101, 1, 2305 },
+{ 0x24, 101, 1, 2303 },
+{ 0x5, 108, 1, 2304 },
+{ 0x71, 41, 1, 18 },
+{ 0x31, 42, 0, 17 },
+{ 0x1a, 100, 1, 2178 },
+{ 0x32, 101, 1, 2177 },
+{ 0x1a, 107, 1, 2175 },
+{ 0x7, 122, 0, 2176 },
+{ 0x6, 100, 1, 2466 },
+{ 0x6, 101, 1, 2465 },
+{ 0xc, 101, 1, 2463 },
+{ 0x3, 108, 0, 2464 },
+{ 0x1, 100, 1, 2482 },
+{ 0x1, 101, 1, 2481 },
+{ 0x1, 102, 1, 2480 },
+{ 0x1, 103, 1, 2479 },
+{ 0x1, 104, 1, 2478 },
+{ 0x1, 105, 1, 2477 },
+{ 0x1, 106, 1, 2476 },
+{ 0x1, 107, 0, 2475 },
+{ 0x3, 100, 1, 2474 },
+{ 0x3, 101, 1, 2473 },
+{ 0x3, 102, 1, 2472 },
+{ 0x3, 103, 1, 2471 },
+{ 0x3, 104, 1, 2470 },
+{ 0x3, 105, 1, 2469 },
+{ 0x3, 106, 1, 2468 },
+{ 0x3, 107, 0, 2467 },
+{ 0x8, 67, 1, 2346 },
+{ 0x8, 68, 1, 2345 },
+{ 0x2, 73, 1, 2340 },
+{ 0x2, 74, 1, 2339 },
+{ 0x1, 76, 1, 2344 },
+{ 0x1, 77, 1, 2343 },
+{ 0x1, 78, 1, 2342 },
+{ 0x1, 79, 1, 2341 },
+{ 0xf, 41, 1, 30 },
+{ 0x7, 42, 0, 29 },
+{ 0x18, 67, 1, 2338 },
+{ 0x18, 68, 1, 2337 },
+{ 0x6, 73, 1, 2332 },
+{ 0x6, 74, 1, 2331 },
+{ 0x3, 76, 1, 2336 },
+{ 0x3, 77, 1, 2335 },
+{ 0x3, 78, 1, 2334 },
+{ 0x3, 79, 1, 2333 },
+{ 0x1b, 41, 0, 15 },
+{ 0x14, 67, 1, 2326 },
+{ 0x22, 68, 1, 2323 },
+{ 0x44, 68, 1, 2325 },
+{ 0xa, 75, 1, 2324 },
+{ 0x35, 41, 0, 13 },
+{ 0x34, 67, 1, 2190 },
+{ 0xc4, 68, 1, 2189 },
+{ 0x38, 74, 1, 2187 },
+{ 0xe, 85, 0, 2188 },
+{ 0xc, 67, 1, 2486 },
+{ 0xa, 68, 1, 2483 },
+{ 0x14, 68, 1, 2485 },
+{ 0x6, 75, 0, 2484 },
+{ 0x2, 67, 1, 2202 },
+{ 0x2, 68, 1, 2201 },
+{ 0x4, 73, 1, 2200 },
+{ 0x4, 74, 0, 2199 },
+{ 0x12, 67, 1, 2198 },
+{ 0x42, 68, 1, 2197 },
+{ 0xc, 73, 1, 2196 },
+{ 0xc, 74, 0, 2195 },
+{ 0xa, 67, 1, 2330 },
+{ 0x12, 68, 1, 2329 },
+{ 0x24, 68, 1, 2327 },
+{ 0x5, 75, 1, 2328 },
+{ 0x1d, 41, 1, 26 },
+{ 0xd, 42, 0, 25 },
+{ 0x1a, 67, 1, 2194 },
+{ 0x32, 68, 1, 2193 },
+{ 0x34, 74, 1, 2191 },
+{ 0x7, 85, 0, 2192 },
+{ 0x6, 67, 1, 2490 },
+{ 0x6, 68, 1, 2489 },
+{ 0xc, 68, 1, 2487 },
+{ 0x3, 75, 0, 2488 },
+{ 0x1, 67, 1, 2506 },
+{ 0x1, 68, 1, 2505 },
+{ 0x1, 69, 1, 2504 },
+{ 0x1, 70, 1, 2503 },
+{ 0x1, 71, 1, 2502 },
+{ 0x1, 72, 1, 2501 },
+{ 0x1, 73, 1, 2500 },
+{ 0x1, 74, 0, 2499 },
+{ 0x3, 67, 1, 2498 },
+{ 0x3, 68, 1, 2497 },
+{ 0x3, 69, 1, 2496 },
+{ 0x3, 70, 1, 2495 },
+{ 0x3, 71, 1, 2494 },
+{ 0x3, 72, 1, 2493 },
+{ 0x3, 73, 1, 2492 },
+{ 0x3, 74, 0, 2491 },
+{ 0x28, 95, 1, 2354 },
+{ 0x44, 96, 1, 2349 },
+{ 0x88, 96, 1, 2353 },
+{ 0x44, 97, 1, 2348 },
+{ 0x88, 97, 1, 2352 },
+{ 0x44, 98, 1, 2347 },
+{ 0x88, 98, 1, 2351 },
+{ 0x28, 99, 0, 2350 },
+{ 0x68, 95, 1, 2210 },
+{ 0x188, 96, 1, 2209 },
+{ 0x188, 97, 1, 2208 },
+{ 0x188, 98, 1, 2207 },
+{ 0x38, 118, 1, 2206 },
+{ 0x38, 119, 1, 2205 },
+{ 0x38, 120, 1, 2204 },
+{ 0x38, 121, 0, 2203 },
+{ 0x18, 95, 1, 2514 },
+{ 0x14, 96, 1, 2509 },
+{ 0x28, 96, 1, 2513 },
+{ 0x14, 97, 1, 2508 },
+{ 0x28, 97, 1, 2512 },
+{ 0x14, 98, 1, 2507 },
+{ 0x28, 98, 1, 2511 },
+{ 0x18, 99, 0, 2510 },
+{ 0x14, 95, 1, 2362 },
+{ 0x24, 96, 1, 2361 },
+{ 0x48, 96, 1, 2357 },
+{ 0x24, 97, 1, 2360 },
+{ 0x48, 97, 1, 2356 },
+{ 0x24, 98, 1, 2359 },
+{ 0x48, 98, 1, 2355 },
+{ 0x14, 99, 0, 2358 },
+{ 0x34, 95, 1, 2218 },
+{ 0x64, 96, 1, 2217 },
+{ 0x64, 97, 1, 2216 },
+{ 0x64, 98, 1, 2215 },
+{ 0x1c, 118, 1, 2214 },
+{ 0x1c, 119, 1, 2213 },
+{ 0x1c, 120, 1, 2212 },
+{ 0x1c, 121, 0, 2211 },
+{ 0xc, 95, 1, 2522 },
+{ 0xc, 96, 1, 2521 },
+{ 0x18, 96, 1, 2517 },
+{ 0xc, 97, 1, 2520 },
+{ 0x18, 97, 1, 2516 },
+{ 0xc, 98, 1, 2519 },
+{ 0x18, 98, 1, 2515 },
+{ 0xc, 99, 0, 2518 },
+{ 0xa, 95, 1, 2370 },
+{ 0x11, 96, 1, 2365 },
+{ 0x22, 96, 1, 2369 },
+{ 0x11, 97, 1, 2364 },
+{ 0x22, 97, 1, 2368 },
+{ 0x11, 98, 1, 2363 },
+{ 0x22, 98, 1, 2367 },
+{ 0xa, 99, 0, 2366 },
+{ 0x1a, 95, 1, 2226 },
+{ 0x62, 96, 1, 2225 },
+{ 0x62, 97, 1, 2224 },
+{ 0x62, 98, 1, 2223 },
+{ 0xe, 118, 1, 2222 },
+{ 0xe, 119, 1, 2221 },
+{ 0xe, 120, 1, 2220 },
+{ 0xe, 121, 0, 2219 },
+{ 0x6, 95, 1, 2530 },
+{ 0x5, 96, 1, 2525 },
+{ 0xa, 96, 1, 2529 },
+{ 0x5, 97, 1, 2524 },
+{ 0xa, 97, 1, 2528 },
+{ 0x5, 98, 1, 2523 },
+{ 0xa, 98, 1, 2527 },
+{ 0x6, 99, 0, 2526 },
+{ 0x5, 95, 1, 2378 },
+{ 0x9, 96, 1, 2377 },
+{ 0x12, 96, 1, 2373 },
+{ 0x9, 97, 1, 2376 },
+{ 0x12, 97, 1, 2372 },
+{ 0x9, 98, 1, 2375 },
+{ 0x12, 98, 1, 2371 },
+{ 0x5, 99, 0, 2374 },
+{ 0xd, 95, 1, 2234 },
+{ 0x19, 96, 1, 2233 },
+{ 0x19, 97, 1, 2232 },
+{ 0x19, 98, 1, 2231 },
+{ 0x7, 118, 1, 2230 },
+{ 0x7, 119, 1, 2229 },
+{ 0x7, 120, 1, 2228 },
+{ 0x7, 121, 0, 2227 },
+{ 0x3, 95, 1, 2538 },
+{ 0x3, 96, 1, 2537 },
+{ 0x6, 96, 1, 2533 },
+{ 0x3, 97, 1, 2536 },
+{ 0x6, 97, 1, 2532 },
+{ 0x3, 98, 1, 2535 },
+{ 0x6, 98, 1, 2531 },
+{ 0x3, 99, 0, 2534 },
+{ 0x28, 62, 1, 2386 },
+{ 0x44, 63, 1, 2381 },
+{ 0x88, 63, 1, 2385 },
+{ 0x44, 64, 1, 2380 },
+{ 0x88, 64, 1, 2384 },
+{ 0x44, 65, 1, 2379 },
+{ 0x88, 65, 1, 2383 },
+{ 0x28, 66, 0, 2382 },
+{ 0x68, 62, 1, 2242 },
+{ 0x188, 63, 1, 2241 },
+{ 0x188, 64, 1, 2240 },
+{ 0x188, 65, 1, 2239 },
+{ 0x38, 81, 1, 2238 },
+{ 0x38, 82, 1, 2237 },
+{ 0x38, 83, 1, 2236 },
+{ 0x38, 84, 0, 2235 },
+{ 0x18, 62, 1, 2546 },
+{ 0x14, 63, 1, 2541 },
+{ 0x28, 63, 1, 2545 },
+{ 0x14, 64, 1, 2540 },
+{ 0x28, 64, 1, 2544 },
+{ 0x14, 65, 1, 2539 },
+{ 0x28, 65, 1, 2543 },
+{ 0x18, 66, 0, 2542 },
+{ 0x14, 62, 1, 2394 },
+{ 0x24, 63, 1, 2393 },
+{ 0x48, 63, 1, 2389 },
+{ 0x24, 64, 1, 2392 },
+{ 0x48, 64, 1, 2388 },
+{ 0x24, 65, 1, 2391 },
+{ 0x48, 65, 1, 2387 },
+{ 0x14, 66, 0, 2390 },
+{ 0x34, 62, 1, 2250 },
+{ 0x64, 63, 1, 2249 },
+{ 0x64, 64, 1, 2248 },
+{ 0x64, 65, 1, 2247 },
+{ 0x1c, 81, 1, 2246 },
+{ 0x1c, 82, 1, 2245 },
+{ 0x1c, 83, 1, 2244 },
+{ 0x1c, 84, 0, 2243 },
+{ 0xc, 62, 1, 2554 },
+{ 0xc, 63, 1, 2553 },
+{ 0x18, 63, 1, 2549 },
+{ 0xc, 64, 1, 2552 },
+{ 0x18, 64, 1, 2548 },
+{ 0xc, 65, 1, 2551 },
+{ 0x18, 65, 1, 2547 },
+{ 0xc, 66, 0, 2550 },
+{ 0xa, 62, 1, 2402 },
+{ 0x11, 63, 1, 2397 },
+{ 0x22, 63, 1, 2401 },
+{ 0x11, 64, 1, 2396 },
+{ 0x22, 64, 1, 2400 },
+{ 0x11, 65, 1, 2395 },
+{ 0x22, 65, 1, 2399 },
+{ 0xa, 66, 0, 2398 },
+{ 0x1a, 62, 1, 2258 },
+{ 0x62, 63, 1, 2257 },
+{ 0x62, 64, 1, 2256 },
+{ 0x62, 65, 1, 2255 },
+{ 0xe, 81, 1, 2254 },
+{ 0xe, 82, 1, 2253 },
+{ 0xe, 83, 1, 2252 },
+{ 0xe, 84, 0, 2251 },
+{ 0x6, 62, 1, 2562 },
+{ 0x5, 63, 1, 2557 },
+{ 0xa, 63, 1, 2561 },
+{ 0x5, 64, 1, 2556 },
+{ 0xa, 64, 1, 2560 },
+{ 0x5, 65, 1, 2555 },
+{ 0xa, 65, 1, 2559 },
+{ 0x6, 66, 0, 2558 },
+{ 0x5, 62, 1, 2410 },
+{ 0x9, 63, 1, 2409 },
+{ 0x12, 63, 1, 2405 },
+{ 0x9, 64, 1, 2408 },
+{ 0x12, 64, 1, 2404 },
+{ 0x9, 65, 1, 2407 },
+{ 0x12, 65, 1, 2403 },
+{ 0x5, 66, 0, 2406 },
+{ 0xd, 62, 1, 2266 },
+{ 0x19, 63, 1, 2265 },
+{ 0x19, 64, 1, 2264 },
+{ 0x19, 65, 1, 2263 },
+{ 0x7, 81, 1, 2262 },
+{ 0x7, 82, 1, 2261 },
+{ 0x7, 83, 1, 2260 },
+{ 0x7, 84, 0, 2259 },
+{ 0x3, 62, 1, 2570 },
+{ 0x3, 63, 1, 2569 },
+{ 0x6, 63, 1, 2565 },
+{ 0x3, 64, 1, 2568 },
+{ 0x6, 64, 1, 2564 },
+{ 0x3, 65, 1, 2567 },
+{ 0x6, 65, 1, 2563 },
+{ 0x3, 66, 0, 2566 },
+{ 0x8, 86, 1, 2434 },
+{ 0x8, 87, 1, 2433 },
+{ 0x2, 88, 1, 2432 },
+{ 0x2, 89, 1, 2431 },
+{ 0x2, 90, 1, 2430 },
+{ 0x2, 91, 1, 2429 },
+{ 0x2, 92, 1, 2428 },
+{ 0x2, 93, 0, 2427 },
+{ 0x18, 86, 1, 2426 },
+{ 0x18, 87, 1, 2425 },
+{ 0x6, 88, 1, 2424 },
+{ 0x6, 89, 1, 2423 },
+{ 0x6, 90, 1, 2422 },
+{ 0x6, 91, 1, 2421 },
+{ 0x6, 92, 1, 2420 },
+{ 0x6, 93, 0, 2419 },
+{ 0x14, 86, 1, 2414 },
+{ 0x22, 87, 1, 2411 },
+{ 0x44, 87, 1, 2413 },
+{ 0xa, 94, 0, 2412 },
+{ 0x34, 86, 1, 2270 },
+{ 0xc4, 87, 1, 2269 },
+{ 0x38, 93, 1, 2267 },
+{ 0xe, 117, 0, 2268 },
+{ 0xc, 86, 1, 2574 },
+{ 0xa, 87, 1, 2571 },
+{ 0x14, 87, 1, 2573 },
+{ 0x6, 94, 0, 2572 },
+{ 0x2, 86, 1, 2282 },
+{ 0x2, 87, 1, 2281 },
+{ 0x4, 92, 1, 2280 },
+{ 0x4, 93, 0, 2279 },
+{ 0x12, 86, 1, 2278 },
+{ 0x42, 87, 1, 2277 },
+{ 0xc, 92, 1, 2276 },
+{ 0xc, 93, 0, 2275 },
+{ 0xa, 86, 1, 2418 },
+{ 0x12, 87, 1, 2417 },
+{ 0x24, 87, 1, 2415 },
+{ 0x5, 94, 0, 2416 },
+{ 0x1a, 86, 1, 2274 },
+{ 0x32, 87, 1, 2273 },
+{ 0x34, 93, 1, 2271 },
+{ 0x7, 117, 0, 2272 },
+{ 0x6, 86, 1, 2578 },
+{ 0x6, 87, 1, 2577 },
+{ 0xc, 87, 1, 2575 },
+{ 0x3, 94, 0, 2576 },
+{ 0x1, 86, 1, 2594 },
+{ 0x1, 87, 1, 2593 },
+{ 0x1, 88, 1, 2592 },
+{ 0x1, 89, 1, 2591 },
+{ 0x1, 90, 1, 2590 },
+{ 0x1, 91, 1, 2589 },
+{ 0x1, 92, 1, 2588 },
+{ 0x1, 93, 0, 2587 },
+{ 0x3, 86, 1, 2586 },
+{ 0x3, 87, 1, 2585 },
+{ 0x3, 88, 1, 2584 },
+{ 0x3, 89, 1, 2583 },
+{ 0x3, 90, 1, 2582 },
+{ 0x3, 91, 1, 2581 },
+{ 0x3, 92, 1, 2580 },
+{ 0x3, 93, 0, 2579 },
+{ 0x8, 53, 1, 2458 },
+{ 0x8, 54, 1, 2457 },
+{ 0x2, 55, 1, 2456 },
+{ 0x2, 56, 1, 2455 },
+{ 0x2, 57, 1, 2454 },
+{ 0x2, 58, 1, 2453 },
+{ 0x2, 59, 1, 2452 },
+{ 0x2, 60, 0, 2451 },
+{ 0x18, 53, 1, 2450 },
+{ 0x18, 54, 1, 2449 },
+{ 0x6, 55, 1, 2448 },
+{ 0x6, 56, 1, 2447 },
+{ 0x6, 57, 1, 2446 },
+{ 0x6, 58, 1, 2445 },
+{ 0x6, 59, 1, 2444 },
+{ 0x6, 60, 0, 2443 },
+{ 0x14, 53, 1, 2438 },
+{ 0x22, 54, 1, 2435 },
+{ 0x44, 54, 1, 2437 },
+{ 0xa, 61, 0, 2436 },
+{ 0x34, 53, 1, 2286 },
+{ 0xc4, 54, 1, 2285 },
+{ 0x38, 60, 1, 2283 },
+{ 0xe, 80, 0, 2284 },
+{ 0xc, 53, 1, 2598 },
+{ 0xa, 54, 1, 2595 },
+{ 0x14, 54, 1, 2597 },
+{ 0x6, 61, 0, 2596 },
+{ 0x2, 53, 1, 2298 },
+{ 0x2, 54, 1, 2297 },
+{ 0x4, 59, 1, 2296 },
+{ 0x4, 60, 0, 2295 },
+{ 0x12, 53, 1, 2294 },
+{ 0x42, 54, 1, 2293 },
+{ 0xc, 59, 1, 2292 },
+{ 0xc, 60, 0, 2291 },
+{ 0xa, 53, 1, 2442 },
+{ 0x12, 54, 1, 2441 },
+{ 0x24, 54, 1, 2439 },
+{ 0x5, 61, 0, 2440 },
+{ 0x1a, 53, 1, 2290 },
+{ 0x32, 54, 1, 2289 },
+{ 0x34, 60, 1, 2287 },
+{ 0x7, 80, 0, 2288 },
+{ 0x6, 53, 1, 2602 },
+{ 0x6, 54, 1, 2601 },
+{ 0xc, 54, 1, 2599 },
+{ 0x3, 61, 0, 2600 },
+{ 0x1, 53, 1, 2618 },
+{ 0x1, 54, 1, 2617 },
+{ 0x1, 55, 1, 2616 },
+{ 0x1, 56, 1, 2615 },
+{ 0x1, 57, 1, 2614 },
+{ 0x1, 58, 1, 2613 },
+{ 0x1, 59, 1, 2612 },
+{ 0x1, 60, 0, 2611 },
+{ 0x3, 53, 1, 2610 },
+{ 0x3, 54, 1, 2609 },
+{ 0x3, 55, 1, 2608 },
+{ 0x3, 56, 1, 2607 },
+{ 0x3, 57, 1, 2606 },
+{ 0x3, 58, 1, 2605 },
+{ 0x3, 59, 1, 2604 },
+{ 0x3, 60, 0, 2603 },
+{ 0x1, 4, 0, 2619 },
+{ 0x1, 296, 0, 2620 },
+{ 0x1, 379, 0, 2621 },
+{ 0x1, 374, 0, 2622 },
+{ 0x2, 358, 0, 2623 },
+{ 0x1, 358, 0, 2626 },
+{ 0x2, 357, 0, 2624 },
+{ 0x1, 357, 0, 2627 },
+{ 0x2, 356, 0, 2625 },
+{ 0x1, 356, 0, 2628 },
+{ 0x1, 355, 0, 2629 },
+{ 0x1, 354, 0, 2630 },
+{ 0x2, 353, 0, 2631 },
+{ 0x1, 353, 0, 2633 },
+{ 0x2, 352, 0, 2632 },
+{ 0x1, 352, 0, 2634 },
+{ 0x1, 382, 0, 2641 },
+{ 0x8, 381, 0, 2635 },
+{ 0x4, 381, 0, 2637 },
+{ 0x2, 381, 0, 2639 },
+{ 0x1, 381, 0, 2642 },
+{ 0x8, 380, 0, 2636 },
+{ 0x4, 380, 0, 2638 },
+{ 0x2, 380, 0, 2640 },
+{ 0x1, 380, 0, 2643 },
+{ 0x1, 351, 0, 2650 },
+{ 0x8, 350, 0, 2644 },
+{ 0x4, 350, 0, 2646 },
+{ 0x2, 350, 0, 2648 },
+{ 0x1, 350, 0, 2651 },
+{ 0x8, 349, 0, 2645 },
+{ 0x4, 349, 0, 2647 },
+{ 0x2, 349, 1, 2649 },
+{ 0x4, 143, 0, 1345 },
+{ 0x1, 349, 0, 2652 },
+{ 0x1, 6, 0, 2653 },
+{ 0x1, 7, 0, 2654 },
+{ 0x1, 295, 0, 2655 },
+{ 0x1, 451, 0, 2656 },
+{ 0x1, 346, 0, 2657 },
+{ 0x1, 13, 0, 2658 },
+{ 0x1, 11, 0, 2659 },
+{ 0x1, 422, 0, 2660 },
+{ 0x1, 394, 0, 2661 },
+{ 0x1, 393, 0, 2662 },
+{ 0x1, 450, 0, 2663 },
+{ 0x1, 345, 0, 2664 },
+{ 0x1, 12, 0, 2665 },
+{ 0x1, 10, 0, 2666 },
+{ 0x1, 5, 0, 2667 },
+{ 0x1, 421, 0, 2668 },
+{ 0x1, 420, 0, 2669 },
+{ 0x1, 1, 0, 2670 },
+{ 0x1, 0, 0, 2671 },
+};
+
--- /dev/null
+/* ia64-asmtab.h -- Header for compacted IA-64 opcode tables.
+ Copyright 1999, 2000 Free Software Foundation, Inc.
+ Contributed by Bob Manson of Cygnus Support <manson@cygnus.com>
+
+ This file is part of GDB, GAS, and the GNU binutils.
+
+ GDB, GAS, and the GNU binutils are free software; you can redistribute
+ them and/or modify them under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either version
+ 2, or (at your option) any later version.
+
+ GDB, GAS, and the GNU binutils are distributed in the hope that they
+ will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this file; see the file COPYING. If not, write to the
+ Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use.
+ * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as
+ * required.
+ * Keith Owens <kaos@sgi.com> 15 May 2006
+ */
+
+#ifndef IA64_ASMTAB_H
+#define IA64_ASMTAB_H
+
+#ifdef __KERNEL__
+#include "ia64.h"
+#else /* __KERNEL__ */
+#include "opcode/ia64.h"
+#endif /* __KERNEL__ */
+
+/* The primary opcode table is made up of the following: */
+struct ia64_main_table
+{
+ /* The entry in the string table that corresponds to the name of this
+ opcode. */
+ unsigned short name_index;
+
+ /* The type of opcode; corresponds to the TYPE field in
+ struct ia64_opcode. */
+ unsigned char opcode_type;
+
+ /* The number of outputs for this opcode. */
+ unsigned char num_outputs;
+
+ /* The base insn value for this opcode. It may be modified by completers. */
+ ia64_insn opcode;
+
+ /* The mask of valid bits in OPCODE. Zeros indicate operand fields. */
+ ia64_insn mask;
+
+ /* The operands of this instruction. Corresponds to the OPERANDS field
+ in struct ia64_opcode. */
+ unsigned char operands[5];
+
+ /* The flags for this instruction. Corresponds to the FLAGS field in
+ struct ia64_opcode. */
+ short flags;
+
+ /* The tree of completers for this instruction; this is an offset into
+ completer_table. */
+ short completers;
+};
+
+/* Each instruction has a set of possible "completers", or additional
+ suffixes that can alter the instruction's behavior, and which has
+ potentially different dependencies.
+
+ The completer entries modify certain bits in the instruction opcode.
+ Which bits are to be modified are marked by the BITS, MASK and
+ OFFSET fields. The completer entry may also note dependencies for the
+ opcode.
+
+ These completers are arranged in a DAG; the pointers are indexes
+ into the completer_table array. The completer DAG is searched by
+ find_completer () and ia64_find_matching_opcode ().
+
+ Note that each completer needs to be applied in turn, so that if we
+ have the instruction
+ cmp.lt.unc
+ the completer entries for both "lt" and "unc" would need to be applied
+ to the opcode's value.
+
+ Some instructions do not require any completers; these contain an
+ empty completer entry. Instructions that require a completer do
+ not contain an empty entry.
+
+ Terminal completers (those completers that validly complete an
+ instruction) are marked by having the TERMINAL_COMPLETER flag set.
+
+ Only dependencies listed in the terminal completer for an opcode are
+ considered to apply to that opcode instance. */
+
+struct ia64_completer_table
+{
+ /* The bit value that this completer sets. */
+ unsigned int bits;
+
+ /* And its mask. 1s are bits that are to be modified in the
+ instruction. */
+ unsigned int mask;
+
+ /* The entry in the string table that corresponds to the name of this
+ completer. */
+ unsigned short name_index;
+
+ /* An alternative completer, or -1 if this is the end of the chain. */
+ short alternative;
+
+ /* A pointer to the DAG of completers that can potentially follow
+ this one, or -1. */
+ short subentries;
+
+ /* The bit offset in the instruction where BITS and MASK should be
+ applied. */
+ unsigned char offset : 7;
+
+ unsigned char terminal_completer : 1;
+
+ /* Index into the dependency list table */
+ short dependencies;
+};
+
+/* This contains sufficient information for the disassembler to resolve
+ the complete name of the original instruction. */
+struct ia64_dis_names
+{
+ /* COMPLETER_INDEX represents the tree of completers that make up
+ the instruction. The LSB represents the top of the tree for the
+ specified instruction.
+
+ A 0 bit indicates to go to the next alternate completer via the
+ alternative field; a 1 bit indicates that the current completer
+ is part of the instruction, and to go down the subentries index.
+ We know we've reached the final completer when we run out of 1
+ bits.
+
+ There is always at least one 1 bit. */
+ unsigned int completer_index : 20;
+
+ /* The index in the main_table[] array for the instruction. */
+ unsigned short insn_index : 11;
+
+ /* If set, the next entry in this table is an alternate possibility
+ for this instruction encoding. Which one to use is determined by
+ the instruction type and other factors (see opcode_verify ()). */
+ unsigned int next_flag : 1;
+
+ /* The disassembly priority of this entry among instructions. */
+ unsigned short priority;
+};
+
+#endif
--- /dev/null
+/* ia64-dis.c -- Disassemble ia64 instructions
+ Copyright 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+ This file is part of GDB, GAS, and the GNU binutils.
+
+ GDB, GAS, and the GNU binutils are free software; you can redistribute
+ them and/or modify them under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either version
+ 2, or (at your option) any later version.
+
+ GDB, GAS, and the GNU binutils are distributed in the hope that they
+ will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this file; see the file COPYING. If not, write to the
+ Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use.
+ * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as
+ * required.
+ * Keith Owens <kaos@sgi.com> 15 May 2006
+ */
+
+#ifdef __KERNEL__
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/dis-asm.h>
+#include "ia64.h"
+
+/* imported from bfd/libbfd.c for kernel */
+bfd_uint64_t
+bfd_getl64 (const void *p ATTRIBUTE_UNUSED)
+{
+#ifdef BFD_HOST_64_BIT
+ const bfd_byte *addr = p;
+ bfd_uint64_t v;
+
+ v = addr[7]; v <<= 8;
+ v |= addr[6]; v <<= 8;
+ v |= addr[5]; v <<= 8;
+ v |= addr[4]; v <<= 8;
+ v |= addr[3]; v <<= 8;
+ v |= addr[2]; v <<= 8;
+ v |= addr[1]; v <<= 8;
+ v |= addr[0];
+
+ return v;
+#else
+ BFD_FAIL();
+ return 0;
+#endif
+
+}
+
+#else /* __KERNEL__ */
+#include <assert.h>
+#include <string.h>
+
+#include "dis-asm.h"
+#include "opcode/ia64.h"
+#endif /* __KERNEL__ */
+
+#define NELEMS(a) ((int) (sizeof (a) / sizeof (a[0])))
+
+/* Disassemble ia64 instruction. */
+
+/* Return the instruction type for OPCODE found in unit UNIT. */
+
+static enum ia64_insn_type
+unit_to_type (ia64_insn opcode, enum ia64_unit unit)
+{
+ enum ia64_insn_type type;
+ int op;
+
+ op = IA64_OP (opcode);
+
+ if (op >= 8 && (unit == IA64_UNIT_I || unit == IA64_UNIT_M))
+ {
+ type = IA64_TYPE_A;
+ }
+ else
+ {
+ switch (unit)
+ {
+ case IA64_UNIT_I:
+ type = IA64_TYPE_I; break;
+ case IA64_UNIT_M:
+ type = IA64_TYPE_M; break;
+ case IA64_UNIT_B:
+ type = IA64_TYPE_B; break;
+ case IA64_UNIT_F:
+ type = IA64_TYPE_F; break;
+ case IA64_UNIT_L:
+ case IA64_UNIT_X:
+ type = IA64_TYPE_X; break;
+ default:
+ type = -1;
+ }
+ }
+ return type;
+}
+
+int
+print_insn_ia64 (bfd_vma memaddr, struct disassemble_info *info)
+{
+ ia64_insn t0, t1, slot[3], template, s_bit, insn;
+ int slotnum, j, status, need_comma, retval, slot_multiplier;
+ const struct ia64_operand *odesc;
+ const struct ia64_opcode *idesc;
+ const char *err, *str, *tname;
+ BFD_HOST_U_64_BIT value;
+ bfd_byte bundle[16];
+ enum ia64_unit unit;
+ char regname[16];
+
+ if (info->bytes_per_line == 0)
+ info->bytes_per_line = 6;
+ info->display_endian = info->endian;
+
+ slot_multiplier = info->bytes_per_line;
+ retval = slot_multiplier;
+
+ slotnum = (((long) memaddr) & 0xf) / slot_multiplier;
+ if (slotnum > 2)
+ return -1;
+
+ memaddr -= (memaddr & 0xf);
+ status = (*info->read_memory_func) (memaddr, bundle, sizeof (bundle), info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return -1;
+ }
+ /* bundles are always in little-endian byte order */
+ t0 = bfd_getl64 (bundle);
+ t1 = bfd_getl64 (bundle + 8);
+ s_bit = t0 & 1;
+ template = (t0 >> 1) & 0xf;
+ slot[0] = (t0 >> 5) & 0x1ffffffffffLL;
+ slot[1] = ((t0 >> 46) & 0x3ffff) | ((t1 & 0x7fffff) << 18);
+ slot[2] = (t1 >> 23) & 0x1ffffffffffLL;
+
+ tname = ia64_templ_desc[template].name;
+ if (slotnum == 0)
+ (*info->fprintf_func) (info->stream, "[%s] ", tname);
+ else
+ (*info->fprintf_func) (info->stream, " ");
+
+ unit = ia64_templ_desc[template].exec_unit[slotnum];
+
+ if (template == 2 && slotnum == 1)
+ {
+ /* skip L slot in MLI template: */
+ slotnum = 2;
+ retval += slot_multiplier;
+ }
+
+ insn = slot[slotnum];
+
+ if (unit == IA64_UNIT_NIL)
+ goto decoding_failed;
+
+ idesc = ia64_dis_opcode (insn, unit_to_type (insn, unit));
+ if (idesc == NULL)
+ goto decoding_failed;
+
+ /* print predicate, if any: */
+
+ if ((idesc->flags & IA64_OPCODE_NO_PRED)
+ || (insn & 0x3f) == 0)
+ (*info->fprintf_func) (info->stream, " ");
+ else
+ (*info->fprintf_func) (info->stream, "(p%02d) ", (int)(insn & 0x3f));
+
+ /* now the actual instruction: */
+
+ (*info->fprintf_func) (info->stream, "%s", idesc->name);
+ if (idesc->operands[0])
+ (*info->fprintf_func) (info->stream, " ");
+
+ need_comma = 0;
+ for (j = 0; j < NELEMS (idesc->operands) && idesc->operands[j]; ++j)
+ {
+ odesc = elf64_ia64_operands + idesc->operands[j];
+
+ if (need_comma)
+ (*info->fprintf_func) (info->stream, ",");
+
+ if (odesc - elf64_ia64_operands == IA64_OPND_IMMU64)
+ {
+ /* special case of 64 bit immediate load: */
+ value = ((insn >> 13) & 0x7f) | (((insn >> 27) & 0x1ff) << 7)
+ | (((insn >> 22) & 0x1f) << 16) | (((insn >> 21) & 0x1) << 21)
+ | (slot[1] << 22) | (((insn >> 36) & 0x1) << 63);
+ }
+ else if (odesc - elf64_ia64_operands == IA64_OPND_IMMU62)
+ {
+ /* 62-bit immediate for nop.x/break.x */
+ value = ((slot[1] & 0x1ffffffffffLL) << 21)
+ | (((insn >> 36) & 0x1) << 20)
+ | ((insn >> 6) & 0xfffff);
+ }
+ else if (odesc - elf64_ia64_operands == IA64_OPND_TGT64)
+ {
+ /* 60-bit immediate for long branches. */
+ value = (((insn >> 13) & 0xfffff)
+ | (((insn >> 36) & 1) << 59)
+ | (((slot[1] >> 2) & 0x7fffffffffLL) << 20)) << 4;
+ }
+ else
+ {
+ err = (*odesc->extract) (odesc, insn, &value);
+ if (err)
+ {
+ (*info->fprintf_func) (info->stream, "%s", err);
+ goto done;
+ }
+ }
+
+ switch (odesc->class)
+ {
+ case IA64_OPND_CLASS_CST:
+ (*info->fprintf_func) (info->stream, "%s", odesc->str);
+ break;
+
+ case IA64_OPND_CLASS_REG:
+ if (odesc->str[0] == 'a' && odesc->str[1] == 'r')
+ {
+ switch (value)
+ {
+ case 0: case 1: case 2: case 3:
+ case 4: case 5: case 6: case 7:
+ sprintf (regname, "ar.k%u", (unsigned int) value);
+ break;
+ case 16: strcpy (regname, "ar.rsc"); break;
+ case 17: strcpy (regname, "ar.bsp"); break;
+ case 18: strcpy (regname, "ar.bspstore"); break;
+ case 19: strcpy (regname, "ar.rnat"); break;
+ case 32: strcpy (regname, "ar.ccv"); break;
+ case 36: strcpy (regname, "ar.unat"); break;
+ case 40: strcpy (regname, "ar.fpsr"); break;
+ case 44: strcpy (regname, "ar.itc"); break;
+ case 64: strcpy (regname, "ar.pfs"); break;
+ case 65: strcpy (regname, "ar.lc"); break;
+ case 66: strcpy (regname, "ar.ec"); break;
+ default:
+ sprintf (regname, "ar%u", (unsigned int) value);
+ break;
+ }
+ (*info->fprintf_func) (info->stream, "%s", regname);
+ }
+ else
+ (*info->fprintf_func) (info->stream, "%s%d", odesc->str, (int)value);
+ break;
+
+ case IA64_OPND_CLASS_IND:
+ (*info->fprintf_func) (info->stream, "%s[r%d]", odesc->str, (int)value);
+ break;
+
+ case IA64_OPND_CLASS_ABS:
+ str = 0;
+ if (odesc - elf64_ia64_operands == IA64_OPND_MBTYPE4)
+ switch (value)
+ {
+ case 0x0: str = "@brcst"; break;
+ case 0x8: str = "@mix"; break;
+ case 0x9: str = "@shuf"; break;
+ case 0xa: str = "@alt"; break;
+ case 0xb: str = "@rev"; break;
+ }
+
+ if (str)
+ (*info->fprintf_func) (info->stream, "%s", str);
+ else if (odesc->flags & IA64_OPND_FLAG_DECIMAL_SIGNED)
+ (*info->fprintf_func) (info->stream, "%lld", (long long) value);
+ else if (odesc->flags & IA64_OPND_FLAG_DECIMAL_UNSIGNED)
+ (*info->fprintf_func) (info->stream, "%llu", (long long) value);
+ else
+ (*info->fprintf_func) (info->stream, "0x%llx", (long long) value);
+ break;
+
+ case IA64_OPND_CLASS_REL:
+ (*info->print_address_func) (memaddr + value, info);
+ break;
+ }
+
+ need_comma = 1;
+ if (j + 1 == idesc->num_outputs)
+ {
+ (*info->fprintf_func) (info->stream, "=");
+ need_comma = 0;
+ }
+ }
+ if (slotnum + 1 == ia64_templ_desc[template].group_boundary
+ || ((slotnum == 2) && s_bit))
+ (*info->fprintf_func) (info->stream, ";;");
+
+ done:
+ ia64_free_opcode ((struct ia64_opcode *)idesc);
+ failed:
+ if (slotnum == 2)
+ retval += 16 - 3*slot_multiplier;
+ return retval;
+
+ decoding_failed:
+ (*info->fprintf_func) (info->stream, " data8 %#011llx", (long long) insn);
+ goto failed;
+}
--- /dev/null
+/* ia64-opc.c -- Functions to access the compacted opcode table
+ Copyright 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
+ Written by Bob Manson of Cygnus Solutions, <manson@cygnus.com>
+
+ This file is part of GDB, GAS, and the GNU binutils.
+
+ GDB, GAS, and the GNU binutils are free software; you can redistribute
+ them and/or modify them under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either version
+ 2, or (at your option) any later version.
+
+ GDB, GAS, and the GNU binutils are distributed in the hope that they
+ will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this file; see the file COPYING. If not, write to the
+ Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use.
+ * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as
+ * required.
+ * Keith Owens <kaos@sgi.com> 15 May 2006
+ */
+
+#ifdef __KERNEL__
+#include <linux/kernel.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <linux/ansidecl.h>
+
+#define xstrdup(string) kstrdup(string, GFP_ATOMIC)
+#define xmalloc(size) kmalloc(size, GFP_ATOMIC)
+#define free(address) kfree(address)
+#define abort() BUG()
+
+#else /* __KERNEL__ */
+#include "ansidecl.h"
+#include "sysdep.h"
+#include "libiberty.h"
+#endif /* __KERNEL__ */
+#include "ia64-asmtab.h"
+#include "ia64-asmtab.c"
+
+static void get_opc_prefix (const char **, char *);
+static short int find_string_ent (const char *);
+static short int find_main_ent (short int);
+static short int find_completer (short int, short int, const char *);
+static ia64_insn apply_completer (ia64_insn, int);
+static int extract_op_bits (int, int, int);
+static int extract_op (int, int *, unsigned int *);
+static int opcode_verify (ia64_insn, int, enum ia64_insn_type);
+static int locate_opcode_ent (ia64_insn, enum ia64_insn_type);
+static struct ia64_opcode *make_ia64_opcode
+ (ia64_insn, const char *, int, int);
+static struct ia64_opcode *ia64_find_matching_opcode
+ (const char *, short int);
+
+const struct ia64_templ_desc ia64_templ_desc[16] =
+ {
+ { 0, { IA64_UNIT_M, IA64_UNIT_I, IA64_UNIT_I }, "MII" }, /* 0 */
+ { 2, { IA64_UNIT_M, IA64_UNIT_I, IA64_UNIT_I }, "MII" },
+ { 0, { IA64_UNIT_M, IA64_UNIT_L, IA64_UNIT_X }, "MLX" },
+ { 0, { 0, }, "-3-" },
+ { 0, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_I }, "MMI" }, /* 4 */
+ { 1, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_I }, "MMI" },
+ { 0, { IA64_UNIT_M, IA64_UNIT_F, IA64_UNIT_I }, "MFI" },
+ { 0, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_F }, "MMF" },
+ { 0, { IA64_UNIT_M, IA64_UNIT_I, IA64_UNIT_B }, "MIB" }, /* 8 */
+ { 0, { IA64_UNIT_M, IA64_UNIT_B, IA64_UNIT_B }, "MBB" },
+ { 0, { 0, }, "-a-" },
+ { 0, { IA64_UNIT_B, IA64_UNIT_B, IA64_UNIT_B }, "BBB" },
+ { 0, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_B }, "MMB" }, /* c */
+ { 0, { 0, }, "-d-" },
+ { 0, { IA64_UNIT_M, IA64_UNIT_F, IA64_UNIT_B }, "MFB" },
+ { 0, { 0, }, "-f-" },
+ };
+
+
+/* Copy the prefix contained in *PTR (up to a '.' or a NUL) to DEST.
+ PTR will be adjusted to point to the start of the next portion
+ of the opcode, or at the NUL character. */
+
+static void
+get_opc_prefix (const char **ptr, char *dest)
+{
+ char *c = strchr (*ptr, '.');
+ if (c != NULL)
+ {
+ memcpy (dest, *ptr, c - *ptr);
+ dest[c - *ptr] = '\0';
+ *ptr = c + 1;
+ }
+ else
+ {
+ int l = strlen (*ptr);
+ memcpy (dest, *ptr, l);
+ dest[l] = '\0';
+ *ptr += l;
+ }
+}
+\f
+/* Find the index of the entry in the string table corresponding to
+ STR; return -1 if one does not exist. */
+
+static short
+find_string_ent (const char *str)
+{
+ short start = 0;
+ short end = sizeof (ia64_strings) / sizeof (const char *);
+ short i = (start + end) / 2;
+
+ if (strcmp (str, ia64_strings[end - 1]) > 0)
+ {
+ return -1;
+ }
+ while (start <= end)
+ {
+ int c = strcmp (str, ia64_strings[i]);
+ if (c < 0)
+ {
+ end = i - 1;
+ }
+ else if (c == 0)
+ {
+ return i;
+ }
+ else
+ {
+ start = i + 1;
+ }
+ i = (start + end) / 2;
+ }
+ return -1;
+}
+\f
+/* Find the opcode in the main opcode table whose name is STRINGINDEX, or
+ return -1 if one does not exist. */
+
+static short
+find_main_ent (short nameindex)
+{
+ short start = 0;
+ short end = sizeof (main_table) / sizeof (struct ia64_main_table);
+ short i = (start + end) / 2;
+
+ if (nameindex < main_table[0].name_index
+ || nameindex > main_table[end - 1].name_index)
+ {
+ return -1;
+ }
+ while (start <= end)
+ {
+ if (nameindex < main_table[i].name_index)
+ {
+ end = i - 1;
+ }
+ else if (nameindex == main_table[i].name_index)
+ {
+ while (i > 0 && main_table[i - 1].name_index == nameindex)
+ {
+ i--;
+ }
+ return i;
+ }
+ else
+ {
+ start = i + 1;
+ }
+ i = (start + end) / 2;
+ }
+ return -1;
+}
+\f
+/* Find the index of the entry in the completer table that is part of
+ MAIN_ENT (starting from PREV_COMPLETER) that matches NAME, or
+ return -1 if one does not exist. */
+
+static short
+find_completer (short main_ent, short prev_completer, const char *name)
+{
+ short name_index = find_string_ent (name);
+
+ if (name_index < 0)
+ {
+ return -1;
+ }
+
+ if (prev_completer == -1)
+ {
+ prev_completer = main_table[main_ent].completers;
+ }
+ else
+ {
+ prev_completer = completer_table[prev_completer].subentries;
+ }
+
+ while (prev_completer != -1)
+ {
+ if (completer_table[prev_completer].name_index == name_index)
+ {
+ return prev_completer;
+ }
+ prev_completer = completer_table[prev_completer].alternative;
+ }
+ return -1;
+}
+\f
+/* Apply the completer referred to by COMPLETER_INDEX to OPCODE, and
+ return the result. */
+
+static ia64_insn
+apply_completer (ia64_insn opcode, int completer_index)
+{
+ ia64_insn mask = completer_table[completer_index].mask;
+ ia64_insn bits = completer_table[completer_index].bits;
+ int shiftamt = (completer_table[completer_index].offset & 63);
+
+ mask = mask << shiftamt;
+ bits = bits << shiftamt;
+ opcode = (opcode & ~mask) | bits;
+ return opcode;
+}
+\f
+/* Extract BITS number of bits starting from OP_POINTER + BITOFFSET in
+ the dis_table array, and return its value. (BITOFFSET is numbered
+ starting from MSB to LSB, so a BITOFFSET of 0 indicates the MSB of the
+ first byte in OP_POINTER.) */
+
+static int
+extract_op_bits (int op_pointer, int bitoffset, int bits)
+{
+ int res = 0;
+
+ op_pointer += (bitoffset / 8);
+
+ if (bitoffset % 8)
+ {
+ unsigned int op = dis_table[op_pointer++];
+ int numb = 8 - (bitoffset % 8);
+ int mask = (1 << numb) - 1;
+ int bata = (bits < numb) ? bits : numb;
+ int delta = numb - bata;
+
+ res = (res << bata) | ((op & mask) >> delta);
+ bitoffset += bata;
+ bits -= bata;
+ }
+ while (bits >= 8)
+ {
+ res = (res << 8) | (dis_table[op_pointer++] & 255);
+ bits -= 8;
+ }
+ if (bits > 0)
+ {
+ unsigned int op = (dis_table[op_pointer++] & 255);
+ res = (res << bits) | (op >> (8 - bits));
+ }
+ return res;
+}
+\f
+/* Examine the state machine entry at OP_POINTER in the dis_table
+ array, and extract its values into OPVAL and OP. The length of the
+ state entry in bits is returned. */
+
+static int
+extract_op (int op_pointer, int *opval, unsigned int *op)
+{
+ int oplen = 5;
+
+ *op = dis_table[op_pointer];
+
+ if ((*op) & 0x40)
+ {
+ opval[0] = extract_op_bits (op_pointer, oplen, 5);
+ oplen += 5;
+ }
+ switch ((*op) & 0x30)
+ {
+ case 0x10:
+ {
+ opval[1] = extract_op_bits (op_pointer, oplen, 8);
+ oplen += 8;
+ opval[1] += op_pointer;
+ break;
+ }
+ case 0x20:
+ {
+ opval[1] = extract_op_bits (op_pointer, oplen, 16);
+ if (! (opval[1] & 32768))
+ {
+ opval[1] += op_pointer;
+ }
+ oplen += 16;
+ break;
+ }
+ case 0x30:
+ {
+ oplen--;
+ opval[2] = extract_op_bits (op_pointer, oplen, 12);
+ oplen += 12;
+ opval[2] |= 32768;
+ break;
+ }
+ }
+ if (((*op) & 0x08) && (((*op) & 0x30) != 0x30))
+ {
+ opval[2] = extract_op_bits (op_pointer, oplen, 16);
+ oplen += 16;
+ if (! (opval[2] & 32768))
+ {
+ opval[2] += op_pointer;
+ }
+ }
+ return oplen;
+}
+\f
+/* Returns a non-zero value if the opcode in the main_table list at
+ PLACE matches OPCODE and is of type TYPE. */
+
+static int
+opcode_verify (ia64_insn opcode, int place, enum ia64_insn_type type)
+{
+ if (main_table[place].opcode_type != type)
+ {
+ return 0;
+ }
+ if (main_table[place].flags
+ & (IA64_OPCODE_F2_EQ_F3 | IA64_OPCODE_LEN_EQ_64MCNT))
+ {
+ const struct ia64_operand *o1, *o2;
+ ia64_insn f2, f3;
+
+ if (main_table[place].flags & IA64_OPCODE_F2_EQ_F3)
+ {
+ o1 = elf64_ia64_operands + IA64_OPND_F2;
+ o2 = elf64_ia64_operands + IA64_OPND_F3;
+ (*o1->extract) (o1, opcode, &f2);
+ (*o2->extract) (o2, opcode, &f3);
+ if (f2 != f3)
+ return 0;
+ }
+ else
+ {
+ ia64_insn len, count;
+
+ /* length must equal 64-count: */
+ o1 = elf64_ia64_operands + IA64_OPND_LEN6;
+ o2 = elf64_ia64_operands + main_table[place].operands[2];
+ (*o1->extract) (o1, opcode, &len);
+ (*o2->extract) (o2, opcode, &count);
+ if (len != 64 - count)
+ return 0;
+ }
+ }
+ return 1;
+}
+\f
+/* Find an instruction entry in the ia64_dis_names array that matches
+ opcode OPCODE and is of type TYPE. Returns either a positive index
+ into the array, or a negative value if an entry for OPCODE could
+ not be found. Checks all matches and returns the one with the highest
+ priority. */
+
+static int
+locate_opcode_ent (ia64_insn opcode, enum ia64_insn_type type)
+{
+ int currtest[41];
+ int bitpos[41];
+ int op_ptr[41];
+ int currstatenum = 0;
+ short found_disent = -1;
+ short found_priority = -1;
+
+ currtest[currstatenum] = 0;
+ op_ptr[currstatenum] = 0;
+ bitpos[currstatenum] = 40;
+
+ while (1)
+ {
+ int op_pointer = op_ptr[currstatenum];
+ unsigned int op;
+ int currbitnum = bitpos[currstatenum];
+ int oplen;
+ int opval[3] = {0};
+ int next_op;
+ int currbit;
+
+ oplen = extract_op (op_pointer, opval, &op);
+
+ bitpos[currstatenum] = currbitnum;
+
+ /* Skip opval[0] bits in the instruction. */
+ if (op & 0x40)
+ {
+ currbitnum -= opval[0];
+ }
+
+ /* The value of the current bit being tested. */
+ currbit = opcode & (((ia64_insn) 1) << currbitnum) ? 1 : 0;
+ next_op = -1;
+
+ /* We always perform the tests specified in the current state in
+ a particular order, falling through to the next test if the
+ previous one failed. */
+ switch (currtest[currstatenum])
+ {
+ case 0:
+ currtest[currstatenum]++;
+ if (currbit == 0 && (op & 0x80))
+ {
+ /* Check for a zero bit. If this test solely checks for
+ a zero bit, we can check for up to 8 consecutive zero
+ bits (the number to check is specified by the lower 3
+ bits in the state code.)
+
+ If the state instruction matches, we go to the very
+ next state instruction; otherwise, try the next test. */
+
+ if ((op & 0xf8) == 0x80)
+ {
+ int count = op & 0x7;
+ int x;
+
+ for (x = 0; x <= count; x++)
+ {
+ int i =
+ opcode & (((ia64_insn) 1) << (currbitnum - x)) ? 1 : 0;
+ if (i)
+ {
+ break;
+ }
+ }
+ if (x > count)
+ {
+ next_op = op_pointer + ((oplen + 7) / 8);
+ currbitnum -= count;
+ break;
+ }
+ }
+ else if (! currbit)
+ {
+ next_op = op_pointer + ((oplen + 7) / 8);
+ break;
+ }
+ }
+ /* FALLTHROUGH */
+ case 1:
+ /* If the bit in the instruction is one, go to the state
+ instruction specified by opval[1]. */
+ currtest[currstatenum]++;
+ if (currbit && (op & 0x30) != 0 && ((op & 0x30) != 0x30))
+ {
+ next_op = opval[1];
+ break;
+ }
+ /* FALLTHROUGH */
+ case 2:
+ /* Don't care. Skip the current bit and go to the state
+ instruction specified by opval[2].
+
+ An encoding of 0x30 is special; this means that a 12-bit
+ offset into the ia64_dis_names[] array is specified. */
+ currtest[currstatenum]++;
+ if ((op & 0x08) || ((op & 0x30) == 0x30))
+ {
+ next_op = opval[2];
+ break;
+ }
+ }
+
+ /* If bit 15 is set in the address of the next state, an offset
+ in the ia64_dis_names array was specified instead. We then
+ check to see if an entry in the list of opcodes matches the
+ opcode we were given; if so, we have succeeded. */
+
+ if ((next_op >= 0) && (next_op & 32768))
+ {
+ short disent = next_op & 32767;
+ short priority = -1;
+
+ if (next_op > 65535)
+ {
+ abort ();
+ }
+
+ /* Run through the list of opcodes to check, trying to find
+ one that matches. */
+ while (disent >= 0)
+ {
+ int place = ia64_dis_names[disent].insn_index;
+
+ priority = ia64_dis_names[disent].priority;
+
+ if (opcode_verify (opcode, place, type)
+ && priority > found_priority)
+ {
+ break;
+ }
+ if (ia64_dis_names[disent].next_flag)
+ {
+ disent++;
+ }
+ else
+ {
+ disent = -1;
+ }
+ }
+
+ if (disent >= 0)
+ {
+ found_disent = disent;
+ found_priority = priority;
+ }
+ /* Try the next test in this state, regardless of whether a match
+ was found. */
+ next_op = -2;
+ }
+
+ /* next_op == -1 is "back up to the previous state".
+ next_op == -2 is "stay in this state and try the next test".
+ Otherwise, transition to the state indicated by next_op. */
+
+ if (next_op == -1)
+ {
+ currstatenum--;
+ if (currstatenum < 0)
+ {
+ return found_disent;
+ }
+ }
+ else if (next_op >= 0)
+ {
+ currstatenum++;
+ bitpos[currstatenum] = currbitnum - 1;
+ op_ptr[currstatenum] = next_op;
+ currtest[currstatenum] = 0;
+ }
+ }
+}
+\f
+/* Construct an ia64_opcode entry based on OPCODE, NAME and PLACE. */
+
+static struct ia64_opcode *
+make_ia64_opcode (ia64_insn opcode, const char *name, int place, int depind)
+{
+ struct ia64_opcode *res =
+ (struct ia64_opcode *) xmalloc (sizeof (struct ia64_opcode));
+ if (res == NULL)
+ {
+ return NULL;
+ }
+ res->name = xstrdup (name);
+ if (res->name == NULL)
+ {
+ free (res);
+ return NULL;
+ }
+ res->type = main_table[place].opcode_type;
+ res->num_outputs = main_table[place].num_outputs;
+ res->opcode = opcode;
+ res->mask = main_table[place].mask;
+ res->operands[0] = main_table[place].operands[0];
+ res->operands[1] = main_table[place].operands[1];
+ res->operands[2] = main_table[place].operands[2];
+ res->operands[3] = main_table[place].operands[3];
+ res->operands[4] = main_table[place].operands[4];
+ res->flags = main_table[place].flags;
+ res->ent_index = place;
+ res->dependencies = &op_dependencies[depind];
+ return res;
+}
+\f
+/* Determine the ia64_opcode entry for the opcode specified by INSN
+ and TYPE. If a valid entry is not found, return NULL. */
+struct ia64_opcode *
+ia64_dis_opcode (ia64_insn insn, enum ia64_insn_type type)
+{
+ int disent = locate_opcode_ent (insn, type);
+
+ if (disent < 0)
+ {
+ return NULL;
+ }
+ else
+ {
+ unsigned int cb = ia64_dis_names[disent].completer_index;
+ static char name[128];
+ int place = ia64_dis_names[disent].insn_index;
+ int ci = main_table[place].completers;
+ ia64_insn tinsn = main_table[place].opcode;
+
+ strcpy (name, ia64_strings [main_table[place].name_index]);
+
+ while (cb)
+ {
+ if (cb & 1)
+ {
+ int cname = completer_table[ci].name_index;
+
+ tinsn = apply_completer (tinsn, ci);
+
+ if (ia64_strings[cname][0] != '\0')
+ {
+ strcat (name, ".");
+ strcat (name, ia64_strings[cname]);
+ }
+ if (cb != 1)
+ {
+ ci = completer_table[ci].subentries;
+ }
+ }
+ else
+ {
+ ci = completer_table[ci].alternative;
+ }
+ if (ci < 0)
+ {
+ abort ();
+ }
+ cb = cb >> 1;
+ }
+ if (tinsn != (insn & main_table[place].mask))
+ {
+ abort ();
+ }
+ return make_ia64_opcode (insn, name, place,
+ completer_table[ci].dependencies);
+ }
+}
+\f
+/* Search the main_opcode table starting from PLACE for an opcode that
+ matches NAME. Return NULL if one is not found. */
+
+static struct ia64_opcode *
+ia64_find_matching_opcode (const char *name, short place)
+{
+ char op[129];
+ const char *suffix;
+ short name_index;
+
+ if (strlen (name) > 128)
+ {
+ return NULL;
+ }
+ suffix = name;
+ get_opc_prefix (&suffix, op);
+ name_index = find_string_ent (op);
+ if (name_index < 0)
+ {
+ return NULL;
+ }
+
+ while (main_table[place].name_index == name_index)
+ {
+ const char *curr_suffix = suffix;
+ ia64_insn curr_insn = main_table[place].opcode;
+ short completer = -1;
+
+ do {
+ if (suffix[0] == '\0')
+ {
+ completer = find_completer (place, completer, suffix);
+ }
+ else
+ {
+ get_opc_prefix (&curr_suffix, op);
+ completer = find_completer (place, completer, op);
+ }
+ if (completer != -1)
+ {
+ curr_insn = apply_completer (curr_insn, completer);
+ }
+ } while (completer != -1 && curr_suffix[0] != '\0');
+
+ if (completer != -1 && curr_suffix[0] == '\0'
+ && completer_table[completer].terminal_completer)
+ {
+ int depind = completer_table[completer].dependencies;
+ return make_ia64_opcode (curr_insn, name, place, depind);
+ }
+ else
+ {
+ place++;
+ }
+ }
+ return NULL;
+}
+\f
+/* Find the next opcode after PREV_ENT that matches PREV_ENT, or return NULL
+ if one does not exist.
+
+ It is the caller's responsibility to invoke ia64_free_opcode () to
+ release any resources used by the returned entry. */
+
+struct ia64_opcode *
+ia64_find_next_opcode (struct ia64_opcode *prev_ent)
+{
+ return ia64_find_matching_opcode (prev_ent->name,
+ prev_ent->ent_index + 1);
+}
+
+/* Find the first opcode that matches NAME, or return NULL if it does
+ not exist.
+
+ It is the caller's responsibility to invoke ia64_free_opcode () to
+ release any resources used by the returned entry. */
+
+struct ia64_opcode *
+ia64_find_opcode (const char *name)
+{
+ char op[129];
+ const char *suffix;
+ short place;
+ short name_index;
+
+ if (strlen (name) > 128)
+ {
+ return NULL;
+ }
+ suffix = name;
+ get_opc_prefix (&suffix, op);
+ name_index = find_string_ent (op);
+ if (name_index < 0)
+ {
+ return NULL;
+ }
+
+ place = find_main_ent (name_index);
+
+ if (place < 0)
+ {
+ return NULL;
+ }
+ return ia64_find_matching_opcode (name, place);
+}
+
+/* Free any resources used by ENT. */
+void
+ia64_free_opcode (struct ia64_opcode *ent)
+{
+ free ((void *)ent->name);
+ free (ent);
+}
+
+const struct ia64_dependency *
+ia64_find_dependency (int index)
+{
+ index = DEP(index);
+
+ if (index < 0
+ || index >= (int)(sizeof(dependencies) / sizeof(dependencies[0])))
+ return NULL;
+
+ return &dependencies[index];
+}
--- /dev/null
+/* ia64-opc.h -- IA-64 opcode table.
+ Copyright 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+
+ This file is part of GDB, GAS, and the GNU binutils.
+
+ GDB, GAS, and the GNU binutils are free software; you can redistribute
+ them and/or modify them under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either version
+ 2, or (at your option) any later version.
+
+ GDB, GAS, and the GNU binutils are distributed in the hope that they
+ will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this file; see the file COPYING. If not, write to the
+ Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use.
+ * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as
+ * required.
+ * Keith Owens <kaos@sgi.com> 15 May 2006
+ */
+
+#ifndef IA64_OPC_H
+#define IA64_OPC_H
+
+#ifdef __KERNEL__
+#include "ia64.h"
+#else /* __KERNEL__ */
+#include "opcode/ia64.h"
+#endif /* __KERNEL__ */
+
+/* define a couple of abbreviations: */
+
+#define bOp(x) (((ia64_insn) ((x) & 0xf)) << 37)
+#define mOp bOp (-1)
+#define Op(x) bOp (x), mOp
+
+#define FIRST IA64_OPCODE_FIRST
+#define X_IN_MLX IA64_OPCODE_X_IN_MLX
+#define LAST IA64_OPCODE_LAST
+#define PRIV IA64_OPCODE_PRIV
+#define NO_PRED IA64_OPCODE_NO_PRED
+#define SLOT2 IA64_OPCODE_SLOT2
+#define PSEUDO IA64_OPCODE_PSEUDO
+#define F2_EQ_F3 IA64_OPCODE_F2_EQ_F3
+#define LEN_EQ_64MCNT IA64_OPCODE_LEN_EQ_64MCNT
+#define MOD_RRBS IA64_OPCODE_MOD_RRBS
+#define POSTINC IA64_OPCODE_POSTINC
+
+#define AR_CCV IA64_OPND_AR_CCV
+#define AR_PFS IA64_OPND_AR_PFS
+#define AR_CSD IA64_OPND_AR_CSD
+#define C1 IA64_OPND_C1
+#define C8 IA64_OPND_C8
+#define C16 IA64_OPND_C16
+#define GR0 IA64_OPND_GR0
+#define IP IA64_OPND_IP
+#define PR IA64_OPND_PR
+#define PR_ROT IA64_OPND_PR_ROT
+#define PSR IA64_OPND_PSR
+#define PSR_L IA64_OPND_PSR_L
+#define PSR_UM IA64_OPND_PSR_UM
+
+#define AR3 IA64_OPND_AR3
+#define B1 IA64_OPND_B1
+#define B2 IA64_OPND_B2
+#define CR3 IA64_OPND_CR3
+#define F1 IA64_OPND_F1
+#define F2 IA64_OPND_F2
+#define F3 IA64_OPND_F3
+#define F4 IA64_OPND_F4
+#define P1 IA64_OPND_P1
+#define P2 IA64_OPND_P2
+#define R1 IA64_OPND_R1
+#define R2 IA64_OPND_R2
+#define R3 IA64_OPND_R3
+#define R3_2 IA64_OPND_R3_2
+
+#define CPUID_R3 IA64_OPND_CPUID_R3
+#define DBR_R3 IA64_OPND_DBR_R3
+#define DTR_R3 IA64_OPND_DTR_R3
+#define ITR_R3 IA64_OPND_ITR_R3
+#define IBR_R3 IA64_OPND_IBR_R3
+#define MR3 IA64_OPND_MR3
+#define MSR_R3 IA64_OPND_MSR_R3
+#define PKR_R3 IA64_OPND_PKR_R3
+#define PMC_R3 IA64_OPND_PMC_R3
+#define PMD_R3 IA64_OPND_PMD_R3
+#define RR_R3 IA64_OPND_RR_R3
+
+#define CCNT5 IA64_OPND_CCNT5
+#define CNT2a IA64_OPND_CNT2a
+#define CNT2b IA64_OPND_CNT2b
+#define CNT2c IA64_OPND_CNT2c
+#define CNT5 IA64_OPND_CNT5
+#define CNT6 IA64_OPND_CNT6
+#define CPOS6a IA64_OPND_CPOS6a
+#define CPOS6b IA64_OPND_CPOS6b
+#define CPOS6c IA64_OPND_CPOS6c
+#define IMM1 IA64_OPND_IMM1
+#define IMM14 IA64_OPND_IMM14
+#define IMM17 IA64_OPND_IMM17
+#define IMM22 IA64_OPND_IMM22
+#define IMM44 IA64_OPND_IMM44
+#define SOF IA64_OPND_SOF
+#define SOL IA64_OPND_SOL
+#define SOR IA64_OPND_SOR
+#define IMM8 IA64_OPND_IMM8
+#define IMM8U4 IA64_OPND_IMM8U4
+#define IMM8M1 IA64_OPND_IMM8M1
+#define IMM8M1U4 IA64_OPND_IMM8M1U4
+#define IMM8M1U8 IA64_OPND_IMM8M1U8
+#define IMM9a IA64_OPND_IMM9a
+#define IMM9b IA64_OPND_IMM9b
+#define IMMU2 IA64_OPND_IMMU2
+#define IMMU21 IA64_OPND_IMMU21
+#define IMMU24 IA64_OPND_IMMU24
+#define IMMU62 IA64_OPND_IMMU62
+#define IMMU64 IA64_OPND_IMMU64
+#define IMMU7a IA64_OPND_IMMU7a
+#define IMMU7b IA64_OPND_IMMU7b
+#define IMMU9 IA64_OPND_IMMU9
+#define INC3 IA64_OPND_INC3
+#define LEN4 IA64_OPND_LEN4
+#define LEN6 IA64_OPND_LEN6
+#define MBTYPE4 IA64_OPND_MBTYPE4
+#define MHTYPE8 IA64_OPND_MHTYPE8
+#define POS6 IA64_OPND_POS6
+#define TAG13 IA64_OPND_TAG13
+#define TAG13b IA64_OPND_TAG13b
+#define TGT25 IA64_OPND_TGT25
+#define TGT25b IA64_OPND_TGT25b
+#define TGT25c IA64_OPND_TGT25c
+#define TGT64 IA64_OPND_TGT64
+
+#endif
--- /dev/null
+/* ia64.h -- Header file for ia64 opcode table
+ Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com> */
+
+/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use.
+ * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as
+ * required.
+ * Keith Owens <kaos@sgi.com> 15 May 2006
+ */
+
+#ifndef opcode_ia64_h
+#define opcode_ia64_h
+
+#ifdef __KERNEL__
+#include <asm/bfd.h>
+#else /* __KERNEL__ */
+#include <sys/types.h>
+
+#include "bfd.h"
+#endif /* __KERNEL__ */
+
+
+typedef BFD_HOST_U_64_BIT ia64_insn;
+
+enum ia64_insn_type
+ {
+ IA64_TYPE_NIL = 0, /* illegal type */
+ IA64_TYPE_A, /* integer alu (I- or M-unit) */
+ IA64_TYPE_I, /* non-alu integer (I-unit) */
+ IA64_TYPE_M, /* memory (M-unit) */
+ IA64_TYPE_B, /* branch (B-unit) */
+ IA64_TYPE_F, /* floating-point (F-unit) */
+ IA64_TYPE_X, /* long encoding (X-unit) */
+ IA64_TYPE_DYN, /* Dynamic opcode */
+ IA64_NUM_TYPES
+ };
+
+enum ia64_unit
+ {
+ IA64_UNIT_NIL = 0, /* illegal unit */
+ IA64_UNIT_I, /* integer unit */
+ IA64_UNIT_M, /* memory unit */
+ IA64_UNIT_B, /* branching unit */
+ IA64_UNIT_F, /* floating-point unit */
+ IA64_UNIT_L, /* long "unit" */
+ IA64_UNIT_X, /* may be integer or branch unit */
+ IA64_NUM_UNITS
+ };
+
+/* Changes to this enumeration must be propagated to the operand table in
+ bfd/cpu-ia64-opc.c
+ */
+enum ia64_opnd
+ {
+ IA64_OPND_NIL, /* no operand---MUST BE FIRST!*/
+
+ /* constants */
+ IA64_OPND_AR_CSD, /* application register csd (ar.csd) */
+ IA64_OPND_AR_CCV, /* application register ccv (ar.ccv) */
+ IA64_OPND_AR_PFS, /* application register pfs (ar.pfs) */
+ IA64_OPND_C1, /* the constant 1 */
+ IA64_OPND_C8, /* the constant 8 */
+ IA64_OPND_C16, /* the constant 16 */
+ IA64_OPND_GR0, /* gr0 */
+ IA64_OPND_IP, /* instruction pointer (ip) */
+ IA64_OPND_PR, /* predicate register (pr) */
+ IA64_OPND_PR_ROT, /* rotating predicate register (pr.rot) */
+ IA64_OPND_PSR, /* processor status register (psr) */
+ IA64_OPND_PSR_L, /* processor status register L (psr.l) */
+ IA64_OPND_PSR_UM, /* processor status register UM (psr.um) */
+
+ /* register operands: */
+ IA64_OPND_AR3, /* third application register # (bits 20-26) */
+ IA64_OPND_B1, /* branch register # (bits 6-8) */
+ IA64_OPND_B2, /* branch register # (bits 13-15) */
+ IA64_OPND_CR3, /* third control register # (bits 20-26) */
+ IA64_OPND_F1, /* first floating-point register # */
+ IA64_OPND_F2, /* second floating-point register # */
+ IA64_OPND_F3, /* third floating-point register # */
+ IA64_OPND_F4, /* fourth floating-point register # */
+ IA64_OPND_P1, /* first predicate # */
+ IA64_OPND_P2, /* second predicate # */
+ IA64_OPND_R1, /* first register # */
+ IA64_OPND_R2, /* second register # */
+ IA64_OPND_R3, /* third register # */
+ IA64_OPND_R3_2, /* third register # (limited to gr0-gr3) */
+
+ /* indirect operands: */
+ IA64_OPND_CPUID_R3, /* cpuid[reg] */
+ IA64_OPND_DBR_R3, /* dbr[reg] */
+ IA64_OPND_DTR_R3, /* dtr[reg] */
+ IA64_OPND_ITR_R3, /* itr[reg] */
+ IA64_OPND_IBR_R3, /* ibr[reg] */
+ IA64_OPND_MR3, /* memory at addr of third register # */
+ IA64_OPND_MSR_R3, /* msr[reg] */
+ IA64_OPND_PKR_R3, /* pkr[reg] */
+ IA64_OPND_PMC_R3, /* pmc[reg] */
+ IA64_OPND_PMD_R3, /* pmd[reg] */
+ IA64_OPND_RR_R3, /* rr[reg] */
+
+ /* immediate operands: */
+ IA64_OPND_CCNT5, /* 5-bit count (31 - bits 20-24) */
+ IA64_OPND_CNT2a, /* 2-bit count (1 + bits 27-28) */
+ IA64_OPND_CNT2b, /* 2-bit count (bits 27-28): 1, 2, 3 */
+ IA64_OPND_CNT2c, /* 2-bit count (bits 30-31): 0, 7, 15, or 16 */
+ IA64_OPND_CNT5, /* 5-bit count (bits 14-18) */
+ IA64_OPND_CNT6, /* 6-bit count (bits 27-32) */
+ IA64_OPND_CPOS6a, /* 6-bit count (63 - bits 20-25) */
+ IA64_OPND_CPOS6b, /* 6-bit count (63 - bits 14-19) */
+ IA64_OPND_CPOS6c, /* 6-bit count (63 - bits 31-36) */
+ IA64_OPND_IMM1, /* signed 1-bit immediate (bit 36) */
+ IA64_OPND_IMMU2, /* unsigned 2-bit immediate (bits 13-14) */
+ IA64_OPND_IMMU7a, /* unsigned 7-bit immediate (bits 13-19) */
+ IA64_OPND_IMMU7b, /* unsigned 7-bit immediate (bits 20-26) */
+ IA64_OPND_SOF, /* 8-bit stack frame size */
+ IA64_OPND_SOL, /* 8-bit size of locals */
+ IA64_OPND_SOR, /* 6-bit number of rotating registers (scaled by 8) */
+ IA64_OPND_IMM8, /* signed 8-bit immediate (bits 13-19 & 36) */
+ IA64_OPND_IMM8U4, /* cmp4*u signed 8-bit immediate (bits 13-19 & 36) */
+ IA64_OPND_IMM8M1, /* signed 8-bit immediate -1 (bits 13-19 & 36) */
+ IA64_OPND_IMM8M1U4, /* cmp4*u signed 8-bit immediate -1 (bits 13-19 & 36)*/
+ IA64_OPND_IMM8M1U8, /* cmp*u signed 8-bit immediate -1 (bits 13-19 & 36) */
+ IA64_OPND_IMMU9, /* unsigned 9-bit immediate (bits 33-34, 20-26) */
+ IA64_OPND_IMM9a, /* signed 9-bit immediate (bits 6-12, 27, 36) */
+ IA64_OPND_IMM9b, /* signed 9-bit immediate (bits 13-19, 27, 36) */
+ IA64_OPND_IMM14, /* signed 14-bit immediate (bits 13-19, 27-32, 36) */
+ IA64_OPND_IMM17, /* signed 17-bit immediate (2*bits 6-12, 24-31, 36) */
+ IA64_OPND_IMMU21, /* unsigned 21-bit immediate (bits 6-25, 36) */
+ IA64_OPND_IMM22, /* signed 22-bit immediate (bits 13-19, 22-36) */
+ IA64_OPND_IMMU24, /* unsigned 24-bit immediate (bits 6-26, 31-32, 36) */
+ IA64_OPND_IMM44, /* signed 44-bit immediate (2^16*bits 6-32, 36) */
+ IA64_OPND_IMMU62, /* unsigned 62-bit immediate */
+ IA64_OPND_IMMU64, /* unsigned 64-bit immediate (lotsa bits...) */
+ IA64_OPND_INC3, /* signed 3-bit (bits 13-15): +/-1, 4, 8, 16 */
+ IA64_OPND_LEN4, /* 4-bit count (bits 27-30 + 1) */
+ IA64_OPND_LEN6, /* 6-bit count (bits 27-32 + 1) */
+ IA64_OPND_MBTYPE4, /* 4-bit mux type (bits 20-23) */
+ IA64_OPND_MHTYPE8, /* 8-bit mux type (bits 20-27) */
+ IA64_OPND_POS6, /* 6-bit count (bits 14-19) */
+ IA64_OPND_TAG13, /* signed 13-bit tag (ip + 16*bits 6-12, 33-34) */
+ IA64_OPND_TAG13b, /* signed 13-bit tag (ip + 16*bits 24-32) */
+ IA64_OPND_TGT25, /* signed 25-bit (ip + 16*bits 6-25, 36) */
+ IA64_OPND_TGT25b, /* signed 25-bit (ip + 16*bits 6-12, 20-32, 36) */
+ IA64_OPND_TGT25c, /* signed 25-bit (ip + 16*bits 13-32, 36) */
+ IA64_OPND_TGT64, /* 64-bit (ip + 16*bits 13-32, 36, 2-40(L)) */
+ IA64_OPND_LDXMOV, /* any symbol, generates R_IA64_LDXMOV. */
+
+ IA64_OPND_COUNT /* # of operand types (MUST BE LAST!) */
+ };
+
+enum ia64_dependency_mode
+{
+ IA64_DV_RAW,
+ IA64_DV_WAW,
+ IA64_DV_WAR,
+};
+
+enum ia64_dependency_semantics
+{
+ IA64_DVS_NONE,
+ IA64_DVS_IMPLIED,
+ IA64_DVS_IMPLIEDF,
+ IA64_DVS_DATA,
+ IA64_DVS_INSTR,
+ IA64_DVS_SPECIFIC,
+ IA64_DVS_STOP,
+ IA64_DVS_OTHER,
+};
+
+enum ia64_resource_specifier
+{
+ IA64_RS_ANY,
+ IA64_RS_AR_K,
+ IA64_RS_AR_UNAT,
+ IA64_RS_AR, /* 8-15, 20, 22-23, 31, 33-35, 37-39, 41-43, 45-47, 67-111 */
+ IA64_RS_ARb, /* 48-63, 112-127 */
+ IA64_RS_BR,
+ IA64_RS_CFM,
+ IA64_RS_CPUID,
+ IA64_RS_CR_IRR,
+ IA64_RS_CR_LRR,
+ IA64_RS_CR, /* 3-7,10-15,18,26-63,75-79,82-127 */
+ IA64_RS_DBR,
+ IA64_RS_FR,
+ IA64_RS_FRb,
+ IA64_RS_GR0,
+ IA64_RS_GR,
+ IA64_RS_IBR,
+ IA64_RS_INSERVICE, /* CR[EOI] or CR[IVR] */
+ IA64_RS_MSR,
+ IA64_RS_PKR,
+ IA64_RS_PMC,
+ IA64_RS_PMD,
+ IA64_RS_PR, /* non-rotating, 1-15 */
+ IA64_RS_PRr, /* rotating, 16-62 */
+ IA64_RS_PR63,
+ IA64_RS_RR,
+
+ IA64_RS_ARX, /* ARs not in RS_AR or RS_ARb */
+ IA64_RS_CRX, /* CRs not in RS_CR */
+ IA64_RS_PSR, /* PSR bits */
+ IA64_RS_RSE, /* implementation-specific RSE resources */
+ IA64_RS_AR_FPSR,
+};
+
+enum ia64_rse_resource
+{
+ IA64_RSE_N_STACKED_PHYS,
+ IA64_RSE_BOF,
+ IA64_RSE_STORE_REG,
+ IA64_RSE_LOAD_REG,
+ IA64_RSE_BSPLOAD,
+ IA64_RSE_RNATBITINDEX,
+ IA64_RSE_CFLE,
+ IA64_RSE_NDIRTY,
+};
+
+/* Information about a given resource dependency */
+struct ia64_dependency
+{
+ /* Name of the resource */
+ const char *name;
+ /* Does this dependency need further specification? */
+ enum ia64_resource_specifier specifier;
+ /* Mode of dependency */
+ enum ia64_dependency_mode mode;
+ /* Dependency semantics */
+ enum ia64_dependency_semantics semantics;
+ /* Register index, if applicable (distinguishes AR, CR, and PSR deps) */
+#define REG_NONE (-1)
+ int regindex;
+ /* Special info on semantics */
+ const char *info;
+};
+
+/* Two arrays of indexes into the ia64_dependency table.
+ chks are dependencies to check for conflicts when an opcode is
+ encountered; regs are dependencies to register (mark as used) when an
+ opcode is used. chks correspond to readers (RAW) or writers (WAW or
+ WAR) of a resource, while regs correspond to writers (RAW or WAW) and
+ readers (WAR) of a resource. */
+struct ia64_opcode_dependency
+{
+ int nchks;
+ const unsigned short *chks;
+ int nregs;
+ const unsigned short *regs;
+};
+
+/* encode/extract the note/index for a dependency */
+#define RDEP(N,X) (((N)<<11)|(X))
+#define NOTE(X) (((X)>>11)&0x1F)
+#define DEP(X) ((X)&0x7FF)
+
+/* A template descriptor describes the execution units that are active
+ for each of the three slots. It also specifies the location of
+ instruction group boundaries that may be present between two slots. */
+struct ia64_templ_desc
+ {
+ int group_boundary; /* 0=no boundary, 1=between slot 0 & 1, etc. */
+ enum ia64_unit exec_unit[3];
+ const char *name;
+ };
+
+/* The opcode table is an array of struct ia64_opcode. */
+
+struct ia64_opcode
+ {
+ /* The opcode name. */
+ const char *name;
+
+ /* The type of the instruction: */
+ enum ia64_insn_type type;
+
+ /* Number of output operands: */
+ int num_outputs;
+
+ /* The opcode itself. Those bits which will be filled in with
+ operands are zeroes. */
+ ia64_insn opcode;
+
+ /* The opcode mask. This is used by the disassembler. This is a
+ mask containing ones indicating those bits which must match the
+ opcode field, and zeroes indicating those bits which need not
+ match (and are presumably filled in by operands). */
+ ia64_insn mask;
+
+ /* An array of operand codes. Each code is an index into the
+ operand table. They appear in the order which the operands must
+ appear in assembly code, and are terminated by a zero. */
+ enum ia64_opnd operands[5];
+
+ /* One bit flags for the opcode. These are primarily used to
+ indicate specific processors and environments support the
+ instructions. The defined values are listed below. */
+ unsigned int flags;
+
+ /* Used by ia64_find_next_opcode (). */
+ short ent_index;
+
+ /* Opcode dependencies. */
+ const struct ia64_opcode_dependency *dependencies;
+ };
+
+/* Values defined for the flags field of a struct ia64_opcode. */
+
+#define IA64_OPCODE_FIRST (1<<0) /* must be first in an insn group */
+#define IA64_OPCODE_X_IN_MLX (1<<1) /* insn is allowed in X slot of MLX */
+#define IA64_OPCODE_LAST (1<<2) /* must be last in an insn group */
+#define IA64_OPCODE_PRIV (1<<3) /* privileged instruct */
+#define IA64_OPCODE_SLOT2 (1<<4) /* insn allowed in slot 2 only */
+#define IA64_OPCODE_NO_PRED (1<<5) /* insn cannot be predicated */
+#define IA64_OPCODE_PSEUDO (1<<6) /* insn is a pseudo-op */
+#define IA64_OPCODE_F2_EQ_F3 (1<<7) /* constraint: F2 == F3 */
+#define IA64_OPCODE_LEN_EQ_64MCNT (1<<8) /* constraint: LEN == 64-CNT */
+#define IA64_OPCODE_MOD_RRBS (1<<9) /* modifies all rrbs in CFM */
+#define IA64_OPCODE_POSTINC (1<<10) /* postincrement MR3 operand */
+
+/* A macro to extract the major opcode from an instruction. */
+#define IA64_OP(i) (((i) >> 37) & 0xf)
+
+enum ia64_operand_class
+ {
+ IA64_OPND_CLASS_CST, /* constant */
+ IA64_OPND_CLASS_REG, /* register */
+ IA64_OPND_CLASS_IND, /* indirect register */
+ IA64_OPND_CLASS_ABS, /* absolute value */
+ IA64_OPND_CLASS_REL, /* IP-relative value */
+ };
+
+/* The operands table is an array of struct ia64_operand. */
+
+struct ia64_operand
+{
+ enum ia64_operand_class class;
+
+ /* Set VALUE as the operand bits for the operand of type SELF in the
+ instruction pointed to by CODE. If an error occurs, *CODE is not
+ modified and the returned string describes the cause of the
+ error. If no error occurs, NULL is returned. */
+ const char *(*insert) (const struct ia64_operand *self, ia64_insn value,
+ ia64_insn *code);
+
+ /* Extract the operand bits for an operand of type SELF from
+ instruction CODE store them in *VALUE. If an error occurs, the
+ cause of the error is described by the string returned. If no
+ error occurs, NULL is returned. */
+ const char *(*extract) (const struct ia64_operand *self, ia64_insn code,
+ ia64_insn *value);
+
+ /* A string whose meaning depends on the operand class. */
+
+ const char *str;
+
+ struct bit_field
+ {
+ /* The number of bits in the operand. */
+ int bits;
+
+ /* How far the operand is left shifted in the instruction. */
+ int shift;
+ }
+ field[4]; /* no operand has more than this many bit-fields */
+
+ unsigned int flags;
+
+ const char *desc; /* brief description */
+};
+
+/* Values defined for the flags field of a struct ia64_operand. */
+
+/* Disassemble as signed decimal (instead of hex): */
+#define IA64_OPND_FLAG_DECIMAL_SIGNED (1<<0)
+/* Disassemble as unsigned decimal (instead of hex): */
+#define IA64_OPND_FLAG_DECIMAL_UNSIGNED (1<<1)
+
+extern const struct ia64_templ_desc ia64_templ_desc[16];
+
+/* The tables are sorted by major opcode number and are otherwise in
+ the order in which the disassembler should consider instructions. */
+extern struct ia64_opcode ia64_opcodes_a[];
+extern struct ia64_opcode ia64_opcodes_i[];
+extern struct ia64_opcode ia64_opcodes_m[];
+extern struct ia64_opcode ia64_opcodes_b[];
+extern struct ia64_opcode ia64_opcodes_f[];
+extern struct ia64_opcode ia64_opcodes_d[];
+
+
+extern struct ia64_opcode *ia64_find_opcode (const char *name);
+extern struct ia64_opcode *ia64_find_next_opcode (struct ia64_opcode *ent);
+
+extern struct ia64_opcode *ia64_dis_opcode (ia64_insn insn,
+ enum ia64_insn_type type);
+
+extern void ia64_free_opcode (struct ia64_opcode *ent);
+extern const struct ia64_dependency *ia64_find_dependency (int index);
+
+/* To avoid circular library dependencies, this array is implemented
+ in bfd/cpu-ia64-opc.c: */
+extern const struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT];
+
+#endif /* opcode_ia64_h */
--- /dev/null
+# Standard architecture specific commands for kdb.
+# These commands are appended to those in kdb/kdb_cmds, see that file for
+# restrictions.
+
+# Standard debugging information for first level support, invoked from archkdb*
+# commands that are defined in kdb/kdb_cmds.
+
+defcmd archkdbcommon "" "Common arch debugging"
+ set LINES 2000000
+ set BTAPROMPT 0
+ -summary
+ -id %ip-0x40
+ -cpu
+ -ps
+ -dmesg 600
+ -bt
+endefcmd
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Breakpoint Handling
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/ptrace.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <asm/pgalloc.h>
+
+
+static char *kdba_rwtypes[] = { "Instruction(Register)", "Data Write",
+ "I/O", "Data Access"};
+
+/*
+ * Table describing processor architecture hardware
+ * breakpoint registers.
+ */
+
+static kdbhard_bp_t kdb_hardbreaks[KDB_MAXHARDBPT];
+
+/*
+ * kdba_db_trap
+ *
+ * Perform breakpoint processing upon entry to the
+ * processor debugger fault. Determine and print
+ * the active breakpoint.
+ *
+ * Parameters:
+ * regs Exception frame containing machine register state
+ * error Error number passed to kdb.
+ * Outputs:
+ * None.
+ * Returns:
+ * KDB_DB_BPT Standard instruction or data breakpoint encountered
+ * KDB_DB_SS Single Step fault ('ss' command or end of 'ssb' command)
+ * KDB_DB_SSB Single Step fault, caller should continue ('ssb' command)
+ * KDB_DB_SSBPT Single step over breakpoint
+ * KDB_DB_NOBPT No existing kdb breakpoint matches this debug exception
+ * Locking:
+ * None.
+ * Remarks:
+ * Yup, there be goto's here.
+ *
+ * If multiple processors receive debug exceptions simultaneously,
+ * one may be waiting at the kdb fence in kdb() while the user
+ * issues a 'bc' command to clear the breakpoint the processor
+ * which is waiting has already encountered. If this is the case,
+ * the debug registers will no longer match any entry in the
+ * breakpoint table, and we'll return the value KDB_DB_NOBPT.
+ * This can cause a panic in die_if_kernel(). It is safer to
+ * disable the breakpoint (bd), go until all processors are past
+ * the breakpoint then clear the breakpoint (bc). This code
+ * recognises a breakpoint even when disabled but not when it has
+ * been cleared.
+ *
+ * WARNING: This routine clears the debug state. It should be called
+ * once per debug and the result cached.
+ */
+
+kdb_dbtrap_t
+kdba_db_trap(struct pt_regs *regs, int error)
+{
+ int i;
+ kdb_dbtrap_t rv = KDB_DB_BPT;
+ kdb_bp_t *bp;
+
+ if (KDB_NULL_REGS(regs))
+ return KDB_DB_NOBPT;
+
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_db_trap: error %d\n", error);
+
+ if (error == 36) {
+ /* Single step */
+ if (KDB_STATE(SSBPT)) {
+ if (KDB_DEBUG(BP))
+ kdb_printf("ssbpt\n");
+ KDB_STATE_CLEAR(SSBPT);
+ for(i=0,bp=kdb_breakpoints;
+ i < KDB_MAXBPT;
+ i++, bp++) {
+ if (KDB_DEBUG(BP))
+ kdb_printf("bp 0x%p enabled %d delayed %d global %d cpu %d\n",
+ bp, bp->bp_enabled, bp->bp_delayed, bp->bp_global, bp->bp_cpu);
+ if (!bp->bp_enabled)
+ continue;
+ if (!bp->bp_global && bp->bp_cpu != smp_processor_id())
+ continue;
+ if (KDB_DEBUG(BP))
+ kdb_printf("bp for this cpu\n");
+ if (bp->bp_delayed) {
+ bp->bp_delayed = 0;
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_installbp\n");
+ kdba_installbp(regs, bp);
+ if (!KDB_STATE(DOING_SS)) {
+ kdba_clearsinglestep(regs);
+ return(KDB_DB_SSBPT);
+ }
+ break;
+ }
+ }
+ if (i == KDB_MAXBPT) {
+ kdb_printf("kdb: Unable to find delayed breakpoint\n");
+ }
+ if (!KDB_STATE(DOING_SS)) {
+ kdba_clearsinglestep(regs);
+ return(KDB_DB_NOBPT);
+ }
+ /* FALLTHROUGH */
+ }
+
+ /*
+ * KDB_STATE_DOING_SS is set when the kernel debugger is using
+ * the processor trap flag to single-step a processor. If a
+ * single step trap occurs and this flag is clear, the SS trap
+ * will be ignored by KDB and the kernel will be allowed to deal
+ * with it as necessary (e.g. for ptrace).
+ */
+ if (!KDB_STATE(DOING_SS))
+ return(KDB_DB_NOBPT);
+
+ /* single step */
+ rv = KDB_DB_SS; /* Indicate single step */
+ if (KDB_STATE(DOING_SSB)) /* No ia64 ssb support yet */
+ KDB_STATE_CLEAR(DOING_SSB); /* No ia64 ssb support yet */
+ if (KDB_STATE(DOING_SSB)) {
+ /* No IA64 ssb support yet */
+ } else {
+ /*
+ * Print current insn
+ */
+ kdb_machreg_t pc = regs->cr_iip + ia64_psr(regs)->ri * 6;
+ kdb_printf("SS trap at ");
+ kdb_symbol_print(pc, NULL, KDB_SP_DEFAULT|KDB_SP_NEWLINE);
+ kdb_id1(pc);
+ KDB_STATE_CLEAR(DOING_SS);
+ }
+
+ if (rv != KDB_DB_SSB)
+ kdba_clearsinglestep(regs);
+ }
+
+ return(rv);
+}
+
+/*
+ * kdba_bp_trap
+ *
+ * Perform breakpoint processing upon entry to the
+ * processor breakpoint instruction fault. Determine and print
+ * the active breakpoint.
+ *
+ * Parameters:
+ * regs Exception frame containing machine register state
+ * error Error number passed to kdb.
+ * Outputs:
+ * None.
+ * Returns:
+ * 0 Standard instruction or data breakpoint encountered
+ * 1 Single Step fault ('ss' command)
+ * 2 Single Step fault, caller should continue ('ssb' command)
+ * 3 No existing kdb breakpoint matches this debug exception
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ * If multiple processors receive debug exceptions simultaneously,
+ * one may be waiting at the kdb fence in kdb() while the user
+ * issues a 'bc' command to clear the breakpoint the processor which
+ * is waiting has already encountered. If this is the case, the
+ * debug registers will no longer match any entry in the breakpoint
+ * table, and we'll return the value '3'. This can cause a panic
+ * in die_if_kernel(). It is safer to disable the breakpoint (bd),
+ * 'go' until all processors are past the breakpoint then clear the
+ * breakpoint (bc). This code recognises a breakpoint even when
+ * disabled but not when it has been cleared.
+ *
+ * WARNING: This routine resets the ip. It should be called
+ * once per breakpoint and the result cached.
+ */
+
+kdb_dbtrap_t
+kdba_bp_trap(struct pt_regs *regs, int error)
+{
+ int i;
+ kdb_dbtrap_t rv;
+ kdb_bp_t *bp;
+
+ if (KDB_NULL_REGS(regs))
+ return KDB_DB_NOBPT;
+
+ /*
+ * Determine which breakpoint was encountered.
+ */
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_bp_trap: ip=0x%lx "
+ "regs=0x%p sp=0x%lx\n",
+ regs->cr_iip, regs, regs->r12);
+
+ rv = KDB_DB_NOBPT; /* Cause kdb() to return */
+
+ for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) {
+ if (bp->bp_free)
+ continue;
+ if (!bp->bp_global && bp->bp_cpu != smp_processor_id())
+ continue;
+ if (bp->bp_addr == regs->cr_iip) {
+ /* Hit this breakpoint. */
+ kdb_printf("Instruction(i) breakpoint #%d at 0x%lx\n",
+ i, regs->cr_iip);
+ kdb_id1(regs->cr_iip);
+ rv = KDB_DB_BPT;
+ bp->bp_delay = 1;
+ /* SSBPT is set when the kernel debugger must single
+ * step a task in order to re-establish an instruction
+ * breakpoint which uses the instruction replacement
+ * mechanism. It is cleared by any action that removes
+ * the need to single-step the breakpoint.
+ */
+ KDB_STATE_SET(SSBPT);
+ break;
+ }
+ }
+
+ return rv;
+}
+
+/*
+ * kdba_handle_bp
+ *
+ * Handle an instruction-breakpoint trap. Called when re-installing
+ * an enabled breakpoint which has has the bp_delay bit set.
+ *
+ * Parameters:
+ * Returns:
+ * Locking:
+ * Remarks:
+ *
+ * Ok, we really need to:
+ * 1) Restore the original instruction byte(s)
+ * 2) Single Step
+ * 3) Restore breakpoint instruction
+ * 4) Continue.
+ *
+ *
+ */
+
+static void
+kdba_handle_bp(struct pt_regs *regs, kdb_bp_t *bp)
+{
+ if (KDB_NULL_REGS(regs))
+ return;
+
+ if (KDB_DEBUG(BP))
+ kdb_printf("regs->cr_iip = 0x%lx\n", regs->cr_iip);
+
+ /*
+ * Setup single step
+ */
+ kdba_setsinglestep(regs);
+
+ /*
+ * Reset delay attribute
+ */
+ bp->bp_delay = 0;
+ bp->bp_delayed = 1;
+}
+
+
+/*
+ * kdba_bptype
+ *
+ * Return a string describing type of breakpoint.
+ *
+ * Parameters:
+ * bph Pointer to hardware breakpoint description
+ * Outputs:
+ * None.
+ * Returns:
+ * Character string.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+char *
+kdba_bptype(kdbhard_bp_t *bph)
+{
+ char *mode;
+
+ mode = kdba_rwtypes[bph->bph_mode];
+
+ return mode;
+}
+
+/*
+ * kdba_printbpreg
+ *
+ * Print register name assigned to breakpoint
+ *
+ * Parameters:
+ * bph Pointer hardware breakpoint structure
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+static void
+kdba_printbpreg(kdbhard_bp_t *bph)
+{
+ kdb_printf(" in dr%ld", bph->bph_reg);
+}
+
+/*
+ * kdba_printbp
+ *
+ * Print string describing hardware breakpoint.
+ *
+ * Parameters:
+ * bph Pointer to hardware breakpoint description
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+void
+kdba_printbp(kdb_bp_t *bp)
+{
+ kdb_printf("\n is enabled");
+ if (bp->bp_hardtype) {
+ kdba_printbpreg(bp->bp_hard);
+ if (bp->bp_hard->bph_mode != 0) {
+ kdb_printf(" for %d bytes",
+ bp->bp_hard->bph_length+1);
+ }
+ }
+}
+
+/*
+ * kdba_parsebp
+ *
+ * Parse architecture dependent portion of the
+ * breakpoint command.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero for success, a kdb diagnostic for failure
+ * Locking:
+ * None.
+ * Remarks:
+ * for IA64 architure, data access, data write and
+ * I/O breakpoints are supported in addition to instruction
+ * breakpoints.
+ *
+ * {datar|dataw|io|inst} [length]
+ */
+
+int
+kdba_parsebp(int argc, const char **argv, int *nextargp, kdb_bp_t *bp)
+{
+ int nextarg = *nextargp;
+ int diag;
+ kdbhard_bp_t *bph = &bp->bp_template;
+
+ bph->bph_mode = 0; /* Default to instruction breakpoint */
+ bph->bph_length = 0; /* Length must be zero for insn bp */
+ if ((argc + 1) != nextarg) {
+ if (strnicmp(argv[nextarg], "datar", sizeof("datar")) == 0) {
+ bph->bph_mode = 3;
+ } else if (strnicmp(argv[nextarg], "dataw", sizeof("dataw")) == 0) {
+ bph->bph_mode = 1;
+ } else if (strnicmp(argv[nextarg], "io", sizeof("io")) == 0) {
+ bph->bph_mode = 2;
+ } else if (strnicmp(argv[nextarg], "inst", sizeof("inst")) == 0) {
+ bph->bph_mode = 0;
+ } else {
+ return KDB_ARGCOUNT;
+ }
+
+ bph->bph_length = 3; /* Default to 4 byte */
+
+ nextarg++;
+
+ if ((argc + 1) != nextarg) {
+ unsigned long len;
+
+ diag = kdbgetularg((char *)argv[nextarg],
+ &len);
+ if (diag)
+ return diag;
+
+
+ if ((len > 4) || (len == 3))
+ return KDB_BADLENGTH;
+
+ bph->bph_length = len;
+ bph->bph_length--; /* Normalize for debug register */
+ nextarg++;
+ }
+
+ if ((argc + 1) != nextarg)
+ return KDB_ARGCOUNT;
+
+ /*
+ * Indicate to architecture independent level that
+ * a hardware register assignment is required to enable
+ * this breakpoint.
+ */
+
+ bph->bph_free = 0;
+ } else {
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_bp: no args, forcehw is %d\n", bp->bp_forcehw);
+ if (bp->bp_forcehw) {
+ /*
+ * We are forced to use a hardware register for this
+ * breakpoint because either the bph or bpha
+ * commands were used to establish this breakpoint.
+ */
+ bph->bph_free = 0;
+ } else {
+ /*
+ * Indicate to architecture dependent level that
+ * the instruction replacement breakpoint technique
+ * should be used for this breakpoint.
+ */
+ bph->bph_free = 1;
+ bp->bp_adjust = 0; /* software, break is fault, not trap */
+ }
+ }
+
+ if (bph->bph_mode == 0 && kdba_verify_rw(bp->bp_addr, bph->bph_length+1)) {
+ kdb_printf("Invalid address for breakpoint, ignoring bp command\n");
+ return KDB_BADADDR;
+ }
+
+ *nextargp = nextarg;
+ if (!bph->bph_free) {
+ kdb_printf("kdba_parsebp hardware breakpoints are not supported yet\n");
+ return KDB_NOTIMP;
+ }
+ return 0;
+}
+
+/*
+ * kdba_allocbp
+ *
+ * Associate a hardware register with a breakpoint.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * A pointer to the allocated register kdbhard_bp_t structure for
+ * success, Null and a non-zero diagnostic for failure.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+kdbhard_bp_t *
+kdba_allocbp(kdbhard_bp_t *bph, int *diagp)
+{
+ int i;
+ kdbhard_bp_t *newbph;
+
+ for(i=0,newbph=kdb_hardbreaks; i < KDB_MAXHARDBPT; i++, newbph++) {
+ if (newbph->bph_free) {
+ break;
+ }
+ }
+
+ if (i == KDB_MAXHARDBPT) {
+ *diagp = KDB_TOOMANYDBREGS;
+ return NULL;
+ }
+
+ *diagp = 0;
+
+ /*
+ * Copy data from template. Can't just copy the entire template
+ * here because the register number in kdb_hardbreaks must be
+ * preserved.
+ */
+ newbph->bph_data = bph->bph_data;
+ newbph->bph_write = bph->bph_write;
+ newbph->bph_mode = bph->bph_mode;
+ newbph->bph_length = bph->bph_length;
+
+ /*
+ * Mark entry allocated.
+ */
+ newbph->bph_free = 0;
+
+ return newbph;
+}
+
+/*
+ * kdba_freebp
+ *
+ * Deallocate a hardware breakpoint
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero for success, a kdb diagnostic for failure
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+void
+kdba_freebp(kdbhard_bp_t *bph)
+{
+ bph->bph_free = 1;
+}
+
+/*
+ * kdba_initbp
+ *
+ * Initialize the breakpoint table for the hardware breakpoint
+ * register.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero for success, a kdb diagnostic for failure
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ * There is one entry per register. On the ia64 architecture
+ * all the registers are interchangeable, so no special allocation
+ * criteria are required.
+ */
+
+void
+kdba_initbp(void)
+{
+ int i;
+ kdbhard_bp_t *bph;
+
+ /*
+ * Clear the hardware breakpoint table
+ */
+
+ memset(kdb_hardbreaks, '\0', sizeof(kdb_hardbreaks));
+
+ for(i=0,bph=kdb_hardbreaks; i<KDB_MAXHARDBPT; i++, bph++) {
+ bph->bph_reg = i;
+ bph->bph_free = 1;
+ }
+}
+
+/*
+ * kdba_installbp
+ *
+ * Install a breakpoint
+ *
+ * Parameters:
+ * regs Exception frame
+ * bp Breakpoint structure for the breakpoint to be installed
+ * Outputs:
+ * None.
+ * Returns:
+ * 0 if breakpoint set, otherwise error.
+ * Locking:
+ * None.
+ * Remarks:
+ * For hardware breakpoints, a debug register is allocated
+ * and assigned to the breakpoint. If no debug register is
+ * available, a warning message is printed and the breakpoint
+ * is disabled.
+ *
+ * For instruction replacement breakpoints, we must single-step
+ * over the replaced instruction at this point so we can re-install
+ * the breakpoint instruction after the single-step. SSBPT is set
+ * when the breakpoint is initially hit and is cleared by any action
+ * that removes the need for single-step over the breakpoint.
+ */
+
+int
+kdba_installbp(struct pt_regs *regs, kdb_bp_t *bp)
+{
+ /*
+ * Install the breakpoint, if it is not already installed.
+ */
+
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdba_installbp bp_installed %d\n", bp->bp_installed);
+ }
+ if (!KDB_STATE(SSBPT))
+ bp->bp_delay = 0;
+ if (!bp->bp_installed) {
+ if (bp->bp_hardtype) {
+ kdba_installdbreg(bp);
+ bp->bp_installed = 1;
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdba_installbp hardware reg %ld at " kdb_bfd_vma_fmt0 "\n",
+ bp->bp_hard->bph_reg, bp->bp_addr);
+ }
+ } else if (bp->bp_delay) {
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_installbp delayed bp\n");
+ kdba_handle_bp(regs, bp);
+ } else {
+ /* Software breakpoints always use slot 0 in the 128 bit
+ * bundle. The template type does not matter, slot 0
+ * can only be M or B and the encodings for break.m and
+ * break.b are the same.
+ */
+ unsigned long break_inst;
+ if (kdb_getarea_size(bp->bp_inst.inst, bp->bp_addr, sizeof(bp->bp_inst.inst))) {
+ kdb_printf("kdba_installbp failed to read software breakpoint at 0x%lx\n", bp->bp_addr);
+ return(1);
+ }
+ break_inst = (bp->bp_inst.inst[0] & ~INST_SLOT0_MASK) | BREAK_INSTR;
+ if (kdb_putarea_size(bp->bp_addr, &break_inst, sizeof(break_inst))) {
+ kdb_printf("kdba_installbp failed to set software breakpoint at 0x%lx\n", bp->bp_addr);
+ return(1);
+ }
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_installbp instruction 0x%lx at " kdb_bfd_vma_fmt0 "\n",
+ BREAK_INSTR, bp->bp_addr);
+ bp->bp_installed = 1;
+ flush_icache_range(bp->bp_addr, bp->bp_addr+16);
+ }
+ }
+ return(0);
+}
+
+/*
+ * kdba_removebp
+ *
+ * Make a breakpoint ineffective.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * 0 if breakpoint removed, otherwise error.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+int
+kdba_removebp(kdb_bp_t *bp)
+{
+ /*
+ * For hardware breakpoints, remove it from the active register,
+ * for software breakpoints, restore the instruction stream.
+ */
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdba_removebp bp_installed %d\n", bp->bp_installed);
+ }
+ if (bp->bp_installed) {
+ if (bp->bp_hardtype) {
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdb: removing hardware reg %ld at " kdb_bfd_vma_fmt0 "\n",
+ bp->bp_hard->bph_reg, bp->bp_addr);
+ }
+ kdba_removedbreg(bp);
+ } else {
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdb: restoring instruction 0x%016lx%016lx at " kdb_bfd_vma_fmt0 "\n",
+ bp->bp_inst.inst[0], bp->bp_inst.inst[1], bp->bp_addr);
+ if (kdba_putarea_size(bp->bp_addr, bp->bp_inst.inst, sizeof(bp->bp_inst.inst)))
+ return(1);
+ }
+ bp->bp_installed = 0;
+ flush_icache_range(bp->bp_addr, bp->bp_addr+16);
+ }
+ return(0);
+}
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Stack Traceback
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kallsyms.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <asm/system.h>
+#include <asm/sections.h>
+
+/*
+ * bt_print_one
+ *
+ * Print one back trace entry.
+ *
+ * Inputs:
+ * ip Current program counter.
+ * symtab Information about symbol that ip falls within.
+ * argcount Maximum number of arguments to print.
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ * None.
+ */
+
+static void
+bt_print_one(kdb_machreg_t ip,
+ const kdb_symtab_t *symtab, int argcount,
+ struct unw_frame_info *info)
+{
+ int btsymarg = 0; /* Convert arguments to symbols */
+ int btsp = 0; /* Print stack and backing store pointers */
+ int args;
+ kdb_machreg_t sp, bsp, cfm;
+
+ kdbgetintenv("BTSYMARG", &btsymarg);
+ kdbgetintenv("BTSP", &btsp);
+
+ unw_get_sp(info, &sp);
+ unw_get_bsp(info, &bsp);
+ unw_get_cfm(info, &cfm);
+ kdb_symbol_print(ip, symtab, KDB_SP_VALUE|KDB_SP_NEWLINE);
+ args = (cfm >> 7) & 0x7f; /* sol */
+ if (!args)
+ args = cfm & 0x7f; /* no in/local, use sof instead */
+ if (argcount && args) {
+ int i, argc = args;
+
+ kdb_printf(" args (");
+ if (argc > argcount)
+ argc = argcount;
+
+ for(i = 0; i < argc; i++){
+ kdb_machreg_t arg;
+ char nat;
+ if (unw_access_gr(info, i+32, &arg, &nat, 0))
+ arg = 0;
+
+ if (i)
+ kdb_printf(", ");
+ kdb_printf("0x%lx", arg);
+ }
+ kdb_printf(")\n");
+ if (btsymarg) {
+ kdb_symtab_t arg_symtab;
+ kdb_machreg_t arg;
+ for(i = 0; i < argc; i++){
+ char nat;
+ if (unw_access_gr(info, i+32, &arg, &nat, 0))
+ arg = 0;
+ if (kdbnearsym(arg, &arg_symtab)) {
+ kdb_printf(" arg %d ", i);
+ kdb_symbol_print(arg, &arg_symtab, KDB_SP_DEFAULT|KDB_SP_NEWLINE);
+ }
+ }
+ }
+ }
+ if (symtab->sym_name) {
+ if (strncmp(symtab->sym_name, "ia64_spinlock_contention", 24) == 0) {
+ kdb_machreg_t r31;
+ char nat;
+ kdb_printf(" r31 (spinlock address) ");
+ if (unw_access_gr(info, 31, &r31, &nat, 0))
+ r31 = 0;
+ kdb_symbol_print(r31, NULL, KDB_SP_VALUE|KDB_SP_NEWLINE);
+ }
+ }
+ if (btsp)
+ kdb_printf(" sp 0x%016lx bsp 0x%016lx cfm 0x%016lx info->pfs_loc 0x%016lx 0x%016lx\n",
+ sp, bsp, cfm, (u64) info->pfs_loc, info->pfs_loc ? *(info->pfs_loc) : 0);
+}
+
+/*
+ * kdba_bt_stack
+ *
+ * Unwind the ia64 backtrace for a specified process.
+ *
+ * Inputs:
+ * argcount
+ * p Pointer to task structure to unwind.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * none.
+ */
+
+static int
+kdba_bt_stack(int argcount, const struct task_struct *p)
+{
+ static char namebuf[KSYM_NAME_LEN+1];
+ kdb_symtab_t symtab;
+ struct unw_frame_info info;
+ struct switch_stack *sw;
+ struct pt_regs *regs = NULL;
+ int count = 0;
+ int btsp = 0; /* Backtrace the kdb code as well */
+ u64 *prev_pfs_loc = NULL;
+ extern char __attribute__ ((weak)) ia64_spinlock_contention_pre3_4[];
+ extern char __attribute__ ((weak)) ia64_spinlock_contention_pre3_4_end[];
+
+ /*
+ * Upon entering kdb_main_loop, the stack frame looks like this:
+ *
+ * +---------------------+
+ * | struct pt_regs |
+ * +---------------------+
+ * | |
+ * | kernel stack |
+ * | |
+ * +=====================+ <--- top of stack upon entering kdb
+ * | struct pt_regs |
+ * +---------------------+
+ * | |
+ * | kdb stack |
+ * | |
+ * +---------------------+
+ * | struct switch_stack |
+ * +=====================+ <--- kdb_running_process[cpu].arch.sw from do_kdba_main_loop
+ *
+ * When looking at another process, we do not have the address of the
+ * current pt_regs, it is NULL. If the process has saved its state, use
+ * that pt_regs instead.
+ */
+
+ kdbgetintenv("BTSP", &btsp);
+
+ if (task_curr(p)) {
+ struct kdb_running_process *krp = kdb_running_process + kdb_process_cpu(p);
+ if (krp->seqno) {
+ sw = krp->arch.sw;
+ regs = krp->regs;
+ }
+ else
+ sw = NULL;
+ }
+ else {
+ /* Not running, assume blocked */
+ sw = (struct switch_stack *) (p->thread.ksp + 16);
+ }
+ if (!sw) {
+ kdb_printf("Process does not have a switch_stack, cannot backtrace\n");
+ kdb_ps1(p);
+ return 0;
+ }
+
+ unw_init_frame_info(&info, (struct task_struct *)p, sw);
+
+ /* If we have the address of pt_regs, suppress backtrace on the frames below
+ * pt_regs. No point in displaying kdb itself, unless the user is debugging
+ * the unwinder using set BTSP=1.
+ */
+ if (regs && !btsp) {
+ kdb_machreg_t sp;
+ if (user_mode(regs)) {
+ kdb_printf("Process was interrupted in user mode, no backtrace available\n");
+ return 0;
+ }
+ do {
+ unw_get_sp(&info, &sp);
+ if (sp >= (kdb_machreg_t)regs)
+ break;
+ } while (unw_unwind(&info) >= 0 && count++ < 200);
+ }
+
+ do {
+ kdb_machreg_t ip;
+
+ /* Avoid unsightly console message from unw_unwind() when attempting
+ * to unwind through the Interrupt Vector Table which has no unwind
+ * information. dispatch_illegal_op_fault() is an exception, it sits
+ * in the 0x3c00 slot.
+ */
+ if (info.ip >= (u64)__start_ivt_text && info.ip < (u64)__end_ivt_text) {
+ if (info.ip < (u64)__start_ivt_text + 0x3c00 ||
+ info.ip >= (u64)__start_ivt_text + 0x4000)
+ return 0;
+ }
+
+ /* WAR for spinlock contention from leaf functions. ia64_spinlock_contention_pre3_4
+ * has ar.pfs == r0. Leaf functions do not modify ar.pfs so ar.pfs remains
+ * as 0, stopping the backtrace. Record the previous ar.pfs when the current
+ * IP is in ia64_spinlock_contention_pre3_4 then unwind, if pfs_loc has not changed
+ * after unwind then use pt_regs.ar_pfs which is where the real ar.pfs is for
+ * leaf functions.
+ */
+ if (prev_pfs_loc && regs && info.pfs_loc == prev_pfs_loc)
+ info.pfs_loc = ®s->ar_pfs;
+ prev_pfs_loc = (info.ip >= (u64)ia64_spinlock_contention_pre3_4 &&
+ info.ip < (u64)ia64_spinlock_contention_pre3_4_end) ?
+ info.pfs_loc : NULL;
+
+ unw_get_ip(&info, &ip);
+ if (ip == 0)
+ break;
+
+ kdbnearsym(ip, &symtab);
+ if (!symtab.sym_name) {
+ kdb_printf("0x%0*lx - No name. May be an area that has no unwind data\n",
+ (int)(2*sizeof(ip)), ip);
+ return 0;
+ }
+ strcpy(namebuf, symtab.sym_name);
+ symtab.sym_name = namebuf;
+ bt_print_one(ip, &symtab, argcount, &info);
+ } while (unw_unwind(&info) >= 0 && count++ < 200);
+ if (count >= 200)
+ kdb_printf("bt truncated, count limit reached\n");
+
+ return 0;
+}
+
+int
+kdba_bt_address(kdb_machreg_t addr, int argcount)
+{
+ kdb_printf("Backtrace from a stack address is not supported on ia64\n");
+ return KDB_NOTIMP;
+}
+
+/*
+ * kdba_bt_process
+ *
+ * Do a backtrace for a specified process.
+ *
+ * Inputs:
+ * p Struct task pointer extracted by 'bt' command.
+ * argcount
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ */
+
+int
+kdba_bt_process(const struct task_struct *p, int argcount)
+{
+ return kdba_bt_stack(argcount, p);
+}
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent FRU functions.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <linux/module.h>
+#include <asm/sal.h>
+#include <asm/sn/sn_sal.h>
+
+MODULE_AUTHOR("Jesse Barnes");
+MODULE_DESCRIPTION("Capture FRU data");
+MODULE_LICENSE("GPL");
+
+/**
+ * kdba_fru - capture FRU data
+ * @argc: arg count
+ * @argv: arg values
+ * @envp: kdb env. vars
+ * @regs: current register state
+ *
+ * Tell the system contollers to capture FRU data
+ */
+static int
+kdba_fru(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ u64 ret;
+
+ kdb_printf("Capturing FRU data...");
+ ret = ia64_sn_fru_capture();
+ kdb_printf("done.\n");
+ return ret;
+}
+
+/**
+ * kdba_fru_init - register 'fru' command with kdb
+ *
+ * Register the 'fru' command with kdb at load time.
+ */
+static int __init
+kdba_fru_init(void)
+{
+ kdb_register("fru", kdba_fru, 0, "Capture FRU data", 0);
+
+ return 0;
+}
+
+/**
+ * kdba_fru_exit - unregister the 'fru' command
+ *
+ * Tell kdb that the 'fru' command is no longer available.
+ */
+static void __exit
+kdba_fru_exit(void)
+{
+ kdb_unregister("fru");
+}
+
+kdb_module_init(kdba_fru_init);
+kdb_module_exit(kdba_fru_exit);
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Instruction Disassembly
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <stdarg.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+
+#define KDBA_PRINTBUF_LEN 64 /* buffer len to print a single instr */
+#define KDBA_READBUFFER_LEN 256 /* buffer for BFD disassembler */
+
+#define BUNDLE_MULTIPLIER 3 /* how many instr/bundle */
+#define BUNDLE_SIZE 16 /* how many bytes/bundle */
+#define KDBA_DEFAULT_IDLEN 3 /* default number of bundles to disassemble */
+
+/*
+ * kdba_dis_getsym
+ *
+ * Get a symbol for the disassembler.
+ *
+ * Parameters:
+ * addr Address for which to get symbol
+ * dip Pointer to disassemble_info
+ * Returns:
+ * 0
+ * Locking:
+ * Remarks:
+ * Not used for kdb.
+ */
+
+/* ARGSUSED */
+static int
+kdba_dis_getsym(bfd_vma addr, disassemble_info *dip)
+{
+
+ return 0;
+}
+
+/*
+ * kdba_printaddress
+ *
+ * Print (symbolically) an address.
+ *
+ * Parameters:
+ * addr Address for which to get symbol
+ * dip Pointer to disassemble_info
+ * flag True if a ":<tab>" sequence should follow the address
+ * Returns:
+ * 0
+ * Locking:
+ * Remarks:
+ *
+ */
+
+/* ARGSUSED */
+static void
+kdba_printaddress(kdb_machreg_t addr, disassemble_info *dip, int flag)
+{
+ kdb_symtab_t symtab;
+ int spaces = 5;
+ unsigned int offset;
+ int slot;
+
+ /* Some code prints slot number, some prints "byte" offset
+ * from start of bundle. Standardise on "byte" offset.
+ */
+ slot = addr & 0x0f;
+ if (slot < 3)
+ slot *= 6;
+ addr = (addr & ~0x0f) + slot;
+
+ /*
+ * Print a symbol name or address as necessary.
+ */
+ dip->fprintf_func(dip->stream, "0x%0*lx ", (int)(2*sizeof(addr)), addr);
+ kdbnearsym(addr, &symtab);
+ if (symtab.sym_name) {
+ /* Do not use kdb_symbol_print here, it always does
+ * kdb_printf but we want dip->fprintf_func.
+ */
+ dip->fprintf_func(dip->stream, "%s", symtab.sym_name);
+ if ((offset = addr - symtab.sym_start) == 0) {
+ spaces += 4;
+ }
+ else {
+ unsigned int o = offset;
+ while (o >>= 4)
+ --spaces;
+ dip->fprintf_func(dip->stream, "+0x%x", offset);
+ }
+ }
+
+ if (flag) {
+ if (spaces < 1) {
+ spaces = 1;
+ }
+ dip->fprintf_func(dip->stream, ":%*s", spaces, " ");
+ }
+}
+
+/*
+ * kdba_dis_printaddr
+ *
+ * Print (symbolically) an address. Called by GNU disassembly
+ * code via disassemble_info structure.
+ *
+ * Parameters:
+ * addr Address for which to get symbol
+ * dip Pointer to disassemble_info
+ * Returns:
+ * 0
+ * Locking:
+ * Remarks:
+ * This function will never append ":<tab>" to the printed
+ * symbolic address.
+ */
+
+static void
+kdba_dis_printaddr(bfd_vma addr, disassemble_info *dip)
+{
+ kdba_printaddress(addr, dip, 0);
+}
+
+/*
+ * kdba_dis_getmem
+ *
+ * Fetch 'length' bytes from 'addr' into 'buf'.
+ *
+ * Parameters:
+ * addr Address for which to get symbol
+ * buf Address of buffer to fill with bytes from 'addr'
+ * length Number of bytes to fetch
+ * dip Pointer to disassemble_info
+ * Returns:
+ * 0
+ * Locking:
+ * Remarks:
+ *
+ */
+
+/* ARGSUSED */
+static int
+kdba_dis_getmem(bfd_vma addr, bfd_byte *buf, unsigned int length, disassemble_info *dip)
+{
+ return kdb_getarea_size(buf, addr, length);
+}
+
+/*
+ * kdba_id_parsemode
+ *
+ * Parse IDMODE environment variable string and
+ * set appropriate value into "disassemble_info" structure.
+ *
+ * Parameters:
+ * mode Mode string
+ * dip Disassemble_info structure pointer
+ * Returns:
+ * Locking:
+ * Remarks:
+ * No mode supported yet.
+ */
+
+int
+kdba_id_parsemode(const char *mode, disassemble_info *dip)
+{
+ if (mode && strcmp(mode, "ia64"))
+ return KDB_BADMODE;
+ return 0;
+}
+
+/*
+ * kdba_check_pc
+ *
+ * Check that the pc is satisfactory.
+ *
+ * Parameters:
+ * pc Program Counter Value.
+ * Returns:
+ * None
+ * Locking:
+ * None.
+ * Remarks:
+ * Can change pc.
+ */
+
+void
+kdba_check_pc(kdb_machreg_t *pc)
+{
+ (*pc) &= ~0xf; /* pc must be 16 byte aligned */
+}
+
+/*
+ * kdba_id_printinsn
+ *
+ * Format and print a single bundle at 'pc'. Return the
+ * length of the bundle.
+ *
+ * Parameters:
+ * pc Program Counter Value.
+ * dip Disassemble_info structure pointer
+ * Returns:
+ * Length of instruction, -1 for error.
+ * Locking:
+ * None.
+ * Remarks:
+ * None.
+ */
+
+int
+kdba_id_printinsn(kdb_machreg_t pc, disassemble_info *dip)
+{
+ int ret;
+ int byte = 0;
+
+ kdba_check_pc(&pc);
+ while (byte < 16) {
+ kdba_dis_printaddr(pc+byte, dip);
+ ret = print_insn_ia64((kdb_machreg_t)(pc+byte), dip);
+ dip->fprintf_func(dip->stream, "\n");
+ if (ret < 0)
+ break;
+ byte += ret;
+ }
+ return(byte);
+}
+
+/*
+ * kdba_id_init
+ *
+ * Initialize the architecture dependent elements of
+ * the disassembly information structure
+ * for the GNU disassembler.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+void __init
+kdba_id_init(disassemble_info *dip)
+{
+ dip->read_memory_func = kdba_dis_getmem;
+ dip->print_address_func = kdba_dis_printaddr;
+ dip->symbol_at_address_func = kdba_dis_getsym;
+
+ dip->flavour = bfd_target_elf_flavour;
+ dip->arch = bfd_arch_ia64;
+ dip->endian = BFD_ENDIAN_LITTLE;
+
+ dip->display_endian = BFD_ENDIAN_LITTLE;
+}
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Console I/O handler
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2006 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/console.h>
+#include <linux/ctype.h>
+#include <linux/keyboard.h>
+#include <linux/serial.h>
+#include <linux/serial_reg.h>
+
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+
+#if defined(CONFIG_SERIAL_8250_CONSOLE) || defined(CONFIG_SERIAL_SGI_L1_CONSOLE)
+#define HAVE_KDBA_SERIAL_CONSOLE
+#endif
+
+/* from include/linux/pc_keyb.h on 2.4 */
+#define KBD_STATUS_REG 0x64 /* Status register (R) */
+#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */
+#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
+#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
+#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
+#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
+
+#ifdef CONFIG_VT_CONSOLE
+#define KDB_BLINK_LED 1
+#else
+#undef KDB_BLINK_LED
+#endif
+
+#ifdef CONFIG_KDB_USB
+struct kdb_usb_exchange kdb_usb_infos;
+
+EXPORT_SYMBOL(kdb_usb_infos);
+
+static unsigned char kdb_usb_keycode[256] = {
+ 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
+ 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
+ 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
+ 27, 43, 84, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
+ 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
+ 72, 73, 82, 83, 86,127,116,117, 85, 89, 90, 91, 92, 93, 94, 95,
+ 120,121,122,123,134,138,130,132,128,129,131,137,133,135,136,113,
+ 115,114, 0, 0, 0,124, 0,181,182,183,184,185,186,187,188,189,
+ 190,191,192,193,194,195,196,197,198, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
+ 150,158,159,128,136,177,178,176,142,152,173,140
+};
+
+/* get_usb_char
+ * This function drives the UHCI controller,
+ * fetch the USB scancode and decode it
+ */
+static int get_usb_char(void)
+{
+ static int usb_lock;
+ unsigned char keycode, spec;
+ extern u_short plain_map[], shift_map[], ctrl_map[];
+
+ /* Is USB initialized ? */
+ if (!kdb_usb_infos.poll_func || !kdb_usb_infos.urb || !kdb_usb_infos.buffer)
+ return -1;
+
+ /* Transfer char if they are present */
+ (*kdb_usb_infos.poll_func)(kdb_usb_infos.uhci, (struct urb *)kdb_usb_infos.urb);
+
+ spec = kdb_usb_infos.buffer[0];
+ keycode = kdb_usb_infos.buffer[2];
+ kdb_usb_infos.buffer[0] = (char)0;
+ kdb_usb_infos.buffer[2] = (char)0;
+
+ if(kdb_usb_infos.buffer[3])
+ return -1;
+
+ /* A normal key is pressed, decode it */
+ if(keycode)
+ keycode = kdb_usb_keycode[keycode];
+
+ /* 2 Keys pressed at one time ? */
+ if (spec && keycode) {
+ switch(spec)
+ {
+ case 0x2:
+ case 0x20: /* Shift */
+ return shift_map[keycode];
+ case 0x1:
+ case 0x10: /* Ctrl */
+ return ctrl_map[keycode];
+ case 0x4:
+ case 0x40: /* Alt */
+ break;
+ }
+ }
+ else {
+ if(keycode) { /* If only one key pressed */
+ switch(keycode)
+ {
+ case 0x1C: /* Enter */
+ return 13;
+
+ case 0x3A: /* Capslock */
+ usb_lock ? (usb_lock = 0) : (usb_lock = 1);
+ break;
+ case 0x0E: /* Backspace */
+ return 8;
+ case 0x0F: /* TAB */
+ return 9;
+ case 0x77: /* Pause */
+ break ;
+ default:
+ if(!usb_lock) {
+ return plain_map[keycode];
+ }
+ else {
+ return shift_map[keycode];
+ }
+ }
+ }
+ }
+ return -1;
+}
+#endif /* CONFIG_KDB_USB */
+
+/*
+ * This module contains code to read characters from the keyboard or a serial
+ * port.
+ *
+ * It is used by the kernel debugger, and is polled, not interrupt driven.
+ *
+ */
+
+#ifdef KDB_BLINK_LED
+/*
+ * send: Send a byte to the keyboard controller. Used primarily to
+ * alter LED settings.
+ */
+
+static void
+kdb_kbdsend(unsigned char byte)
+{
+ int timeout;
+ for (timeout = 200 * 1000; timeout && (inb(KBD_STATUS_REG) & KBD_STAT_IBF); timeout--);
+ outb(byte, KBD_DATA_REG);
+ udelay(40);
+ for (timeout = 200 * 1000; timeout && (~inb(KBD_STATUS_REG) & KBD_STAT_OBF); timeout--);
+ inb(KBD_DATA_REG);
+ udelay(40);
+}
+
+static void
+kdb_toggleled(int led)
+{
+ static int leds;
+
+ leds ^= led;
+
+ kdb_kbdsend(KBD_CMD_SET_LEDS);
+ kdb_kbdsend((unsigned char)leds);
+}
+#endif /* KDB_BLINK_LED */
+
+#ifdef HAVE_KDBA_SERIAL_CONSOLE
+
+struct kdb_serial kdb_serial;
+enum kdba_serial_console kdba_serial_console;
+static int get_serial_char(void);
+
+/* There must be a serial_inp_xxx() and get_serial_char_xxx() for each type
+ * of console. See enum kdba_serial_console in include/asm-$(ARCH)/kdbprivate.h.
+ */
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+
+static unsigned int
+serial_inp_standard(const struct kdb_serial *kdb_serial, int offset)
+{
+ offset <<= kdb_serial->ioreg_shift;
+
+ switch (kdb_serial->io_type) {
+ case SERIAL_IO_MEM:
+ return readb((void __iomem *)(kdb_serial->iobase + offset));
+ break;
+ default:
+ return inb(kdb_serial->iobase + offset);
+ break;
+ }
+}
+
+/* Check if there is a byte ready at the serial port */
+static int
+get_serial_char_standard(void)
+{
+ unsigned char ch;
+ static unsigned long fifon;
+ if (fifon == 0) {
+ /* try to set the FIFO */
+ fifon = kdb_serial.iobase +
+ (UART_FCR << kdb_serial.ioreg_shift);
+ switch (kdb_serial.io_type) {
+ case SERIAL_IO_MEM:
+ writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
+ UART_FCR_CLEAR_XMIT), (void __iomem *)fifon);
+ break;
+ default:
+ outb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
+ UART_FCR_CLEAR_XMIT), fifon);
+ break;
+ }
+ }
+
+ if (kdb_serial.iobase == 0)
+ return -1;
+
+ if (serial_inp_standard(&kdb_serial, UART_LSR) & UART_LSR_DR) {
+ ch = serial_inp_standard(&kdb_serial, UART_RX);
+ if (ch == 0x7f)
+ ch = 8;
+ return ch;
+ }
+ return -1;
+}
+
+#else /* !CONFIG_SERIAL_8250_CONSOLE */
+
+#define get_serial_char_standard() -1
+
+#endif /* CONFIG_SERIAL_8250_CONSOLE */
+
+#ifdef CONFIG_SERIAL_SGI_L1_CONSOLE
+
+extern u64 master_node_bedrock_address;
+
+/* UART registers on the Bedrock start at 0x80 */
+
+extern int l1_serial_in_polled(void);
+extern int l1_control_in_polled(int);
+
+/* Read a byte from the L1 port. kdb_serial is ignored */
+static unsigned int
+serial_inp_sgi_l1(const struct kdb_serial *kdb_serial, int offset)
+{
+ if (offset & 0x80) {
+ int counter = 10000;
+ unsigned int value;
+ while ( counter-- ) {
+ value = l1_serial_in_polled();
+ /* Gobble up the 0's */
+ if ( value )
+ return(value);
+ }
+ return(0);
+ }
+ else {
+ return l1_control_in_polled(offset);
+ }
+}
+
+/* Check if there is a byte ready at the L1 port. */
+static int
+get_serial_char_sgi_l1(void)
+{
+ unsigned char ch;
+ int status;
+
+ if ((status = serial_inp_sgi_l1(&kdb_serial, UART_LSR)) & UART_LSR_DR) {
+ ch = serial_inp_sgi_l1(&kdb_serial, UART_RX | 0x80); /* bedrock offset */
+ if (ch == 0x7f)
+ ch = 8;
+ return ch;
+ }
+ return -1;
+}
+
+#else /* !CONFIG_SERIAL_SGI_L1_CONSOLE */
+
+#define get_serial_char_sgi_l1() -1
+
+#endif /* CONFIG_SERIAL_SGI_L1_CONSOLE */
+
+/* Select the serial console input at run time, to handle generic kernels */
+
+static int
+get_serial_char(void)
+{
+ switch (kdba_serial_console) {
+ case KDBA_SC_NONE:
+ return -1;
+ case KDBA_SC_STANDARD:
+ return get_serial_char_standard();
+ case KDBA_SC_SGI_L1:
+ return get_serial_char_sgi_l1();
+ }
+ /* gcc is not smart enough to realize that all paths return before here :( */
+ return -1;
+}
+
+#endif /* HAVE_KDBA_SERIAL_CONSOLE */
+
+#ifdef CONFIG_VT_CONSOLE
+
+static int kbd_exists = -1;
+
+/*
+ * Check if the keyboard controller has a keypress for us.
+ * Some parts (Enter Release, LED change) are still blocking polled here,
+ * but hopefully they are all short.
+ */
+static int get_kbd_char(void)
+{
+ int scancode, scanstatus;
+ static int shift_lock; /* CAPS LOCK state (0-off, 1-on) */
+ static int shift_key; /* Shift next keypress */
+ static int ctrl_key;
+ u_short keychar;
+ extern u_short plain_map[], shift_map[], ctrl_map[];
+
+ if (kbd_exists <= 0) {
+ if (kbd_exists == 0)
+ return -1;
+
+ if (inb(KBD_STATUS_REG) == 0xff && inb(KBD_DATA_REG) == 0xff) {
+ kbd_exists = 0;
+ return -1;
+ }
+ kbd_exists = 1;
+ }
+
+ if ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0)
+ return -1;
+
+ /*
+ * Fetch the scancode
+ */
+ scancode = inb(KBD_DATA_REG);
+ scanstatus = inb(KBD_STATUS_REG);
+
+ /*
+ * Ignore mouse events.
+ */
+ if (scanstatus & KBD_STAT_MOUSE_OBF)
+ return -1;
+
+ /*
+ * Ignore release, trigger on make
+ * (except for shift keys, where we want to
+ * keep the shift state so long as the key is
+ * held down).
+ */
+
+ if (((scancode&0x7f) == 0x2a) || ((scancode&0x7f) == 0x36)) {
+ /*
+ * Next key may use shift table
+ */
+ if ((scancode & 0x80) == 0) {
+ shift_key=1;
+ } else {
+ shift_key=0;
+ }
+ return -1;
+ }
+
+ if ((scancode&0x7f) == 0x1d) {
+ /*
+ * Left ctrl key
+ */
+ if ((scancode & 0x80) == 0) {
+ ctrl_key = 1;
+ } else {
+ ctrl_key = 0;
+ }
+ return -1;
+ }
+
+ if ((scancode & 0x80) != 0)
+ return -1;
+
+ scancode &= 0x7f;
+
+ /*
+ * Translate scancode
+ */
+
+ if (scancode == 0x3a) {
+ /*
+ * Toggle caps lock
+ */
+ shift_lock ^= 1;
+
+#ifdef KDB_BLINK_LED
+ kdb_toggleled(0x4);
+#endif
+ return -1;
+ }
+
+ if (scancode == 0x0e) {
+ /*
+ * Backspace
+ */
+ return 8;
+ }
+
+ /* Special Key */
+ switch (scancode) {
+ case 0xF: /* Tab */
+ return 9;
+ case 0x53: /* Del */
+ return 4;
+ case 0x47: /* Home */
+ return 1;
+ case 0x4F: /* End */
+ return 5;
+ case 0x4B: /* Left */
+ return 2;
+ case 0x48: /* Up */
+ return 16;
+ case 0x50: /* Down */
+ return 14;
+ case 0x4D: /* Right */
+ return 6;
+ }
+
+ if (scancode == 0xe0) {
+ return -1;
+ }
+
+ /*
+ * For Japanese 86/106 keyboards
+ * See comment in drivers/char/pc_keyb.c.
+ * - Masahiro Adegawa
+ */
+ if (scancode == 0x73) {
+ scancode = 0x59;
+ } else if (scancode == 0x7d) {
+ scancode = 0x7c;
+ }
+
+ if (!shift_lock && !shift_key && !ctrl_key) {
+ keychar = plain_map[scancode];
+ } else if (shift_lock || shift_key) {
+ keychar = shift_map[scancode];
+ } else if (ctrl_key) {
+ keychar = ctrl_map[scancode];
+ } else {
+ keychar = 0x0020;
+ kdb_printf("Unknown state/scancode (%d)\n", scancode);
+ }
+ keychar &= 0x0fff;
+ switch (KTYP(keychar)) {
+ case KT_LETTER:
+ case KT_LATIN:
+ if (isprint(keychar))
+ break; /* printable characters */
+ /* drop through */
+ case KT_SPEC:
+ if (keychar == K_ENTER)
+ break;
+ /* drop through */
+ default:
+ return(-1); /* ignore unprintables */
+ }
+
+ if ((scancode & 0x7f) == 0x1c) {
+ /*
+ * enter key. All done. Absorb the release scancode.
+ */
+ while ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0)
+ ;
+
+ /*
+ * Fetch the scancode
+ */
+ scancode = inb(KBD_DATA_REG);
+ scanstatus = inb(KBD_STATUS_REG);
+
+ while (scanstatus & KBD_STAT_MOUSE_OBF) {
+ scancode = inb(KBD_DATA_REG);
+ scanstatus = inb(KBD_STATUS_REG);
+ }
+ return 13;
+ }
+
+ return keychar & 0xff;
+}
+#endif /* CONFIG_VT_CONSOLE */
+
+#ifdef KDB_BLINK_LED
+
+/* Leave numlock alone, setting it messes up laptop keyboards with the keypad
+ * mapped over normal keys.
+ */
+static int kdba_blink_mask = 0x1 | 0x4;
+
+#ifdef CONFIG_SMP
+#define BOGOMIPS (local_cpu_data->loops_per_jiffy/(500000/HZ))
+#else
+#define BOGOMIPS (loops_per_jiffy/(500000/HZ))
+#endif
+static int blink_led(void)
+{
+ static long delay;
+
+ if (kbd_exists == 0)
+ return -1;
+
+ if (--delay < 0) {
+ if (BOGOMIPS == 0) /* early kdb */
+ delay = 150000000/1000; /* arbitrary bogomips */
+ else
+ delay = 150000000/BOGOMIPS; /* Roughly 1 second when polling */
+ kdb_toggleled(kdba_blink_mask);
+ }
+ return -1;
+}
+#endif
+
+get_char_func poll_funcs[] = {
+#if defined(CONFIG_VT_CONSOLE)
+ get_kbd_char,
+#endif
+#ifdef HAVE_KDBA_SERIAL_CONSOLE
+ get_serial_char,
+#endif
+#ifdef KDB_BLINK_LED
+ blink_led,
+#endif
+#ifdef CONFIG_KDB_USB
+ get_usb_char,
+#endif
+ NULL
+};
+
+/* Dummy versions of kdba_local_arch_setup, kdba_local_arch_cleanup.
+ * FIXME: ia64 with legacy keyboard might need the same code as i386.
+ */
+
+void kdba_local_arch_setup(void) {}
+void kdba_local_arch_cleanup(void) {}
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Longjump Support.
+ */
+
+/* setjmp() and longjmp() assembler support for kdb on ia64.
+
+ This code was copied from glibc CVS as of 2001-06-27 and modified where
+ necessary to fit the kernel. No glibc lines were changed or deleted, all
+ adjustments are wrapped in #ifdef __KERNEL__, except for the added
+ .mem.offset lines, they work in or out of the kenrel. The original code is
+ in sysdeps/unix/sysv/linux/ia64/{setjmp.S,__longjmp.S}.
+
+ glibc has setjmp (save signals) and _setjmp (do not save signals). Kernel
+ code does not have signals, only kdba_setjmp_asm() is used.
+
+ Keith Owens <kaos@melbourne.sgi.com> 2001-06-27
+ */
+
+/* Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, write to the Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ The layout of the jmp_buf is as follows. This is subject to change
+ and user-code should never depend on the particular layout of
+ jmp_buf!
+
+
+ offset: description:
+ ------- ------------
+ 0x000 stack pointer (r12) ; unchangeable (see _JMPBUF_UNWINDS)
+ 0x008 r1 (gp)
+ 0x010 caller's unat
+ 0x018 fpsr
+ 0x020 r4
+ 0x028 r5
+ 0x030 r6
+ 0x038 r7
+ 0x040 rp (b0)
+ 0x048 b1
+ 0x050 b2
+ 0x058 b3
+ 0x060 b4
+ 0x068 b5
+ 0x070 ar.pfs
+ 0x078 ar.lc
+ 0x080 pr
+ 0x088 ar.bsp ; unchangeable (see __longjmp.S)
+ 0x090 ar.unat
+ 0x098 &__jmp_buf ; address of the jmpbuf (needed to locate NaT bits in unat)
+ 0x0a0 f2
+ 0x0b0 f3
+ 0x0c0 f4
+ 0x0d0 f5
+ 0x0e0 f16
+ 0x0f0 f17
+ 0x100 f18
+ 0x110 f19
+ 0x120 f20
+ 0x130 f21
+ 0x130 f22
+ 0x140 f23
+ 0x150 f24
+ 0x160 f25
+ 0x170 f26
+ 0x180 f27
+ 0x190 f28
+ 0x1a0 f29
+ 0x1b0 f30
+ 0x1c0 f31 */
+
+#ifndef __KERNEL__
+
+#include <sysdep.h>
+#include <features.h>
+
+ /* The following two entry points are the traditional entry points: */
+
+LEAF(setjmp)
+ alloc r8=ar.pfs,2,0,0,0
+ mov in1=1
+ br.cond.sptk.many __sigsetjmp
+END(setjmp)
+
+LEAF(_setjmp)
+ alloc r8=ar.pfs,2,0,0,0
+ mov in1=0
+ br.cond.sptk.many __sigsetjmp
+END(_setjmp)
+
+ /* __sigsetjmp(__jmp_buf buf, int savemask) */
+
+ENTRY(__sigsetjmp)
+
+#else /* __KERNEL __ */
+#include <asm/asmmacro.h>
+#define ret br.ret.sptk.few rp
+GLOBAL_ENTRY(kdba_setjmp)
+#endif /* !__KERNEL__ */
+
+ .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
+ alloc loc1=ar.pfs,2,2,2,0
+ mov r16=ar.unat
+ ;;
+ mov r17=ar.fpsr
+ mov r2=in0
+ add r3=8,in0
+ ;;
+.mem.offset 0,0;
+ st8.spill.nta [r2]=sp,16 // r12 (sp)
+.mem.offset 8,0;
+ st8.spill.nta [r3]=gp,16 // r1 (gp)
+ ;;
+ st8.nta [r2]=r16,16 // save caller's unat
+ st8.nta [r3]=r17,16 // save fpsr
+ add r8=0xa0,in0
+ ;;
+.mem.offset 160,0;
+ st8.spill.nta [r2]=r4,16 // r4
+.mem.offset 168,0;
+ st8.spill.nta [r3]=r5,16 // r5
+ add r9=0xb0,in0
+ ;;
+ stf.spill.nta [r8]=f2,32
+ stf.spill.nta [r9]=f3,32
+ mov loc0=rp
+ .body
+ ;;
+ stf.spill.nta [r8]=f4,32
+ stf.spill.nta [r9]=f5,32
+ mov r17=b1
+ ;;
+ stf.spill.nta [r8]=f16,32
+ stf.spill.nta [r9]=f17,32
+ mov r18=b2
+ ;;
+ stf.spill.nta [r8]=f18,32
+ stf.spill.nta [r9]=f19,32
+ mov r19=b3
+ ;;
+ stf.spill.nta [r8]=f20,32
+ stf.spill.nta [r9]=f21,32
+ mov r20=b4
+ ;;
+ stf.spill.nta [r8]=f22,32
+ stf.spill.nta [r9]=f23,32
+ mov r21=b5
+ ;;
+ stf.spill.nta [r8]=f24,32
+ stf.spill.nta [r9]=f25,32
+ mov r22=ar.lc
+ ;;
+ stf.spill.nta [r8]=f26,32
+ stf.spill.nta [r9]=f27,32
+ mov r24=pr
+ ;;
+ stf.spill.nta [r8]=f28,32
+ stf.spill.nta [r9]=f29,32
+ ;;
+ stf.spill.nta [r8]=f30
+ stf.spill.nta [r9]=f31
+
+.mem.offset 0,0;
+ st8.spill.nta [r2]=r6,16 // r6
+.mem.offset 8,0;
+ st8.spill.nta [r3]=r7,16 // r7
+ ;;
+ mov r23=ar.bsp
+ mov r25=ar.unat
+#ifndef __KERNEL__
+ mov out0=in0
+#endif /* !__KERNEL__ */
+
+ st8.nta [r2]=loc0,16 // b0
+ st8.nta [r3]=r17,16 // b1
+#ifndef __KERNEL__
+ mov out1=in1
+#endif /* !__KERNEL__ */
+ ;;
+ st8.nta [r2]=r18,16 // b2
+ st8.nta [r3]=r19,16 // b3
+ ;;
+ st8.nta [r2]=r20,16 // b4
+ st8.nta [r3]=r21,16 // b5
+ ;;
+ st8.nta [r2]=loc1,16 // ar.pfs
+ st8.nta [r3]=r22,16 // ar.lc
+ ;;
+ st8.nta [r2]=r24,16 // pr
+ st8.nta [r3]=r23,16 // ar.bsp
+ ;;
+ st8.nta [r2]=r25 // ar.unat
+ st8.nta [r3]=in0 // &__jmp_buf
+#ifndef __KERNEL__
+ br.call.dpnt.few rp=__sigjmp_save
+.ret0: // force a new bundle ::q
+#endif /* !_KERNEL__ */
+ mov r8=0
+ mov rp=loc0
+ mov ar.pfs=loc1
+ ret
+#ifndef __KERNEL__
+END(__sigsetjmp)
+
+weak_extern(_setjmp)
+weak_extern(setjmp)
+
+#else /* __KERNEL__ */
+END(kdba_setjmp)
+#endif /* !_KERNEL__ */
+
+/* Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, write to the Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Note that __sigsetjmp() did NOT flush the register stack. Instead,
+ we do it here since __longjmp() is usually much less frequently
+ invoked than __sigsetjmp(). The only difficulty is that __sigsetjmp()
+ didn't (and wouldn't be able to) save ar.rnat either. This is a problem
+ because if we're not careful, we could end up loading random NaT bits.
+ There are two cases:
+
+ (i) ar.bsp < ia64_rse_rnat_addr(jmpbuf.ar_bsp)
+ ar.rnat contains the desired bits---preserve ar.rnat
+ across loadrs and write to ar.bspstore
+
+ (ii) ar.bsp >= ia64_rse_rnat_addr(jmpbuf.ar_bsp)
+ The desired ar.rnat is stored in
+ ia64_rse_rnat_addr(jmpbuf.ar_bsp). Load those
+ bits into ar.rnat after setting ar.bspstore. */
+
+#ifndef __KERNEL__
+#include <sysdep.h>
+#include <features.h>
+#endif /* !__KERNEL__ */
+
+# define pPos p6 /* is rotate count positive? */
+# define pNeg p7 /* is rotate count negative? */
+
+
+ /* __longjmp(__jmp_buf buf, int val) */
+
+#ifndef __KERNEL__
+LEAF(__longjmp)
+#else /* __KERNEL__ */
+GLOBAL_ENTRY(kdba_longjmp)
+#endif /* !__KERNEL__ */
+ alloc r8=ar.pfs,2,1,0,0
+ mov r27=ar.rsc
+ add r2=0x98,in0 // r2 <- &jmpbuf.orig_jmp_buf_addr
+ ;;
+ ld8 r8=[r2],-16 // r8 <- orig_jmp_buf_addr
+ mov r10=ar.bsp
+ and r11=~0x3,r27 // clear ar.rsc.mode
+ ;;
+ flushrs // flush dirty regs to backing store (must be first in insn grp)
+ ld8 r23=[r2],8 // r23 <- jmpbuf.ar_bsp
+ sub r8=r8,in0 // r8 <- &orig_jmpbuf - &jmpbuf
+ ;;
+ ld8 r25=[r2] // r25 <- jmpbuf.ar_unat
+ extr.u r8=r8,3,6 // r8 <- (&orig_jmpbuf - &jmpbuf)/8 & 0x3f
+ ;;
+ cmp.lt pNeg,pPos=r8,r0
+ mov r2=in0
+ ;;
+(pPos) mov r16=r8
+(pNeg) add r16=64,r8
+(pPos) sub r17=64,r8
+(pNeg) sub r17=r0,r8
+ ;;
+ mov ar.rsc=r11 // put RSE in enforced lazy mode
+ shr.u r8=r25,r16
+ add r3=8,in0 // r3 <- &jmpbuf.r1
+ shl r9=r25,r17
+ ;;
+ or r25=r8,r9
+ ;;
+ mov r26=ar.rnat
+ mov ar.unat=r25 // setup ar.unat (NaT bits for r1, r4-r7, and r12)
+ ;;
+ ld8.fill.nta sp=[r2],16 // r12 (sp)
+ ld8.fill.nta gp=[r3],16 // r1 (gp)
+ dep r11=-1,r23,3,6 // r11 <- ia64_rse_rnat_addr(jmpbuf.ar_bsp)
+ ;;
+ ld8.nta r16=[r2],16 // caller's unat
+ ld8.nta r17=[r3],16 // fpsr
+ ;;
+ ld8.fill.nta r4=[r2],16 // r4
+ ld8.fill.nta r5=[r3],16 // r5 (gp)
+ cmp.geu p8,p0=r10,r11 // p8 <- (ar.bsp >= jmpbuf.ar_bsp)
+ ;;
+ ld8.fill.nta r6=[r2],16 // r6
+ ld8.fill.nta r7=[r3],16 // r7
+ ;;
+ mov ar.unat=r16 // restore caller's unat
+ mov ar.fpsr=r17 // restore fpsr
+ ;;
+ ld8.nta r16=[r2],16 // b0
+ ld8.nta r17=[r3],16 // b1
+ ;;
+(p8) ld8 r26=[r11] // r26 <- *ia64_rse_rnat_addr(jmpbuf.ar_bsp)
+ mov ar.bspstore=r23 // restore ar.bspstore
+ ;;
+ ld8.nta r18=[r2],16 // b2
+ ld8.nta r19=[r3],16 // b3
+ ;;
+ ld8.nta r20=[r2],16 // b4
+ ld8.nta r21=[r3],16 // b5
+ ;;
+ ld8.nta r11=[r2],16 // ar.pfs
+ ld8.nta r22=[r3],56 // ar.lc
+ ;;
+ ld8.nta r24=[r2],32 // pr
+ mov b0=r16
+ ;;
+ ldf.fill.nta f2=[r2],32
+ ldf.fill.nta f3=[r3],32
+ mov b1=r17
+ ;;
+ ldf.fill.nta f4=[r2],32
+ ldf.fill.nta f5=[r3],32
+ mov b2=r18
+ ;;
+ ldf.fill.nta f16=[r2],32
+ ldf.fill.nta f17=[r3],32
+ mov b3=r19
+ ;;
+ ldf.fill.nta f18=[r2],32
+ ldf.fill.nta f19=[r3],32
+ mov b4=r20
+ ;;
+ ldf.fill.nta f20=[r2],32
+ ldf.fill.nta f21=[r3],32
+ mov b5=r21
+ ;;
+ ldf.fill.nta f22=[r2],32
+ ldf.fill.nta f23=[r3],32
+ mov ar.lc=r22
+ ;;
+ ldf.fill.nta f24=[r2],32
+ ldf.fill.nta f25=[r3],32
+ cmp.eq p8,p9=0,in1
+ ;;
+ ldf.fill.nta f26=[r2],32
+ ldf.fill.nta f27=[r3],32
+ mov ar.pfs=r11
+ ;;
+ ldf.fill.nta f28=[r2],32
+ ldf.fill.nta f29=[r3],32
+ ;;
+ ldf.fill.nta f30=[r2]
+ ldf.fill.nta f31=[r3]
+(p8) mov r8=1
+
+ mov ar.rnat=r26 // restore ar.rnat
+ ;;
+ mov ar.rsc=r27 // restore ar.rsc
+(p9) mov r8=in1
+
+ invala // virt. -> phys. regnum mapping may change
+ mov pr=r24,-1
+ ret
+#ifndef __KERNEL__
+END(__longjmp)
+#else /* __KERNEL__ */
+END(kdba_longjmp)
+#endif /* !_KERNEL__ */
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent POD functions.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2006 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <linux/module.h>
+#include <asm/sal.h>
+#include <asm/sn/sn_sal.h>
+
+MODULE_AUTHOR("Jesse Barnes");
+MODULE_DESCRIPTION("Enter POD through KDB");
+MODULE_LICENSE("GPL");
+
+/**
+ * kdba_pod - enter POD mode from kdb
+ * @argc: arg count
+ * @argv: arg values
+ * @envp: kdb env. vars
+ * @regs: current register state
+ *
+ * Enter POD mode from kdb using SGI SN specific SAL function call.
+ */
+static int
+kdba_pod(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ kdb_printf("WARNING: pod commands are dangerous unless you know exactly\n"
+ "what you are doing. If in doubt, type exit immediately.\n");
+ return ia64_sn_pod_mode();
+}
+
+/**
+ * kdba_pod_init - register 'pod' command with kdb
+ *
+ * Register the 'pod' command with kdb at load time.
+ */
+static int __init
+kdba_pod_init(void)
+{
+ if (ia64_platform_is("sn2"))
+ kdb_register("pod", kdba_pod, NULL, "Enter POD", 0);
+
+ return 0;
+}
+
+/**
+ * kdba_pod_exit - unregister the 'pod' command
+ *
+ * Tell kdb that the 'pod' command is no longer available.
+ */
+static void __exit
+kdba_pod_exit(void)
+{
+ if (ia64_platform_is("sn2"))
+ kdb_unregister("pod");
+}
+
+kdb_module_init(kdba_pod_init);
+kdb_module_exit(kdba_pod_exit);
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Support Functions
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2006 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (C) David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+
+#include <linux/string.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/rse.h>
+#include <asm/delay.h>
+#ifdef CONFIG_SMP
+#include <asm/hw_irq.h>
+#endif
+#include <asm/mca.h>
+
+struct kdb_running_process *kdb_running_process_save; /* [NR_CPUS] */
+static int kdba_show_handlers = 0;
+
+static int
+kdba_itm (int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int diag;
+ unsigned long val;
+
+ diag = kdbgetularg(argv[1], &val);
+ if (diag)
+ return diag;
+ kdb_printf("new itm=" kdb_machreg_fmt "\n", val);
+
+ ia64_set_itm(val);
+ return 0;
+}
+
+static void
+kdba_show_intregs(void)
+{
+ u64 lid, tpr, lrr0, lrr1, itv, pmv, cmcv;
+
+ asm ("mov %0=cr.lid" : "=r"(lid));
+ asm ("mov %0=cr.tpr" : "=r"(tpr));
+ asm ("mov %0=cr.lrr0" : "=r"(lrr0));
+ asm ("mov %0=cr.lrr1" : "=r"(lrr1));
+ kdb_printf("lid=" kdb_machreg_fmt ", tpr=" kdb_machreg_fmt ", lrr0=" kdb_machreg_fmt ", llr1=" kdb_machreg_fmt "\n", lid, tpr, lrr0, lrr1);
+
+ asm ("mov %0=cr.itv" : "=r"(itv));
+ asm ("mov %0=cr.pmv" : "=r"(pmv));
+ asm ("mov %0=cr.cmcv" : "=r"(cmcv));
+ kdb_printf("itv=" kdb_machreg_fmt ", pmv=" kdb_machreg_fmt ", cmcv=" kdb_machreg_fmt "\n", itv, pmv, cmcv);
+
+ kdb_printf("irr=0x%016lx,0x%016lx,0x%016lx,0x%016lx\n",
+ ia64_getreg(_IA64_REG_CR_IRR0), ia64_getreg(_IA64_REG_CR_IRR1), ia64_getreg(_IA64_REG_CR_IRR2), ia64_getreg(_IA64_REG_CR_IRR3));
+
+ kdb_printf("itc=0x%016lx, itm=0x%016lx\n", ia64_get_itc(), ia64_get_itm());
+}
+
+static int
+kdba_sir (int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ kdba_show_intregs();
+
+ return 0;
+}
+
+/*
+ * kdba_pt_regs
+ *
+ * Format a struct pt_regs
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * If no address is supplied, it uses regs.
+ */
+
+static int
+kdba_pt_regs(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int diag;
+ kdb_machreg_t addr;
+ long offset = 0;
+ int nextarg;
+ struct pt_regs *p;
+
+ if (argc == 0) {
+ addr = (kdb_machreg_t) regs;
+ } else if (argc == 1) {
+ nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
+ if (diag)
+ return diag;
+ } else {
+ return KDB_ARGCOUNT;
+ }
+
+ p = (struct pt_regs *) addr;
+ kdb_printf("struct pt_regs %p-%p\n", p, (unsigned char *)p + sizeof(*p) - 1);
+ kdb_print_nameval("b6", p->b6);
+ kdb_print_nameval("b7", p->b7);
+ kdb_printf(" ar_csd 0x%lx\n", p->ar_csd);
+ kdb_printf(" ar_ssd 0x%lx\n", p->ar_ssd);
+ kdb_print_nameval("r8", p->r8);
+ kdb_print_nameval("r9", p->r9);
+ kdb_print_nameval("r10", p->r10);
+ kdb_print_nameval("r11", p->r11);
+ kdb_printf(" cr_ipsr 0x%lx\n", p->cr_ipsr);
+ kdb_print_nameval("cr_iip", p->cr_iip);
+ kdb_printf(" cr_ifs 0x%lx\n", p->cr_ifs);
+ kdb_printf(" ar_unat 0x%lx\n", p->ar_unat);
+ kdb_printf(" ar_pfs 0x%lx\n", p->ar_pfs);
+ kdb_printf(" ar_rsc 0x%lx\n", p->ar_rsc);
+ kdb_printf(" ar_rnat 0x%lx\n", p->ar_rnat);
+ kdb_printf(" ar_bspstore 0x%lx\n", p->ar_bspstore);
+ kdb_printf(" pr 0x%lx\n", p->pr);
+ kdb_print_nameval("b0", p->b0);
+ kdb_printf(" loadrs 0x%lx\n", p->loadrs);
+ kdb_print_nameval("r1", p->r1);
+ kdb_print_nameval("r12", p->r12);
+ kdb_print_nameval("r13", p->r13);
+ kdb_printf(" ar_fpsr 0x%lx\n", p->ar_fpsr);
+ kdb_print_nameval("r15", p->r15);
+ kdb_print_nameval("r14", p->r14);
+ kdb_print_nameval("r2", p->r2);
+ kdb_print_nameval("r3", p->r3);
+ kdb_print_nameval("r16", p->r16);
+ kdb_print_nameval("r17", p->r17);
+ kdb_print_nameval("r18", p->r18);
+ kdb_print_nameval("r19", p->r19);
+ kdb_print_nameval("r20", p->r20);
+ kdb_print_nameval("r21", p->r21);
+ kdb_print_nameval("r22", p->r22);
+ kdb_print_nameval("r23", p->r23);
+ kdb_print_nameval("r24", p->r24);
+ kdb_print_nameval("r25", p->r25);
+ kdb_print_nameval("r26", p->r26);
+ kdb_print_nameval("r27", p->r27);
+ kdb_print_nameval("r28", p->r28);
+ kdb_print_nameval("r29", p->r29);
+ kdb_print_nameval("r30", p->r30);
+ kdb_print_nameval("r31", p->r31);
+ kdb_printf(" ar_ccv 0x%lx\n", p->ar_ccv);
+ kdb_printf(" f6 0x%lx 0x%lx\n", p->f6.u.bits[0], p->f6.u.bits[1]);
+ kdb_printf(" f7 0x%lx 0x%lx\n", p->f7.u.bits[0], p->f7.u.bits[1]);
+ kdb_printf(" f8 0x%lx 0x%lx\n", p->f8.u.bits[0], p->f8.u.bits[1]);
+ kdb_printf(" f9 0x%lx 0x%lx\n", p->f9.u.bits[0], p->f9.u.bits[1]);
+ kdb_printf(" f10 0x%lx 0x%lx\n", p->f10.u.bits[0], p->f10.u.bits[1]);
+ kdb_printf(" f11 0x%lx 0x%lx\n", p->f11.u.bits[0], p->f11.u.bits[1]);
+
+ return 0;
+}
+
+/*
+ * kdba_stackdepth
+ *
+ * Print processes that are using more than a specific percentage of their
+ * stack.
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * If no percentage is supplied, it uses 60.
+ */
+
+static int
+kdba_stackdepth(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int diag, threshold, used;
+ long percentage;
+ unsigned long esp;
+ long offset = 0;
+ int nextarg;
+ struct task_struct *p, *g;
+ struct switch_stack *sw;
+
+ if (argc == 0) {
+ percentage = 60;
+ } else if (argc == 1) {
+ nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &percentage, &offset, NULL, regs);
+ if (diag)
+ return diag;
+ } else {
+ return KDB_ARGCOUNT;
+ }
+ percentage = max_t(int, percentage, 1);
+ percentage = min_t(int, percentage, 100);
+ threshold = ((2 * THREAD_SIZE * percentage) / 100 + 1) >> 1;
+ kdb_printf("stackdepth: processes using more than %ld%% (%d bytes) of stack\n",
+ percentage, threshold);
+ do_each_thread(g, p) {
+ if (task_curr(p)) {
+ struct kdb_running_process *krp = kdb_running_process + kdb_process_cpu(p);
+ if (krp->seqno)
+ sw = krp->arch.sw;
+ else
+ sw = NULL;
+ } else
+ sw = (struct switch_stack *) (p->thread.ksp + 16);
+ if (!sw)
+ continue;
+ esp = (unsigned long) sw;
+ used = THREAD_SIZE - (esp - sw->ar_bspstore);
+ if (used >= threshold) {
+ kdb_ps1(p);
+ kdb_printf(" esp %lx bsp %lx used %d\n", esp, sw->ar_bspstore, used);
+ }
+ } while_each_thread(g, p);
+
+ return 0;
+}
+
+/*
+ * kdb_switch_stack
+ *
+ * Format a struct switch_stack
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * If no address is supplied, it uses kdb_running_process[smp_processor_id()].arch.sw.
+ */
+
+static int
+kdba_switch_stack(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int diag;
+ kdb_machreg_t addr;
+ long offset = 0;
+ int nextarg;
+ struct switch_stack *p;
+
+ if (argc == 0) {
+ addr = (kdb_machreg_t) kdb_running_process[smp_processor_id()].arch.sw;
+ } else if (argc == 1) {
+ nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
+ if (diag)
+ return diag;
+ } else {
+ return KDB_ARGCOUNT;
+ }
+
+ p = (struct switch_stack *) addr;
+ kdb_printf("struct switch_stack %p-%p\n", p, (unsigned char *)p + sizeof(*p) - 1);
+ kdb_printf(" caller_unat 0x%lx\n", p->caller_unat);
+ kdb_printf(" ar_fpsr 0x%lx\n", p->ar_fpsr);
+ kdb_printf(" f2 0x%lx 0x%lx\n", p->f2.u.bits[0], p->f2.u.bits[1]);
+ kdb_printf(" f3 0x%lx 0x%lx\n", p->f3.u.bits[0], p->f3.u.bits[1]);
+ kdb_printf(" f4 0x%lx 0x%lx\n", p->f4.u.bits[0], p->f4.u.bits[1]);
+ kdb_printf(" f5 0x%lx 0x%lx\n", p->f5.u.bits[0], p->f5.u.bits[1]);
+ kdb_printf(" f12 0x%lx 0x%lx\n", p->f12.u.bits[0], p->f12.u.bits[1]);
+ kdb_printf(" f13 0x%lx 0x%lx\n", p->f13.u.bits[0], p->f13.u.bits[1]);
+ kdb_printf(" f14 0x%lx 0x%lx\n", p->f14.u.bits[0], p->f14.u.bits[1]);
+ kdb_printf(" f15 0x%lx 0x%lx\n", p->f15.u.bits[0], p->f15.u.bits[1]);
+ kdb_printf(" f16 0x%lx 0x%lx\n", p->f16.u.bits[0], p->f16.u.bits[1]);
+ kdb_printf(" f17 0x%lx 0x%lx\n", p->f17.u.bits[0], p->f17.u.bits[1]);
+ kdb_printf(" f18 0x%lx 0x%lx\n", p->f18.u.bits[0], p->f18.u.bits[1]);
+ kdb_printf(" f19 0x%lx 0x%lx\n", p->f19.u.bits[0], p->f19.u.bits[1]);
+ kdb_printf(" f20 0x%lx 0x%lx\n", p->f20.u.bits[0], p->f20.u.bits[1]);
+ kdb_printf(" f21 0x%lx 0x%lx\n", p->f21.u.bits[0], p->f21.u.bits[1]);
+ kdb_printf(" f22 0x%lx 0x%lx\n", p->f22.u.bits[0], p->f22.u.bits[1]);
+ kdb_printf(" f23 0x%lx 0x%lx\n", p->f23.u.bits[0], p->f23.u.bits[1]);
+ kdb_printf(" f24 0x%lx 0x%lx\n", p->f24.u.bits[0], p->f24.u.bits[1]);
+ kdb_printf(" f25 0x%lx 0x%lx\n", p->f25.u.bits[0], p->f25.u.bits[1]);
+ kdb_printf(" f26 0x%lx 0x%lx\n", p->f26.u.bits[0], p->f26.u.bits[1]);
+ kdb_printf(" f27 0x%lx 0x%lx\n", p->f27.u.bits[0], p->f27.u.bits[1]);
+ kdb_printf(" f28 0x%lx 0x%lx\n", p->f28.u.bits[0], p->f28.u.bits[1]);
+ kdb_printf(" f29 0x%lx 0x%lx\n", p->f29.u.bits[0], p->f29.u.bits[1]);
+ kdb_printf(" f30 0x%lx 0x%lx\n", p->f30.u.bits[0], p->f30.u.bits[1]);
+ kdb_printf(" f31 0x%lx 0x%lx\n", p->f31.u.bits[0], p->f31.u.bits[1]);
+ kdb_print_nameval("r4", p->r4);
+ kdb_print_nameval("r5", p->r5);
+ kdb_print_nameval("r6", p->r6);
+ kdb_print_nameval("r7", p->r7);
+ kdb_print_nameval("b0", p->b0);
+ kdb_print_nameval("b1", p->b1);
+ kdb_print_nameval("b2", p->b2);
+ kdb_print_nameval("b3", p->b3);
+ kdb_print_nameval("b4", p->b4);
+ kdb_print_nameval("b5", p->b5);
+ kdb_printf(" ar_pfs 0x%lx\n", p->ar_pfs);
+ kdb_printf(" ar_lc 0x%lx\n", p->ar_lc);
+ kdb_printf(" ar_unat 0x%lx\n", p->ar_unat);
+ kdb_printf(" ar_rnat 0x%lx\n", p->ar_rnat);
+ kdb_printf(" ar_bspstore 0x%lx\n", p->ar_bspstore);
+ kdb_printf(" pr 0x%lx\n", p->pr);
+
+ return 0;
+}
+
+/*
+ * kdb_minstate
+ *
+ * Format the PAL minstate area.
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * None.
+ */
+
+static int
+kdba_minstate(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int diag;
+ kdb_machreg_t addr;
+ long offset = 0;
+ int nextarg;
+ pal_min_state_area_t *p;
+
+ if (argc == 1) {
+ nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
+ if (diag)
+ return diag;
+ } else {
+ return KDB_ARGCOUNT;
+ }
+
+ p = (pal_min_state_area_t *) addr;
+ kdb_printf("PAL minstate %p-%p\n", p, (unsigned char *)p + sizeof(*p) - 1);
+ kdb_printf(" pmsa_nat_bits 0x%lx\n", p->pmsa_nat_bits);
+ kdb_print_nameval("r1", p->pmsa_gr[1-1]);
+ kdb_print_nameval("r2", p->pmsa_gr[2-1]);
+ kdb_print_nameval("r3", p->pmsa_gr[3-1]);
+ kdb_print_nameval("r4", p->pmsa_gr[4-1]);
+ kdb_print_nameval("r5", p->pmsa_gr[5-1]);
+ kdb_print_nameval("r6", p->pmsa_gr[6-1]);
+ kdb_print_nameval("r7", p->pmsa_gr[7-1]);
+ kdb_print_nameval("r8", p->pmsa_gr[8-1]);
+ kdb_print_nameval("r9", p->pmsa_gr[9-1]);
+ kdb_print_nameval("r10", p->pmsa_gr[10-1]);
+ kdb_print_nameval("r11", p->pmsa_gr[11-1]);
+ kdb_print_nameval("r12", p->pmsa_gr[12-1]);
+ kdb_print_nameval("r13", p->pmsa_gr[13-1]);
+ kdb_print_nameval("r14", p->pmsa_gr[14-1]);
+ kdb_print_nameval("r15", p->pmsa_gr[15-1]);
+ kdb_printf(" Bank 0\n");
+ kdb_print_nameval("r16", p->pmsa_bank0_gr[16-16]);
+ kdb_print_nameval("r17", p->pmsa_bank0_gr[17-16]);
+ kdb_print_nameval("r18", p->pmsa_bank0_gr[18-16]);
+ kdb_print_nameval("r19", p->pmsa_bank0_gr[19-16]);
+ kdb_print_nameval("r20", p->pmsa_bank0_gr[20-16]);
+ kdb_print_nameval("r21", p->pmsa_bank0_gr[21-16]);
+ kdb_print_nameval("r22", p->pmsa_bank0_gr[22-16]);
+ kdb_print_nameval("r23", p->pmsa_bank0_gr[23-16]);
+ kdb_print_nameval("r24", p->pmsa_bank0_gr[24-16]);
+ kdb_print_nameval("r25", p->pmsa_bank0_gr[25-16]);
+ kdb_print_nameval("r26", p->pmsa_bank0_gr[26-16]);
+ kdb_print_nameval("r27", p->pmsa_bank0_gr[27-16]);
+ kdb_print_nameval("r28", p->pmsa_bank0_gr[28-16]);
+ kdb_print_nameval("r29", p->pmsa_bank0_gr[29-16]);
+ kdb_print_nameval("r30", p->pmsa_bank0_gr[30-16]);
+ kdb_print_nameval("r31", p->pmsa_bank0_gr[31-16]);
+ kdb_printf(" Bank 1\n");
+ kdb_print_nameval("r16", p->pmsa_bank1_gr[16-16]);
+ kdb_print_nameval("r17", p->pmsa_bank1_gr[17-16]);
+ kdb_print_nameval("r18", p->pmsa_bank1_gr[18-16]);
+ kdb_print_nameval("r19", p->pmsa_bank1_gr[19-16]);
+ kdb_print_nameval("r20", p->pmsa_bank1_gr[20-16]);
+ kdb_print_nameval("r21", p->pmsa_bank1_gr[21-16]);
+ kdb_print_nameval("r22", p->pmsa_bank1_gr[22-16]);
+ kdb_print_nameval("r23", p->pmsa_bank1_gr[23-16]);
+ kdb_print_nameval("r24", p->pmsa_bank1_gr[24-16]);
+ kdb_print_nameval("r25", p->pmsa_bank1_gr[25-16]);
+ kdb_print_nameval("r26", p->pmsa_bank1_gr[26-16]);
+ kdb_print_nameval("r27", p->pmsa_bank1_gr[27-16]);
+ kdb_print_nameval("r28", p->pmsa_bank1_gr[28-16]);
+ kdb_print_nameval("r29", p->pmsa_bank1_gr[29-16]);
+ kdb_print_nameval("r30", p->pmsa_bank1_gr[30-16]);
+ kdb_print_nameval("r31", p->pmsa_bank1_gr[31-16]);
+ kdb_printf(" pr 0x%lx\n", p->pmsa_pr);
+ kdb_print_nameval("b0", p->pmsa_br0);
+ kdb_printf(" ar.rsc 0x%lx\n", p->pmsa_rsc);
+ kdb_print_nameval("cr.iip", p->pmsa_iip);
+ kdb_printf(" cr.ipsr 0x%lx\n", p->pmsa_ipsr);
+ kdb_printf(" cr.ifs 0x%lx\n", p->pmsa_ifs);
+ kdb_print_nameval("cr.xip", p->pmsa_xip);
+ kdb_printf(" cr.xpsr 0x%lx\n", p->pmsa_xpsr);
+ kdb_printf(" cr.xfs 0x%lx\n", p->pmsa_xfs);
+ kdb_print_nameval("b1", p->pmsa_br1);
+
+ return 0;
+}
+
+/*
+ * kdba_cpuinfo
+ *
+ * Format struct cpuinfo_ia64.
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * If no cpu is supplied, it prints cpuinfo for all online cpus.
+ */
+
+static int
+kdba_cpuinfo(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int diag;
+ long cpunum = -1;
+ long offset = 0;
+ int nextarg, c, i;
+ struct cpuinfo_ia64 *cpuinfo;
+
+ if (argc == 1) {
+ nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &cpunum, &offset, NULL, regs);
+ if (diag)
+ return diag;
+ if (cpunum >= NR_CPUS || !cpu_online(cpunum))
+ return KDB_BADCPUNUM;
+ } else if (argc > 1) {
+ return KDB_ARGCOUNT;
+ }
+
+ for (c = (cpunum < 0 ? 0 : cpunum);
+ c < (cpunum < 0 ? NR_CPUS : cpunum+1);
+ ++c) {
+ if (!cpu_online(c))
+ continue;
+ cpuinfo = cpu_data(c);
+ kdb_printf("struct cpuinfo_ia64 for cpu %d is at 0x%p\n", c, cpuinfo);
+ kdb_printf(" softirq_pending 0x%x\n", cpuinfo->softirq_pending);
+ kdb_printf(" itm_delta %ld\n", cpuinfo->itm_delta);
+ kdb_printf(" itm_next %ld\n", cpuinfo->itm_next);
+ kdb_printf(" nsec_per_cyc %ld\n", cpuinfo->nsec_per_cyc);
+ kdb_printf(" unimpl_va_mask 0x%lx\n", cpuinfo->unimpl_va_mask);
+ kdb_printf(" unimpl_pa_mask 0x%lx\n", cpuinfo->unimpl_pa_mask);
+ kdb_printf(" itc_freq %ld\n", cpuinfo->itc_freq);
+ kdb_printf(" proc_freq %ld\n", cpuinfo->proc_freq);
+ kdb_printf(" cyc_per_usec %ld\n", cpuinfo->cyc_per_usec);
+ kdb_printf(" cyc_per_usec %ld\n", cpuinfo->cyc_per_usec);
+#if 0 /* RJA per-cpu MCA */
+ kdb_printf(" percpu_paddr 0x%lx\n", cpuinfo->percpu_paddr);
+#endif
+ kdb_printf(" ptce_base 0x%lx\n", cpuinfo->ptce_base);
+ kdb_printf(" ptce_count %d %d\n", cpuinfo->ptce_count[0], cpuinfo->ptce_count[1]);
+ kdb_printf(" ptce_stride %d %d\n", cpuinfo->ptce_stride[0], cpuinfo->ptce_stride[1]);
+#if 0 /* RJA per-cpu MCA */
+ kdb_printf(" pal_paddr 0x%lx\n", cpuinfo->pal_paddr);
+ kdb_printf(" pal_base 0x%lx\n", cpuinfo->pal_base);
+#endif
+ kdb_printf(" ksoftirqd 0x%p\n", cpuinfo->ksoftirqd);
+#ifdef CONFIG_SMP
+ kdb_printf(" loops_per_jiffy %ld\n", cpuinfo->loops_per_jiffy);
+ kdb_printf(" cpu %d\n", cpuinfo->cpu);
+ kdb_printf(" socket_id %d\n", cpuinfo->socket_id);
+ kdb_printf(" core_id %d\n", cpuinfo->core_id);
+ kdb_printf(" thread_id %d\n", cpuinfo->thread_id);
+ kdb_printf(" num_log %d\n", cpuinfo->num_log);
+ kdb_printf(" cores_per_socket %d\n", cpuinfo->cores_per_socket);
+ kdb_printf(" threads_per_core %d\n", cpuinfo->threads_per_core);
+#endif
+ kdb_printf(" ppn 0x%lx\n", cpuinfo->ppn);
+ kdb_printf(" features 0x%lx\n", cpuinfo->features);
+ kdb_printf(" number %d\n", cpuinfo->number);
+ kdb_printf(" revision %d\n", cpuinfo->revision);
+ kdb_printf(" model %d\n", cpuinfo->model);
+ kdb_printf(" family %d\n", cpuinfo->family);
+ kdb_printf(" archrev %d\n", cpuinfo->archrev);
+ kdb_printf(" vendor ");
+ for (i = 0; i < sizeof(cpuinfo->vendor); ++i)
+ kdb_printf(" 0x%02x", cpuinfo->vendor[i]);
+ kdb_printf("\n");
+#ifdef CONFIG_NUMA
+ kdb_printf(" node_data 0x%p\n", cpuinfo->node_data);
+#endif
+#if 0 /* RJA per-cpu MCA */
+ kdb_printf(" ia64_pa_mca_data 0x%p\n", cpuinfo->ia64_pa_mca_data);
+#endif
+ }
+ return 0;
+}
+
+void
+kdba_installdbreg(kdb_bp_t *bp)
+{
+ /* FIXME: code this */
+}
+
+void
+kdba_removedbreg(kdb_bp_t *bp)
+{
+ /* FIXME: code this */
+}
+
+static kdb_machreg_t
+kdba_getdr(int regnum)
+{
+ kdb_machreg_t contents = 0;
+ unsigned long reg = (unsigned long)regnum;
+
+ __asm__ ("mov %0=ibr[%1]"::"r"(contents),"r"(reg));
+// __asm__ ("mov ibr[%0]=%1"::"r"(dbreg_cond),"r"(value));
+
+ return contents;
+}
+
+
+static void
+get_fault_regs(fault_regs_t *fr)
+{
+ fr->ifa = 0 ;
+ fr->isr = 0 ;
+
+ __asm__ ("rsm psr.ic;;") ;
+ ia64_srlz_d();
+ __asm__ ("mov %0=cr.ifa" : "=r"(fr->ifa));
+ __asm__ ("mov %0=cr.isr" : "=r"(fr->isr));
+ __asm__ ("ssm psr.ic;;") ;
+ ia64_srlz_d();
+}
+
+static void
+show_kernel_regs (void)
+{
+ unsigned long kr[8];
+ int i;
+
+ asm ("mov %0=ar.k0" : "=r"(kr[0])); asm ("mov %0=ar.k1" : "=r"(kr[1]));
+ asm ("mov %0=ar.k2" : "=r"(kr[2])); asm ("mov %0=ar.k3" : "=r"(kr[3]));
+ asm ("mov %0=ar.k4" : "=r"(kr[4])); asm ("mov %0=ar.k5" : "=r"(kr[5]));
+ asm ("mov %0=ar.k6" : "=r"(kr[6])); asm ("mov %0=ar.k7" : "=r"(kr[7]));
+
+ for (i = 0; i < 4; ++i)
+ kdb_printf(" kr%d: %016lx kr%d: %016lx\n", 2*i, kr[2*i], 2*i+1, kr[2*i+1]);
+ kdb_printf("\n");
+}
+
+static int
+change_cur_stack_frame(int regno, unsigned long *contents)
+{
+ unsigned long sof, i, cfm, sp, *bsp, __user *ubsp;
+ struct unw_frame_info info;
+ mm_segment_t old_fs;
+ int cpu = kdb_process_cpu(kdb_current_task);
+ struct kdb_running_process *krp = kdb_running_process + cpu;
+
+ if (kdb_current_task != krp->p) {
+ kdb_printf("Stacked registers are not available for tasks that are not running.\n");
+ kdb_printf("Use bt with a large BTARGS value instead\n");
+ return 0;
+ }
+ unw_init_frame_info(&info, krp->p, krp->arch.sw);
+ do {
+ if (unw_unwind(&info) < 0) {
+ kdb_printf("Failed to unwind\n");
+ return 0;
+ }
+ unw_get_sp(&info, &sp);
+ } while (sp <= (unsigned long) kdb_current_regs);
+ unw_get_bsp(&info, (unsigned long *) &bsp);
+ unw_get_cfm(&info, &cfm);
+
+ if (!bsp) {
+ kdb_printf("Unable to get Current Stack Frame\n");
+ return 0;
+ }
+
+ sof = (cfm & 0x7f);
+
+ if(((unsigned long)regno - 32) >= (sof - 2)) return 1;
+
+ old_fs = set_fs(KERNEL_DS);
+ for (i = 0; i < (regno - 32); ++i)
+ bsp = ia64_rse_skip_regs(bsp, 1);
+ ubsp = (unsigned long __user *) bsp;
+ put_user(*contents, ubsp);
+ set_fs(old_fs);
+
+ return 0 ;
+}
+
+static int
+show_cur_stack_frame(int regno, unsigned long *contents)
+{
+ unsigned long sof, i, cfm, val, sp, *bsp, __user *ubsp;
+ struct unw_frame_info info;
+ mm_segment_t old_fs;
+ int cpu = kdb_process_cpu(kdb_current_task);
+ struct kdb_running_process *krp = kdb_running_process + cpu;
+
+ if (kdb_current_task != krp->p) {
+ kdb_printf("Stacked registers are not available for tasks that are not running.\n");
+ kdb_printf("Use bt with a large BTARGS value instead\n");
+ return 0;
+ }
+ unw_init_frame_info(&info, krp->p, krp->arch.sw);
+ do {
+ if (unw_unwind(&info) < 0) {
+ kdb_printf("Failed to unwind\n");
+ return 0;
+ }
+ unw_get_sp(&info, &sp);
+ } while (sp <= (unsigned long) kdb_current_regs);
+ unw_get_bsp(&info, (unsigned long *) &bsp);
+ unw_get_cfm(&info, &cfm);
+
+ if (!bsp) {
+ kdb_printf("Unable to display Current Stack Frame\n");
+ return 0;
+ }
+
+ sof = (cfm & 0x7f);
+
+ if (regno) {
+ if ((unsigned) regno - 32 >= sof)
+ return 0;
+ bsp = ia64_rse_skip_regs(bsp, regno - 32);
+ old_fs = set_fs(KERNEL_DS);
+ ubsp = (unsigned long __user *) bsp;
+ get_user(val, ubsp);
+ set_fs(old_fs);
+ *contents = val;
+ return 1;
+ }
+
+ old_fs = set_fs(KERNEL_DS);
+ for (i = 0; i < sof; ++i) {
+ ubsp = (unsigned long __user *) bsp;
+ get_user(val, ubsp);
+ kdb_printf(" r%lu: %016lx ", 32 + i, val);
+ if (!((i + 1) % 3))
+ kdb_printf("\n");
+ bsp = ia64_rse_skip_regs(bsp, 1);
+ }
+ kdb_printf("\n");
+ set_fs(old_fs);
+
+ return 0 ;
+}
+
+/*
+ * kdba_getregcontents
+ *
+ * Return the contents of the register specified by the
+ * input string argument. Return an error if the string
+ * does not match a machine register.
+ *
+ * The following pseudo register names are supported:
+ * ®s - Prints address of exception frame
+ * kesp - Prints kernel stack pointer at time of fault
+ * sstk - Prints switch stack for ia64
+ * %<regname> - Uses the value of the registers at the
+ * last time the user process entered kernel
+ * mode, instead of the registers at the time
+ * kdb was entered.
+ *
+ * Parameters:
+ * regname Pointer to string naming register
+ * regs Pointer to structure containing registers.
+ * Outputs:
+ * *contents Pointer to unsigned long to recieve register contents
+ * Returns:
+ * 0 Success
+ * KDB_BADREG Invalid register name
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ * Note that this function is really machine independent. The kdb
+ * register list is not, however.
+ */
+
+static struct kdbregs {
+ char *reg_name;
+ size_t reg_offset;
+} kdbreglist[] = {
+ { "psr", offsetof(struct pt_regs, cr_ipsr) },
+ { "ifs", offsetof(struct pt_regs, cr_ifs) },
+ { "ip", offsetof(struct pt_regs, cr_iip) },
+
+ { "unat", offsetof(struct pt_regs, ar_unat) },
+ { "pfs", offsetof(struct pt_regs, ar_pfs) },
+ { "rsc", offsetof(struct pt_regs, ar_rsc) },
+
+ { "rnat", offsetof(struct pt_regs, ar_rnat) },
+ { "bsps", offsetof(struct pt_regs, ar_bspstore) },
+ { "pr", offsetof(struct pt_regs, pr) },
+
+ { "ldrs", offsetof(struct pt_regs, loadrs) },
+ { "ccv", offsetof(struct pt_regs, ar_ccv) },
+ { "fpsr", offsetof(struct pt_regs, ar_fpsr) },
+
+ { "b0", offsetof(struct pt_regs, b0) },
+ { "b6", offsetof(struct pt_regs, b6) },
+ { "b7", offsetof(struct pt_regs, b7) },
+
+ { "r1",offsetof(struct pt_regs, r1) },
+ { "r2",offsetof(struct pt_regs, r2) },
+ { "r3",offsetof(struct pt_regs, r3) },
+
+ { "r8",offsetof(struct pt_regs, r8) },
+ { "r9",offsetof(struct pt_regs, r9) },
+ { "r10",offsetof(struct pt_regs, r10) },
+
+ { "r11",offsetof(struct pt_regs, r11) },
+ { "r12",offsetof(struct pt_regs, r12) },
+ { "r13",offsetof(struct pt_regs, r13) },
+
+ { "r14",offsetof(struct pt_regs, r14) },
+ { "r15",offsetof(struct pt_regs, r15) },
+ { "r16",offsetof(struct pt_regs, r16) },
+
+ { "r17",offsetof(struct pt_regs, r17) },
+ { "r18",offsetof(struct pt_regs, r18) },
+ { "r19",offsetof(struct pt_regs, r19) },
+
+ { "r20",offsetof(struct pt_regs, r20) },
+ { "r21",offsetof(struct pt_regs, r21) },
+ { "r22",offsetof(struct pt_regs, r22) },
+
+ { "r23",offsetof(struct pt_regs, r23) },
+ { "r24",offsetof(struct pt_regs, r24) },
+ { "r25",offsetof(struct pt_regs, r25) },
+
+ { "r26",offsetof(struct pt_regs, r26) },
+ { "r27",offsetof(struct pt_regs, r27) },
+ { "r28",offsetof(struct pt_regs, r28) },
+
+ { "r29",offsetof(struct pt_regs, r29) },
+ { "r30",offsetof(struct pt_regs, r30) },
+ { "r31",offsetof(struct pt_regs, r31) },
+
+};
+
+static const int nkdbreglist = sizeof(kdbreglist) / sizeof(struct kdbregs);
+
+int
+kdba_getregcontents(const char *regname, struct pt_regs *regs, unsigned long *contents)
+{
+ int i;
+
+ if (strcmp(regname, "isr") == 0) {
+ fault_regs_t fr ;
+ get_fault_regs(&fr) ;
+ *contents = fr.isr ;
+ return 0 ;
+ }
+
+ if (!regs) {
+ kdb_printf("%s: pt_regs not available, use bt* or pid to select a different task\n", __FUNCTION__);
+ return KDB_BADREG;
+ }
+
+ if (strcmp(regname, "®s") == 0) {
+ *contents = (unsigned long)regs;
+ return 0;
+ }
+
+ if (strcmp(regname, "sstk") == 0) {
+ *contents = (unsigned long)getprsregs(regs) ;
+ return 0;
+ }
+
+ if (strcmp(regname, "ksp") == 0) {
+ *contents = (unsigned long) (regs + 1);
+ return 0;
+ }
+
+ for (i=0; i<nkdbreglist; i++) {
+ if (strstr(kdbreglist[i].reg_name, regname))
+ break;
+ }
+
+ if (i == nkdbreglist) {
+ /* Lets check the rse maybe */
+ if (regname[0] == 'r')
+ if (show_cur_stack_frame(simple_strtoul(regname+1, NULL, 0), contents))
+ return 0 ;
+ return KDB_BADREG;
+ }
+
+ *contents = *(unsigned long *)((unsigned long)regs +
+ kdbreglist[i].reg_offset);
+
+ return 0;
+}
+
+/*
+ * kdba_setregcontents
+ *
+ * Set the contents of the register specified by the
+ * input string argument. Return an error if the string
+ * does not match a machine register.
+ *
+ * Supports modification of user-mode registers via
+ * %<register-name>
+ *
+ * Parameters:
+ * regname Pointer to string naming register
+ * regs Pointer to structure containing registers.
+ * contents Unsigned long containing new register contents
+ * Outputs:
+ * Returns:
+ * 0 Success
+ * KDB_BADREG Invalid register name
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+int
+kdba_setregcontents(const char *regname,
+ struct pt_regs *regs,
+ unsigned long contents)
+{
+ int i, ret = 0, fixed = 0;
+ char *endp;
+ unsigned long regno;
+
+ if (regname[0] == '%') {
+ regname++;
+ regs = (struct pt_regs *)
+ (kdb_current_task->thread.ksp - sizeof(struct pt_regs));
+ }
+
+ if (!regs) {
+ kdb_printf("%s: pt_regs not available, use bt* or pid to select a different task\n", __FUNCTION__);
+ return KDB_BADREG;
+ }
+
+ /* fixed registers */
+ for (i=0; i<nkdbreglist; i++) {
+ if (strnicmp(kdbreglist[i].reg_name,
+ regname,
+ strlen(regname)) == 0) {
+ fixed = 1;
+ break;
+ }
+ }
+
+ /* stacked registers */
+ if (!fixed) {
+ regno = (simple_strtoul(®name[1], &endp, 10));
+ if ((regname[0] == 'r') && regno > (unsigned long)31) {
+ ret = change_cur_stack_frame(regno, &contents);
+ if(!ret) return 0;
+ }
+ }
+
+ if ((i == nkdbreglist)
+ || (strlen(kdbreglist[i].reg_name) != strlen(regname))
+ || ret) {
+ return KDB_BADREG;
+ }
+
+ /* just in case of "standard" register */
+ *(unsigned long *)((unsigned long)regs + kdbreglist[i].reg_offset) =
+ contents;
+
+ return 0;
+}
+
+/*
+ * kdba_dumpregs
+ *
+ * Dump the specified register set to the display.
+ *
+ * Parameters:
+ * regs Pointer to structure containing registers.
+ * type Character string identifying register set to dump
+ * extra string further identifying register (optional)
+ * Outputs:
+ * Returns:
+ * 0 Success
+ * Locking:
+ * None.
+ * Remarks:
+ * This function will dump the general register set if the type
+ * argument is NULL (struct pt_regs). The alternate register
+ * set types supported by this function:
+ *
+ * d Debug registers
+ * c Control registers
+ * u User registers at most recent entry to kernel
+ * i Interrupt registers -- same as "irr" command
+ * Following not yet implemented:
+ * m Model Specific Registers (extra defines register #)
+ * r Memory Type Range Registers (extra defines register)
+ *
+ * For now, all registers are covered as follows:
+ *
+ * rd - dumps all regs
+ * rd %isr - current interrupt status reg, read freshly
+ * rd s - valid stacked regs
+ * rd %sstk - gets switch stack addr. dump memory and search
+ * rd d - debug regs, may not be too useful
+ * rd k - dump kernel regs
+ *
+ * ARs TB Done
+ * OTHERS TB Decided ??
+ *
+ * Intel wish list
+ * These will be implemented later - Srinivasa
+ *
+ * type action
+ * ---- ------
+ * g dump all General static registers
+ * s dump all general Stacked registers
+ * f dump all Floating Point registers
+ * p dump all Predicate registers
+ * b dump all Branch registers
+ * a dump all Application registers
+ * c dump all Control registers
+ *
+ */
+
+int
+kdba_dumpregs(struct pt_regs *regs,
+ const char *type,
+ const char *extra)
+
+{
+ int i;
+ int count = 0;
+
+ if (type
+ && (type[0] == 'u')) {
+ type = NULL;
+ regs = (struct pt_regs *)
+ (kdb_current_task->thread.ksp - sizeof(struct pt_regs));
+ }
+
+ if (type == NULL) {
+ if (!regs) {
+ kdb_printf("%s: pt_regs not available, use bt* or pid to select a different task\n", __FUNCTION__);
+ return KDB_BADREG;
+ }
+ for (i=0; i<nkdbreglist; i++) {
+ kdb_printf("%4s: 0x%16.16lx ",
+ kdbreglist[i].reg_name,
+ *(unsigned long *)((unsigned long)regs +
+ kdbreglist[i].reg_offset));
+
+ if ((++count % 3) == 0)
+ kdb_printf("\n");
+ }
+
+ kdb_printf("®s = %p\n", (void *)regs);
+
+ return 0;
+ }
+
+ switch (type[0]) {
+ case 'd':
+ {
+ for(i=0; i<8; i+=2) {
+ kdb_printf("idr%d: 0x%16.16lx idr%d: 0x%16.16lx\n", i,
+ kdba_getdr(i), i+1, kdba_getdr(i+1));
+
+ }
+ return 0;
+ }
+ case 'i':
+ kdba_show_intregs();
+ break;
+ case 'k':
+ show_kernel_regs();
+ break;
+ case 'm':
+ break;
+ case 'r':
+ break;
+
+ case 's':
+ {
+ if (!regs) {
+ kdb_printf("%s: pt_regs not available, use bt* or pid to select a different task\n", __FUNCTION__);
+ return KDB_BADREG;
+ }
+ show_cur_stack_frame(0, NULL) ;
+
+ return 0 ;
+ }
+
+ case '%':
+ {
+ unsigned long contents ;
+
+ if (!kdba_getregcontents(type+1, regs, &contents))
+ kdb_printf("%s = 0x%16.16lx\n", type+1, contents) ;
+ else
+ kdb_printf("diag: Invalid register %s\n", type+1) ;
+
+ return 0 ;
+ }
+
+ default:
+ return KDB_BADREG;
+ }
+
+ /* NOTREACHED */
+ return 0;
+}
+
+kdb_machreg_t
+kdba_getpc(struct pt_regs *regs)
+{
+ return regs ? regs->cr_iip + ia64_psr(regs)->ri : 0;
+}
+
+int
+kdba_setpc(struct pt_regs *regs, kdb_machreg_t newpc)
+{
+ if (KDB_NULL_REGS(regs))
+ return KDB_BADREG;
+ regs->cr_iip = newpc & ~0xf;
+ ia64_psr(regs)->ri = newpc & 0x3;
+ KDB_STATE_SET(IP_ADJUSTED);
+ return 0;
+}
+
+struct kdba_main_loop_data {
+ kdb_reason_t reason;
+ kdb_reason_t reason2;
+ int error;
+ kdb_dbtrap_t db_result;
+ struct pt_regs *regs;
+ int ret;
+};
+
+/*
+ * do_kdba_main_loop
+ *
+ * Invoked from kdba_main_loop via unw_init_running() after that routine
+ * has pushed a struct switch_stack.
+ *
+ * Inputs:
+ * info Unwind information.
+ * data kdb data passed as void * to unw_init_running.
+ * Returns:
+ * none (unw_init_running requires void). vdata->ret is set to
+ * 0 KDB was invoked for an event which it wasn't responsible
+ * 1 KDB handled the event for which it was invoked.
+ * Outputs:
+ * none
+ * Locking:
+ * None.
+ * Remarks:
+ * unw_init_running() creates struct switch_stack then struct
+ * unw_frame_info. We get the address of the info so step over
+ * that to get switch_stack. Just hope that unw_init_running
+ * does not change its stack usage. unw_init_running adds padding
+ * to put switch_stack on a 16 byte boundary.
+ */
+
+static KDBA_UNWIND_HANDLER(do_kdba_main_loop, struct kdba_main_loop_data, data->reason,
+ data->ret = kdb_main_loop(data->reason, data->reason2, data->error, data->db_result, data->regs));
+
+/*
+ * kdba_main_loop
+ *
+ * Do any architecture specific set up before entering the main kdb loop.
+ * The primary function of this routine is to make all processes look the
+ * same to kdb, kdb must be able to list a process without worrying if the
+ * process is running or blocked, so make all processes look as though they
+ * are blocked.
+ *
+ * Inputs:
+ * reason The reason KDB was invoked
+ * error The hardware-defined error code
+ * error2 kdb's current reason code. Initially error but can change
+ * acording to kdb state.
+ * db_result Result from break or debug point.
+ * regs The exception frame at time of fault/breakpoint. If reason
+ * is SILENT or CPU_UP then regs is NULL, otherwise it should
+ * always be valid.
+ * Returns:
+ * 0 KDB was invoked for an event which it wasn't responsible
+ * 1 KDB handled the event for which it was invoked.
+ * Outputs:
+ * Builds a switch_stack structure before calling the main loop.
+ * Locking:
+ * None.
+ * Remarks:
+ * none.
+ */
+
+int
+kdba_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error,
+ kdb_dbtrap_t db_result, struct pt_regs *regs)
+{
+ struct kdba_main_loop_data data;
+ KDB_DEBUG_STATE("kdba_main_loop", reason);
+ data.reason = reason;
+ data.reason2 = reason2;
+ data.error = error;
+ data.db_result = db_result;
+ data.regs = regs;
+ unw_init_running(do_kdba_main_loop, &data);
+ return(data.ret);
+}
+
+void
+kdba_disableint(kdb_intstate_t *state)
+{
+ unsigned long *fp = (unsigned long *)state;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ *fp = flags;
+}
+
+void
+kdba_restoreint(kdb_intstate_t *state)
+{
+ unsigned long flags = *(unsigned long *)state;
+ local_irq_restore(flags);
+}
+
+void
+kdba_setsinglestep(struct pt_regs *regs)
+{
+ if (KDB_NULL_REGS(regs))
+ return;
+ ia64_psr(regs)->ss = 1;
+}
+
+void
+kdba_clearsinglestep(struct pt_regs *regs)
+{
+ if (KDB_NULL_REGS(regs))
+ return;
+ ia64_psr(regs)->ss = 0;
+}
+
+/*
+ * kdb_tpa
+ *
+ * Virtual to Physical address translation command.
+ *
+ * tpa <addr>
+ *
+ * Parameters:
+ * argc Count of arguments in argv
+ * argv Space delimited command line arguments
+ * envp Environment value
+ * regs Exception frame at entry to kernel debugger
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero for success, a kdb diagnostic if failure.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+#define __xtpa(x) ({ia64_va _v; asm("tpa %0=%1" : "=r"(_v.l) : "r"(x)); _v.l;})
+static int
+kdba_tpa(int argc, const char **argv, const char **envp, struct pt_regs* regs)
+{
+ kdb_machreg_t addr;
+ int diag;
+ long offset = 0;
+ int nextarg;
+ char c;
+
+ nextarg = 1;
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
+ if (diag)
+ return diag;
+ if (kdb_getarea(c, addr))
+ return(0);
+ kdb_printf("vaddr: 0x%lx , paddr: 0x%lx\n", addr, __xtpa(addr));
+ return(0);
+}
+#if defined(CONFIG_NUMA)
+static int
+kdba_tpav(int argc, const char **argv, const char **envp, struct pt_regs* regs)
+{
+ kdb_machreg_t addr, end, paddr;
+ int diag;
+ long offset = 0;
+ int nextarg, nid, nid_old;
+ char c;
+
+ nextarg = 1;
+ if (argc != 2)
+ return KDB_ARGCOUNT;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
+ if (diag)
+ return diag;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &end, &offset, NULL, regs);
+ if (diag)
+ return diag;
+ if (kdb_getarea(c, addr))
+ return(0);
+ if (kdb_getarea(c, end))
+ return(0);
+ paddr=__xtpa(addr);
+ nid = paddr_to_nid(paddr);
+ kdb_printf("begin: 0x%lx , paddr: 0x%lx , nid: %d\n", addr, __xtpa(addr), nid);
+ for(;addr<end; addr += PAGE_SIZE) {
+ nid_old=nid;
+ paddr =__xtpa(addr);
+ nid = paddr_to_nid(paddr);
+ if (nid != nid_old)
+ kdb_printf("NOT on same NODE: addr: 0x%lx , paddr: 0x%lx , nid: %d\n", addr, paddr, nid);
+ }
+ paddr=__xtpa(end);
+ nid=paddr_to_nid(end);
+ kdb_printf("end: 0x%lx , paddr: 0x%lx , nid: %d\n", end, paddr, nid);
+ return(0);
+}
+#endif
+
+#if defined(CONFIG_SMP)
+/*
+ * kdba_sendinit
+ *
+ * This function implements the 'init' command.
+ *
+ * init [<cpunum>]
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ */
+
+static int
+kdba_sendinit(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ unsigned long cpunum;
+ int diag;
+
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+
+ diag = kdbgetularg(argv[1], &cpunum);
+ if (diag)
+ return diag;
+
+ if (cpunum >= NR_CPUS || !cpu_online(cpunum))
+ return KDB_BADCPUNUM;
+
+ platform_send_ipi(cpunum, 0, IA64_IPI_DM_INIT, 0);
+ return 0;
+}
+
+/* Invoked once from kdb_wait_for_cpus when waiting for cpus. For those cpus
+ * that have not responded to the normal KDB interrupt yet, hit them with an
+ * INIT event.
+ */
+void
+kdba_wait_for_cpus(void)
+{
+ int c;
+ if (KDB_FLAG(CATASTROPHIC))
+ return;
+ kdb_printf(" Sending INIT to cpus that have not responded yet\n");
+ for_each_online_cpu(c)
+ if (kdb_running_process[c].seqno < kdb_seqno - 1)
+ platform_send_ipi(c, 0, IA64_IPI_DM_INIT, 0);
+}
+
+#endif /* CONFIG_SMP */
+
+/* This code is sensitive to the layout of the MCA/INIT stack (see mca_asm.h)
+ * and to the stack layout that ia64_mca_modify_original_stack() creates when
+ * it makes the original task look blocked.
+ */
+static void
+kdba_handlers_modify(struct task_struct *p, int cpu)
+{
+ struct kdb_running_process *work, *save;
+ work = kdb_running_process + cpu;
+ save = kdb_running_process_save + cpu;
+ *work = *save;
+ if (!kdba_show_handlers && REGION_NUMBER(p) >= RGN_GATE &&
+ (p->thread_info->flags & _TIF_MCA_INIT)) {
+ struct ia64_sal_os_state *sos = (struct ia64_sal_os_state *)
+ ((unsigned long)save->p + MCA_SOS_OFFSET);
+ char *p;
+ if (!sos->prev_task)
+ return;
+ work->p = sos->prev_task;
+ p = (char *)sos->prev_task->thread.ksp;
+ p += 16;
+ work->arch.sw = (struct switch_stack *)p;
+ p += sizeof(struct switch_stack);
+ work->regs = (struct pt_regs *)p;
+ work->irq_depth = 2; /* any value >1 will do */
+ }
+}
+
+/* Turn the display of the MCA/INIT handlers on or off, or display the status
+ * of the MCA/INIT handlers.
+ */
+static int
+kdba_handlers(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int cpu;
+ struct kdb_running_process *krp;
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+ if (strcmp(argv[1], "show") == 0)
+ kdba_show_handlers = 1;
+ else if (strcmp(argv[1], "hide") == 0)
+ kdba_show_handlers = 0;
+ else if (strcmp(argv[1], "status") != 0) {
+ kdb_printf("handlers <show|hide|status>\n");
+ return 0;
+ }
+ for (cpu = 0, krp = kdb_running_process_save; cpu < NR_CPUS; ++cpu, ++krp) {
+ if (krp->p)
+ kdba_handlers_modify(krp->p, cpu);
+ }
+ if (strcmp(argv[1], "status") != 0)
+ return 0;
+ kdb_printf("handlers status is %s\n", kdba_show_handlers ? "'show'" : "'hide'");
+ kdb_printf(" cpu handler task command original task command\n");
+ for (cpu = 0, krp = kdb_running_process_save; cpu < NR_CPUS; ++cpu, ++krp) {
+ struct task_struct *p = krp->p;
+ if (!p)
+ continue;
+ kdb_printf("%4d", cpu);
+ if (p->thread_info->flags & _TIF_MCA_INIT) {
+ struct ia64_sal_os_state *sos;
+ kdb_printf(" " kdb_machreg_fmt0 " %-*s ",
+ (unsigned long)p, (int)sizeof(p->comm), p->comm);
+ sos = (struct ia64_sal_os_state *)((unsigned long)p + MCA_SOS_OFFSET);
+ p = sos->prev_task;
+ } else
+ kdb_printf("%*s", (int)(1+2+16+1+sizeof(p->comm)+2), " ");
+ if (p)
+ kdb_printf(" " kdb_machreg_fmt0 " %-*s",
+ (unsigned long)p, (int)sizeof(p->comm), p->comm);
+ kdb_printf("\n");
+ }
+ return 0;
+}
+
+/* Executed once on each cpu at startup. */
+void
+kdba_cpu_up(void)
+{
+}
+
+/*
+ * kdba_init
+ *
+ * Architecture specific initialization.
+ *
+ * Parameters:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ * None.
+ */
+
+void
+kdba_init(void)
+{
+ kdb_running_process_save = kzalloc(
+ sizeof(*kdb_running_process_save) * NR_CPUS, GFP_KERNEL);
+ BUG_ON(!kdb_running_process_save);
+ kdb_register("irr", kdba_sir, "", "Show interrupt registers", 0);
+ kdb_register("itm", kdba_itm, "", "Set new ITM value", 0);
+#if defined(CONFIG_SMP)
+ kdb_register("init", kdba_sendinit, "", "Send INIT to cpu", 0);
+#endif
+ kdb_register("pt_regs", kdba_pt_regs, "address", "Format struct pt_regs", 0);
+ kdb_register("switch_stack", kdba_switch_stack, "address", "Format struct switch_stack", 0);
+ kdb_register("minstate", kdba_minstate, "address", "Format PAL minstate", 0);
+ kdb_register("tpa", kdba_tpa, "<vaddr>", "Translate virtual to physical address", 0);
+#if defined(CONFIG_NUMA)
+ kdb_register("tpav", kdba_tpav, "<begin addr> <end addr>", "Verify that physical addresses corresponding to virtual addresses from <begin addr> to <end addr> are in same node", 0);
+#endif
+ kdb_register("stackdepth", kdba_stackdepth, "[percentage]", "Print processes using >= stack percentage", 0);
+ kdb_register("cpuinfo", kdba_cpuinfo, "[cpu]", "Print struct cpuinfo_ia64", 0);
+ kdb_register("handlers", kdba_handlers, "<show|hide|status>", "Control the display of MCA/INIT handlers", 0);
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ kdba_serial_console = KDBA_SC_STANDARD;
+#endif
+#ifdef CONFIG_SERIAL_SGI_L1_CONSOLE
+ if (ia64_platform_is("sn2"))
+ kdba_serial_console = KDBA_SC_SGI_L1;
+#endif
+ return;
+}
+
+/*
+ * kdba_adjust_ip
+ *
+ * Architecture specific adjustment of instruction pointer before leaving
+ * kdb.
+ *
+ * Parameters:
+ * reason The reason KDB was invoked
+ * error The hardware-defined error code
+ * regs The exception frame at time of fault/breakpoint. If reason
+ * is SILENT or CPU_UP then regs is NULL, otherwise it should
+ * always be valid.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ * On IA64, KDB_ENTER() and KDB_ENTER_SLAVE() use break which is a fault,
+ * not a trap. The instruction pointer must be stepped before leaving
+ * kdb, otherwise we get a loop.
+ */
+
+void
+kdba_adjust_ip(kdb_reason_t reason, int error, struct pt_regs *regs)
+{
+ if ((reason == KDB_REASON_ENTER || reason == KDB_REASON_ENTER_SLAVE) &&
+ !KDB_STATE(IP_ADJUSTED)) {
+ if (KDB_NULL_REGS(regs))
+ return;
+ if (ia64_psr(regs)->ri < 2)
+ kdba_setpc(regs, regs->cr_iip + ia64_psr(regs)->ri + 1);
+ else
+ kdba_setpc(regs, regs->cr_iip + 16);
+ }
+}
+
+void
+kdba_save_running(struct kdba_running_process *k, struct pt_regs *regs)
+{
+ struct kdb_running_process *work, *save;
+ int cpu = smp_processor_id();
+ work = kdb_running_process + cpu;
+ save = kdb_running_process_save + cpu;
+ *save = *work;
+ if (!regs)
+ return;
+ kdba_handlers_modify((struct task_struct *)regs->r13, cpu);
+}
+
+void
+kdba_unsave_running(struct kdba_running_process *k, struct pt_regs *regs)
+{
+ memset(kdb_running_process_save + smp_processor_id(), 0,
+ sizeof(*kdb_running_process_save));
+}
+
+void
+kdba_set_current_task(const struct task_struct *p)
+{
+ int cpu = kdb_process_cpu(p);
+ struct kdb_running_process *work, *save;
+ work = kdb_running_process + cpu;
+ save = kdb_running_process_save + cpu;
+ kdb_current_task = p;
+ if (task_curr(p)) {
+ kdb_current_regs = work->regs;
+ return;
+ }
+ kdb_current_regs = NULL;
+ /* For most blocked tasks we cannot get the pt_regs without doing an
+ * unwind, which is not worth doing. For tasks interrupted by
+ * MCA/INIT, when the user is not working on the handlers, we must use
+ * the registers at the time of interrupt.
+ */
+ if (work->p == save->p || work->p != p)
+ return;
+ kdb_current_regs = (struct pt_regs *)(work->p->thread.ksp + 16 +
+ sizeof(struct switch_stack));
+}
+
+int
+kdba_putarea_size(unsigned long to_xxx, void *from, size_t size)
+{
+ mm_segment_t oldfs = get_fs();
+ int r;
+
+ if (to_xxx >> 61 <= 4) {
+ return kdb_putuserarea_size(to_xxx, from, size);
+ }
+
+ set_fs(KERNEL_DS);
+ r = __copy_to_user_inatomic((void __user *)to_xxx, from, size);
+ set_fs(oldfs);
+ return r;
+}
+
+int
+kdba_getarea_size(void *to, unsigned long from_xxx, size_t size)
+{
+ mm_segment_t oldfs = get_fs();
+ int r;
+
+ if (from_xxx >> 61 <= 4)
+ return kdb_getuserarea_size(to, from_xxx, size);
+
+ set_fs(KERNEL_DS);
+ r = __copy_from_user_inatomic(to, (void __user *)from_xxx, size);
+ set_fs(oldfs);
+ return r;
+}
+
+int
+kdba_verify_rw(unsigned long addr, size_t size)
+{
+ unsigned char data[(__force size_t) size];
+ return(kdba_getarea_size(data, addr, size) || kdba_putarea_size(addr, data, size));
+}
#include <linux/workqueue.h>
#include <linux/cpumask.h>
#include <linux/cpu.h>
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h> /* for switch state wrappers */
+#endif /* CONFIG_KDB */
#include <asm/delay.h>
#include <asm/kdebug.h>
*/
ia64_sal_mc_rendez();
+#ifdef CONFIG_KDB
+ /* We get here when the MCA monarch has entered and has woken up the
+ * slaves. Do a KDB rendezvous to meet the monarch cpu.
+ */
+ KDB_ENTER_SLAVE();
+#endif
+
if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", regs, (long)&nd, 0, 0)
== NOTIFY_STOP)
ia64_mca_spin(__FUNCTION__);
== NOTIFY_STOP)
ia64_mca_spin(__FUNCTION__);
+#ifdef CONFIG_KDB
+ kdb_save_flags();
+ KDB_FLAG_CLEAR(CATASTROPHIC);
+ KDB_FLAG_CLEAR(RECOVERY);
+ if (recover)
+ KDB_FLAG_SET(RECOVERY);
+ else
+ KDB_FLAG_SET(CATASTROPHIC);
+ KDB_FLAG_SET(NOIPI); /* do not send IPI for MCA/INIT events */
+ KDB_ENTER();
+ kdb_restore_flags();
+#endif /* CONFIG_KDB */
+
set_curr_task(cpu, previous_current);
monarch_cpu = -1;
}
}
}
printk("\n\n");
+#ifdef CONFIG_KDB
+ KDB_FLAG_SET(NOIPI); /* do not send IPI for MCA/INIT events */
+ KDB_ENTER();
+ KDB_FLAG_CLEAR(NOIPI);
+#else /* !CONFIG_KDB */
if (read_trylock(&tasklist_lock)) {
do_each_thread (g, t) {
printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm);
} while_each_thread (g, t);
read_unlock(&tasklist_lock);
}
+#endif /* CONFIG_KDB */
/* FIXME: This will not restore zapped printk locks. */
RESTORE_LOGLEVEL(console_loglevel);
return NOTIFY_DONE;
int cpu = smp_processor_id();
struct ia64_mca_notify_die nd =
{ .sos = sos, .monarch_cpu = &monarch_cpu };
+#ifdef CONFIG_KDB
+ int kdba_recalcitrant = 0;
+ /* kdba_wait_for_cpus() sends INIT to recalcitrant cpus which ends up
+ * calling this routine. If KDB is waiting for the IPI to be processed
+ * then treat all INIT events as slaves, kdb_initial_cpu is the
+ * monarch.
+ */
+ if (KDB_STATE(WAIT_IPI)) {
+ monarch_cpu = kdb_initial_cpu;
+ sos->monarch = 0;
+ KDB_STATE_CLEAR(WAIT_IPI);
+ kdba_recalcitrant = 1;
+ }
+#endif /* CONFIG_KDB */
(void) notify_die(DIE_INIT_ENTER, "INIT", regs, (long)&nd, 0, 0);
ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT;
while (monarch_cpu == -1)
cpu_relax(); /* spin until monarch enters */
+#ifdef CONFIG_KDB
+ KDB_ENTER_SLAVE();
+ if (kdba_recalcitrant)
+ monarch_cpu = -1;
+#endif /* CONFIG_KDB */
if (notify_die(DIE_INIT_SLAVE_ENTER, "INIT", regs, (long)&nd, 0, 0)
== NOTIFY_STOP)
ia64_mca_spin(__FUNCTION__);
printk(KERN_INFO "Increasing MCA rendezvous timeout from "
"%ld to %ld milliseconds\n", timeout, isrv.v0);
timeout = isrv.v0;
+#ifdef CONFIG_KDB
+ /* kdb must wait long enough for the MCA timeout to trip
+ * and process. The MCA timeout is in milliseconds.
+ */
+ kdb_wait_for_cpus_secs = max(kdb_wait_for_cpus_secs, (int)(timeout/1000) + 10);
+#endif /* CONFIG_KDB */
(void) notify_die(DIE_MCA_NEW_TIMEOUT, "MCA", NULL, timeout, 0, 0);
continue;
}
#include <asm/current.h>
#include <asm/delay.h>
#include <asm/machvec.h>
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#endif /* CONFIG_KDB */
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/page.h>
#define IPI_CALL_FUNC 0
#define IPI_CPU_STOP 1
+#ifdef CONFIG_KDB
+#define IPI_KDB_INTERRUPT 2
+#endif /* CONFIG_KDB */
#define IPI_KDUMP_CPU_STOP 3
/* This needs to be cacheline aligned because it is written to by *other* CPUs. */
case IPI_KDUMP_CPU_STOP:
unw_init_running(kdump_cpu_freeze, NULL);
break;
+#endif
+#ifdef CONFIG_KDB
+ case IPI_KDB_INTERRUPT:
+ if (!kdb_ipi(regs, NULL))
+ printk(KERN_ERR "kdb_ipi() rejected IPI_KDB_INTERRUPT\n");
+ break;
#endif
default:
printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", this_cpu, which);
{
return -EINVAL;
}
+
+#if defined(CONFIG_KDB)
+void
+smp_kdb_stop(void)
+{
+ if (!KDB_FLAG(NOIPI)) {
+ /* cpumask_t cpu_mask = cpu_online_map;
+ cpu_clear(smp_processor_id(), cpu_mask); */
+ send_IPI_allbutself(IPI_KDB_INTERRUPT);
+ }
+}
+#endif /* CONFIG_KDB */
+
#include <linux/tty.h>
#include <linux/vt_kern.h> /* For unblank_screen() */
#include <linux/module.h> /* for EXPORT_SYMBOL */
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#endif /* CONFIG_KDB */
#include <linux/hardirq.h>
#include <linux/kprobes.h>
#include <linux/delay.h> /* for ssleep() */
die.lock_owner = -1;
spin_unlock_irq(&die.lock);
+#ifdef CONFIG_KDB
+ (void)kdb(KDB_REASON_OOPS, err, regs);
+#endif /* CONFIG_KDB */
+
if (panic_on_oops)
panic("Fatal exception");
if (break_num < 0x80000) {
sig = SIGILL; code = __ILL_BREAK;
} else {
+#ifdef CONFIG_KDB
+ if (break_num == KDB_BREAK_ENTER &&
+ kdb(KDB_REASON_ENTER, break_num, regs))
+ return; /* kdb handled it */
+ if (break_num == KDB_BREAK_ENTER_SLAVE &&
+ kdb(KDB_REASON_ENTER_SLAVE, break_num, regs))
+ return; /* kdb handled it */
+ if (break_num == KDB_BREAK_BREAK &&
+ kdb(KDB_REASON_BREAK, break_num, regs))
+ return; /* kdb handled it */
+#endif /* CONFIG_KDB */
if (notify_die(DIE_BREAK, "bad break", regs, break_num, TRAP_BRKPT, SIGTRAP)
== NOTIFY_STOP)
return;
if (notify_die(DIE_FAULT, "ia64_fault", ®s, vector, siginfo.si_code, SIGTRAP)
== NOTIFY_STOP)
return;
+#ifdef CONFIG_KDB
+ if (!user_mode(®s) && kdb(KDB_REASON_DEBUG, vector, ®s))
+ return; /* kdb handled this */
+#endif /* CONFIG_KDB */
siginfo.si_signo = SIGTRAP;
siginfo.si_errno = 0;
siginfo.si_addr = (void __user *) ifa;
#ifdef UNW_DEBUG
static unsigned int unw_debug_level = UNW_DEBUG;
-# define UNW_DEBUG_ON(n) unw_debug_level >= n
- /* Do not code a printk level, not all debug lines end in newline */
-# define UNW_DPRINT(n, ...) if (UNW_DEBUG_ON(n)) printk(__VA_ARGS__)
+# ifdef CONFIG_KDB
+# include <linux/kdb.h>
+# include <linux/kdbprivate.h>
+# define UNW_DEBUG_ON(n) (unw_debug_level >= n && !KDB_IS_RUNNING())
+# define UNW_DPRINT(n, ...) if (UNW_DEBUG_ON(n)) kdb_printf(__VA_ARGS__)
+# else /* !CONFIG_KDB */
+# define UNW_DEBUG_ON(n) unw_debug_level >= n
+ /* Do not code a printk level, not all debug lines end in newline */
+# define UNW_DPRINT(n, ...) if (UNW_DEBUG_ON(n)) printk(__VA_ARGS__)
+# endif /* CONFIG_KDB */
+# undef inline
# define inline
#else /* !UNW_DEBUG */
# define UNW_DEBUG_ON(n) 0
# define UNW_DPRINT(n, ...)
#endif /* UNW_DEBUG */
+#define UNW_KMALLOC(s, f) kmalloc(s, f)
+#define UNW_KFREE(p) kfree(p)
+
#if UNW_STATS
# define STAT(x...) x
#else
# define STAT(x...)
#endif
-#define alloc_reg_state() kmalloc(sizeof(struct unw_reg_state), GFP_ATOMIC)
-#define free_reg_state(usr) kfree(usr)
-#define alloc_labeled_state() kmalloc(sizeof(struct unw_labeled_state), GFP_ATOMIC)
-#define free_labeled_state(usr) kfree(usr)
+#define alloc_reg_state() UNW_KMALLOC(sizeof(struct unw_reg_state), GFP_ATOMIC)
+#define free_reg_state(usr) UNW_KFREE(usr)
+#define alloc_labeled_state() UNW_KMALLOC(sizeof(struct unw_labeled_state), GFP_ATOMIC)
+#define free_labeled_state(usr) UNW_KFREE(usr)
typedef unsigned long unw_word;
typedef unsigned char unw_hash_index_t;
return NULL;
}
- table = kmalloc(sizeof(*table), GFP_USER);
+ table = UNW_KMALLOC(sizeof(*table), GFP_USER);
if (!table)
return NULL;
write_unlock(&tmp->lock);
}
- kfree(table);
+ UNW_KFREE(table);
}
static int __init
size += 3*8 + 8 + 8*UNW_LENGTH(*(u64 *) (segbase + entry->info_offset));
size += 8; /* reserve space for "end of table" marker */
- unw.gate_table = kmalloc(size, GFP_KERNEL);
+ unw.gate_table = UNW_KMALLOC(size, GFP_KERNEL);
if (!unw.gate_table) {
unw.gate_table_size = 0;
printk(KERN_ERR "%s: unable to create unwind data for gate page!\n", __FUNCTION__);
static int xpc_kdebug_ignore;
+static int xpc_kdebug_entered;
/* systune related variables for /proc/sys directories */
break;
case DIE_KDEBUG_ENTER:
+ xpc_kdebug_entered = 1;
+
/* Should lack of heartbeat be ignored by other partitions? */
if (!xpc_kdebug_ignore) {
break;
break;
case DIE_KDEBUG_LEAVE:
+ xpc_kdebug_entered = 0;
+
/* Is lack of heartbeat being ignored by other partitions? */
if (!xpc_kdebug_ignore) {
break;
}
+int
+xpc_kdebug_force_disengage(void)
+{
+ if (!xpc_kdebug_entered) {
+ /* not being called from kdebug */
+ return 1;
+ }
+
+ xpc_vars->heartbeat_offline = 0;
+ xpc_die_disengage();
+ return 0;
+}
+EXPORT_SYMBOL_GPL(xpc_kdebug_force_disengage);
+
+
int __init
xpc_init(void)
{
/* this partition's reserved page pointers */
struct xpc_rsvd_page *xpc_rsvd_page;
+EXPORT_SYMBOL_GPL(xpc_rsvd_page);
static u64 *xpc_part_nasids;
static u64 *xpc_mach_nasids;
struct xpc_vars *xpc_vars;
+EXPORT_SYMBOL_GPL(xpc_vars);
struct xpc_vars_part *xpc_vars_part;
static int xp_nasid_mask_bytes; /* actual size in bytes of nasid mask */
* another variable.
*/
struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1];
+EXPORT_SYMBOL_GPL(xpc_partitions);
/*
framebuffer memory).
The cmdline option 'xmon' or 'xmon=early' will drop into xmon
very early during boot. 'xmon=on' will just enable the xmon
- debugger hooks. 'xmon=off' will disable the debugger hooks
- if CONFIG_XMON_DEFAULT is set.
+ debugger hooks.
config XMON_DEFAULT
bool "Enable xmon by default"
depends on XMON
help
- xmon is normally disabled unless booted with 'xmon=on'.
- Use 'xmon=off' to disable xmon init during runtime.
+ If you say Y here, the system will invoke xmon when a serious
+ error occurs (unless you booted with 'xmon=off'). If you say N,
+ xmon will be included in the kernel but will not be entered when
+ a serious error occurs, until it has been activated - instead the
+ kernel will print an oops message. Xmon can be activated by
+ "echo 1 >/proc/sys/kernel/xmon" as root, by pressing alt-sysrq-x,
+ or by giving the 'xmon' or 'xmon=early' or 'xmon=on' boot command
+ line options. If in doubt say N.
+
+config KDB
+ bool "KDB"
+ depends on DEBUGGER
+ select KALLSYMS
+ select KALLSYMS_ALL
+ help
+ Include the kdb kernel monitor/debugger.
+ Unless you are intending to debug the kernel, say N here.
+
+config KDB_MODULES
+ bool "Enable additional KDB modules"
+ depends on KDB
+ help
+ Include additional KDB support for viewing buffer heads,
+ pages, inodes, dentrys, vm areas and scsi devices and
+ scsi commands.
+
+config KDB_OFF
+ bool "Turn KDB off by default."
+ depends on KDB
+ help
+ KDB will remain built into the kernel, but will be turned off.
+ "echo 1 > /proc/sys/kernel/kdb" to turn it on.
+
+config KDB_CONTINUE_CATASTROPHIC
+ int "KDB continues after catastrophic errors"
+ depends on KDB
+ default "0"
+ help
+ This integer controls the behaviour of kdb when the kernel gets a
+ catastrophic error, i.e. for a panic, oops, NMI or other watchdog
+ tripping. CONFIG_KDB_CONTINUE_CATASTROPHIC interacts with
+ /proc/sys/kernel/kdb and CONFIG_LKCD_DUMP (if your kernel has the
+ LKCD patch).
+ When KDB is active (/proc/sys/kernel/kdb == 1) and a catastrophic
+ error occurs, nothing extra happens until you type 'go'.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 0 (default). The first time
+ you type 'go', kdb warns you. The second time you type 'go', KDB
+ tries to continue - no guarantees that the kernel is still usable.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 1. KDB tries to continue - no
+ guarantees that the kernel is still usable.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 2. If your kernel has the LKCD
+ patch and LKCD is configured to take a dump then KDB forces a dump.
+ Whether or not a dump is taken, KDB forces a reboot.
+ When KDB is not active (/proc/sys/kernel/kdb == 0) and a catastrophic
+ error occurs, the following steps are automatic, no human
+ intervention is required.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 0 (default) or 1. KDB attempts
+ to continue - no guarantees that the kernel is still usable.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 2. If your kernel has the LKCD
+ patch and LKCD is configured to take a dump then KDB automatically
+ forces a dump. Whether or not a dump is taken, KDB forces a
+ reboot.
+ If you are not sure, say 0.
+
+config KDB_USB
+ bool "Support for USB Keyboard in KDB (OHCI only)"
+ depends on KDB && USB_OHCI_HCD
+ help
+ If you want to use kdb from a OHCI USB keyboard then say Y here.
+ If you say N then kdb can only be used from a PC (AT) keyboard
+ or a serial console.
config IRQSTACKS
bool "Use separate kernel stacks when processing interrupts"
arch/powerpc/platforms/
core-$(CONFIG_MATH_EMULATION) += arch/powerpc/math-emu/
core-$(CONFIG_XMON) += arch/powerpc/xmon/
+core-$(CONFIG_KDB) += arch/powerpc/kdb/
drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
$(BOOT_TARGETS): vmlinux
$(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
+install:
+ $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
+
define archhelp
@echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage.*)'
@echo ' install - Install kernel using'
@echo -n ' Image: $@ '
@if [ -f $@ ]; then echo 'is ready' ; else echo 'not made'; fi
-install: $(CONFIGURE) $(BOOTIMAGE)
- sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)"
+install:
+ sh $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)"
clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.strip)
--- /dev/null
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+#
+
+obj-y := kdba_bt.o kdba_bp.o kdba_id.o kdba_io.o kdbasupport.o
+
+# Warning: running with a minimal-toc means that kdb_setjmp will break
+# due to saving the wrong r30. A solution would be to move it into setjmp.S
+EXTRA_CFLAGS = -mno-minimal-toc
+
+override CFLAGS := $(CFLAGS) -I. -Iarch/powerpc/kdb
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Breakpoint Handling
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/ptrace.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include "privinst.h"
+
+static char *kdba_rwtypes[] = { "Instruction(Register)", "Data Write",
+ "I/O", "Data Access"};
+
+extern void set_all_DABR(unsigned long val);
+
+/*
+ * Table describing processor architecture hardware
+ * breakpoint registers.
+ */
+
+kdbhard_bp_t kdb_hardbreaks[KDB_MAXHARDBPT];
+
+/*
+ * kdba_db_trap
+ *
+ * Perform breakpoint processing upon entry to the
+ * processor debugger fault. Determine and print
+ * the active breakpoint.
+ *
+ * Parameters:
+ * ef Exception frame containing machine register state
+ * error Error number passed to kdb.
+ * Outputs:
+ * None.
+ * Returns:
+ * KDB_DB_BPT Standard instruction or data breakpoint encountered
+ * KDB_DB_SS Single Step fault ('ss' command or end of 'ssb' command)
+ * KDB_DB_SSB Single Step fault, caller should continue ('ssb' command)
+ * KDB_DB_SSBPT Single step over breakpoint
+ * KDB_DB_NOBPT No existing kdb breakpoint matches this debug exception
+ * Locking:
+ * None.
+ * Remarks:
+ * Yup, there be goto's here.
+ *
+ * If multiple processors receive debug exceptions simultaneously,
+ * one may be waiting at the kdb fence in kdb() while the user
+ * issues a 'bc' command to clear the breakpoint the processor
+ * which is waiting has already encountered. If this is the case,
+ * the debug registers will no longer match any entry in the
+ * breakpoint table, and we'll return the value KDB_DB_NOBPT.
+ * This can cause a panic in die_if_kernel(). It is safer to
+ * disable the breakpoint (bd), go until all processors are past
+ * the breakpoint then clear the breakpoint (bc). This code
+ * recognises a breakpoint even when disabled but not when it has
+ * been cleared.
+ *
+ * WARNING: This routine clears the debug state. It should be called
+ * once per debug and the result cached.
+ */
+
+kdb_dbtrap_t
+kdba_db_trap(kdb_eframe_t ef, int error_unused)
+{
+ kdb_machreg_t msr,trap;
+ int rw = 0, reg = 0;
+ int i;
+ kdb_dbtrap_t rv = KDB_DB_BPT;
+ kdb_bp_t *bp;
+ unsigned long primary;
+ unsigned long extended;
+
+ if (KDB_NULL_REGS(ef))
+ return KDB_DB_NOBPT;
+
+ msr = get_msr();
+ trap = ef->trap;
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdb: msr 0x%lx trap 0x%lx\n", msr, trap);
+ if (msr & MSR_SE || ((trap & 0x700) || (trap & 0xd00)))
+ {
+ if (KDB_STATE(SSBPT)) {
+ if (KDB_DEBUG(BP))
+ kdb_printf("ssbpt\n");
+ KDB_STATE_CLEAR(SSBPT);
+ for(i=0,bp=kdb_breakpoints;
+ i < KDB_MAXBPT;
+ i++, bp++) {
+ if (KDB_DEBUG(BP))
+ kdb_printf("bp 0x%p enabled %d delayed %d global %d cpu %d\n",
+ bp, bp->bp_enabled, bp->bp_delayed, bp->bp_global, bp->bp_cpu);
+ if (!bp->bp_enabled)
+ continue;
+ if (!bp->bp_global && bp->bp_cpu != smp_processor_id())
+ continue;
+ if (KDB_DEBUG(BP))
+ kdb_printf("bp for this cpu\n");
+ if (bp->bp_delayed) {
+ bp->bp_delayed = 0;
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_installbp\n");
+ kdba_installbp(ef, bp);
+ if (!KDB_STATE(DOING_SS)) {
+ set_msr(get_msr() & ~MSR_SE);
+ return(KDB_DB_SSBPT);
+ }
+ break;
+ }
+ }
+ if (i == KDB_MAXBPT) {
+ kdb_printf("kdb: Unable to find delayed breakpoint\n");
+ }
+ if (!KDB_STATE(DOING_SS)) {
+ set_msr(get_msr() & ~MSR_SE);
+ return(KDB_DB_NOBPT);
+ }
+ /* FALLTHROUGH */
+ }
+
+ /*
+ * KDB_STATE_DOING_SS is set when the kernel debugger is using
+ * the processor trap flag to single-step a processor. If a
+ * single step trap occurs and this flag is clear, the SS trap
+ * will be ignored by KDB and the kernel will be allowed to deal
+ * with it as necessary (e.g. for ptrace).
+ */
+ if (!KDB_STATE(DOING_SS))
+ goto unknown;
+
+ /* single step */
+ rv = KDB_DB_SS; /* Indicate single step */
+ if (KDB_STATE(DOING_SSB)) {
+ unsigned long instruction;
+
+ kdb_id1(ef->nip);
+ kdb_getarea(instruction,ef->nip);
+ primary=instruction & 0xfc00000000000000;
+ extended=instruction & 0x000007fe00000000;
+ if ((primary == 0x4800000000000000) ||
+ (primary == 0x4000000000000000) ||
+ ((primary == 0x4c00000000000000) &&
+ ((extended == 0x0000042000000000) ||
+ (extended == 0x0000002000000000)))) {
+ /*
+ * End the ssb command here.
+ */
+ KDB_STATE_CLEAR(DOING_SSB);
+ KDB_STATE_CLEAR(DOING_SS);
+ } else {
+ const char *argv[] = {"ssb", NULL};
+ rv = KDB_DB_SSB; /* Indicate ssb - dismiss immediately */
+ kdb_ss(0, argv, NULL, ef);
+ }
+ } else {
+ /*
+ * Print current insn
+ */
+ kdb_printf("SS trap at ");
+ kdb_symbol_print(ef->nip, NULL, KDB_SP_DEFAULT|KDB_SP_NEWLINE);
+ kdb_printf(" "); /* wms */
+ kdb_id1(ef->nip);
+ KDB_STATE_CLEAR(DOING_SS);
+ }
+
+ if (rv != KDB_DB_SSB)
+ set_msr(get_msr() & ~MSR_SE);
+ }
+ if (rv > 0)
+ goto handled;
+
+ /*
+ * Determine which breakpoint was encountered.
+ */
+ for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) {
+ if (!(bp->bp_free)
+ && (bp->bp_global || bp->bp_cpu == smp_processor_id())
+ && (bp->bp_hard)
+ && (bp->bp_hard->bph_reg == reg)) {
+ /*
+ * Hit this breakpoint.
+ */
+ kdb_printf("%s breakpoint #%d at " kdb_bfd_vma_fmt "\n",
+ kdba_rwtypes[rw],
+ i, (long )bp->bp_addr);
+
+ /*
+ * For an instruction breakpoint, disassemble
+ * the current instruction.
+ */
+ if (rw == 0) {
+ kdb_id1(ef->nip);
+ }
+
+ goto handled;
+ }
+ }
+
+unknown:
+ rv = KDB_DB_NOBPT; /* Cause kdb() to return */
+
+handled:
+
+
+ return rv;
+}
+
+/*
+ * kdba_bp_trap
+ *
+ * Perform breakpoint processing upon entry to the
+ * processor breakpoint instruction fault. Determine and print
+ * the active breakpoint.
+ *
+ * Parameters:
+ * ef Exception frame containing machine register state
+ * error Error number passed to kdb.
+ * Outputs:
+ * None.
+ * Returns:
+ * 0 Standard instruction or data breakpoint encountered
+ * 1 Single Step fault ('ss' command)
+ * 2 Single Step fault, caller should continue ('ssb' command)
+ * 3 No existing kdb breakpoint matches this debug exception
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ * If multiple processors receive debug exceptions simultaneously,
+ * one may be waiting at the kdb fence in kdb() while the user
+ * issues a 'bc' command to clear the breakpoint the processor which
+ * is waiting has already encountered. If this is the case, the
+ * debug registers will no longer match any entry in the breakpoint
+ * table, and we'll return the value '3'. This can cause a panic
+ * in die_if_kernel(). It is safer to disable the breakpoint (bd),
+ * 'go' until all processors are past the breakpoint then clear the
+ * breakpoint (bc). This code recognises a breakpoint even when
+ * disabled but not when it has been cleared.
+ *
+ * WARNING: This routine resets the eip. It should be called
+ * once per breakpoint and the result cached.
+ */
+
+kdb_dbtrap_t
+kdba_bp_trap(kdb_eframe_t ef, int error_unused)
+{
+ int i;
+ kdb_dbtrap_t rv;
+ kdb_bp_t *bp;
+
+ if (KDB_NULL_REGS(ef))
+ return KDB_DB_NOBPT;
+ /*
+ * Determine which breakpoint was encountered.
+ */
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_bp_trap: eip=0x%lx (not adjusted) "
+ "msr=0x%lx trap=0x%lx ef=0x%p esp=0x%lx\n",
+ ef->nip, ef->msr, ef->trap, ef, ef->gpr[1]);
+
+ rv = KDB_DB_NOBPT; /* Cause kdb() to return */
+
+ for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) {
+ if (bp->bp_free)
+ continue;
+ if (!bp->bp_global && bp->bp_cpu != smp_processor_id())
+ continue;
+ if (bp->bp_addr == (ef->nip - bp->bp_adjust)) {
+ /* Hit this breakpoint. */
+ ef->nip -= bp->bp_adjust;
+ kdb_printf("Instruction(i) breakpoint #%d at 0x%lx (adjusted)\n",
+ i, ef->nip);
+ kdb_id1(ef->nip);
+ rv = KDB_DB_BPT;
+ bp->bp_delay = 1;
+ /* SSBPT is set when the kernel debugger must single
+ * step a task in order to re-establish an instruction
+ * breakpoint which uses the instruction replacement
+ * mechanism. It is cleared by any action that removes
+ * the need to single-step the breakpoint
+ */
+ KDB_STATE_SET(SSBPT);
+ break;
+ }
+ }
+
+ return rv;
+}
+
+/*
+ * kdba_handle_bp
+ *
+ * Handle an instruction-breakpoint trap. Called when re-installing
+ * an enabled breakpoint which has has the bp_delay bit set.
+ *
+ * Parameters:
+ * Returns:
+ * Locking:
+ * Remarks:
+ *
+ * Ok, we really need to:
+ * 1) Restore the original instruction byte
+ * 2) Single Step
+ * 3) Restore breakpoint instruction
+ * 4) Continue.
+ *
+ *
+ */
+
+static void
+kdba_handle_bp(kdb_eframe_t ef, kdb_bp_t *bp)
+{
+ if (KDB_NULL_REGS(ef)) {
+ kdb_printf("kdba_handle_bp: ef == NULL\n");
+ return;
+ }
+
+ if (KDB_DEBUG(BP))
+ kdb_printf("ef->eip = 0x%lx\n", ef->nip);
+
+ /*
+ * Setup single step
+ */
+ kdba_setsinglestep(ef);
+
+ /*
+ * Reset delay attribute
+ */
+ bp->bp_delay = 0;
+ bp->bp_delayed = 1;
+}
+
+
+/*
+ * kdba_bptype
+ *
+ * Return a string describing type of breakpoint.
+ *
+ * Parameters:
+ * bph Pointer to hardware breakpoint description
+ * Outputs:
+ * None.
+ * Returns:
+ * Character string.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+char *
+kdba_bptype(kdbhard_bp_t *bph)
+{
+ char *mode;
+
+ mode = kdba_rwtypes[bph->bph_mode];
+
+ return mode;
+}
+
+/*
+ * kdba_printbpreg
+ *
+ * Print register name assigned to breakpoint
+ *
+ * Parameters:
+ * bph Pointer hardware breakpoint structure
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+void
+kdba_printbpreg(kdbhard_bp_t *bph)
+{
+ kdb_printf(" in dr%ld", bph->bph_reg);
+}
+
+/*
+ * kdba_printbp
+ *
+ * Print string describing hardware breakpoint.
+ *
+ * Parameters:
+ * bph Pointer to hardware breakpoint description
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+void
+kdba_printbp(kdb_bp_t *bp)
+{
+ kdb_printf("\n is enabled");
+ if (bp->bp_hardtype) {
+ kdba_printbpreg(bp->bp_hard);
+ if (bp->bp_hard->bph_mode != 0) {
+ kdb_printf(" for %d bytes",
+ bp->bp_hard->bph_length+1);
+ }
+ }
+}
+
+/*
+ * kdba_parsebp
+ *
+ * Parse architecture dependent portion of the
+ * breakpoint command.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero for success, a kdb diagnostic for failure
+ * Locking:
+ * None.
+ * Remarks:
+ * for Ia32 architure, data access, data write and
+ * I/O breakpoints are supported in addition to instruction
+ * breakpoints.
+ *
+ * {datar|dataw|io|inst} [length]
+ */
+
+int
+kdba_parsebp(int argc, const char **argv, int *nextargp, kdb_bp_t *bp)
+{
+ int nextarg = *nextargp;
+ int diag;
+ kdbhard_bp_t *bph = &bp->bp_template;
+
+ bph->bph_mode = 0; /* Default to instruction breakpoint */
+ bph->bph_length = 0; /* Length must be zero for insn bp */
+ if ((argc + 1) != nextarg) {
+ if (strnicmp(argv[nextarg], "datar", sizeof("datar")) == 0) {
+ bph->bph_mode = 3;
+ } else if (strnicmp(argv[nextarg], "dataw", sizeof("dataw")) == 0) {
+ bph->bph_mode = 1;
+ } else if (strnicmp(argv[nextarg], "io", sizeof("io")) == 0) {
+ bph->bph_mode = 2;
+ } else if (strnicmp(argv[nextarg], "inst", sizeof("inst")) == 0) {
+ bph->bph_mode = 0;
+ } else {
+ return KDB_ARGCOUNT;
+ }
+
+ bph->bph_length = 3; /* Default to 4 byte */
+
+ nextarg++;
+
+ if ((argc + 1) != nextarg) {
+ unsigned long len;
+
+ diag = kdbgetularg((char *)argv[nextarg],
+ &len);
+ if (diag)
+ return diag;
+
+
+ if ((len > 4) || (len == 3))
+ return KDB_BADLENGTH;
+
+ bph->bph_length = len;
+ bph->bph_length--; /* Normalize for debug register */
+ nextarg++;
+ }
+
+ if ((argc + 1) != nextarg)
+ return KDB_ARGCOUNT;
+
+ /*
+ * Indicate to architecture independent level that
+ * a hardware register assignment is required to enable
+ * this breakpoint.
+ */
+
+ bph->bph_free = 0;
+ } else {
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_bp: no args, forcehw is %d\n", bp->bp_forcehw);
+ if (bp->bp_forcehw) {
+ /*
+ * We are forced to use a hardware register for this
+ * breakpoint because either the bph or bpha
+ * commands were used to establish this breakpoint.
+ */
+ bph->bph_free = 0;
+ } else {
+ /*
+ * Indicate to architecture dependent level that
+ * the instruction replacement breakpoint technique
+ * should be used for this breakpoint.
+ */
+ bph->bph_free = 1;
+ bp->bp_adjust = PPC64_ADJUST_OFFSET;
+ }
+ }
+
+ *nextargp = nextarg;
+ return 0;
+}
+
+/*
+ * kdba_allocbp
+ *
+ * Associate a hardware register with a breakpoint.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * A pointer to the allocated register kdbhard_bp_t structure for
+ * success, Null and a non-zero diagnostic for failure.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+kdbhard_bp_t *
+kdba_allocbp(kdbhard_bp_t *bph, int *diagp)
+{
+ int i;
+ kdbhard_bp_t *newbph;
+
+ for(i=0,newbph=kdb_hardbreaks; i < KDB_MAXHARDBPT; i++, newbph++) {
+ if (newbph->bph_free) {
+ break;
+ }
+ }
+
+ if (i == KDB_MAXHARDBPT) {
+ *diagp = KDB_TOOMANYDBREGS;
+ return NULL;
+ }
+
+ *diagp = 0;
+
+ /*
+ * Copy data from template. Can't just copy the entire template
+ * here because the register number in kdb_hardbreaks must be
+ * preserved.
+ */
+ newbph->bph_data = bph->bph_data;
+ newbph->bph_write = bph->bph_write;
+ newbph->bph_mode = bph->bph_mode;
+ newbph->bph_length = bph->bph_length;
+
+ /*
+ * Mark entry allocated.
+ */
+ newbph->bph_free = 0;
+
+ return newbph;
+}
+
+/*
+ * kdba_freebp
+ *
+ * Deallocate a hardware breakpoint
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero for success, a kdb diagnostic for failure
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+void
+kdba_freebp(kdbhard_bp_t *bph)
+{
+ bph->bph_free = 1;
+}
+
+/*
+ * kdba_initbp
+ *
+ * Initialize the breakpoint table for the hardware breakpoint
+ * register.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero for success, a kdb diagnostic for failure
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ * There is one entry per register. On the ia32 architecture
+ * all the registers are interchangeable, so no special allocation
+ * criteria are required.
+ */
+
+void
+kdba_initbp(void)
+{
+ int i;
+ kdbhard_bp_t *bph;
+
+ /*
+ * Clear the hardware breakpoint table
+ */
+
+ memset(kdb_hardbreaks, '\0', sizeof(kdb_hardbreaks));
+
+ for(i=0,bph=kdb_hardbreaks; i<KDB_MAXHARDBPT; i++, bph++) {
+ bph->bph_reg = i;
+ bph->bph_free = 1;
+ }
+}
+
+/*
+ * kdba_installbp
+ *
+ * Install a breakpoint
+ *
+ * Parameters:
+ * ef Exception frame
+ * bp Breakpoint structure for the breakpoint to be installed
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ * For hardware breakpoints, a debug register is allocated
+ * and assigned to the breakpoint. If no debug register is
+ * available, a warning message is printed and the breakpoint
+ * is disabled.
+ *
+ * For instruction replacement breakpoints, we must single-step
+ * over the replaced instruction at this point so we can re-install
+ * the breakpoint instruction after the single-step. SSBPT is set
+ * when the breakpoint is initially hit and is cleared by any action
+ * that removes the need for single-step over the breakpoint.
+ */
+
+int
+kdba_installbp(kdb_eframe_t ef, kdb_bp_t *bp)
+{
+ int rc;
+ /*
+ * Install the breakpoint, if it is not already installed.
+ */
+
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdba_installbp bp_installed %d\n", bp->bp_installed);
+ }
+ if (!KDB_STATE(SSBPT))
+ bp->bp_delay = 0;
+ if (!bp->bp_installed) {
+ if (bp->bp_hardtype) {
+ kdba_installdbreg(bp);
+ bp->bp_installed = 1;
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdba_installbp hardware reg %ld at " kdb_bfd_vma_fmt "\n",
+ (long unsigned int) bp->bp_hard->bph_reg, (long unsigned int) bp->bp_addr);
+ }
+ } else if (bp->bp_delay) {
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_installbp delayed bp\n");
+ kdba_handle_bp(ef, bp);
+ } else {
+ if (KDB_DEBUG(BP))
+ kdb_printf("0x%lx 0x%lx 0x%lx\n",bp->bp_inst,bp->bp_addr,sizeof(bp->bp_addr));
+ rc = kdb_getword(&bp->bp_inst, bp->bp_addr,sizeof(bp->bp_addr));
+ if (kdb_putword(bp->bp_addr, PPC64_BREAKPOINT_INSTRUCTION,sizeof(PPC64_BREAKPOINT_INSTRUCTION)))
+ return (1);
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_installbp instruction 0x%x at " kdb_bfd_vma_fmt "\n",
+ PPC64_BREAKPOINT_INSTRUCTION, bp->bp_addr);
+ bp->bp_installed = 1;
+ }
+ }
+ return 0;
+}
+
+/*
+ * kdba_removebp
+ *
+ * Make a breakpoint ineffective.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+int
+kdba_removebp(kdb_bp_t *bp)
+{
+ /*
+ * For hardware breakpoints, remove it from the active register,
+ * for software breakpoints, restore the instruction stream.
+ */
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdba_removebp bp_installed %d\n", bp->bp_installed);
+ }
+ if (bp->bp_installed) {
+ if (bp->bp_hardtype) {
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdb: removing hardware reg %ld at " kdb_bfd_vma_fmt "\n",
+ bp->bp_hard->bph_reg, bp->bp_addr);
+ }
+ kdba_removedbreg(bp);
+ } else
+ {
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdb: restoring instruction 0x%lx at " kdb_bfd_vma_fmt "\n",
+ bp->bp_inst, bp->bp_addr);
+ kdb_putword(bp->bp_addr, bp->bp_inst,sizeof(bp->bp_inst));
+ }
+ bp->bp_installed = 0;
+ }
+return 0;
+}
+
+/* install data breakpoint */
+void
+kdba_installdbreg(kdb_bp_t *bp) {
+ /* set_dabr is the kdb form, using mtspr instructions */
+ set_dabr(bp->bp_addr);
+}
+
+/* remove data breakpoint-- set it to zero. */
+void
+kdba_removedbreg(kdb_bp_t *bp) {
+ /* set_dabr is the kdb form, using mtspr instructions */
+ set_dabr(0x0);
+}
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Stack Traceback
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kallsyms.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <linux/ptrace.h> /* for STACK_FRAME_OVERHEAD */
+#include <asm/system.h>
+
+/* human name vector lookup. */
+static
+const char *getvecname(unsigned long vec)
+{
+ char *ret;
+ switch (vec) {
+ case 0x100: ret = "(System Reset)"; break;
+ case 0x200: ret = "(Machine Check)"; break;
+ case 0x300: ret = "(Data Access)"; break;
+ case 0x400: ret = "(Instruction Access)"; break;
+ case 0x500: ret = "(Hardware Interrupt)"; break;
+ case 0x600: ret = "(Alignment)"; break;
+ case 0x700: ret = "(Program Check)"; break;
+ case 0x800: ret = "(FPU Unavailable)"; break;
+ case 0x900: ret = "(Decrementer)"; break;
+ case 0xc00: ret = "(System Call)"; break;
+ case 0xd00: ret = "(Single Step)"; break;
+ case 0xf00: ret = "(Performance Monitor)"; break;
+ default: ret = "";
+ }
+ return ret;
+}
+
+extern unsigned long kdba_getword(unsigned long addr, size_t width);
+
+/* Copy a block of memory using kdba_getword().
+ * This is not efficient.
+ */
+static void kdba_getmem(unsigned long addr, void *p, int size)
+{
+ unsigned char *dst = (unsigned char *)p;
+ while (size > 0) {
+ *dst++ = kdba_getword(addr++, 1);
+ size--;
+ }
+}
+
+/*
+ * kdba_bt_stack_ppc
+ *
+ * kdba_bt_stack with ppc specific parameters.
+ * Specification as kdba_bt_stack plus :-
+ *
+ * Inputs:
+ * As kba_bt_stack plus
+ * regs_esp If 1 get esp from the registers (exception frame), if 0
+ * get esp from kdba_getregcontents.
+ */
+
+static int
+kdba_bt_stack_ppc(struct pt_regs *regs, kdb_machreg_t *addr, int argcount,
+ const struct task_struct *p, int regs_esp)
+{
+
+ kdb_machreg_t esp, eip, ebp;
+
+ const char *name;
+ unsigned long symsize, symoffset;
+ char *symmodname;
+ int flag = 0;
+ kdb_machreg_t lr;
+ static char namebuf[KSYM_NAME_LEN+1];
+
+ /*
+ * The caller may have supplied an address at which the
+ * stack traceback operation should begin. This address
+ * is assumed by this code to point to a return-address
+ * on the stack to be traced back.
+ *
+ * The end result of this will make it appear as if a function
+ * entitled '<unknown>' was called from the function which
+ * contains return-address.
+ */
+ if (!addr)
+ addr = (kdb_machreg_t *)p->thread.ksp;
+
+ if (addr && (!p || !task_curr(p))) {
+ eip = 0;
+ esp = *addr;
+ ebp = 0;
+ } else {
+ if (task_curr(p)) {
+ struct kdb_running_process *krp = kdb_running_process + task_cpu(p);
+ if (!krp->seqno) {
+ kdb_printf("Process did not save state, cannot backtrace \n");
+ kdb_ps1(p);
+ return 0;
+ }
+ regs = krp->regs;
+ } else {
+ if (!regs)
+ regs = p->thread.regs;
+ }
+ if (KDB_NULL_REGS(regs))
+ return KDB_BADREG;
+ ebp = regs->link;
+ eip = regs->nip;
+ if (regs_esp)
+ esp = regs->gpr[1];
+ else
+ kdba_getregcontents("esp", regs, &esp);
+ }
+
+ kdb_printf(" SP(esp) PC(eip) Function(args)\n");
+
+ /* (Ref: 64-bit PowerPC ELF ABI Supplement:
+ Ian Lance Taylor, Zembu Labs).
+ A PPC stack frame looks like this:
+
+ High Address
+ Back Chain
+ FP reg save area
+ GP reg save area
+ Local var space
+ Parameter save area (SP+48)
+ TOC save area (SP+40)
+ link editor doubleword (SP+32)
+ compiler doubleword (SP+24)
+ LR save (SP+16)
+ CR save (SP+8)
+ Back Chain (SP+0)
+
+ Note that the LR (ret addr) may not be saved in the *current* frame if
+ no functions have been called from the current function.
+ */
+
+ /*
+ * Run through the activation records and print them.
+ */
+ while (1) {
+ kdb_printf("0x%016lx 0x%016lx ", esp, eip);
+ name = NULL;
+ if (esp >= PAGE_OFFSET) {
+ /*
+ * if this fails, eip is outside of kernel space,
+ * dont trust it.
+ */
+ if (eip > PAGE_OFFSET) {
+ name = kallsyms_lookup(eip, &symsize,
+ &symoffset, &symmodname, namebuf);
+ }
+ if (name) {
+ kdb_printf("%s", name);
+ } else {
+ kdb_printf("NO_SYMBOL or Userspace");
+ }
+ }
+
+ /*
+ * if this fails, eip is outside of kernel space,
+ * dont trust data.
+ */
+ if (eip > PAGE_OFFSET) {
+ if (eip - symoffset > 0) {
+ kdb_printf(" +0x%lx", /*eip -*/ symoffset);
+ }
+ }
+ kdb_printf("\n");
+ if (!flag && (task_curr(p))) {
+ unsigned long start = 0, end = 0;
+
+ flag++;
+ if ((!regs) || (regs->link < PAGE_OFFSET) ||
+ (regs->link == eip))
+ goto next_frame;
+
+ lr = regs->link;
+ start = eip - symoffset;
+ end = eip - symoffset + symsize;
+ if (lr >= start && lr < end)
+ goto next_frame;
+
+ name = NULL;
+ name = kallsyms_lookup(lr, &symsize,
+ &symoffset, &symmodname, namebuf);
+ if (name)
+ kdb_printf("0x%016lx 0x%016lx (lr) %s +0x%lx\n",
+ esp, lr, name, symoffset);
+ }
+
+next_frame:
+ if (esp < PAGE_OFFSET) { /* below kernelspace.. */
+ kdb_printf("<Stack contents outside of kernel space. %.16lx>\n", esp );
+ break;
+ } else {
+ unsigned long *sp = (unsigned long *)esp;
+ if (esp <= (unsigned long) p->thread_info + THREAD_SIZE
+ + sizeof(struct pt_regs) + 400
+ && sp[12] == 0x7265677368657265ul) {
+ struct pt_regs eregs;
+ kdba_getmem(esp + STACK_FRAME_OVERHEAD,
+ &eregs, sizeof(eregs));
+ kdb_printf("--- Exception: %lx: %s ",
+ eregs.trap, getvecname(eregs.trap));
+ name = kallsyms_lookup(eregs.nip, &symsize,
+ &symoffset, &symmodname, namebuf);
+ if (name) {
+ kdb_printf("at %s +0x%lx\n",
+ name, symoffset);
+ } else {
+ kdb_printf("NO_SYMBOL or Userspace\n");
+ }
+ kdb_printf("--- eframe at %lx\n",
+ esp + STACK_FRAME_OVERHEAD);
+ flag = 0;
+ /*
+ * we want to follow exception registers,
+ * not into user stack. ...
+ */
+ esp = eregs.gpr[1];
+ eip = eregs.nip;
+ regs = &eregs;
+ } else {
+ esp = kdba_getword(esp, 8);
+ if (!esp)
+ break;
+ eip = kdba_getword(esp+16, 8); /* saved lr */
+ }
+ }
+ }
+ return 0;
+}
+
+
+/*
+ * kdba_bt_stack
+ *
+ * This function implements the 'bt' command. Print a stack
+ * traceback.
+ *
+ * bt [<address-expression>] (addr-exp is for alternate stacks)
+ * btp <pid> (Kernel stack for <pid>)
+ *
+ * address expression refers to a return address on the stack. It
+ * may be preceeded by a frame pointer.
+ *
+ * Inputs:
+ * regs registers at time kdb was entered.
+ * addr Pointer to Address provided to 'bt' command, if any.
+ * argcount
+ * p Pointer to task for 'btp' command.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * mds comes in handy when examining the stack to do a manual
+ * traceback.
+ */
+
+int
+kdba_bt_stack(struct pt_regs *regs, kdb_machreg_t *addr, int argcount,
+ struct task_struct *p)
+{
+ return(kdba_bt_stack_ppc(regs, addr, argcount, p, 0));
+}
+
+/*
+ * kdba_bt_address
+ *
+ * Do a backtrace starting at a specified stack address. Handy
+ * if the stack is somwhere unexpected/unusual.
+ *
+ * Inputs:
+ * addr Address provided to 'bt' command.
+ * argcount
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ */
+
+int
+kdba_bt_address(kdb_machreg_t addr, int argcount)
+{
+ return kdba_bt_stack(NULL, &addr, argcount, NULL);
+}
+
+/*
+ * kdba_bt_process
+ *
+ * Do a backtrace for a specified process.
+ *
+ * Inputs:
+ * p Struct task pointer extracted by 'bt' command.
+ * argcount
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ */
+int
+kdba_bt_process(const struct task_struct *p, int argcount)
+{
+ return (kdba_bt_stack_ppc(NULL, NULL, argcount, p, 0));
+}
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Instruction Disassembly
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <stdarg.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/kdb.h>
+#define ATTRIBUTE_UNUSED
+#include <linux/kdbprivate.h>
+
+void kdba_dis_printaddr(unsigned long);
+int kdba_print_insn_powerpc(unsigned long, unsigned long, int);
+
+/* So that our copy doesn't collide with xmon's... */
+#define printf kdb_printf
+#define print_insn_powerpc kdba_print_insn_powerpc
+#define powerpc_opcodes kdba_powerpc_opcodes
+#define powerpc_num_opcodes kdba_powerpc_num_opcodes
+#define powerpc_operands kdba_powerpc_operands
+#define print_address kdba_dis_printaddr
+
+#include "../xmon/ppc-dis.c"
+#include "../xmon/ppc-opc.c"
+
+static disassemble_info *kdba_dip;
+
+/*
+ * kdba_dis_getsym
+ *
+ * Get a symbol for the disassembler.
+ *
+ * Parameters:
+ * addr Address for which to get symbol
+ * dip Pointer to disassemble_info
+ * Returns:
+ * 0
+ * Locking:
+ * Remarks:
+ * Not used for kdb.
+ */
+
+/* ARGSUSED */
+static int
+kdba_dis_getsym(bfd_vma addr, disassemble_info *dip)
+{
+
+ return 0;
+}
+
+/*
+ * kdba_printaddress
+ *
+ * Print (symbolically) an address.
+ *
+ * Parameters:
+ * addr Address for which to get symbol
+ * dip Pointer to disassemble_info
+ * flag True if a ":<tab>" sequence should follow the address
+ * Returns:
+ * number of chars printed
+ * Locking:
+ * Remarks:
+ *
+ */
+
+/* ARGSUSED */
+void
+kdba_printaddress(kdb_machreg_t addr, disassemble_info *dip, int flag)
+{
+ kdb_symtab_t symtab;
+
+ /*
+ * Print a symbol name or address as necessary.
+ */
+ kdbnearsym(addr, &symtab);
+ if (symtab.sym_name) {
+ /* Do not use kdb_symbol_print here, it always does
+ * kdb_printf but we want dip->fprintf_func.
+ */
+ dip->fprintf_func(dip->stream,
+ "0x%0*lx %s",
+ 2*(int)sizeof(addr), addr, symtab.sym_name);
+ /* Add offset if needed. Pad output with blanks to get
+ * consistent size symbols for disassembly listings.
+ */
+ if (addr == symtab.sym_start) {
+ if (!flag)
+ dip->fprintf_func(dip->stream, " ");
+ } else {
+ int len, i;
+ char buf[20];
+ sprintf(buf, "%lx", addr - symtab.sym_start);
+ dip->fprintf_func(dip->stream, "+0x%s", buf);
+ if (!flag) {
+ len = strlen(buf);
+ for (i = len; i < 6; i++)
+ dip->fprintf_func(dip->stream, " ");
+ }
+ }
+
+ } else {
+ dip->fprintf_func(dip->stream, "0x%0*lx ",
+ 2*(int)sizeof(addr), addr);
+ }
+
+ if (flag)
+ dip->fprintf_func(dip->stream, ": ");
+}
+
+/*
+ * kdba_dis_printaddr
+ *
+ * Print (symbolically) an address. Called by GNU disassembly
+ * code via disassemble_info structure.
+ *
+ * Parameters:
+ * addr Address for which to get symbol
+ * dip Pointer to disassemble_info
+ * Returns:
+ * number of chars printed.
+ * Locking:
+ * Remarks:
+ * This function will never append ":<tab>" to the printed
+ * symbolic address.
+ */
+
+void
+kdba_dis_printaddr(bfd_vma addr)
+{
+ return kdba_printaddress(addr, kdba_dip, 0);
+}
+
+/*
+ * kdba_dis_getmem
+ *
+ * Fetch 'length' bytes from 'addr' into 'buf'.
+ *
+ * Parameters:
+ * addr Address for which to get symbol
+ * buf Address of buffer to fill with bytes from 'addr'
+ * length Number of bytes to fetch
+ * dip Pointer to disassemble_info
+ * Returns:
+ * 0
+ * Locking:
+ * Remarks:
+ *
+ */
+extern int kdba_getword(unsigned long addr, size_t width);
+
+
+/* ARGSUSED */
+static int
+kdba_dis_getmem(bfd_vma addr, bfd_byte *buf, unsigned int length, disassemble_info *dip)
+{
+ bfd_byte *bp = buf;
+ int i;
+
+ /*
+ * Fill the provided buffer with bytes from
+ * memory, starting at address 'addr' for 'length bytes.
+ *
+ */
+
+ for(i=0; i<length; i++ ){
+ *bp++ = (bfd_byte)kdba_getword(addr++, sizeof(bfd_byte));
+ }
+
+ return 0;
+}
+
+/*
+ * kdba_id_parsemode
+ *
+ * Parse IDMODE environment variable string and
+ * set appropriate value into "disassemble_info" structure.
+ *
+ * Parameters:
+ * mode Mode string
+ * dip Disassemble_info structure pointer
+ * Returns:
+ * Locking:
+ * Remarks:
+ * We handle the values 'x86' and '8086' to enable either
+ * 32-bit instruction set or 16-bit legacy instruction set.
+ */
+
+int
+kdba_id_parsemode(const char *mode, disassemble_info *dip)
+{
+ return 0;
+}
+
+/*
+ * kdba_check_pc
+ *
+ * Check that the pc is satisfactory.
+ *
+ * Parameters:
+ * pc Program Counter Value.
+ * Returns:
+ * None
+ * Locking:
+ * None.
+ * Remarks:
+ * Can change pc.
+ */
+
+void
+kdba_check_pc(kdb_machreg_t *pc)
+{
+ /* No action */
+}
+
+/*
+ * kdba_id_printinsn
+ *
+ * Format and print a single instruction at 'pc'. Return the
+ * length of the instruction.
+ *
+ * Parameters:
+ * pc Program Counter Value.
+ * dip Disassemble_info structure pointer
+ * Returns:
+ * Length of instruction, -1 for error.
+ * Locking:
+ * None.
+ * Remarks:
+ * Depends on 'IDMODE' environment variable.
+ */
+
+int
+kdba_id_printinsn(kdb_machreg_t pc, disassemble_info *dip)
+{
+#define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
+ bfd_byte buf[4];
+ unsigned long inst;
+
+ kdba_printaddress(pc, dip, 1);
+ if (kdba_dis_getmem(pc, buf, 4, dip))
+ return -1;
+ inst = GETWORD(buf);
+ kdba_dip = dip;
+ return kdba_print_insn_powerpc(inst, pc, 0);
+}
+
+/*
+ * kdba_id_init
+ *
+ * Initialize the architecture dependent elements of
+ * the disassembly information structure
+ * for the GNU disassembler.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+void __init
+kdba_id_init(disassemble_info *dip)
+{
+ dip->read_memory_func = kdba_dis_getmem;
+/* dip->print_address_func = kdba_dis_printaddr; */
+ dip->symbol_at_address_func = kdba_dis_getsym;
+
+ dip->flavour = bfd_target_elf_flavour;
+ dip->arch = bfd_arch_powerpc;
+ dip->mach = bfd_mach_ppc_750;
+ dip->endian = BFD_ENDIAN_BIG;
+
+ dip->display_endian = BFD_ENDIAN_BIG;
+}
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Console I/O handler
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/console.h>
+#include <linux/ctype.h>
+#include <linux/keyboard.h>
+#include <linux/serial.h>
+#include <linux/serial_reg.h>
+
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <asm/udbg.h>
+
+#ifdef CONFIG_KDB_USB
+struct kdb_usb_exchange kdb_usb_infos;
+
+EXPORT_SYMBOL(kdb_usb_infos);
+
+static unsigned char kdb_usb_keycode[256] = {
+ 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
+ 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
+ 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
+ 27, 43, 84, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
+ 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
+ 72, 73, 82, 83, 86,127,116,117, 85, 89, 90, 91, 92, 93, 94, 95,
+ 120,121,122,123,134,138,130,132,128,129,131,137,133,135,136,113,
+ 115,114, 0, 0, 0,124, 0,181,182,183,184,185,186,187,188,189,
+ 190,191,192,193,194,195,196,197,198, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
+ 150,158,159,128,136,177,178,176,142,152,173,140
+};
+
+/* get_usb_char
+ * This function drives the UHCI controller,
+ * fetch the USB scancode and decode it
+ */
+static int get_usb_char(void)
+{
+ static int usb_lock;
+ unsigned char keycode, spec;
+ extern u_short plain_map[], shift_map[], ctrl_map[];
+
+ /* Is USB initialized ? */
+ if (!kdb_usb_infos.poll_func || !kdb_usb_infos.urb || !kdb_usb_infos.buffer)
+ return -1;
+
+ udelay(1000); /* G5 keyboard unusable without this */
+
+ /* Transfer char if they are present */
+ (*kdb_usb_infos.poll_func)(kdb_usb_infos.uhci, (struct urb *)kdb_usb_infos.urb);
+
+ spec = kdb_usb_infos.buffer[0];
+ keycode = kdb_usb_infos.buffer[2];
+ kdb_usb_infos.buffer[0] = (char)0;
+ kdb_usb_infos.buffer[2] = (char)0;
+
+ if(kdb_usb_infos.buffer[3])
+ return -1;
+
+ /* A normal key is pressed, decode it */
+ if(keycode)
+ keycode = kdb_usb_keycode[keycode];
+
+ /* 2 Keys pressed at one time ? */
+ if (spec && keycode) {
+ switch(spec)
+ {
+ case 0x2:
+ case 0x20: /* Shift */
+ return shift_map[keycode];
+ case 0x1:
+ case 0x10: /* Ctrl */
+ return ctrl_map[keycode];
+ case 0x4:
+ case 0x40: /* Alt */
+ break;
+ }
+ }
+ else {
+ if(keycode) { /* If only one key pressed */
+ switch(keycode)
+ {
+ case 0x1C: /* Enter */
+ return 13;
+
+ case 0x3A: /* Capslock */
+ usb_lock ? (usb_lock = 0) : (usb_lock = 1);
+ break;
+ case 0x0E: /* Backspace */
+ return 8;
+ case 0x0F: /* TAB */
+ return 9;
+ case 0x77: /* Pause */
+ break ;
+ default:
+ if(!usb_lock) {
+ return plain_map[keycode];
+ }
+ else {
+ return shift_map[keycode];
+ }
+ }
+ }
+ }
+ return -1;
+}
+#endif /* CONFIG_KDB_USB */
+
+/*
+ * This module contains code to read characters from the keyboard or a serial
+ * port.
+ *
+ * It is used by the kernel debugger, and is polled, not interrupt driven.
+ *
+ */
+
+#if defined(CONFIG_SERIAL_8250_CONSOLE) || defined(CONFIG_SERIAL_CORE_CONSOLE)
+#define CONFIG_SERIAL_CONSOLE
+#endif
+
+#if defined(CONFIG_SERIAL_CONSOLE)
+
+struct kdb_serial kdb_serial;
+
+static unsigned int
+serial_inp(struct kdb_serial *kdb_serial, unsigned long offset)
+{
+ offset <<= kdb_serial->ioreg_shift;
+
+ switch (kdb_serial->io_type) {
+ case SERIAL_IO_MEM:
+ return readb((void __iomem *)(kdb_serial->iobase + offset));
+ break;
+ default:
+ return inb(kdb_serial->iobase + offset);
+ break;
+ }
+}
+
+/* Check if there is a byte ready at the serial port */
+static int get_serial_char(void)
+{
+ unsigned char ch;
+
+ if (kdb_serial.iobase == 0)
+ return -1;
+
+ if (serial_inp(&kdb_serial, UART_LSR) & UART_LSR_DR) {
+ ch = serial_inp(&kdb_serial, UART_RX);
+ if (ch == 0x7f)
+ ch = 8;
+ return ch;
+ }
+ return -1;
+}
+#endif /* CONFIG_SERIAL_CONSOLE */
+
+static int
+get_udbg_char(void)
+{
+ int key = udbg_getc_poll? udbg_getc_poll(): 0;
+ return key? key: -1;
+}
+
+get_char_func poll_funcs[] = {
+#ifdef CONFIG_SERIAL_CONSOLE
+ get_serial_char,
+#endif
+#ifdef CONFIG_KDB_USB
+ get_usb_char,
+#endif
+ get_udbg_char,
+ NULL
+};
+
+void kdba_local_arch_setup(void)
+{
+ /* Any local setup needed here */
+}
+
+void kdba_local_arch_cleanup(void)
+{
+ /* Any local cleanup needed here */
+}
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Support Functions
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/string.h>
+#include <linux/stddef.h>
+#include <linux/kallsyms.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ptrace.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/iommu.h>
+#include <asm/rtas.h>
+#include "privinst.h"
+
+extern const char *kdb_diemsg;
+unsigned long cpus_in_kdb=0;
+volatile unsigned long kdb_do_reboot=0;
+
+/* prototypes */
+int valid_ppc64_kernel_address(unsigned long addr, unsigned long size);
+int kdba_excprint(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+int kdba_super_regs(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+int kdba_dissect_msr(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+int kdba_halt(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+int kdba_dump_tce_table(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+int kdba_kernelversion(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+int kdba_dmesg(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+int kdba_rd(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+int kdba_bt(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+unsigned long kdba_getword(unsigned long addr, size_t width);
+
+extern int kdb_dmesg(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+extern int kdb_ps(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+
+extern int kdb_parse(const char *cmdstr, struct pt_regs *regs);
+
+/* 60secs * 1000*1000 usecs/sec.
+ * HMC interface requires larger amount of time,.. */
+#define KDB_RESET_TIMEOUT 60*1000*1000
+
+/* kdb will use UDBG */
+#define USE_UDBG
+
+#ifdef USE_UDBG
+#include <asm/udbg.h>
+#endif
+
+#include <linux/kbd_kern.h>
+#include <linux/sysrq.h>
+#include <linux/interrupt.h>
+
+#ifdef CONFIG_MAGIC_SYSRQ
+static void
+sysrq_handle_kdb(int key, struct pt_regs *pt_regs, struct kbd_struct *kbd, struct tty_struct *tty)
+{
+ kdb_become_debugger();
+ kdb(KDB_REASON_KEYBOARD,0,pt_regs);
+}
+
+static struct sysrq_key_op sysrq_kdb_op =
+{
+ handler: (void*)sysrq_handle_kdb,
+ help_msg: "kDb",
+ action_msg: "Entering kdb",
+};
+#endif
+
+/*
+ * kdba_getregcontents
+ *
+ * Return the contents of the register specified by the
+ * input string argument. Return an error if the string
+ * does not match a machine register.
+ *
+ * The following pseudo register names are supported:
+ * ®s - Prints address of exception frame
+ * kesp - Prints kernel stack pointer at time of fault
+ * cesp - Prints current kernel stack pointer, inside kdb
+ * ceflags - Prints current flags, inside kdb
+ * %<regname> - Uses the value of the registers at the
+ * last time the user process entered kernel
+ * mode, instead of the registers at the time
+ * kdb was entered.
+ *
+ * Parameters:
+ * regname Pointer to string naming register
+ * regs Pointer to structure containing registers.
+ * Outputs:
+ * *contents Pointer to unsigned long to recieve register contents
+ * Returns:
+ * 0 Success
+ * KDB_BADREG Invalid register name
+ * Locking:
+ * None.
+ * Remarks:
+ * If kdb was entered via an interrupt from the kernel itself then
+ * ss and esp are *not* on the stack.
+ */
+
+static struct kdbregs {
+ char *reg_name;
+ size_t reg_offset;
+} kdbreglist[] = {
+ { "gpr0", offsetof(struct pt_regs, gpr[0]) },
+ { "gpr1", offsetof(struct pt_regs, gpr[1]) },
+ { "gpr2", offsetof(struct pt_regs, gpr[2]) },
+ { "gpr3", offsetof(struct pt_regs, gpr[3]) },
+ { "gpr4", offsetof(struct pt_regs, gpr[4]) },
+ { "gpr5", offsetof(struct pt_regs, gpr[5]) },
+ { "gpr6", offsetof(struct pt_regs, gpr[6]) },
+ { "gpr7", offsetof(struct pt_regs, gpr[7]) },
+ { "gpr8", offsetof(struct pt_regs, gpr[8]) },
+ { "gpr9", offsetof(struct pt_regs, gpr[9]) },
+ { "gpr10", offsetof(struct pt_regs, gpr[10]) },
+ { "gpr11", offsetof(struct pt_regs, gpr[11]) },
+ { "gpr12", offsetof(struct pt_regs, gpr[12]) },
+ { "gpr13", offsetof(struct pt_regs, gpr[13]) },
+ { "gpr14", offsetof(struct pt_regs, gpr[14]) },
+ { "gpr15", offsetof(struct pt_regs, gpr[15]) },
+ { "gpr16", offsetof(struct pt_regs, gpr[16]) },
+ { "gpr17", offsetof(struct pt_regs, gpr[17]) },
+ { "gpr18", offsetof(struct pt_regs, gpr[18]) },
+ { "gpr19", offsetof(struct pt_regs, gpr[19]) },
+ { "gpr20", offsetof(struct pt_regs, gpr[20]) },
+ { "gpr21", offsetof(struct pt_regs, gpr[21]) },
+ { "gpr22", offsetof(struct pt_regs, gpr[22]) },
+ { "gpr23", offsetof(struct pt_regs, gpr[23]) },
+ { "gpr24", offsetof(struct pt_regs, gpr[24]) },
+ { "gpr25", offsetof(struct pt_regs, gpr[25]) },
+ { "gpr26", offsetof(struct pt_regs, gpr[26]) },
+ { "gpr27", offsetof(struct pt_regs, gpr[27]) },
+ { "gpr28", offsetof(struct pt_regs, gpr[28]) },
+ { "gpr29", offsetof(struct pt_regs, gpr[29]) },
+ { "gpr30", offsetof(struct pt_regs, gpr[30]) },
+ { "gpr31", offsetof(struct pt_regs, gpr[31]) },
+ { "nip", offsetof(struct pt_regs, nip) },
+ { "msr", offsetof(struct pt_regs, msr) },
+ { "esp", offsetof(struct pt_regs, gpr[1]) },
+ { "orig_gpr3", offsetof(struct pt_regs, orig_gpr3) },
+ { "ctr", offsetof(struct pt_regs, ctr) },
+ { "link", offsetof(struct pt_regs, link) },
+ { "xer", offsetof(struct pt_regs, xer) },
+ { "ccr", offsetof(struct pt_regs, ccr) },
+ { "mq", offsetof(struct pt_regs, softe) /* mq */ },
+ { "trap", offsetof(struct pt_regs, trap) },
+ { "dar", offsetof(struct pt_regs, dar) },
+ { "dsisr", offsetof(struct pt_regs, dsisr) },
+ { "result", offsetof(struct pt_regs, result) },
+};
+
+static const int nkdbreglist = sizeof(kdbreglist) / sizeof(struct kdbregs);
+
+unsigned long
+getsp(void)
+{
+ unsigned long x;
+ asm("mr %0,1" : "=r" (x):);
+ return x;
+}
+
+int
+kdba_getregcontents(const char *regname,
+ struct pt_regs *regs,
+ kdb_machreg_t *contents)
+{
+ int i;
+
+ if (strcmp(regname, "®s") == 0) {
+ *contents = (unsigned long)regs;
+ return 0;
+ }
+
+ if (strcmp(regname, "kesp") == 0) {
+ *contents = (unsigned long) current->thread.ksp;
+ return 0;
+ }
+
+ if (strcmp(regname, "cesp") == 0) {
+ *contents = getsp();
+ return 0;
+ }
+
+ if (strcmp(regname, "ceflags") == 0) {
+ long flags;
+ local_save_flags(flags);
+ *contents = flags;
+ return 0;
+ }
+
+ if (regname[0] == '%') {
+ /* User registers: %%e[a-c]x, etc */
+ regname++;
+ regs = (struct pt_regs *)
+ (current->thread.ksp - sizeof(struct pt_regs));
+ }
+
+ for (i=0; i<nkdbreglist; i++) {
+ if (strnicmp(kdbreglist[i].reg_name,
+ regname,
+ strlen(regname)) == 0)
+ break;
+ }
+
+ if ((i < nkdbreglist)
+ && (strlen(kdbreglist[i].reg_name) == strlen(regname))) {
+ *contents = *(unsigned long *)((unsigned long)regs +
+ kdbreglist[i].reg_offset);
+ return(0);
+ }
+
+ return KDB_BADREG;
+}
+
+/*
+ * kdba_setregcontents
+ *
+ * Set the contents of the register specified by the
+ * input string argument. Return an error if the string
+ * does not match a machine register.
+ *
+ * Supports modification of user-mode registers via
+ * %<register-name>
+ *
+ * Parameters:
+ * regname Pointer to string naming register
+ * regs Pointer to structure containing registers.
+ * contents Unsigned long containing new register contents
+ * Outputs:
+ * Returns:
+ * 0 Success
+ * KDB_BADREG Invalid register name
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+int
+kdba_setregcontents(const char *regname,
+ struct pt_regs *regs,
+ unsigned long contents)
+{
+ int i;
+
+ if (regname[0] == '%') {
+ regname++;
+ regs = (struct pt_regs *)
+ (current->thread.ksp - sizeof(struct pt_regs));
+ }
+
+ for (i=0; i<nkdbreglist; i++) {
+ if (strnicmp(kdbreglist[i].reg_name,
+ regname,
+ strlen(regname)) == 0)
+ break;
+ }
+
+ if ((i < nkdbreglist)
+ && (strlen(kdbreglist[i].reg_name) == strlen(regname))) {
+ *(unsigned long *)((unsigned long)regs
+ + kdbreglist[i].reg_offset) = contents;
+ return 0;
+ }
+
+ return KDB_BADREG;
+}
+
+/*
+ * kdba_dumpregs
+ *
+ * Dump the specified register set to the display.
+ *
+ * Parameters:
+ * regs Pointer to structure containing registers.
+ * type Character string identifying register set to dump
+ * extra string further identifying register (optional)
+ * Outputs:
+ * Returns:
+ * 0 Success
+ * Locking:
+ * None.
+ * Remarks:
+ * This function will dump the general register set if the type
+ * argument is NULL (struct pt_regs). The alternate register
+ * set types supported by this function:
+ *
+ * d Debug registers
+ * c Control registers
+ * u User registers at most recent entry to kernel
+ * Following not yet implemented:
+ * m Model Specific Registers (extra defines register #)
+ * r Memory Type Range Registers (extra defines register)
+ */
+
+int
+kdba_dumpregs(struct pt_regs *regs,
+ const char *type,
+ const char *extra)
+{
+ int i;
+ int count = 0;
+
+ if (type
+ && (type[0] == 'u')) {
+ type = NULL;
+ regs = (struct pt_regs *)
+ (current->thread.ksp - sizeof(struct pt_regs));
+ }
+
+ if (type == NULL) {
+ struct kdbregs *rlp;
+ kdb_machreg_t contents;
+
+ for (i=0, rlp=kdbreglist; i<nkdbreglist; i++,rlp++) {
+ kdba_getregcontents(rlp->reg_name, regs, &contents);
+ kdb_printf("%-5s = 0x%p%c", rlp->reg_name, (void *)contents, (++count % 2) ? ' ' : '\n');
+ }
+
+ kdb_printf("®s = 0x%p\n", regs);
+ return 0;
+ } else { /* dump a specific register */
+ kdb_machreg_t contents;
+ if (KDB_BADREG==kdba_getregcontents(type, regs, &contents))
+ kdb_printf("register %-5s not found \n",type);
+ else
+ kdb_printf("%-5s = 0x%p%c", type, (void *)contents, '\n');
+ return 0;
+ }
+
+ switch (type[0]) {
+ case 'm':
+ break;
+ case 'r':
+ break;
+ default:
+ return KDB_BADREG;
+ }
+
+ /* NOTREACHED */
+ return 0;
+}
+
+kdb_machreg_t
+kdba_getpc(kdb_eframe_t ef)
+{
+ return ef ? ef->nip : 0;
+}
+
+int
+kdba_setpc(kdb_eframe_t ef, kdb_machreg_t newpc)
+{
+ /* for ppc64, newpc passed in is actually a function descriptor for kdb. */
+ ef->nip = kdba_getword(newpc+8, 8);
+ KDB_STATE_SET(IP_ADJUSTED);
+ return 0;
+}
+
+/*
+ * kdba_main_loop
+ *
+ * Do any architecture specific set up before entering the main kdb loop.
+ * The primary function of this routine is to make all processes look the
+ * same to kdb, kdb must be able to list a process without worrying if the
+ * process is running or blocked, so make all process look as though they
+ * are blocked.
+ *
+ * Inputs:
+ * reason The reason KDB was invoked
+ * error The hardware-defined error code
+ * error2 kdb's current reason code. Initially error but can change
+ * acording to kdb state.
+ * db_result Result from break or debug point.
+ * ef The exception frame at time of fault/breakpoint. If reason
+ * is KDB_REASON_SILENT then ef is NULL, otherwise it should
+ * always be valid.
+ * Returns:
+ * 0 KDB was invoked for an event which it wasn't responsible
+ * 1 KDB handled the event for which it was invoked.
+ * Outputs:
+ * Sets nip and esp in current->thread.
+ * Locking:
+ * None.
+ * Remarks:
+ * none.
+ */
+
+int
+kdba_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error,
+ kdb_dbtrap_t db_result, kdb_eframe_t ef)
+{
+ int rv;
+ kdb_do_reboot=0;
+
+ /* case where incoming registers are missing */
+ if (ef == NULL)
+ {
+ struct pt_regs regs;
+ asm volatile ("std 0,0(%0)\n\
+ std 1,8(%0)\n\
+ std 2,16(%0)\n\
+ std 3,24(%0)\n\
+ std 4,32(%0)\n\
+ std 5,40(%0)\n\
+ std 6,48(%0)\n\
+ std 7,56(%0)\n\
+ std 8,64(%0)\n\
+ std 9,72(%0)\n\
+ std 10,80(%0)\n\
+ std 11,88(%0)\n\
+ std 12,96(%0)\n\
+ std 13,104(%0)\n\
+ std 14,112(%0)\n\
+ std 15,120(%0)\n\
+ std 16,128(%0)\n\
+ std 17,136(%0)\n\
+ std 18,144(%0)\n\
+ std 19,152(%0)\n\
+ std 20,160(%0)\n\
+ std 21,168(%0)\n\
+ std 22,176(%0)\n\
+ std 23,184(%0)\n\
+ std 24,192(%0)\n\
+ std 25,200(%0)\n\
+ std 26,208(%0)\n\
+ std 27,216(%0)\n\
+ std 28,224(%0)\n\
+ std 29,232(%0)\n\
+ std 30,240(%0)\n\
+ std 31,248(%0)" : : "b" (®s));
+ /* one extra step back.. this frame disappears */
+ regs.gpr[1] = kdba_getword(regs.gpr[1], 8);
+ /* Fetch the link reg for this stack frame.
+ NOTE: the prev kdb_printf fills in the lr. */
+ regs.nip = regs.link = ((unsigned long *)regs.gpr[1])[2];
+ regs.msr = get_msr();
+ regs.ctr = get_ctr();
+ regs.xer = get_xer();
+ regs.ccr = get_cr();
+ regs.trap = 0;
+ /*current->thread.regs = ®s; */
+ ef = ®s;
+ }
+ cpus_in_kdb++;
+ kdb_save_running(ef);
+ rv = kdb_main_loop(reason, reason2, error, db_result, ef);
+ kdb_unsave_running(ef);
+ cpus_in_kdb--;
+ return rv;
+}
+
+void
+kdba_disableint(kdb_intstate_t *state)
+{
+ unsigned long *fp = (unsigned long *)state;
+ unsigned long flags;
+ local_irq_save(flags);
+ *fp = flags;
+}
+
+void
+kdba_restoreint(kdb_intstate_t *state)
+{
+ unsigned long flags = *(unsigned long *)state;
+ local_irq_restore(flags);
+}
+
+void
+kdba_setsinglestep(struct pt_regs *regs)
+{
+ regs->msr |= MSR_SE;
+}
+
+void
+kdba_clearsinglestep(struct pt_regs *regs)
+{
+ if (!KDB_STATE(DOING_SSB)) {
+ regs->msr &= ~MSR_SE;
+ }
+}
+
+int
+kdba_getcurrentframe(struct pt_regs *regs)
+{
+ regs->gpr[1] = getsp();
+ /* this stack pointer becomes invalid after we return,
+ * so take another step back. */
+ regs->gpr[1] = kdba_getword(regs->gpr[1], 8);
+ return 0;
+}
+
+int
+kdba_setjmp(kdb_jmp_buf *buf)
+{
+ asm volatile (
+ "mflr 0; std 0,0(%0)\n\
+ std 1,8(%0)\n\
+ std 2,16(%0)\n\
+ mfcr 0; std 0,24(%0)\n\
+ std 13,32(%0)\n\
+ std 14,40(%0)\n\
+ std 15,48(%0)\n\
+ std 16,56(%0)\n\
+ std 17,64(%0)\n\
+ std 18,72(%0)\n\
+ std 19,80(%0)\n\
+ std 20,88(%0)\n\
+ std 21,96(%0)\n\
+ std 22,104(%0)\n\
+ std 23,112(%0)\n\
+ std 24,120(%0)\n\
+ std 25,128(%0)\n\
+ std 26,136(%0)\n\
+ std 27,144(%0)\n\
+ std 28,152(%0)\n\
+ std 29,160(%0)\n\
+ std 30,168(%0)\n\
+ std 31,176(%0)\n\
+ " : : "r" (buf));
+ return 0;
+}
+
+void
+kdba_longjmp(kdb_jmp_buf *buf, int val)
+{
+ if (val == 0)
+ val = 1;
+ asm volatile (
+ "ld 13,32(%0)\n\
+ ld 14,40(%0)\n\
+ ld 15,48(%0)\n\
+ ld 16,56(%0)\n\
+ ld 17,64(%0)\n\
+ ld 18,72(%0)\n\
+ ld 19,80(%0)\n\
+ ld 20,88(%0)\n\
+ ld 21,96(%0)\n\
+ ld 22,104(%0)\n\
+ ld 23,112(%0)\n\
+ ld 24,120(%0)\n\
+ ld 25,128(%0)\n\
+ ld 26,136(%0)\n\
+ ld 27,144(%0)\n\
+ ld 28,152(%0)\n\
+ ld 29,160(%0)\n\
+ ld 30,168(%0)\n\
+ ld 31,176(%0)\n\
+ ld 0,24(%0)\n\
+ mtcrf 0x38,0\n\
+ ld 0,0(%0)\n\
+ ld 1,8(%0)\n\
+ ld 2,16(%0)\n\
+ mtlr 0\n\
+ mr 3,%1\n\
+ " : : "r" (buf), "r" (val));
+}
+
+/*
+ * kdba_getword
+ *
+ * Architecture specific function to access kernel virtual
+ * address space.
+ *
+ * Parameters:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ * None.
+ */
+
+/* if (access_ok(VERIFY_READ,__gu_addr,size)) \ */
+
+extern inline void sync(void)
+{
+ asm volatile("sync; isync");
+}
+
+extern void longjmp(u_int *, int);
+
+unsigned long
+kdba_getword(unsigned long addr, size_t width)
+{
+ /*
+ * This function checks the address for validity. Any address
+ * in the range PAGE_OFFSET to high_memory is legal, any address
+ * which maps to a vmalloc region is legal, and any address which
+ * is a user address, we use get_user() to verify validity.
+ */
+
+ if (!valid_ppc64_kernel_address(addr, width)) {
+ /*
+ * Would appear to be an illegal kernel address;
+ * Print a message once, and don't print again until
+ * a legal address is used.
+ */
+ if (!KDB_STATE(SUPPRESS)) {
+ kdb_printf(" kdb: Not a kernel-space address 0x%lx \n",addr);
+ KDB_STATE_SET(SUPPRESS);
+ }
+ return 0L;
+ }
+
+
+ /*
+ * A good address. Reset error flag.
+ */
+ KDB_STATE_CLEAR(SUPPRESS);
+
+ switch (width) {
+ case 8:
+ { unsigned long *lp;
+
+ lp = (unsigned long *)(addr);
+ return *lp;
+ }
+ case 4:
+ { unsigned int *ip;
+
+ ip = (unsigned int *)(addr);
+ return *ip;
+ }
+ case 2:
+ { unsigned short *sp;
+
+ sp = (unsigned short *)(addr);
+ return *sp;
+ }
+ case 1:
+ { unsigned char *cp;
+
+ cp = (unsigned char *)(addr);
+ return *cp;
+ }
+ }
+
+ kdb_printf("kdbgetword: Bad width\n");
+ return 0L;
+}
+
+/*
+ * kdba_putword
+ *
+ * Architecture specific function to access kernel virtual
+ * address space.
+ *
+ * Parameters:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ * None.
+ */
+
+unsigned long
+kdba_putword(unsigned long addr, size_t size, unsigned long contents)
+{
+ /*
+ * This function checks the address for validity. Any address
+ * in the range PAGE_OFFSET to high_memory is legal, any address
+ * which maps to a vmalloc region is legal, and any address which
+ * is a user address, we use get_user() to verify validity.
+ */
+
+ if (addr < PAGE_OFFSET) {
+ /*
+ * Usermode address.
+ */
+ unsigned long diag;
+
+ switch (size) {
+ case 4:
+ { unsigned long *lp;
+
+ lp = (unsigned long *) addr;
+ diag = put_user(contents, lp);
+ break;
+ }
+ case 2:
+ { unsigned short *sp;
+
+ sp = (unsigned short *) addr;
+ diag = put_user(contents, sp);
+ break;
+ }
+ case 1:
+ { unsigned char *cp;
+
+ cp = (unsigned char *) addr;
+ diag = put_user(contents, cp);
+ break;
+ }
+ default:
+ kdb_printf("kdba_putword: Bad width\n");
+ return 0;
+ }
+
+ if (diag) {
+ if (!KDB_STATE(SUPPRESS)) {
+ kdb_printf("kdb: Bad user address 0x%lx\n", addr);
+ KDB_STATE_SET(SUPPRESS);
+ }
+ return 0;
+ }
+ KDB_STATE_CLEAR(SUPPRESS);
+ return 0;
+ }
+
+#if 0
+ if (addr > (unsigned long)high_memory) {
+ if (!kdb_vmlist_check(addr, addr+size)) {
+ /*
+ * Would appear to be an illegal kernel address;
+ * Print a message once, and don't print again until
+ * a legal address is used.
+ */
+ if (!KDB_STATE(SUPPRESS)) {
+ kdb_printf("kdb: xx Bad kernel address 0x%lx\n", addr);
+ KDB_STATE_SET(SUPPRESS);
+ }
+ return 0L;
+ }
+ }
+#endif
+
+ /*
+ * A good address. Reset error flag.
+ */
+ KDB_STATE_CLEAR(SUPPRESS);
+
+ switch (size) {
+ case 4:
+ { unsigned long *lp;
+
+ lp = (unsigned long *)(addr);
+ *lp = contents;
+ return 0;
+ }
+ case 2:
+ { unsigned short *sp;
+
+ sp = (unsigned short *)(addr);
+ *sp = (unsigned short) contents;
+ return 0;
+ }
+ case 1:
+ { unsigned char *cp;
+
+ cp = (unsigned char *)(addr);
+ *cp = (unsigned char) contents;
+ return 0;
+ }
+ }
+
+ kdb_printf("kdba_putword: Bad width 0x%lx\n",size);
+ return 0;
+}
+
+/*
+ * kdba_callback_die
+ *
+ * Callback function for kernel 'die' function.
+ *
+ * Parameters:
+ * regs Register contents at time of trap
+ * error_code Trap-specific error code value
+ * trapno Trap number
+ * vp Pointer to die message
+ * Returns:
+ * Returns 1 if fault handled by kdb.
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ */
+int
+kdba_callback_die(struct pt_regs *regs, int error_code, long trapno, void *vp)
+{
+ /*
+ * Save a pointer to the message provided to 'die()'.
+ */
+ kdb_diemsg = (char *)vp;
+
+ return kdb(KDB_REASON_OOPS, error_code, (kdb_eframe_t) regs);
+}
+
+/*
+ * kdba_callback_bp
+ *
+ * Callback function for kernel breakpoint trap.
+ *
+ * Parameters:
+ * regs Register contents at time of trap
+ * error_code Trap-specific error code value
+ * trapno Trap number
+ * vp Not Used.
+ * Returns:
+ * Returns 1 if fault handled by kdb.
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ */
+
+int
+kdba_callback_bp(struct pt_regs *regs, int error_code, long trapno, void *vp)
+{
+ int diag;
+
+ if (KDB_DEBUG(BP))
+ kdb_printf("cb_bp: e_c = %d tn = %ld regs = 0x%p\n", error_code,
+ trapno, regs);
+
+ diag = kdb(KDB_REASON_BREAK, error_code, (kdb_eframe_t) regs);
+
+ if (KDB_DEBUG(BP))
+ kdb_printf("cb_bp: e_c = %d tn = %ld regs = 0x%p diag = %d\n", error_code,
+ trapno, regs, diag);
+ return diag;
+}
+
+/*
+ * kdba_callback_debug
+ *
+ * Callback function for kernel debug register trap.
+ *
+ * Parameters:
+ * regs Register contents at time of trap
+ * error_code Trap-specific error code value
+ * trapno Trap number
+ * vp Not used.
+ * Returns:
+ * Returns 1 if fault handled by kdb.
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ */
+
+int
+kdba_callback_debug(struct pt_regs *regs, int error_code, long trapno, void *vp)
+{
+ return kdb(KDB_REASON_DEBUG, error_code, (kdb_eframe_t) regs);
+}
+
+/*
+ * kdba_adjust_ip
+ *
+ * Architecture specific adjustment of instruction pointer before leaving
+ * kdb.
+ *
+ * Parameters:
+ * reason The reason KDB was invoked
+ * error The hardware-defined error code
+ * ef The exception frame at time of fault/breakpoint. If reason
+ * is KDB_REASON_SILENT then ef is NULL, otherwise it should
+ * always be valid.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ * noop on ix86.
+ */
+
+void
+kdba_adjust_ip(kdb_reason_t reason, int error, kdb_eframe_t ef)
+{
+ return;
+}
+
+
+#if 0 /* comment this as of now - looks like nobody is using it*/
+/*
+ * kdba_find_tb_table
+ *
+ * Find the traceback table (defined by the ELF64 ABI) located at
+ * the end of the function containing pc.
+ *
+ * Parameters:
+ * nip starting instruction addr.
+ * does not need to be at the start of the func.
+ * tab table to populate if successful
+ * Returns:
+ * non-zero if successful. unsuccessful means that
+ * a valid tb table was not found
+ * Locking:
+ * None.
+ * Remarks:
+ * None.
+ */
+int kdba_find_tb_table(kdb_machreg_t nip, kdbtbtable_t *tab)
+{
+ kdb_machreg_t codeaddr = nip;
+ kdb_machreg_t codeaddr_max;
+ kdb_machreg_t tbtab_start;
+ int instr;
+ int num_parms;
+
+ if (tab == NULL)
+ return 0;
+ memset(tab, 0, sizeof(tab));
+
+ if (nip < PAGE_OFFSET) {
+ /* this is gonna fail for userspace, at least for now.. */
+ return 0;
+ }
+
+ /* Scan instructions starting at codeaddr for 128k max */
+ for (codeaddr_max = codeaddr + 128*1024*4;
+ codeaddr < codeaddr_max;
+ codeaddr += 4) {
+ instr = kdba_getword(codeaddr, 4);
+ if (instr == 0) {
+ /* table should follow. */
+ int version;
+ unsigned long flags;
+ tbtab_start = codeaddr; /* save it to compute func start addr */
+ codeaddr += 4;
+ flags = kdba_getword(codeaddr, 8);
+ tab->flags = flags;
+ version = (flags >> 56) & 0xff;
+ if (version != 0)
+ continue; /* No tb table here. */
+ /* Now, like the version, some of the flags are values
+ that are more conveniently extracted... */
+ tab->fp_saved = (flags >> 24) & 0x3f;
+ tab->gpr_saved = (flags >> 16) & 0x3f;
+ tab->fixedparms = (flags >> 8) & 0xff;
+ tab->floatparms = (flags >> 1) & 0x7f;
+ codeaddr += 8;
+ num_parms = tab->fixedparms + tab->floatparms;
+ if (num_parms) {
+ unsigned int parminfo;
+ int parm;
+ if (num_parms > 32)
+ return 1; /* incomplete */
+ parminfo = kdba_getword(codeaddr, 4);
+ /* decode parminfo...32 bits.
+ A zero means fixed. A one means float and the
+ following bit determines single (0) or double (1).
+ */
+ for (parm = 0; parm < num_parms; parm++) {
+ if (parminfo & 0x80000000) {
+ parminfo <<= 1;
+ if (parminfo & 0x80000000)
+ tab->parminfo[parm] = KDBTBTAB_PARMDFLOAT;
+ else
+ tab->parminfo[parm] = KDBTBTAB_PARMSFLOAT;
+ } else {
+ tab->parminfo[parm] = KDBTBTAB_PARMFIXED;
+ }
+ parminfo <<= 1;
+ }
+ codeaddr += 4;
+ }
+ if (flags & KDBTBTAB_FLAGSHASTBOFF) {
+ tab->tb_offset = kdba_getword(codeaddr, 4);
+ if (tab->tb_offset > 0) {
+ tab->funcstart = tbtab_start - tab->tb_offset;
+ }
+ codeaddr += 4;
+ }
+ /* hand_mask appears to be always be omitted. */
+ if (flags & KDBTBTAB_FLAGSHASCTL) {
+ /* Assume this will never happen for C or asm */
+ return 1; /* incomplete */
+ }
+ if (flags & KDBTBTAB_FLAGSNAMEPRESENT) {
+ int i;
+ short namlen = kdba_getword(codeaddr, 2);
+ if (namlen >= sizeof(tab->name))
+ namlen = sizeof(tab->name)-1;
+ codeaddr += 2;
+ for (i = 0; i < namlen; i++) {
+ tab->name[i] = kdba_getword(codeaddr++, 1);
+ }
+ tab->name[namlen] = '\0';
+ }
+ /* Fake up a symtab entry in case the caller finds it useful */
+ tab->symtab.value = tab->symtab.sym_start = tab->funcstart;
+ tab->symtab.sym_name = tab->name;
+ tab->symtab.sym_end = tbtab_start;
+ return 1;
+ }
+ }
+ return 0; /* hit max...sorry. */
+}
+#endif /* if 0 */
+
+int
+kdba_putarea_size(unsigned long to_xxx, void *from, size_t size)
+{
+ return __copy_to_user((void *)to_xxx,from,size);
+}
+
+/*
+ * valid_ppc64_kernel_address() returns '1' if the address passed in is
+ * within a valid range. Function returns 0 if address is outside valid ranges.
+ */
+
+/*
+
+ KERNELBASE c000000000000000
+ (good range)
+ high_memory c0000000 20000000
+
+ VMALLOC_START d000000000000000
+ (good range)
+ VMALLOC_END VMALLOC_START + VALID_EA_BITS
+
+ IMALLOC_BASE e000000000000000
+ (good range)
+ IMALLOC_END IMALLOC_START + VALID_EA_BITS
+
+*/
+
+int
+valid_ppc64_kernel_address(unsigned long addr, unsigned long size)
+{
+ unsigned long i;
+ unsigned long end = (addr + size - 1);
+
+ int userspace_enabled=0;
+
+/* set USERSPACE=1 to enable userspace memory lookups*/
+ kdbgetintenv("USERSPACE", &userspace_enabled);
+
+ for (i = addr; i <= end; i++) {
+ if (
+ (!userspace_enabled &&
+ ((unsigned long)i < (unsigned long)KERNELBASE )) ||
+ (((unsigned long)i > (unsigned long)high_memory) &&
+ ((unsigned long)i < (unsigned long)VMALLOC_START) ) ||
+ (((unsigned long)i > (unsigned long)VMALLOC_END) &&
+ ((unsigned long)i < (unsigned long)IMALLOC_BASE) ) ||
+ ( (unsigned long)i > (unsigned long)IMALLOC_END ) ) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+int
+kdba_getarea_size(void *to, unsigned long from_xxx, size_t size)
+{
+ int is_valid_kern_addr = valid_ppc64_kernel_address(from_xxx, size);
+ int diag = 0;
+
+ if (is_valid_kern_addr) {
+ memcpy(to, (void *)from_xxx, size);
+ } else {
+ /* user space address, just return. */
+ diag = -1;
+ }
+
+ return diag;
+}
+
+int
+kdba_verify_rw(unsigned long addr, size_t size)
+{
+ unsigned char data[size];
+ return(kdba_getarea_size(data, addr, size) || kdba_putarea_size(addr, data, size));
+}
+
+/*
+ * kdba_readarea_size, reads size-lump of memory into to* passed in, returns size.
+ * Making it feel a bit more like mread.. when i'm clearer on kdba end, probally will
+ * remove one of these.
+ */
+int
+kdba_readarea_size(unsigned long from_xxx,void *to, size_t size)
+{
+ int is_valid_kern_addr = valid_ppc64_kernel_address(from_xxx, size);
+
+ *((volatile char *)to) = '\0';
+ *((volatile char *)to + size - 1) = '\0';
+
+ if (is_valid_kern_addr) {
+ memcpy(to, (void *)from_xxx, size);
+ return size;
+ }
+
+ /* user-space, just return... */
+ return 0;
+}
+
+/* utilities migrated from Xmon or other kernel debug tools. */
+
+/*
+Notes for migrating functions from xmon...
+Add functions to this file. parmlist for functions must match
+ (int argc, const char **argv, const char **envp, struct pt_regs *fp)
+add function prototype to kdbasupport.c
+add function hook to kdba_init() within kdbasupport.c
+
+Common bits...
+mread() function calls need to be changed to kdba_readarea_size calls. straightforward change.
+This:
+ nr = mread(codeaddr, &namlen, 2);
+becomes this:
+ nr = kdba_readarea_size(codeaddr,&namlen,2);
+*/
+
+#define EOF (-1)
+
+/* prototypes */
+int scanhex(unsigned long *);
+int hexdigit(int c);
+/* int kdba_readarea_size(unsigned long from_xxx,void *to, size_t size); */
+void machine_halt(void);
+
+/* Very cheap human name for vector lookup. */
+static
+const char *getvecname(unsigned long vec)
+{
+ char *ret;
+ switch (vec) {
+ case 0x100: ret = "(System Reset)"; break;
+ case 0x200: ret = "(Machine Check)"; break;
+ case 0x300: ret = "(Data Access)"; break;
+ case 0x400: ret = "(Instruction Access)"; break;
+ case 0x500: ret = "(Hardware Interrupt)"; break;
+ case 0x600: ret = "(Alignment)"; break;
+ case 0x700: ret = "(Program Check)"; break;
+ case 0x800: ret = "(FPU Unavailable)"; break;
+ case 0x900: ret = "(Decrementer)"; break;
+ case 0xc00: ret = "(System Call)"; break;
+ case 0xd00: ret = "(Single Step)"; break;
+ case 0xf00: ret = "(Performance Monitor)"; break;
+ default: ret = "";
+ }
+ return ret;
+}
+
+int
+kdba_halt(int argc, const char **argv, const char **envp, struct pt_regs *fp)
+{
+ kdb_printf("halting machine. ");
+ machine_halt();
+ return 0;
+}
+
+static inline void
+kdba_printname (unsigned long addr)
+{
+ const char *name;
+ char *modname;
+ long size, offset;
+ char tmpstr[128];
+
+ name = kallsyms_lookup(addr, &size, &offset, &modname, tmpstr);
+ if (name) {
+ if (modname)
+ kdb_printf(" (%s:%s+0x%lx)", modname, name, offset);
+ else
+ kdb_printf(" (%s+0x%lx)", name, offset);
+ }
+}
+
+int
+kdba_excprint(int argc, const char **argv,
+ const char **envp, struct pt_regs *fp)
+{
+ struct task_struct *c;
+
+#ifdef CONFIG_SMP
+ kdb_printf("cpu %d: ", smp_processor_id());
+#endif /* CONFIG_SMP */
+
+ kdb_printf("Vector: %lx %s at [%p]\n", fp->trap, getvecname(fp->trap), fp);
+ kdb_printf(" pc: %lx", fp->nip);
+
+ kdba_printname (fp->nip);
+ kdb_printf("\n");
+ kdb_printf(" lr: %lx", fp->link);
+ kdba_printname (fp->link);
+
+ kdb_printf("\n");
+ kdb_printf(" sp: %lx\n", fp->gpr[1]);
+ kdb_printf(" msr: %lx\n", fp->msr);
+
+ if (fp->trap == 0x300 || fp->trap == 0x380 || fp->trap == 0x600) {
+ kdb_printf(" dar: %lx\n", fp->dar);
+ kdb_printf(" dsisr: %lx\n", fp->dsisr);
+ }
+
+ /* XXX: need to copy current or we die. Why? */
+ c = current;
+ kdb_printf(" current = 0x%p\n", c);
+ kdb_printf(" paca = 0x%p\n", get_paca());
+ if (c) {
+ kdb_printf(" current = %p, pid = %ld, comm = %s\n",
+ c, (unsigned long)c->pid, (char *)c->comm);
+ }
+ return 0;
+}
+
+int
+kdba_dissect_msr(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ long int msr;
+
+ if (argc==0)
+ msr = regs->msr;
+ else
+ kdbgetularg(argv[1], &msr);
+
+ kdb_printf("msr: %lx (",msr);
+ {
+ if (msr & MSR_SF) kdb_printf("SF ");
+ if (msr & MSR_ISF) kdb_printf("ISF ");
+ if (msr & MSR_HV) kdb_printf("HV ");
+ if (msr & MSR_VEC) kdb_printf("VEC ");
+ if (msr & MSR_POW) kdb_printf("POW/"); /* pow/we share */
+ if (msr & MSR_WE) kdb_printf("WE ");
+ if (msr & MSR_TGPR) kdb_printf("TGPR/"); /* tgpr/ce share */
+ if (msr & MSR_CE) kdb_printf("CE ");
+ if (msr & MSR_ILE) kdb_printf("ILE ");
+ if (msr & MSR_EE) kdb_printf("EE ");
+ if (msr & MSR_PR) kdb_printf("PR ");
+ if (msr & MSR_FP) kdb_printf("FP ");
+ if (msr & MSR_ME) kdb_printf("ME ");
+ if (msr & MSR_FE0) kdb_printf("FE0 ");
+ if (msr & MSR_SE) kdb_printf("SE ");
+ if (msr & MSR_BE) kdb_printf("BE/"); /* be/de share */
+ if (msr & MSR_DE) kdb_printf("DE ");
+ if (msr & MSR_FE1) kdb_printf("FE1 ");
+ if (msr & MSR_IP) kdb_printf("IP ");
+ if (msr & MSR_IR) kdb_printf("IR ");
+ if (msr & MSR_DR) kdb_printf("DR ");
+ if (msr & MSR_PE) kdb_printf("PE ");
+ if (msr & MSR_PX) kdb_printf("PX ");
+ if (msr & MSR_RI) kdb_printf("RI ");
+ if (msr & MSR_LE) kdb_printf("LE ");
+ }
+ kdb_printf(")\n");
+
+ if (msr & MSR_SF) kdb_printf(" 64 bit mode enabled \n");
+ if (msr & MSR_ISF) kdb_printf(" Interrupt 64b mode valid on 630 \n");
+ if (msr & MSR_HV) kdb_printf(" Hypervisor State \n");
+ if (msr & MSR_VEC) kdb_printf(" Enable Altivec \n");
+ if (msr & MSR_POW) kdb_printf(" Enable Power Management \n");
+ if (msr & MSR_WE) kdb_printf(" Wait State Enable \n");
+ if (msr & MSR_TGPR) kdb_printf(" TLB Update registers in use \n");
+ if (msr & MSR_CE) kdb_printf(" Critical Interrupt Enable \n");
+ if (msr & MSR_ILE) kdb_printf(" Interrupt Little Endian \n");
+ if (msr & MSR_EE) kdb_printf(" External Interrupt Enable \n");
+ if (msr & MSR_PR) kdb_printf(" Problem State / Privilege Level \n");
+ if (msr & MSR_FP) kdb_printf(" Floating Point enable \n");
+ if (msr & MSR_ME) kdb_printf(" Machine Check Enable \n");
+ if (msr & MSR_FE0) kdb_printf(" Floating Exception mode 0 \n");
+ if (msr & MSR_SE) kdb_printf(" Single Step \n");
+ if (msr & MSR_BE) kdb_printf(" Branch Trace \n");
+ if (msr & MSR_DE) kdb_printf(" Debug Exception Enable \n");
+ if (msr & MSR_FE1) kdb_printf(" Floating Exception mode 1 \n");
+ if (msr & MSR_IP) kdb_printf(" Exception prefix 0x000/0xFFF \n");
+ if (msr & MSR_IR) kdb_printf(" Instruction Relocate \n");
+ if (msr & MSR_DR) kdb_printf(" Data Relocate \n");
+ if (msr & MSR_PE) kdb_printf(" Protection Enable \n");
+ if (msr & MSR_PX) kdb_printf(" Protection Exclusive Mode \n");
+ if (msr & MSR_RI) kdb_printf(" Recoverable Exception \n");
+ if (msr & MSR_LE) kdb_printf(" Little Endian \n");
+ kdb_printf(".\n");
+
+ return 0;
+}
+
+int
+kdba_super_regs(int argc, const char **argv, const char **envp, struct pt_regs *regs){
+ int i;
+ unsigned long sp, toc;
+
+ kdb_printf("sr::");
+ asm("mr %0,1" : "=r" (sp) :);
+ asm("mr %0,2" : "=r" (toc) :);
+
+ kdb_printf("msr = %.16lx sprg0= %.16lx\n", get_msr(), get_sprg0());
+ kdb_printf("pvr = %.16lx sprg1= %.16lx\n", get_pvr(), get_sprg1());
+ kdb_printf("dec = %.16lx sprg2= %.16lx\n", get_our_dec(), get_sprg2());
+ kdb_printf("sp = %.16lx sprg3= %.16lx\n", sp, get_sprg3());
+ kdb_printf("toc = %.16lx dar = %.16lx\n", toc, get_dar());
+ kdb_printf("srr0 = %.16lx srr1 = %.16lx\n", get_srr0(), get_srr1());
+ kdb_printf("asr = %.16lx\n", get_asr());
+ for (i = 0; i < 8; ++i) {
+ kdb_printf("sr%.2ld = %.16lx sr%.2ld = %.16lx\n",
+ (long int)i, (unsigned long)get_sr(i),
+ (long int)(i+8), (long unsigned int) get_sr(i+8));
+ }
+ return 0;
+}
+
+int
+kdba_dump_tce_table(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ struct iommu_table it;
+ unsigned long tce_table_address;
+ unsigned long bitmap, alloced = 0;
+ int nr, i, j;
+
+ if (argc == 0) {
+ kdb_printf("need address\n");
+ return 0;
+ } else
+ kdbgetularg(argv[1], &tce_table_address);
+
+ /* with address, read contents of memory and dump tce table. */
+ nr = kdba_readarea_size(tce_table_address + 0, &it.it_busno, 8);
+ if (nr == 0) {
+ kdb_printf("Invalid address\n");
+ return 0;
+ }
+ nr = kdba_readarea_size(tce_table_address, &it,
+ sizeof(struct iommu_table));
+
+ kdb_printf("\n");
+ kdb_printf("tce_table at address %s:\n",argv[1]);
+ kdb_printf("it_busno: 0x%lx\n", (unsigned long)it.it_busno);
+ kdb_printf("it_size: 0x%lx\n", (unsigned long)it.it_size);
+ kdb_printf("it_offset: 0x%lx\n", (unsigned long)it.it_offset);
+ kdb_printf("it_base: 0x%lx\n", (unsigned long)it.it_base);
+ kdb_printf("it_index: 0x%lx\n", (unsigned long)it.it_index);
+ kdb_printf("it_type: 0x%lx\n", (unsigned long)it.it_type);
+ kdb_printf("it_blocksize: 0x%lx\n", (unsigned long)it.it_blocksize);
+ kdb_printf("it_hint: 0x%lx\n", (unsigned long)it.it_hint);
+ kdb_printf("it_largehint: 0x%lx\n", (unsigned long)it.it_largehint);
+ kdb_printf("it_halfpoint: 0x%lx\n", (unsigned long)it.it_halfpoint);
+ kdb_printf("it_map: 0x%lx\n", (unsigned long)it.it_map);
+
+ if (it.it_map &&
+ (valid_ppc64_kernel_address((unsigned long)it.it_map, 8))) {
+ for (i = 0; i < (it.it_size/64); i++) {
+ nr = kdba_readarea_size((unsigned long)(it.it_map + (i * 8)), &bitmap, 8);
+ if (bitmap) {
+ for (j = 0; j < 64; j++) {
+ if ((bitmap >> j) & 0x01)
+ alloced++;
+ }
+ }
+ }
+ }
+
+ kdb_printf("TCE entries alloced = %ld\n", alloced);
+ kdb_printf("TCE entries free = %ld\n", it.it_size - alloced);
+
+ kdb_printf("\n");
+ return 0;
+}
+
+int
+kdba_kernelversion(int argc, const char **argv,
+ const char **envp, struct pt_regs *regs)
+{
+ kdb_printf("%s\n",linux_banner);
+ return 0;
+}
+
+char *kdb_dumpall_cmds[] = {
+ "excp\n",
+ "bt\n",
+ "rd\n",
+ "dmesg\n",
+ "msr\n",
+ "superreg\n",
+ "ps\n",
+ "cpu\n",
+ "set BTAPROMPT=none\n",
+ "bta\n",
+ 0
+};
+
+char *kdb_dumpbasic_cmds[] = {
+ "excp\n",
+ "bt\n",
+ "rd\n",
+ "dmesg 25\n",
+ "msr\n",
+ "superreg\n",
+ "ps\n",
+ "cpu\n",
+ 0
+};
+
+/* dump with "all" parm will dump all.
+ * all other variations dump basic.
+ * See the dump*_cmds defined above
+ */
+int
+kdba_dump(int argc, const char **argv, const char **envp, struct pt_regs *fp)
+{
+ int i, diag;
+ kdb_printf("dump-all\n");
+ if ((argc==1)&& (strcmp(argv[1], "all")==0)) {
+ for (i = 0; kdb_dumpall_cmds[i]; ++i) {
+ kdb_printf("kdb_cmd[%d]%s: %s",
+ i, " ", kdb_dumpall_cmds[i]);
+ diag = kdb_parse(kdb_dumpall_cmds[i], fp);
+ if (diag)
+ kdb_printf("command failed, kdb diag %d\n", diag);
+ }
+ } else {
+ kdb_printf("dump-basic\n");
+ for (i = 0; kdb_dumpbasic_cmds[i]; ++i) {
+ kdb_printf("kdb_cmd[%d]%s: %s",
+ i, " ", kdb_dumpbasic_cmds[i]);
+ diag = kdb_parse(kdb_dumpbasic_cmds[i], fp);
+ if (diag)
+ kdb_printf("command failed, kdb diag %d\n", diag);
+ }
+ }
+ return 0;
+}
+
+#ifdef CONFIG_PPC_RTAS
+
+/* enable or disable surveillance.. based on rtasd.c function.
+ * no arguments - display current timeout value.
+ * one argument - 'off' or '0' turn off surveillance.
+ * - '1-255' set surveillance timeout to argument.
+ */
+
+int
+kdba_surveillance(int argc, const char **argv,
+ const char **envp, struct pt_regs *fp)
+{
+ unsigned long timeout;
+ int ibm_indicator_token = 9000;
+ int error;
+ int ret;
+
+ if (argc==0) {
+ goto surveillance_status;
+ } else if (((argc==1)&& (strcmp(argv[1], "off")==0))) {
+ timeout=0;
+ } else {
+ kdbgetularg(argv[1], &timeout);
+ }
+
+ error = rtas_call(rtas_token("set-indicator"), 3, 1, &ret,
+ ibm_indicator_token, 0, timeout);
+ /* kdb_printf("Surveillance set-indicator returned value: 0x%x\n",ret); */
+
+ if (error)
+ kdb_printf("surveillance rtas_call failure 0x%x \n",error);
+
+surveillance_status:
+ rtas_call(rtas_token("get-sensor-state"), 2, 2, &ret,
+ ibm_indicator_token,
+ 0 /* instance */);
+ kdb_printf("Current surveillance timeout is %d minutes%s.\n",
+ ret, ret==0?" (disabled)":"");
+ return 0;
+}
+#endif /* CONFIG_PPC_RTAS */
+
+/* generic debugger() hooks into kdb.
+ * These eliminate the need to add
+ * ifdef CONFIG_KDB goop to traps.c and fault.c
+ */
+
+void
+kdb_reset_debugger(struct pt_regs *regs)
+{
+ int cpu=smp_processor_id();
+ static int reset_cpu = -1;
+ static spinlock_t reset_lock = SPIN_LOCK_UNLOCKED;
+
+ spin_lock(&reset_lock);
+ if (reset_cpu == -1 || reset_cpu == cpu) {
+ reset_cpu = cpu;
+ spin_unlock(&reset_lock);
+ if (kdb_on) {
+ kdb(KDB_REASON_ENTER, regs->trap, (kdb_eframe_t) regs);
+ } else {
+ kdb_on=1;
+ kdb_do_reboot=1;
+ udelay(KDB_RESET_TIMEOUT);
+ kdb_on=0;
+ if (kdb_do_reboot) {
+ ppc_md.restart("rebooting...");
+ return; /* not reached */
+ } else {
+ return;
+ }
+ }
+ } else {
+ spin_unlock(&reset_lock);
+ return;
+ }
+}
+
+int
+kdb_debugger(struct pt_regs *regs)
+{
+ if (regs) {
+ if (regs->trap==0x100) {
+ kdb_reset_debugger(regs);
+ if (!(regs->msr & MSR_RI)) {
+ /* unrecoverable exception, spin forever,
+ * don't return to exception handler
+ */
+ while (1) {}
+ }
+ } else {
+ kdb(KDB_REASON_ENTER,regs->trap,regs); /* ok */
+ }
+ } else { /* regs invalid */
+ kdb(KDB_REASON_SILENT,0,regs);
+ }
+ return 1;
+}
+
+int
+kdb_debugger_bpt(struct pt_regs *regs)
+{
+ if (regs) {
+ if (regs->msr & MSR_SE) {
+ regs->msr &= ~MSR_SE;
+ return kdb(KDB_REASON_DEBUG, regs->trap, regs);
+ }
+ return kdb(KDB_REASON_BREAK,regs->trap,regs);
+ } else /* regs invalid */
+ return kdb(KDB_REASON_SILENT,0,regs);
+}
+
+int
+kdb_debugger_sstep(struct pt_regs *regs)
+{
+ if (regs)
+ return kdb(KDB_REASON_DEBUG,regs->trap,regs); /* ok */
+ else /* regs invalid */
+ return kdb(KDB_REASON_SILENT,0,regs);
+}
+
+int
+kdb_debugger_iabr_match(struct pt_regs *regs)
+{
+ if (regs)
+ return kdb(KDB_REASON_BREAK,regs->trap,regs);
+ else /* regs invalid */
+ return kdb(KDB_REASON_SILENT,0,regs);
+}
+
+int
+kdb_debugger_dabr_match(struct pt_regs *regs)
+{
+ if (regs)
+ return kdb(KDB_REASON_BREAK,regs->trap,regs);
+ else /* regs invalid */
+ return kdb(KDB_REASON_SILENT,0,regs);
+}
+
+int kdb_debugger_ipi(struct pt_regs *regs)
+{
+#ifdef CONFIG_SMP
+ return kdb_ipi(regs, NULL);
+#else
+ return 0;
+#endif
+}
+
+int
+kdba_state(int argc, const char **argv, const char **envp, struct pt_regs *fp)
+{
+ int i;
+ for (i=0;i<NR_CPUS;i++) {
+ if ( kdb_state[i] != 0 ) {
+ kdb_printf("kdb_state[%d] = %x" ,i,kdb_state[i]);
+ kdb_printf(" [");
+ if KDB_STATE_CPU(KDB,i) kdb_printf("KDB,");
+ if KDB_STATE_CPU(LEAVING,i) kdb_printf("LEAVING,");
+ if KDB_STATE_CPU(CMD,i) kdb_printf("CMD,");
+ if KDB_STATE_CPU(KDB_CONTROL,i) kdb_printf("KDB_CONTROL,");
+ if KDB_STATE_CPU(HOLD_CPU,i) kdb_printf("HOLD_CPU,");
+ if KDB_STATE_CPU(DOING_SS,i) kdb_printf("DOING_SS,");
+ if KDB_STATE_CPU(DOING_SSB,i) kdb_printf("DOING_SSB,");
+ if KDB_STATE_CPU(SSBPT,i) kdb_printf("SSBPT,");
+ if KDB_STATE_CPU(REENTRY,i) kdb_printf("REENTRY,");
+ if KDB_STATE_CPU(SUPPRESS,i) kdb_printf("SUPPRESS,");
+ if KDB_STATE_CPU(LONGJMP,i) kdb_printf("LONGJMP,");
+ if KDB_STATE_CPU(PRINTF_LOCK,i) kdb_printf("PRINTF_LOCK,");
+ if KDB_STATE_CPU(WAIT_IPI,i) kdb_printf("WAIT_IPI,");
+ if KDB_STATE_CPU(RECURSE,i) kdb_printf("RECURSE,");
+ if KDB_STATE_CPU(IP_ADJUSTED,i) kdb_printf("IP_ADJUSTED,");
+ kdb_printf("]\n");
+ }
+ }
+ return 0;
+}
+
+void kdb_become_debugger(void)
+{
+ __debugger = kdb_debugger;
+ __debugger_ipi = kdb_debugger_ipi;
+ __debugger_bpt = kdb_debugger_bpt;
+ __debugger_sstep = kdb_debugger_sstep;
+ __debugger_iabr_match = kdb_debugger_iabr_match;
+ __debugger_dabr_match = kdb_debugger_dabr_match;
+ __debugger_fault_handler = NULL; /* this guy is normally off. */
+
+ if (__debugger_on != NULL && __debugger_on != &kdb_on)
+ *__debugger_on = 0;
+ __debugger_on = &kdb_on;
+}
+
+void
+kdba_set_current_task(const struct task_struct *p)
+{
+ kdb_current_task = p;
+ if (task_curr(p)) {
+ struct kdb_running_process *krp =
+ kdb_running_process + kdb_process_cpu(p);
+ kdb_current_regs = krp->regs;
+ return;
+ }
+ kdb_current_regs = NULL;
+}
+
+void
+kdba_cpu_up(void)
+{
+}
+
+/*
+ * kdba_init
+ * Architecture specific initialization.
+ *
+ * kdb_register("commandname", # name of command user
+ * will use to invoke function
+ * function_name, # name of function within the code
+ * "function example usage", # sample usage
+ * "function description", # brief description.
+ * 0 # if i hit enter again,
+ * will command repeat itself ?
+ * Note: functions must take parameters as such:
+ * functionname(int argc, const char **argv, const char **envp,
+ * struct pt_regs *regs)
+ */
+
+void __init
+kdba_init(void)
+{
+#ifdef CONFIG_MAGIC_SYSRQ
+ register_sysrq_key('d', &sysrq_kdb_op);
+#endif
+#ifndef CONFIG_KDB_OFF
+ kdb_become_debugger();
+#endif
+ kdb_register("excp", kdba_excprint, "excp", "print exception info", 0);
+ kdb_register("superreg", kdba_super_regs, "superreg", "display super_regs", 0);
+ kdb_register("msr", kdba_dissect_msr, "msr", "dissect msr", 0);
+ kdb_register("halt", kdba_halt, "halt", "halt machine", 0);
+ kdb_register("tce_table", kdba_dump_tce_table, "tce_table <addr> [full]", "dump the tce table located at <addr>", 0);
+ kdb_register("kernel", kdba_kernelversion, "version", "display running kernel version", 0);
+ kdb_register("dump", kdba_dump, "dump (all|basic)", "dump all info", 0);
+ kdb_register("state", kdba_state, "state ", "dump state of all processors", 0);
+#ifdef CONFIG_PPC_RTAS
+ kdb_register("surv", kdba_surveillance, "surv [off|1-255] ", "disable/change surveillance timeout", 0);
+#endif
+}
+
+#ifdef CONFIG_SMP
+void
+smp_kdb_stop(void)
+{
+ smp_send_debugger_break(MSG_ALL_BUT_SELF);
+}
+
+void
+kdba_wait_for_cpus(void)
+{
+}
+#endif
--- /dev/null
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define GETREG(reg) \
+ static inline unsigned long get_ ## reg (void) \
+ { unsigned long ret; asm volatile ("mf" #reg " %0" : "=r" (ret) :); return ret; }
+
+#define SETREG(reg) \
+ static inline void set_ ## reg (unsigned long val) \
+ { asm volatile ("mt" #reg " %0" : : "r" (val)); }
+
+GETREG(asr)
+GETREG(msr)
+SETREG(msr)
+SETREG(msrd)
+GETREG(cr)
+
+#define GSETSPR(n, name) \
+ static inline long get_ ## name (void) \
+ { long ret; asm volatile ("mfspr %0," #n : "=r" (ret) : ); return ret; } \
+ static inline void set_ ## name (long val) \
+ { asm volatile ("mtspr " #n ",%0" : : "r" (val)); }
+
+GSETSPR(0, mq)
+GSETSPR(1, xer)
+GSETSPR(4, rtcu)
+GSETSPR(5, our_rtcl) // clashes with asm/time.h
+GSETSPR(8, lr)
+GSETSPR(9, ctr)
+GSETSPR(18, dsisr)
+GSETSPR(19, dar)
+GSETSPR(22, our_dec) // clashes with asm/time.h
+GSETSPR(25, sdr1)
+GSETSPR(26, srr0)
+GSETSPR(27, srr1)
+GSETSPR(272, sprg0)
+GSETSPR(273, sprg1)
+GSETSPR(274, sprg2)
+GSETSPR(275, sprg3)
+GSETSPR(282, ear)
+GSETSPR(287, pvr)
+GSETSPR(528, bat0u)
+GSETSPR(529, bat0l)
+GSETSPR(530, bat1u)
+GSETSPR(531, bat1l)
+GSETSPR(532, bat2u)
+GSETSPR(533, bat2l)
+GSETSPR(534, bat3u)
+GSETSPR(535, bat3l)
+GSETSPR(1008, hid0)
+GSETSPR(1009, hid1)
+GSETSPR(1010, iabr)
+GSETSPR(1013, our_dabr) // clashes with asm/system.h
+GSETSPR(1023, pir)
+
+static inline int get_sr(int n)
+{
+ int ret = 0;
+
+#if 0
+// DRENG does not assemble
+ asm (" mfsrin %0,%1" : "=r" (ret) : "r" (n << 28));
+#endif
+ return ret;
+}
+
+static inline void set_sr(int n, int val)
+{
+#if 0
+// DRENG does not assemble
+ asm ("mtsrin %0,%1" : : "r" (val), "r" (n << 28));
+#endif
+}
+
+static inline void store_inst(void *p)
+{
+ asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
+}
+
+static inline void cflush(void *p)
+{
+ asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
+}
+
+static inline void cinval(void *p)
+{
+ asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
+}
+
#include <linux/kprobes.h>
#include <linux/kexec.h>
#include <linux/backlight.h>
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#endif
#include <asm/kdebug.h>
#include <asm/pgtable.h>
int (*__debugger_iabr_match)(struct pt_regs *regs);
int (*__debugger_dabr_match)(struct pt_regs *regs);
int (*__debugger_fault_handler)(struct pt_regs *regs);
+int *__debugger_on;
-EXPORT_SYMBOL(__debugger);
+EXPORT_SYMBOL(debugger);
EXPORT_SYMBOL(__debugger_ipi);
EXPORT_SYMBOL(__debugger_bpt);
EXPORT_SYMBOL(__debugger_sstep);
EXPORT_SYMBOL(__debugger_iabr_match);
EXPORT_SYMBOL(__debugger_dabr_match);
EXPORT_SYMBOL(__debugger_fault_handler);
+
+int debugger(struct pt_regs *regs)
+{
+ if (__debugger_on == NULL || *__debugger_on == 0) {
+ /* pick a debugger */
+#ifdef CONFIG_KDB
+ if (kdb_on)
+ kdb_become_debugger();
+#endif
+#ifdef CONFIG_XMON
+ if (xmon_on)
+ xmon_init(1);
+#endif
+ if (__debugger_on == NULL || *__debugger_on == 0)
+ return 0;
+ }
+ if (__debugger)
+ return __debugger(regs);
+ return 0;
+}
#endif
ATOMIC_NOTIFIER_HEAD(powerpc_die_chain);
}
printk(KERN_CRIT "kernel BUG in %s at %s:%ld!\n",
bug->function, bug->file, bug->line);
-
+ regs->nip += 4; /* step over the twi instruction */
return 0;
}
#define EOF (-1)
+#ifndef printf
#define printf xmon_printf
+#endif
#define putchar xmon_putchar
extern int xmon_putchar(int c);
else
{
if (operand->bits == 3)
- printf("cr%d", value);
+ printf("cr%ld", value);
else
{
static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
const int powerpc_num_opcodes =
sizeof (powerpc_opcodes) / sizeof (powerpc_opcodes[0]);
\f
+#if 0
/* The macro table. This is only used by the assembler. */
/* The expressions of the form (-x ! 31) & (x | 31) have the value 0
const int powerpc_num_macros =
sizeof (powerpc_macros) / sizeof (powerpc_macros[0]);
+#endif
#define scanhex xmon_scanhex
#define skipbl xmon_skipbl
+#ifdef CONFIG_XMON_DEFAULT
+int xmon_on = 1;
+#else
+int xmon_on;
+#endif
+
#ifdef CONFIG_SMP
cpumask_t cpus_in_xmon = CPU_MASK_NONE;
static unsigned long xmon_taken = 1;
__debugger_iabr_match = xmon_iabr_match;
__debugger_dabr_match = xmon_dabr_match;
__debugger_fault_handler = xmon_fault_handler;
- } else {
+ if (__debugger_on != NULL && __debugger_on != &xmon_on)
+ *__debugger_on = 0;
+ __debugger_on = &xmon_on;
+ } else if (__debugger_on == &xmon_on) {
__debugger = NULL;
__debugger_ipi = NULL;
__debugger_bpt = NULL;
__debugger_iabr_match = NULL;
__debugger_dabr_match = NULL;
__debugger_fault_handler = NULL;
+ __debugger_on = NULL;
}
+ xmon_on = enable;
xmon_map_scc();
}
of the kernel code won't be covered by a 2MB TLB anymore.
If in doubt, say "N".
+config KDB
+ bool "Built-in Kernel Debugger support"
+ depends on DEBUG_KERNEL
+ help
+ This option provides a built-in kernel debugger. The built-in
+ kernel debugger contains commands which allow memory to be examined,
+ instructions to be disassembled and breakpoints to be set. For details,
+ see Documentation/kdb/kdb.mm and the manual pages kdb_bt, kdb_ss, etc.
+ Kdb can also be used via the serial port. Set up the system to
+ have a serial console (see Documentation/serial-console.txt).
+ The key sequence <escape>KDB on the serial port will cause the
+ kernel debugger to be entered with input from the serial port and
+ output to the serial console. If unsure, say N.
+
+config KDB_MODULES
+ tristate "KDB modules"
+ depends on KDB
+ help
+ KDB can be extended by adding your own modules, in directory
+ kdb/modules. This option selects the way that these modules should
+ be compiled, as free standing modules (select M) or built into the
+ kernel (select Y). If unsure say M.
+
+config KDB_OFF
+ bool "KDB off by default"
+ depends on KDB
+ help
+ Normally kdb is activated by default, as long as CONFIG_KDB is set.
+ If you want to ship a kernel with kdb support but only have kdb
+ turned on when the user requests it then select this option. When
+ compiled with CONFIG_KDB_OFF, kdb ignores all events unless you boot
+ with kdb=on or you echo "1" > /proc/sys/kernel/kdb. This option also
+ works in reverse, if kdb is normally activated, you can boot with
+ kdb=off or echo "0" > /proc/sys/kernel/kdb to deactivate kdb. If
+ unsure, say N.
+
+config KDB_CONTINUE_CATASTROPHIC
+ int "KDB continues after catastrophic errors"
+ depends on KDB
+ default "0"
+ help
+ This integer controls the behaviour of kdb when the kernel gets a
+ catastrophic error, i.e. for a panic, oops, NMI or other watchdog
+ tripping. CONFIG_KDB_CONTINUE_CATASTROPHIC interacts with
+ /proc/sys/kernel/kdb and CONFIG_DUMP (if your kernel has the LKCD
+ patch).
+ When KDB is active (/proc/sys/kernel/kdb == 1) and a catastrophic
+ error occurs, nothing extra happens until you type 'go'.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 0 (default). The first time
+ you type 'go', kdb warns you. The second time you type 'go', KDB
+ tries to continue - no guarantees that the kernel is still usable.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 1. KDB tries to continue - no
+ guarantees that the kernel is still usable.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 2. If your kernel has the LKCD
+ patch and LKCD is configured to take a dump then KDB forces a dump.
+ Whether or not a dump is taken, KDB forces a reboot.
+ When KDB is not active (/proc/sys/kernel/kdb == 0) and a catastrophic
+ error occurs, the following steps are automatic, no human
+ intervention is required.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 0 (default) or 1. KDB attempts
+ to continue - no guarantees that the kernel is still usable.
+ CONFIG_KDB_CONTINUE_CATASTROPHIC == 2. If your kernel has the LKCD
+ patch and LKCD is configured to take a dump then KDB automatically
+ forces a dump. Whether or not a dump is taken, KDB forces a
+ reboot.
+ If you are not sure, say 0.
+
+config KDB_USB
+ bool "Support for USB Keyboard in KDB (OHCI only)"
+ depends on KDB && USB_OHCI_HCD
+ help
+ If you want to use kdb from a OHCI USB keyboard then say Y here. If you
+ say N then kdb can only be used from a PC (AT) keyboard or a serial
+ console.
+
config IOMMU_DEBUG
depends on IOMMU && DEBUG_KERNEL
bool "Enable IOMMU debugging"
core-$(CONFIG_IA32_EMULATION) += arch/x86_64/ia32/
drivers-$(CONFIG_PCI) += arch/x86_64/pci/
drivers-$(CONFIG_OPROFILE) += arch/x86_64/oprofile/
+drivers-$(CONFIG_KDB) += arch/x86_64/kdb/
boot := arch/x86_64/boot
--- /dev/null
+2006-09-20 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-x86_64-1.
+
+2006-09-15 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc7-x86_64-1.
+
+2006-08-30 Keith Owens <kaos@sgi.com>
+
+ * Do not print debugstackptr in cpu_pda, it will be deleted soon.
+ * Add KDB_ENTER().
+ * Add warning for problems when following alternate stacks.
+ * kdb v4.4-2.6.18-rc5-x86_64-3.
+
+2006-08-29 Keith Owens <kaos@sgi.com>
+
+ * Rewrite all backtrace code.
+ * Add pt_regs and cpu_pda commands.
+ * Include patch to define orig_ist, to be removed once that patch is in
+ the community tree.
+ * kdb v4.4-2.6.18-rc5-x86_64-2.
+
+2006-08-28 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc5-x86_64-1.
+
+2006-08-08 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc4-x86_64-1.
+
+2006-08-04 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc3-x86_64-1.
+
+2006-07-18 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc2-x86_64-1.
+
+2006-07-12 Keith Owens <kaos@sgi.com>
+
+ * sparse cleanups
+ * kdb v4.4-2.6.18-rc1-x86_64-2.
+
+2006-07-07 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc1-x86_64-1.
+
+2006-07-04 Keith Owens <kaos@sgi.com>
+
+ * Make KDB rendezvous on x86_64 a two stage approach.
+ * Move smp_kdb_stop() and smp_kdb_interrupt() to kdbasupport.c.
+ * Move setting of interrupt traps to kdbasupport.c.
+ * Add KDB_REASON_CPU_UP support.
+ * Move per cpu setup to kdba_cpu_up().
+ * Delete kdba_enable_mce, architectures now do their own setup.
+ * Delete kdba_enable_lbr, kdba_disable_lbr, kdba_print_lbr,
+ page_fault_mca. Only ever implemented on x86, difficult to maintain
+ and rarely used in the field.
+ * Replace #ifdef KDB_HAVE_LONGJMP with #ifdef kdba_setjmp.
+ * kdb v4.4-2.6.17-x86_64-2.
+
+2006-06-19 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-x86_64-1.
+
+2006-05-31 Keith Owens <kaos@sgi.com>
+
+ * Define arch/x86_64/kdb/kdb_cmds.
+ * kdb v4.4-2.6.17-rc5-x86_64-2.
+
+2006-05-25 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-rc5-x86_64-1.
+
+2006-05-15 Keith Owens <kaos@sgi.com>
+
+ * Refresh bfd related files from binutils 2.16.91.0.2.
+ * kdb v4.4-2.6.17-rc4-x86_64-2.
+
+2006-05-12 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6-17-rc4-x86_64-1.
+
+2006-04-22 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6-17-rc2-x86_64-1.
+
+2006-04-13 Keith Owens <kaos@sgi.com>
+
+ * Remove trailing white space.
+ * kdb v4.4-2.6-17-rc1-x86_64-1.
+
+2006-03-25 Jack F. Vogel <jfv@bluesong.net>
+ * Sync with Keith's changes for 2.6.16
+ * code from Andi Kleen to support above
+
+2005-09-30 Jack F. Vogel <jfv@bluesong.net>
+ * Port to 2.6.14-rc2
+ * sync with a couple changes from Keith
+ * Add backtrace code from Jim Houston
+ (thanks Jim)
+
+2005-08-31 Jack F. Vogel <jfv@bluesong.net>
+ * Change to linker script for kexec
+ thanks to Steven Dake <sdake@mvista.com>
+
+2005-08-30 Jack F. Vogel <jfv@bluesong.net>
+ * Notify struct should not be devinit
+ thanks IWAMOTO Toshihiro <iwamoto@valinux.co.jp>
+
+2005-08-25 Jack F. Vogel <jfv@bluesong.net>
+ * Update to 2.6.11
+ * Fix to synchronize with the notify changes
+ thanks to Jim Houston.
+
+2004-09-30 Keith Owens <kaos@sgi.com>
+ * Port to 2.6.9-rc2
+ * Fix line editting characters. Jim Houston, Comcast.
+ * kdb v4.4-2.6.9-rc2-x86-64-1.
+
+2004-08-15 Jack F. Vogel <jfv@bluesong.net>
+ * Port to 2.6.8
+ * tighten up the code, using the built-in
+ die_chain notify interface, thanks to
+ Andi Kleen for pointing this out.
+
+2004-05-15 Jack F. Vogel <jfv@bluesong.net>
+ * port to 2.6.6 for x86_64
+
+2003-12-15 Cliff Neighbors <cliff@fabric7.com>
+ * initial port from i386 to x86_64
+
+2002-08-10 Keith Owens <kaos@sgi.com>
+
+ * Replace kdb_port with kdb_serial to support memory mapped I/O.
+ Note: This needs kdb v2.3-2.4.19-common-2 or later.
+ * kdb v2.3-2.4.19-i386-3.
+
+2002-08-09 Keith Owens <kaos@sgi.com>
+
+ * Use -fno-optimize-sibling-calls for kdb if gcc supports it.
+ * .text.lock does not consume an activation frame.
+ * kdb v2.3-2.4.19-i386-2.
+
+2002-08-07 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.19.
+ * Remove individual SGI copyrights, the general SGI copyright applies.
+ * New .text.lock name. Hugh Dickins.
+ * Set KERNEL_CS in kdba_getcurrentframe. Hugh Dickins.
+ * Clean up disassembly layout. Hugh Dickins, Keith Owens.
+ * Replace hard coded stack size with THREAD_SIZE. Hugh Dickins.
+ * Better stack layout on bt with no frame pointers. Hugh Dickins.
+ * Make i386 IO breakpoints (bpha <address> IO) work again.
+ Martin Wilck, Keith Owens.
+ * Remove fixed KDB_MAX_COMMANDS size.
+ * Add set_fs() around __copy_to_user on kernel addresses.
+ Randolph Chung.
+ * Position i386 for CONFIG_NUMA_REPLICATE.
+ * kdb v2.3-2.4.19-i386-1.
+
+2002-07-09 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.19-rc1.
+
+2002-06-14 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.19-pre10.
+ * kdb v2.1-2.4.19-pre10-i386-1.
+
+2002-04-09 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.19-pre6.
+ * kdb v2.1-2.4.19-pre6-i386-1.
+
+2002-02-26 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.18.
+ * kdb v2.1-2.4.18-i386-1.
+
+2002-01-18 Keith Owens <kaos@sgi.com>
+
+ * Use new kdb_get/put functions.
+ * Define kdba_{get,put}area_size functions for i386.
+ * Remove over-engineered dblist callback functions.
+ * Correctly handle failing call disp32 in backtrace.
+ * Remove bp_instvalid flag, redundant code.
+ * Remove dead code.
+ * kdb v2.1-2.4.17-i386-1.
+
+2002-01-04 Keith Owens <kaos@sgi.com>
+
+ * Sync xfs <-> kdb i386 code.
+
--- /dev/null
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+#
+
+obj-$(CONFIG_KDB) := kdba_bt.o kdba_bp.o kdba_id.o kdba_io.o kdbasupport.o x86_64-dis.o
+
+override CFLAGS := $(CFLAGS:%-pg=% )
--- /dev/null
+# Standard architecture specific commands for kdb.
+# These commands are appended to those in kdb/kdb_cmds, see that file for
+# restrictions.
+
+# Standard debugging information for first level support, invoked from archkdb*
+# commands that are defined in kdb/kdb_cmds.
+
+defcmd archkdbcommon "" "Common arch debugging"
+ set LINES 2000000
+ set BTAPROMPT 0
+ -summary
+ -id %rip-24
+ -cpu
+ -ps
+ -dmesg 600
+ -bt
+ -cpu_pda *
+endefcmd
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Breakpoint Handling
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/ptrace.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+
+
+static char *kdba_rwtypes[] = { "Instruction(Register)", "Data Write",
+ "I/O", "Data Access"};
+
+/*
+ * Table describing processor architecture hardware
+ * breakpoint registers.
+ */
+
+kdbhard_bp_t kdb_hardbreaks[KDB_MAXHARDBPT];
+
+/*
+ * kdba_db_trap
+ *
+ * Perform breakpoint processing upon entry to the
+ * processor debugger fault. Determine and print
+ * the active breakpoint.
+ *
+ * Parameters:
+ * regs Exception frame containing machine register state
+ * error Error number passed to kdb.
+ * Outputs:
+ * None.
+ * Returns:
+ * KDB_DB_BPT Standard instruction or data breakpoint encountered
+ * KDB_DB_SS Single Step fault ('ss' command or end of 'ssb' command)
+ * KDB_DB_SSB Single Step fault, caller should continue ('ssb' command)
+ * KDB_DB_SSBPT Single step over breakpoint
+ * KDB_DB_NOBPT No existing kdb breakpoint matches this debug exception
+ * Locking:
+ * None.
+ * Remarks:
+ * Yup, there be goto's here.
+ *
+ * If multiple processors receive debug exceptions simultaneously,
+ * one may be waiting at the kdb fence in kdb() while the user
+ * issues a 'bc' command to clear the breakpoint the processor
+ * which is waiting has already encountered. If this is the case,
+ * the debug registers will no longer match any entry in the
+ * breakpoint table, and we'll return the value KDB_DB_NOBPT.
+ * This can cause a panic in die_if_kernel(). It is safer to
+ * disable the breakpoint (bd), go until all processors are past
+ * the breakpoint then clear the breakpoint (bc). This code
+ * recognises a breakpoint even when disabled but not when it has
+ * been cleared.
+ *
+ * WARNING: This routine clears the debug state. It should be called
+ * once per debug and the result cached.
+ */
+
+kdb_dbtrap_t
+kdba_db_trap(struct pt_regs *regs, int error_unused)
+{
+ kdb_machreg_t dr6;
+ kdb_machreg_t dr7;
+ int rw, reg;
+ int i;
+ kdb_dbtrap_t rv = KDB_DB_BPT;
+ kdb_bp_t *bp;
+
+ if (KDB_NULL_REGS(regs))
+ return KDB_DB_NOBPT;
+
+ dr6 = kdba_getdr6();
+ dr7 = kdba_getdr7();
+
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdb: dr6 0x%lx dr7 0x%lx\n", dr6, dr7);
+ if (dr6 & DR6_BS) {
+ if (KDB_STATE(SSBPT)) {
+ if (KDB_DEBUG(BP))
+ kdb_printf("ssbpt\n");
+ KDB_STATE_CLEAR(SSBPT);
+ for(i=0,bp=kdb_breakpoints;
+ i < KDB_MAXBPT;
+ i++, bp++) {
+ if (KDB_DEBUG(BP))
+ kdb_printf("bp 0x%p enabled %d delayed %d global %d cpu %d\n",
+ bp, bp->bp_enabled, bp->bp_delayed, bp->bp_global, bp->bp_cpu);
+ if (!bp->bp_enabled)
+ continue;
+ if (!bp->bp_global && bp->bp_cpu != smp_processor_id())
+ continue;
+ if (KDB_DEBUG(BP))
+ kdb_printf("bp for this cpu\n");
+ if (bp->bp_delayed) {
+ bp->bp_delayed = 0;
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_installbp\n");
+ kdba_installbp(regs, bp);
+ if (!KDB_STATE(DOING_SS)) {
+ regs->eflags &= ~EF_TF;
+ return(KDB_DB_SSBPT);
+ }
+ break;
+ }
+ }
+ if (i == KDB_MAXBPT) {
+ kdb_printf("kdb: Unable to find delayed breakpoint\n");
+ }
+ if (!KDB_STATE(DOING_SS)) {
+ regs->eflags &= ~EF_TF;
+ return(KDB_DB_NOBPT);
+ }
+ /* FALLTHROUGH */
+ }
+
+ /*
+ * KDB_STATE_DOING_SS is set when the kernel debugger is using
+ * the processor trap flag to single-step a processor. If a
+ * single step trap occurs and this flag is clear, the SS trap
+ * will be ignored by KDB and the kernel will be allowed to deal
+ * with it as necessary (e.g. for ptrace).
+ */
+ if (!KDB_STATE(DOING_SS))
+ goto unknown;
+
+ /* single step */
+ rv = KDB_DB_SS; /* Indicate single step */
+ if (KDB_STATE(DOING_SSB)) {
+ unsigned char instruction[2];
+
+ kdb_id1(regs->rip);
+ if (kdb_getarea(instruction, regs->rip) ||
+ (instruction[0]&0xf0) == 0xe0 || /* short disp jumps */
+ (instruction[0]&0xf0) == 0x70 || /* Misc. jumps */
+ instruction[0] == 0xc2 || /* ret */
+ instruction[0] == 0x9a || /* call */
+ (instruction[0]&0xf8) == 0xc8 || /* enter, leave, iret, int, */
+ ((instruction[0] == 0x0f) &&
+ ((instruction[1]&0xf0)== 0x80))
+ ) {
+ /*
+ * End the ssb command here.
+ */
+ KDB_STATE_CLEAR(DOING_SSB);
+ KDB_STATE_CLEAR(DOING_SS);
+ } else {
+ rv = KDB_DB_SSB; /* Indicate ssb - dismiss immediately */
+ }
+ } else {
+ /*
+ * Print current insn
+ */
+ kdb_printf("SS trap at ");
+ kdb_symbol_print(regs->rip, NULL, KDB_SP_DEFAULT|KDB_SP_NEWLINE);
+ kdb_id1(regs->rip);
+ KDB_STATE_CLEAR(DOING_SS);
+ }
+
+ if (rv != KDB_DB_SSB)
+ regs->eflags &= ~EF_TF;
+ }
+
+ if (dr6 & DR6_B0) {
+ rw = DR7_RW0(dr7);
+ reg = 0;
+ goto handle;
+ }
+
+ if (dr6 & DR6_B1) {
+ rw = DR7_RW1(dr7);
+ reg = 1;
+ goto handle;
+ }
+
+ if (dr6 & DR6_B2) {
+ rw = DR7_RW2(dr7);
+ reg = 2;
+ goto handle;
+ }
+
+ if (dr6 & DR6_B3) {
+ rw = DR7_RW3(dr7);
+ reg = 3;
+ goto handle;
+ }
+
+ if (rv > 0)
+ goto handled;
+
+ goto unknown; /* dismiss */
+
+handle:
+ /*
+ * Set Resume Flag
+ */
+ regs->eflags |= EF_RF;
+
+ /*
+ * Determine which breakpoint was encountered.
+ */
+ for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) {
+ if (!(bp->bp_free)
+ && (bp->bp_global || bp->bp_cpu == smp_processor_id())
+ && (bp->bp_hard)
+ && (bp->bp_hard->bph_reg == reg)) {
+ /*
+ * Hit this breakpoint.
+ */
+ kdb_printf("%s breakpoint #%d at " kdb_bfd_vma_fmt "\n",
+ kdba_rwtypes[rw],
+ i, bp->bp_addr);
+ /*
+ * For an instruction breakpoint, disassemble
+ * the current instruction.
+ */
+ if (rw == 0) {
+ kdb_id1(regs->rip);
+ }
+
+ goto handled;
+ }
+ }
+
+unknown:
+ regs->eflags |= EF_RF; /* Supress further faults */
+ rv = KDB_DB_NOBPT; /* Cause kdb() to return */
+
+handled:
+
+ /*
+ * Clear the pending exceptions.
+ */
+ kdba_putdr6(0);
+
+ return rv;
+}
+
+/*
+ * kdba_bp_trap
+ *
+ * Perform breakpoint processing upon entry to the
+ * processor breakpoint instruction fault. Determine and print
+ * the active breakpoint.
+ *
+ * Parameters:
+ * regs Exception frame containing machine register state
+ * error Error number passed to kdb.
+ * Outputs:
+ * None.
+ * Returns:
+ * 0 Standard instruction or data breakpoint encountered
+ * 1 Single Step fault ('ss' command)
+ * 2 Single Step fault, caller should continue ('ssb' command)
+ * 3 No existing kdb breakpoint matches this debug exception
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ * If multiple processors receive debug exceptions simultaneously,
+ * one may be waiting at the kdb fence in kdb() while the user
+ * issues a 'bc' command to clear the breakpoint the processor which
+ * is waiting has already encountered. If this is the case, the
+ * debug registers will no longer match any entry in the breakpoint
+ * table, and we'll return the value '3'. This can cause a panic
+ * in die_if_kernel(). It is safer to disable the breakpoint (bd),
+ * 'go' until all processors are past the breakpoint then clear the
+ * breakpoint (bc). This code recognises a breakpoint even when
+ * disabled but not when it has been cleared.
+ *
+ * WARNING: This routine resets the rip. It should be called
+ * once per breakpoint and the result cached.
+ */
+
+kdb_dbtrap_t
+kdba_bp_trap(struct pt_regs *regs, int error_unused)
+{
+ int i;
+ kdb_dbtrap_t rv;
+ kdb_bp_t *bp;
+
+ if (KDB_NULL_REGS(regs))
+ return KDB_DB_NOBPT;
+ /*
+ * Determine which breakpoint was encountered.
+ */
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_bp_trap: rip=0x%lx (not adjusted) "
+ "eflags=0x%lx ef=0x%p rsp=0x%lx\n",
+ regs->rip, regs->eflags, regs, regs->rsp);
+
+ rv = KDB_DB_NOBPT; /* Cause kdb() to return */
+
+ for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) {
+ if (bp->bp_free)
+ continue;
+ if (!bp->bp_global && bp->bp_cpu != smp_processor_id())
+ continue;
+ if ((void *)bp->bp_addr == (void *)(regs->rip - bp->bp_adjust)) {
+ /* Hit this breakpoint. */
+ regs->rip -= bp->bp_adjust;
+ kdb_printf("Instruction(i) breakpoint #%d at 0x%lx (adjusted)\n",
+ i, regs->rip);
+ kdb_id1(regs->rip);
+ rv = KDB_DB_BPT;
+ bp->bp_delay = 1;
+ /* SSBPT is set when the kernel debugger must single
+ * step a task in order to re-establish an instruction
+ * breakpoint which uses the instruction replacement
+ * mechanism. It is cleared by any action that removes
+ * the need to single-step the breakpoint.
+ */
+ KDB_STATE_SET(SSBPT);
+ break;
+ }
+ }
+
+ return rv;
+}
+
+/*
+ * kdba_handle_bp
+ *
+ * Handle an instruction-breakpoint trap. Called when re-installing
+ * an enabled breakpoint which has has the bp_delay bit set.
+ *
+ * Parameters:
+ * Returns:
+ * Locking:
+ * Remarks:
+ *
+ * Ok, we really need to:
+ * 1) Restore the original instruction byte
+ * 2) Single Step
+ * 3) Restore breakpoint instruction
+ * 4) Continue.
+ *
+ *
+ */
+
+static void
+kdba_handle_bp(struct pt_regs *regs, kdb_bp_t *bp)
+{
+
+ if (KDB_NULL_REGS(regs))
+ return;
+
+ if (KDB_DEBUG(BP))
+ kdb_printf("regs->rip = 0x%lx\n", regs->rip);
+
+ /*
+ * Setup single step
+ */
+ kdba_setsinglestep(regs);
+
+ /*
+ * Reset delay attribute
+ */
+ bp->bp_delay = 0;
+ bp->bp_delayed = 1;
+}
+
+
+/*
+ * kdba_bptype
+ *
+ * Return a string describing type of breakpoint.
+ *
+ * Parameters:
+ * bph Pointer to hardware breakpoint description
+ * Outputs:
+ * None.
+ * Returns:
+ * Character string.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+char *
+kdba_bptype(kdbhard_bp_t *bph)
+{
+ char *mode;
+
+ mode = kdba_rwtypes[bph->bph_mode];
+
+ return mode;
+}
+
+/*
+ * kdba_printbpreg
+ *
+ * Print register name assigned to breakpoint
+ *
+ * Parameters:
+ * bph Pointer hardware breakpoint structure
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+void
+kdba_printbpreg(kdbhard_bp_t *bph)
+{
+ kdb_printf(" in dr%ld", bph->bph_reg);
+}
+
+/*
+ * kdba_printbp
+ *
+ * Print string describing hardware breakpoint.
+ *
+ * Parameters:
+ * bph Pointer to hardware breakpoint description
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+void
+kdba_printbp(kdb_bp_t *bp)
+{
+ kdb_printf("\n is enabled");
+ if (bp->bp_hardtype) {
+ kdba_printbpreg(bp->bp_hard);
+ if (bp->bp_hard->bph_mode != 0) {
+ kdb_printf(" for %d bytes",
+ bp->bp_hard->bph_length+1);
+ }
+ }
+}
+
+/*
+ * kdba_parsebp
+ *
+ * Parse architecture dependent portion of the
+ * breakpoint command.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero for success, a kdb diagnostic for failure
+ * Locking:
+ * None.
+ * Remarks:
+ * for Ia32 architure, data access, data write and
+ * I/O breakpoints are supported in addition to instruction
+ * breakpoints.
+ *
+ * {datar|dataw|io|inst} [length]
+ */
+
+int
+kdba_parsebp(int argc, const char **argv, int *nextargp, kdb_bp_t *bp)
+{
+ int nextarg = *nextargp;
+ int diag;
+ kdbhard_bp_t *bph = &bp->bp_template;
+
+ bph->bph_mode = 0; /* Default to instruction breakpoint */
+ bph->bph_length = 0; /* Length must be zero for insn bp */
+ if ((argc + 1) != nextarg) {
+ if (strnicmp(argv[nextarg], "datar", sizeof("datar")) == 0) {
+ bph->bph_mode = 3;
+ } else if (strnicmp(argv[nextarg], "dataw", sizeof("dataw")) == 0) {
+ bph->bph_mode = 1;
+ } else if (strnicmp(argv[nextarg], "io", sizeof("io")) == 0) {
+ bph->bph_mode = 2;
+ } else if (strnicmp(argv[nextarg], "inst", sizeof("inst")) == 0) {
+ bph->bph_mode = 0;
+ } else {
+ return KDB_ARGCOUNT;
+ }
+
+ bph->bph_length = 3; /* Default to 4 byte */
+
+ nextarg++;
+
+ if ((argc + 1) != nextarg) {
+ unsigned long len;
+
+ diag = kdbgetularg((char *)argv[nextarg],
+ &len);
+ if (diag)
+ return diag;
+
+
+ if ((len > 4) || (len == 3))
+ return KDB_BADLENGTH;
+
+ bph->bph_length = len;
+ bph->bph_length--; /* Normalize for debug register */
+ nextarg++;
+ }
+
+ if ((argc + 1) != nextarg)
+ return KDB_ARGCOUNT;
+
+ /*
+ * Indicate to architecture independent level that
+ * a hardware register assignment is required to enable
+ * this breakpoint.
+ */
+
+ bph->bph_free = 0;
+ } else {
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_bp: no args, forcehw is %d\n", bp->bp_forcehw);
+ if (bp->bp_forcehw) {
+ /*
+ * We are forced to use a hardware register for this
+ * breakpoint because either the bph or bpha
+ * commands were used to establish this breakpoint.
+ */
+ bph->bph_free = 0;
+ } else {
+ /*
+ * Indicate to architecture dependent level that
+ * the instruction replacement breakpoint technique
+ * should be used for this breakpoint.
+ */
+ bph->bph_free = 1;
+ bp->bp_adjust = 1; /* software, int 3 is one byte */
+ }
+ }
+
+ if (bph->bph_mode != 2 && kdba_verify_rw(bp->bp_addr, bph->bph_length+1)) {
+ kdb_printf("Invalid address for breakpoint, ignoring bp command\n");
+ return KDB_BADADDR;
+ }
+
+ *nextargp = nextarg;
+ return 0;
+}
+
+/*
+ * kdba_allocbp
+ *
+ * Associate a hardware register with a breakpoint.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * A pointer to the allocated register kdbhard_bp_t structure for
+ * success, Null and a non-zero diagnostic for failure.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+kdbhard_bp_t *
+kdba_allocbp(kdbhard_bp_t *bph, int *diagp)
+{
+ int i;
+ kdbhard_bp_t *newbph;
+
+ for(i=0,newbph=kdb_hardbreaks; i < KDB_MAXHARDBPT; i++, newbph++) {
+ if (newbph->bph_free) {
+ break;
+ }
+ }
+
+ if (i == KDB_MAXHARDBPT) {
+ *diagp = KDB_TOOMANYDBREGS;
+ return NULL;
+ }
+
+ *diagp = 0;
+
+ /*
+ * Copy data from template. Can't just copy the entire template
+ * here because the register number in kdb_hardbreaks must be
+ * preserved.
+ */
+ newbph->bph_data = bph->bph_data;
+ newbph->bph_write = bph->bph_write;
+ newbph->bph_mode = bph->bph_mode;
+ newbph->bph_length = bph->bph_length;
+
+ /*
+ * Mark entry allocated.
+ */
+ newbph->bph_free = 0;
+
+ return newbph;
+}
+
+/*
+ * kdba_freebp
+ *
+ * Deallocate a hardware breakpoint
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero for success, a kdb diagnostic for failure
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+void
+kdba_freebp(kdbhard_bp_t *bph)
+{
+ bph->bph_free = 1;
+}
+
+/*
+ * kdba_initbp
+ *
+ * Initialize the breakpoint table for the hardware breakpoint
+ * register.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero for success, a kdb diagnostic for failure
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ * There is one entry per register. On the ia32 architecture
+ * all the registers are interchangeable, so no special allocation
+ * criteria are required.
+ */
+
+void
+kdba_initbp(void)
+{
+ int i;
+ kdbhard_bp_t *bph;
+
+ /*
+ * Clear the hardware breakpoint table
+ */
+
+ memset(kdb_hardbreaks, '\0', sizeof(kdb_hardbreaks));
+
+ for(i=0,bph=kdb_hardbreaks; i<KDB_MAXHARDBPT; i++, bph++) {
+ bph->bph_reg = i;
+ bph->bph_free = 1;
+ }
+}
+
+/*
+ * kdba_installbp
+ *
+ * Install a breakpoint
+ *
+ * Parameters:
+ * regs Exception frame
+ * bp Breakpoint structure for the breakpoint to be installed
+ * Outputs:
+ * None.
+ * Returns:
+ * 0 if breakpoint installed.
+ * Locking:
+ * None.
+ * Remarks:
+ * For hardware breakpoints, a debug register is allocated
+ * and assigned to the breakpoint. If no debug register is
+ * available, a warning message is printed and the breakpoint
+ * is disabled.
+ *
+ * For instruction replacement breakpoints, we must single-step
+ * over the replaced instruction at this point so we can re-install
+ * the breakpoint instruction after the single-step.
+ */
+
+int
+kdba_installbp(struct pt_regs *regs, kdb_bp_t *bp)
+{
+ /*
+ * Install the breakpoint, if it is not already installed.
+ */
+
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdba_installbp bp_installed %d\n", bp->bp_installed);
+ }
+ if (!KDB_STATE(SSBPT))
+ bp->bp_delay = 0;
+ if (!bp->bp_installed) {
+ if (bp->bp_hardtype) {
+ kdba_installdbreg(bp);
+ bp->bp_installed = 1;
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdba_installbp hardware reg %ld at " kdb_bfd_vma_fmt "\n",
+ bp->bp_hard->bph_reg, bp->bp_addr);
+ }
+ } else if (bp->bp_delay) {
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_installbp delayed bp\n");
+ kdba_handle_bp(regs, bp);
+ } else {
+ if (kdb_getarea_size(&(bp->bp_inst), bp->bp_addr, 1) ||
+ kdb_putword(bp->bp_addr, IA32_BREAKPOINT_INSTRUCTION, 1)) {
+ kdb_printf("kdba_installbp failed to set software breakpoint at " kdb_bfd_vma_fmt "\n", bp->bp_addr);
+ return(1);
+ }
+ bp->bp_installed = 1;
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdba_installbp instruction 0x%x at " kdb_bfd_vma_fmt "\n",
+ IA32_BREAKPOINT_INSTRUCTION, bp->bp_addr);
+ }
+ }
+ return(0);
+}
+
+/*
+ * kdba_removebp
+ *
+ * Make a breakpoint ineffective.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+int
+kdba_removebp(kdb_bp_t *bp)
+{
+ /*
+ * For hardware breakpoints, remove it from the active register,
+ * for software breakpoints, restore the instruction stream.
+ */
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdba_removebp bp_installed %d\n", bp->bp_installed);
+ }
+ if (bp->bp_installed) {
+ if (bp->bp_hardtype) {
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdb: removing hardware reg %ld at " kdb_bfd_vma_fmt "\n",
+ bp->bp_hard->bph_reg, bp->bp_addr);
+ }
+ kdba_removedbreg(bp);
+ } else {
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdb: restoring instruction 0x%x at " kdb_bfd_vma_fmt "\n",
+ bp->bp_inst, bp->bp_addr);
+ if (kdb_putword(bp->bp_addr, bp->bp_inst, 1))
+ return(1);
+ }
+ bp->bp_installed = 0;
+ }
+ return(0);
+}
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Stack Traceback
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kallsyms.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <asm/system.h>
+
+typedef struct __kdb_activation_record {
+ kdb_machreg_t start; /* -> start of activation record */
+ kdb_machreg_t end; /* -> end+1 of activation record */
+ kdb_machreg_t ret; /* Return address to caller */
+ kdb_machreg_t oldfp; /* Frame pointer for caller's frame */
+ kdb_machreg_t fp; /* Frame pointer for callee's frame */
+ kdb_machreg_t arg0; /* -> First argument on stack (in previous ar) */
+ unsigned long locals; /* Bytes allocated for local variables */
+ unsigned long regs; /* Bytes allocated for saved registers */
+ unsigned long args; /* Bytes allocated for arguments (in previous ar) */
+ unsigned long setup; /* Bytes allocated for setup data */
+} kdb_ar_t;
+
+#define KDB_STACK_DIRECTION (-1) /* Stack grows down */
+#define SP_SANITY(ss, sp) 1
+#define SS(sp) ((sp) & -THREAD_SIZE) /* XXX */
+
+/*
+ * kdba_find_return
+ *
+ * Given a starting point on the stack and symtab data for the
+ * current function, scan up the stack looking for a return
+ * address for this function.
+ * Inputs:
+ * sp Starting stack pointer for scan
+ * ss Start of stack for current process
+ * symtab kallsyms symbol data for the function
+ * Outputs:
+ * None.
+ * Returns:
+ * Position on stack of return address, 0 if not found.
+ * Locking:
+ * None.
+ * Remarks:
+ * This is sensitive to the calling sequence generated by gcc.
+ */
+
+
+static kdb_machreg_t
+kdba_find_return(kdb_machreg_t sp, kdb_machreg_t ss, const kdb_symtab_t *symtab)
+{
+ kdb_machreg_t ret;
+ kdb_symtab_t caller_symtab;
+ unsigned long disp8;
+ unsigned long disp32;
+ unsigned char code[7];
+#define retaddr(off) code[sizeof(code)+(off)]
+
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" kdba_find_return: start\n");
+ }
+
+ if (SP_SANITY(ss, sp) == 0) {
+ kdb_printf(" sp is in wrong stack 0x%lx\n", sp);
+ return(0);
+ }
+
+ if ((sp & (THREAD_SIZE - 1)) < sizeof(struct task_struct)) {
+ kdb_printf(" sp is inside task_struct\n");
+ return(0);
+ }
+
+ for (;ret = 0, sp & (THREAD_SIZE-1);sp += 8) {
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" sp=0x%lx", sp);
+ }
+ if (kdb_getword(&ret, sp, 8))
+ break;
+ kdbnearsym(ret, &caller_symtab);
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" ret=");
+ kdb_symbol_print(ret, &caller_symtab, KDB_SP_DEFAULT|KDB_SP_SYMSIZE);
+ }
+ if (!caller_symtab.sym_name) {
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf("\n");
+ }
+ continue; /* not a valid kernel address */
+ }
+ KDB_STATE_SET(SUPPRESS);
+ if (kdb_getarea(code, ret-sizeof(code)) ||
+ kdb_getword(&disp32, ret-4, 4) ||
+ kdb_getword(&disp8, ret-1, 1))
+ continue; /* not a valid return address */
+ if (retaddr(-5) == 0xe8) {
+ /* call disp32 */
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" call disp32");
+ }
+ if (ret + (s32) disp32 == symtab->sym_start) {
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" matched\n");
+ }
+ break; /* call to this function */
+ }
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" failed");
+ }
+ } else if (retaddr(-7) == 0xff && retaddr(-6) == 0x14 && retaddr(-5) == 0x85) {
+ /* call *disp32(,%rax,4), used by syscall.
+ * Cannot calculate address, assume it is valid
+ * if the current function name starts with
+ * 'sys_' or 'old_'.
+ */
+ if (KDB_DEBUG(ARA)) {
+ /* XXX FIXME */
+ kdb_printf(" call *0xnnnn(,%%rax,4)");
+ }
+ if (strncmp(symtab->sym_name, "sys_", 4) == 0 ||
+ strncmp(symtab->sym_name, "old_", 4) == 0) {
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" matched\n");
+ }
+ break; /* probably call to this function */
+ }
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" failed");
+ }
+ } else if (retaddr(-2) == 0xff && (retaddr(-1) & 0xf8) == 0xd0) {
+ /* call *%reg. Cannot validate, have to assume
+ * it is valid.
+ */
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" call *%%reg, assume valid\n");
+ }
+ break; /* hope it is a call to this function */
+ } else if (retaddr(-3) == 0xff && (retaddr(-2) & 0xf8) == 0x50) {
+ /* call *disp8(%reg). Cannot validate, have to assume
+ * it is valid.
+ */
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" call *disp8(%%reg), assume valid\n");
+ }
+ break; /* hope it is a call to this function */
+ } else if (strcmp(caller_symtab.sym_name, "ret_from_intr") == 0
+ && ret == caller_symtab.sym_start) {
+ /* ret_from_intr is pushed on stack for interrupts */
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" ret_from_intr matched\n");
+ }
+ break; /* special case, hand crafted frame */
+ }
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf("\n");
+ }
+ }
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" end ret=0x%lx sp=0x%lx\n", ret, sp);
+ }
+ if (ret)
+ return(sp);
+ return(0);
+}
+
+/*
+ * kdba_prologue
+ *
+ * This function analyzes a gcc-generated function prototype
+ * with or without frame pointers to determine the amount of
+ * automatic storage and register save storage is used on the
+ * stack of the target function. It only counts instructions
+ * that have been executed up to but excluding the current rip.
+ * Inputs:
+ * code Start address of function code to analyze
+ * pc Current program counter within function
+ * sp Current stack pointer for function
+ * ss Start of stack for current process
+ * fp Current frame pointer for function, may not be valid
+ * caller 1 if looking for data on the caller frame, 0 for callee.
+ * Outputs:
+ * ar Activation record, all fields may be set. fp and oldfp
+ * are 0 if they cannot be extracted. return is 0 if the
+ * code cannot find a valid return address. args and arg0
+ * are 0 if the number of arguments cannot be safely
+ * calculated.
+ * Returns:
+ * 1 if prologue is valid, 0 otherwise. If pc is 0 treat it as a
+ * valid prologue to allow bt on wild branches.
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ * x86_64 prologues
+ *
+ * kdba_prologue():
+ * push %r15
+ * mov %rdi,%r15
+ * push %r14
+ * mov %rsi,%r14
+ * push %r13
+ * push %r12
+ * push %rbp
+ * mov %rdx,%rbp
+ *
+ * leaf fn w/ 1 arg:
+ * push %rbp
+ * mov %rsp,%rbp
+ * mov %rdi,0xfffffffffffffff8(%rbp)
+ *
+ */
+
+int
+kdba_prologue(const kdb_symtab_t *symtab, kdb_machreg_t pc, kdb_machreg_t sp,
+ kdb_machreg_t fp, kdb_machreg_t ss, int caller, kdb_ar_t *ar)
+{
+ kdb_machreg_t ret_p, code = symtab->sym_start;
+ int oldfp_present = 0, unwound = 0;
+ unsigned char instruction[6];
+
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf("kdba_prologue: code=0x%lx %s pc=0x%lx sp=0x%lx fp=0x%lx\n",
+ code, symtab->sym_name, pc, sp, fp);
+ }
+
+ /* Special case for wild branches. Assumes top of stack is return address */
+ if (pc == 0) {
+ memset(ar, 0, sizeof(*ar));
+ ar->setup = 8;
+ ar->end = sp;
+ ar->start = ar->end + 8;
+ kdb_getword(&(ar->ret), sp, 8);
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" pc==0: ret=0x%lx\n", ar->ret);
+ }
+ return(1);
+ }
+
+ if (code == 0 || sp & 3 || (SP_SANITY(ss, sp) == 0))
+ return(0);
+
+ ar->end = sp; /* End of activation record +1 */
+
+ /* Special cases galore when the caller pc is within entry.S.
+ * The return address for these routines is outside the kernel,
+ * so the normal algorithm to find the frame does not work.
+ * Hand craft the frame to no setup, regs, locals etc, assume 6
+ * parameters.
+ * This list was extracted from entry.S by looking for all call
+ * instructions that were eventually followed by RESTORE_ALL,
+ * take the label before each such instruction.
+ */
+ if (caller &&
+ (strcmp(symtab->sym_name, "lcall7") == 0 ||
+ strcmp(symtab->sym_name, "lcall27") == 0 ||
+ strcmp(symtab->sym_name, "kdb_call") == 0 ||
+ strcmp(symtab->sym_name, "system_call") == 0 ||
+ strcmp(symtab->sym_name, "tracesys") == 0 ||
+ strcmp(symtab->sym_name, "signal_return") == 0 ||
+ strcmp(symtab->sym_name, "v86_signal_return") == 0 ||
+ strcmp(symtab->sym_name, "tracesys") == 0 ||
+ strcmp(symtab->sym_name, "tracesys_exit") == 0 ||
+ strcmp(symtab->sym_name, "handle_softirq") == 0 ||
+ strcmp(symtab->sym_name, "reschedule") == 0 ||
+ strcmp(symtab->sym_name, "error_code") == 0 ||
+ strcmp(symtab->sym_name, "device_not_available") == 0 ||
+ strcmp(symtab->sym_name, "nmi") == 0)) {
+ ar->start = ar->end + 6*8; /* 6 parameters */
+ if (SP_SANITY(ss, ar->start) == 0)
+ ar->start = 0;
+ return(1);
+ }
+
+ ar->setup = 8; /* Return address is always on stack */
+
+ /* Kludge. If we are sitting on 'ret' then the stack has been unwound,
+ * ignore all the startup code.
+ */
+ if (kdb_getarea(instruction[0], pc))
+ return(0);
+ if (instruction[0] == 0xc3) {
+ /* ret */
+ unwound = 1;
+ }
+
+ if (kdb_getarea(instruction, code))
+ return(0);
+ if (!unwound && code < pc && instruction[0] == 0x55) {
+ /* pushl %rbp */
+ ar->setup += 8; /* Frame pointer is on stack */
+ oldfp_present = 1;
+ ++code;
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" pushq %%rbp\n");
+ }
+ if (code < pc && instruction[0] == 0x89 && instruction[1] == 0xe5) {
+ /* movl %esp,%ebp */
+ if (fp >= sp && SP_SANITY(ss, fp))
+ ar->fp = fp; /* %rbp has been set */
+ code += 2;
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" movq %%rsp,%%rbp, fp=0x%lx\n", ar->fp);
+ }
+ }
+ }
+
+ if (!unwound && code < pc) {
+ if (instruction[0] == 0x83 && instruction[1] == 0xec) {
+ /* subl $xx,%rsp */
+ kdb_getword(&(ar->locals), (unsigned long)(instruction+2), 1);
+ code += 3;
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" subl $xx,%%rsp, locals=%ld\n", ar->locals);
+ }
+ } else if (instruction[0] == 0x81 && instruction[1] == 0xec) {
+ /* subl $xxxxxxxx,%rsp */
+ kdb_getword(&(ar->locals), (unsigned long)(instruction+2), 8);
+ code += 6;
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" subl $xxxxxxxx,%%rsp, locals=%ld\n", ar->locals);
+ }
+ }
+ }
+
+ while (!unwound && code < pc &&
+ kdb_getarea(instruction, code) == 0 &&
+ (instruction[0] & 0xf8) == 0x50) {
+ /* pushl %reg */
+ ar->regs += 8;
+ ++code;
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" pushq %%reg, regs=%ld\n", ar->regs);
+ }
+ }
+
+ /* Check the return address. It must point within the kernel
+ * and the code at that location must be a valid entry sequence.
+ */
+ if (ar->fp) {
+ ret_p = ar->fp + ar->setup;
+ }
+ else {
+ ret_p = ar->end + ar->regs + ar->locals + ar->setup;
+ }
+ ret_p -= 8;
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" ret_p(0)=0x%lx\n", ret_p);
+ }
+ ar->ret = 0;
+ if ((SP_SANITY(ss, ret_p) != 0) &&
+ (ret_p = kdba_find_return(ret_p, ss, symtab))) {
+ kdb_getword(&(ar->ret), ret_p, 8);
+ }
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" ret_p(1)=0x%lx ret=0x%lx\n", ret_p, ar->ret);
+ }
+ if (ar->ret) {
+ ar->fp = ret_p - ar->setup + 8; /* "accurate" fp */
+ ar->start = ret_p + 8;
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" fp=0x%lx start=0x%lx\n", ar->fp, ar->start);
+ }
+ }
+ if (oldfp_present) {
+ if (ar->fp)
+ kdb_getword(&(ar->oldfp), ar->fp, 8);
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" oldfp=0x%lx", ar->oldfp);
+ }
+ if (ar->oldfp <= ar->fp || (SP_SANITY(ss, ar->oldfp) == 0)) {
+ ar->oldfp = 0;
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf(" (out of range)");
+ }
+ }
+ if (KDB_DEBUG(ARA)) {
+ kdb_printf("\n");
+ }
+ }
+ return(1);
+}
+
+/*
+ * kdb_get_next_ar
+ *
+ * Get the next activation record from the stack.
+ *
+ * Inputs:
+ * arend Last byte +1 of the activation record. sp for the first
+ * frame, start of callee's activation record otherwise.
+ * pc Current program counter within this function. pc for
+ * the first frame, caller's return address otherwise.
+ * fp Current frame pointer. Register fp for the first
+ * frame, oldfp otherwise. 0 if not known.
+ * ss Start of stack for the current process.
+ * Outputs:
+ * ar Activation record.
+ * symtab kallsyms symbol table data for the calling function.
+ * Returns:
+ * 1 if ar is usable, 0 if not.
+ * Locking:
+ * None.
+ * Remarks:
+ * Activation Record format, assuming a stack that grows down
+ * (KDB_STACK_DIRECTION == -1).
+ *
+ * +-----------------------------+ ^ =====================
+ * | Return address, frame 3 | |
+ * +-----------------------------+ |
+ * | Frame Pointer, frame 3 |>--'
+ * +-----------------------------+<--.
+ * | Locals and automatics, | |
+ * | frame 2. (variable size) | | AR 2
+ * +-----------------------------+ |
+ * | Save registers, | |
+ * | frame 2. (variable size) | |
+ * +-----------------------------+ |
+ * | Arguments to frame 1, | |
+ * | (variable size) | |
+ * +-----------------------------+ | =====================
+ * | Return address, frame 2 | |
+ * +-----------------------------+ |
+ * | Frame Pointer, frame 2 |>--'
+ * +-----------------------------+<--.
+ * | Locals and automatics, | |
+ * | frame 1. (variable size) | | AR 1
+ * +-----------------------------+ |
+ * | Save registers, | |
+ * | frame 1. (variable size) | |
+ * +-----------------------------+ |
+ * | Arguments to frame 0, | |
+ * | (variable size) | |
+ * +-----------------------------+ | -- (5) =====================
+ * | Return address, frame 1 | |
+ * +-----------------------------+ | -- (0)
+ * | Frame Pointer, frame 1 |>--'
+ * +-----------------------------+ -- (1), (2)
+ * | Locals and automatics, |
+ * | frame 0. (variable size) | AR 0
+ * +-----------------------------+ -- (3)
+ * | Save registers, |
+ * | frame 0. (variable size) |
+ * +-----------------------------+ -- (4) =====================
+ *
+ * The stack for the top frame can be in one of several states.
+ * (0) Immediately on entry to the function, stack pointer (sp) is
+ * here.
+ * (1) If the function was compiled with frame pointers and the 'push
+ * fp' instruction has been executed then the pointer to the
+ * previous frame is on the stack. However there is no guarantee
+ * that this saved pointer is valid, the calling function might
+ * not have frame pointers. sp is adjusted by wordsize after
+ * 'push fp'.
+ * (2) If the function was compiled with frame pointers and the 'copy
+ * sp to fp' instruction has been executed then fp points here.
+ * (3) If the function startup has 'adjust sp by 0xnn bytes' and that
+ * instruction has been executed then sp has been adjusted by
+ * 0xnn bytes for local and automatic variables.
+ * (4) If the function startup has one or more 'push reg' instructions
+ * and any have been executed then sp has been adjusted by
+ * wordsize bytes for each register saved.
+ *
+ * As the function exits it rewinds the stack, typically to (1) then (0).
+ *
+ * The stack entries for the lower frames is normally are in state (5).
+ * (5) Arguments for the called frame are on to the stack.
+ * However lower frames can be incomplete if there is an interrupt in
+ * progress.
+ *
+ * An activation record runs from the return address for a function
+ * through to the return address for the next function or sp, whichever
+ * comes first. For each activation record we extract :-
+ *
+ * start Address of the activation record.
+ * end Address of the last byte+1 in the activation record.
+ * ret Return address to caller.
+ * oldfp Frame pointer to previous frame, 0 if this function was
+ * not compiled with frame pointers.
+ * fp Frame pointer for the current frame, 0 if this function
+ * was not compiled with frame pointers or fp has not been
+ * set yet.
+ * arg0 Address of the first argument (in the previous activation
+ * record).
+ * locals Bytes allocated to locals and automatics.
+ * regs Bytes allocated to saved registers.
+ * args Bytes allocated to arguments (in the previous activation
+ * record).
+ * setup Bytes allocated to setup data on stack (return address,
+ * frame pointer).
+ *
+ * Although the kernel might be compiled with frame pointers, we still
+ * have to assume the worst and validate the frame. Some calls from
+ * asm code to C code might not use frame pointers. Third party binary
+ * only modules might be compiled without frame pointers, even when the
+ * rest of the kernel has frame pointers. Some routines are always
+ * compiled with frame pointers, even if the overall kernel is not. A
+ * routine compiled with frame pointers can be called from a routine
+ * without frame pointers, the previous "frame pointer" is saved on
+ * stack but it contains garbage.
+ *
+ * We check the object code to see if it saved a frame pointer and we
+ * validate that pointer. Basically frame pointers are hints.
+ */
+
+#define FORCE_ARG(ar,n) (ar)->setup = (ar)->locals = (ar)->regs = \
+ (ar)->fp = (ar)->oldfp = (ar)->ret = 0; \
+ (ar)->start = (ar)->end - KDB_STACK_DIRECTION*(n)*sizeof(unsigned long);
+
+int
+kdb_get_next_ar(kdb_machreg_t arend, kdb_machreg_t pc, kdb_machreg_t fp,
+ kdb_machreg_t ss, kdb_ar_t *ar, kdb_symtab_t *symtab)
+{
+ static char namebuf1[KSYM_NAME_LEN+1]; /* accessed from outside */
+ static char namebuf2[KSYM_NAME_LEN+1]; /* accessed from callees */
+
+ if (KDB_DEBUG(AR)) {
+ kdb_printf("kdb_get_next_ar: arend=0x%lx pc=0x%lx fp=0x%lx\n",
+ arend, pc, fp);
+ }
+
+ memset(ar, 0, sizeof(*ar));
+ if (kdbnearsym(pc, symtab)) {
+ strcpy(namebuf1, symtab->sym_name);
+ symtab->sym_name = namebuf1;
+ } else {
+ symtab->sym_name = "<unknown>";
+ symtab->mod_name = "kernel";
+ if (KDB_DEBUG(AR)) {
+ kdb_printf("kdb_get_next_ar: callee not in kernel\n");
+ }
+ pc = 0;
+ }
+
+ if (!kdba_prologue(symtab, pc, arend, fp, ss, 0, ar)) {
+ if (KDB_DEBUG(AR)) {
+ kdb_printf("kdb_get_next_ar: callee prologue failed\n");
+ }
+ return(0);
+ }
+ if (KDB_DEBUG(AR)) {
+ kdb_printf("kdb_get_next_ar: callee activation record\n");
+ kdb_printf(" start=0x%lx end=0x%lx ret=0x%lx oldfp=0x%lx fp=0x%lx\n",
+ ar->start, ar->end, ar->ret, ar->oldfp, ar->fp);
+ kdb_printf(" locals=%ld regs=%ld setup=%ld\n",
+ ar->locals, ar->regs, ar->setup);
+ }
+
+ if (ar->ret) {
+ /* Run the caller code to get arguments to callee function */
+ kdb_symtab_t caller_symtab;
+ kdb_ar_t caller_ar;
+ memset(&caller_ar, 0, sizeof(caller_ar));
+ if (kdbnearsym(ar->ret, &caller_symtab)) {
+ strcpy(namebuf2, caller_symtab.sym_name);
+ caller_symtab.sym_name = namebuf2;
+ }
+ if (caller_symtab.sym_name == NULL) {
+ if (KDB_DEBUG(AR)) {
+ kdb_printf("kdb_get_next_ar: caller not in kernel\n");
+ }
+ } else if (kdba_prologue(&caller_symtab, ar->ret,
+ ar->start, ar->oldfp, ss, 1, &caller_ar)) {
+ /* some caller data extracted */ ;
+ } else if (strcmp(symtab->sym_name, "do_exit") == 0) {
+ /* non-standard caller, force one argument */
+ FORCE_ARG(&caller_ar, 1);
+ } else if (KDB_DEBUG(AR)) {
+ kdb_printf("kdb_get_next_ar: caller prologue failed\n");
+ }
+ if (KDB_DEBUG(AR)) {
+ kdb_printf("kdb_get_next_ar: caller activation record\n");
+ kdb_printf(" start=0x%lx end=0x%lx ret=0x%lx"
+ " oldfp=0x%lx fp=0x%lx\n",
+ caller_ar.start, caller_ar.end, caller_ar.ret,
+ caller_ar.oldfp, caller_ar.fp);
+ kdb_printf(" locals=%ld regs=%ld args=%ld setup=%ld\n",
+ caller_ar.locals, caller_ar.regs,
+ caller_ar.args, caller_ar.setup);
+ }
+ if (caller_ar.start) {
+ ar->args = KDB_STACK_DIRECTION*(caller_ar.end - caller_ar.start) -
+ (caller_ar.setup + caller_ar.locals + caller_ar.regs);
+ if (ar->args < 0)
+ ar->args = 0;
+ if (ar->args) {
+ ar->arg0 = ar->start -
+ KDB_STACK_DIRECTION*(ar->args - sizeof (ar->args));
+ if (KDB_DEBUG(AR)) {
+ kdb_printf(" callee arg0=0x%lx args=%ld\n",
+ ar->arg0, ar->args);
+ }
+ }
+ }
+ }
+
+ return(1);
+}
+
+/*
+ * bt_print_one
+ *
+ * Print one back trace entry.
+ *
+ * Inputs:
+ * rip Current program counter, or return address.
+ * rsp Stack pointer rsp when at rip.
+ * ar Activation record for this frame.
+ * symtab Information about symbol that rip falls within.
+ * argcount Maximum number of arguments to print.
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ * None.
+ */
+
+static void
+bt_print_one(kdb_machreg_t rip, kdb_machreg_t rsp, const kdb_ar_t *ar,
+ const kdb_symtab_t *symtab, int argcount)
+{
+ int btsymarg = 0;
+ kdb_machreg_t word;
+
+ kdbgetintenv("BTSYMARG", &btsymarg);
+
+ kdb_printf("%16lx", rsp);
+ kdb_symbol_print(rip, symtab, KDB_SP_SPACEB|KDB_SP_VALUE);
+ if (argcount && ar->args) {
+ int i, argc = ar->args / 8;
+
+ kdb_printf(" (");
+ if (argc > argcount)
+ argc = argcount;
+
+ for(i=1; i<=argc; i++){
+ kdb_machreg_t argp = ar->arg0 - ar->args + 8*i;
+
+ if (i != 1)
+ kdb_printf(" ");
+ kdb_getword(&word, argp, sizeof(word));
+ kdb_printf("%lx", word);
+ }
+ kdb_printf(")");
+ }
+ kdb_printf("\n");
+ if (argcount && ar->args && btsymarg) {
+ int i, argc = ar->args / 8;
+ kdb_symtab_t arg_symtab;
+ kdb_machreg_t arg;
+ for(i=1; i<=argc; i++){
+ kdb_machreg_t argp = ar->arg0 - ar->args + 8*i;
+ kdb_getword(&arg, argp, sizeof(arg));
+ if (kdbnearsym(arg, &arg_symtab)) {
+ kdb_printf(" ");
+ kdb_symbol_print(arg, &arg_symtab, KDB_SP_DEFAULT|KDB_SP_NEWLINE);
+ }
+ }
+ }
+}
+
+/*
+ * kdba_bt_stack
+ *
+ * Inputs:
+ * addr Pointer to Address provided to 'bt' command, if any.
+ * argcount
+ * p Pointer to task for 'btp' command.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * mds comes in handy when examining the stack to do a manual
+ * traceback.
+ */
+
+static int
+kdba_bt_stack(kdb_machreg_t addr, int argcount, const struct task_struct *p)
+{
+ extern void thread_return(void);
+ kdb_ar_t ar;
+ kdb_machreg_t rip, rsp, rbp, ss, cs;
+ kdb_symtab_t symtab;
+ int count;
+
+ /*
+ * The caller may have supplied an address at which the
+ * stack traceback operation should begin. This address
+ * is assumed by this code to point to a return-address
+ * on the stack to be traced back.
+ *
+ * The end result of this will make it appear as if a function
+ * entitled '<unknown>' was called from the function which
+ * contains return-address.
+ */
+ if (addr) {
+ rip = 0;
+ rbp = 0;
+ rsp = addr;
+ cs = __KERNEL_CS; /* have to assume kernel space */
+ } else {
+ if (task_curr(p)) {
+ struct kdb_running_process *krp = kdb_running_process + task_cpu(p);
+ struct pt_regs *regs;
+
+ if (!krp->seqno) {
+ kdb_printf("Process did not save state, cannot backtrace\n");
+ kdb_ps1(p);
+ return 0;
+ }
+ regs = krp->regs;
+ if (KDB_NULL_REGS(regs))
+ return KDB_BADREG;
+ kdba_getregcontents("rip", regs, &rip);
+ kdba_getregcontents("rbp", regs, &rbp);
+ kdba_getregcontents("rsp", regs, &rsp);
+ kdba_getregcontents("cs", regs, &cs);
+ }
+ else {
+ /* Not on cpu, assume blocked. Blocked tasks do
+ * not have pt_regs. p->thread.rsp is set, rsp
+ * points to the rbp value, assume kernel space.
+ */
+ rsp = p->thread.rsp;
+ /*
+ * The rip is no longer in the thread struct.
+ * We know that the stack value was saved in
+ * schedule near the label thread_return.
+ * Setting rip to thread_return-1 lets the
+ * stack trace find that we are in schedule
+ * and correctly decode its prologue. We
+ * extract the saved rbp and adjust the stack
+ * to undo the effects of the inline assembly
+ * code which switches the stack.
+ */
+ rbp = *(unsigned long *)rsp;
+ rip = (kdb_machreg_t)&thread_return-1;
+ rsp = rsp + 16;
+ cs = __KERNEL_CS;
+ }
+ }
+ ss = rsp & -THREAD_SIZE;
+
+ if ((cs & 0xffff) != __KERNEL_CS) {
+ kdb_printf("Stack is not in kernel space, backtrace not available\n");
+ return 0;
+ }
+
+ kdb_printf("RSP RIP Function (args)\n");
+
+ /*
+ * Run through the activation records and print them.
+ */
+
+ for (count = 0; count < 200; ++count) {
+ if (!kdb_get_next_ar(rsp, rip, rbp, ss, &ar, &symtab)) {
+ break;
+ }
+
+ if (strcmp("ret_from_intr", symtab.sym_name) == 0 ||
+ strcmp("error_code", symtab.sym_name) == 0) {
+ if (strcmp("ret_from_intr", symtab.sym_name) == 0) {
+ /*
+ * Non-standard frame. ret_from_intr is
+ * preceded by 9 registers (ebx, ecx, edx, esi,
+ * edi, ebp, eax, ds, cs), original eax and the
+ * return address for a total of 11 words.
+ */
+ ar.start = ar.end + 11*4;
+ }
+ if (strcmp("error_code", symtab.sym_name) == 0) {
+ /*
+ * Non-standard frame. error_code is preceded
+ * by two parameters (-> registers, error code),
+ * 9 registers (ebx, ecx, edx, esi, edi, ebp,
+ * eax, ds, cs), original eax and the return
+ * address for a total of 13 words.
+ */
+ ar.start = ar.end + 13*4;
+ }
+ /* Print the non-standard entry without args */
+ bt_print_one(rip, rsp, &ar, &symtab, 0);
+ kdb_printf("Interrupt registers:\n");
+ kdba_dumpregs((struct pt_regs *)(ar.end), NULL, NULL);
+ /* Step the frame to the interrupted code */
+ kdb_getword(&rip, ar.start-8, 8);
+ rbp = 0;
+ rsp = ar.start;
+ if ((((struct pt_regs *)(ar.end))->cs & 0xffff) != __KERNEL_CS) {
+ kdb_printf("Interrupt from user space, end of kernel trace\n");
+ break;
+ }
+ continue;
+ }
+
+ bt_print_one(rip, rsp, &ar, &symtab, argcount);
+
+ if (ar.ret == 0)
+ break; /* End of frames */
+ rip = ar.ret;
+ rbp = ar.oldfp;
+ rsp = ar.start;
+ }
+ if (count >= 200)
+ kdb_printf("bt truncated, count limit reached\n");
+
+ return 0;
+}
+
+/*
+ * kdba_bt_address
+ *
+ * Do a backtrace starting at a specified stack address. Use this if the
+ * heuristics get the i386 stack decode wrong.
+ *
+ * Inputs:
+ * addr Address provided to 'bt' command.
+ * argcount
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * mds %esp comes in handy when examining the stack to do a manual
+ * traceback.
+ */
+
+int
+kdba_bt_address(kdb_machreg_t addr, int argcount)
+{
+ return kdba_bt_stack(addr, argcount, NULL);
+}
+
+/*
+ * kdba_bt_process
+ *
+ * Do a backtrace for a specified process.
+ *
+ * Inputs:
+ * p Struct task pointer extracted by 'bt' command.
+ * argcount
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ */
+
+int
+kdba_bt_process(const struct task_struct *p, int argcount)
+{
+ return kdba_bt_stack(0, argcount, p);
+}
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Instruction Disassembly
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <stdarg.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+
+/*
+ * kdba_dis_getsym
+ *
+ * Get a symbol for the disassembler.
+ *
+ * Parameters:
+ * addr Address for which to get symbol
+ * dip Pointer to disassemble_info
+ * Returns:
+ * 0
+ * Locking:
+ * Remarks:
+ * Not used for kdb.
+ */
+
+/* ARGSUSED */
+static int
+kdba_dis_getsym(bfd_vma addr, disassemble_info *dip)
+{
+
+ return 0;
+}
+
+/*
+ * kdba_printaddress
+ *
+ * Print (symbolically) an address.
+ *
+ * Parameters:
+ * addr Address for which to get symbol
+ * dip Pointer to disassemble_info
+ * flag True if a ":<tab>" sequence should follow the address
+ * Returns:
+ * 0
+ * Locking:
+ * Remarks:
+ *
+ */
+
+/* ARGSUSED */
+void
+kdba_printaddress(kdb_machreg_t addr, disassemble_info *dip, int flag)
+{
+ kdb_symtab_t symtab;
+ int spaces = 5;
+ unsigned int offset;
+
+ /*
+ * Print a symbol name or address as necessary.
+ */
+ kdbnearsym(addr, &symtab);
+ if (symtab.sym_name) {
+ /* Do not use kdb_symbol_print here, it always does
+ * kdb_printf but we want dip->fprintf_func.
+ */
+ dip->fprintf_func(dip->stream,
+ kdb_machreg_fmt0 " %s", addr, symtab.sym_name);
+ if ((offset = addr - symtab.sym_start) == 0) {
+ spaces += 4;
+ }
+ else {
+ unsigned int o = offset;
+ while (o >>= 4)
+ --spaces;
+ dip->fprintf_func(dip->stream, "+0x%x", offset);
+ }
+
+ } else {
+ dip->fprintf_func(dip->stream, kdb_machreg_fmt0, addr);
+ }
+
+ if (flag) {
+ if (spaces < 1) {
+ spaces = 1;
+ }
+ dip->fprintf_func(dip->stream, ":%*s", spaces, " ");
+ }
+}
+
+/*
+ * kdba_dis_printaddr
+ *
+ * Print (symbolically) an address. Called by GNU disassembly
+ * code via disassemble_info structure.
+ *
+ * Parameters:
+ * addr Address for which to get symbol
+ * dip Pointer to disassemble_info
+ * Returns:
+ * 0
+ * Locking:
+ * Remarks:
+ * This function will never append ":<tab>" to the printed
+ * symbolic address.
+ */
+
+static void
+kdba_dis_printaddr(bfd_vma addr, disassemble_info *dip)
+{
+ kdba_printaddress(addr, dip, 0);
+}
+
+/*
+ * kdba_dis_getmem
+ *
+ * Fetch 'length' bytes from 'addr' into 'buf'.
+ *
+ * Parameters:
+ * addr Address for which to get symbol
+ * buf Address of buffer to fill with bytes from 'addr'
+ * length Number of bytes to fetch
+ * dip Pointer to disassemble_info
+ * Returns:
+ * 0 if data is available, otherwise error.
+ * Locking:
+ * Remarks:
+ *
+ */
+
+/* ARGSUSED */
+static int
+kdba_dis_getmem(bfd_vma addr, bfd_byte *buf, unsigned int length, disassemble_info *dip)
+{
+ return kdb_getarea_size(buf, addr, length);
+}
+
+/*
+ * kdba_id_parsemode
+ *
+ * Parse IDMODE environment variable string and
+ * set appropriate value into "disassemble_info" structure.
+ *
+ * Parameters:
+ * mode Mode string
+ * dip Disassemble_info structure pointer
+ * Returns:
+ * Locking:
+ * Remarks:
+ * We handle the values 'x86' and '8086' to enable either
+ * 32-bit instruction set or 16-bit legacy instruction set.
+ */
+
+int
+kdba_id_parsemode(const char *mode, disassemble_info *dip)
+{
+ if (mode) {
+ if (strcmp(mode, "x86_64") == 0) {
+ dip->mach = bfd_mach_x86_64;
+ } else if (strcmp(mode, "x86") == 0) {
+ dip->mach = bfd_mach_i386_i386;
+ } else if (strcmp(mode, "8086") == 0) {
+ dip->mach = bfd_mach_i386_i8086;
+ } else {
+ return KDB_BADMODE;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * kdba_check_pc
+ *
+ * Check that the pc is satisfactory.
+ *
+ * Parameters:
+ * pc Program Counter Value.
+ * Returns:
+ * None
+ * Locking:
+ * None.
+ * Remarks:
+ * Can change pc.
+ */
+
+void
+kdba_check_pc(kdb_machreg_t *pc)
+{
+ /* No action */
+}
+
+/*
+ * kdba_id_printinsn
+ *
+ * Format and print a single instruction at 'pc'. Return the
+ * length of the instruction.
+ *
+ * Parameters:
+ * pc Program Counter Value.
+ * dip Disassemble_info structure pointer
+ * Returns:
+ * Length of instruction, -1 for error.
+ * Locking:
+ * None.
+ * Remarks:
+ * Depends on 'IDMODE' environment variable.
+ */
+
+int
+kdba_id_printinsn(kdb_machreg_t pc, disassemble_info *dip)
+{
+ kdba_printaddress(pc, dip, 1);
+ return print_insn_i386_att(pc, dip);
+}
+
+/*
+ * kdba_id_init
+ *
+ * Initialize the architecture dependent elements of
+ * the disassembly information structure
+ * for the GNU disassembler.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+void __init
+kdba_id_init(disassemble_info *dip)
+{
+ dip->read_memory_func = kdba_dis_getmem;
+ dip->print_address_func = kdba_dis_printaddr;
+ dip->symbol_at_address_func = kdba_dis_getsym;
+
+ dip->flavour = bfd_target_elf_flavour;
+ dip->arch = bfd_arch_i386;
+ dip->mach = bfd_mach_x86_64;
+ dip->endian = BFD_ENDIAN_LITTLE;
+
+ dip->display_endian = BFD_ENDIAN_LITTLE;
+}
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Console I/O handler
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2006 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/console.h>
+#include <linux/ctype.h>
+#include <linux/keyboard.h>
+#include <linux/serial.h>
+#include <linux/serial_reg.h>
+
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <asm/pc_keyb.h>
+
+#ifdef CONFIG_VT_CONSOLE
+#define KDB_BLINK_LED 1
+#else
+#undef KDB_BLINK_LED
+#endif
+
+#ifdef CONFIG_KDB_USB
+struct kdb_usb_exchange kdb_usb_infos;
+
+EXPORT_SYMBOL(kdb_usb_infos);
+
+static unsigned char kdb_usb_keycode[256] = {
+ 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
+ 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
+ 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
+ 27, 43, 84, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
+ 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
+ 72, 73, 82, 83, 86,127,116,117, 85, 89, 90, 91, 92, 93, 94, 95,
+ 120,121,122,123,134,138,130,132,128,129,131,137,133,135,136,113,
+ 115,114, 0, 0, 0,124, 0,181,182,183,184,185,186,187,188,189,
+ 190,191,192,193,194,195,196,197,198, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
+ 150,158,159,128,136,177,178,176,142,152,173,140
+};
+
+/* get_usb_char
+ * This function drives the UHCI controller,
+ * fetch the USB scancode and decode it
+ */
+static int get_usb_char(void)
+{
+ static int usb_lock;
+ unsigned char keycode, spec;
+ extern u_short plain_map[], shift_map[], ctrl_map[];
+
+ /* Is USB initialized ? */
+ if (!kdb_usb_infos.poll_func || !kdb_usb_infos.urb || !kdb_usb_infos.buffer)
+ return -1;
+
+ /* Transfer char if they are present */
+ (*kdb_usb_infos.poll_func)(kdb_usb_infos.uhci, (struct urb *)kdb_usb_infos.urb);
+
+ spec = kdb_usb_infos.buffer[0];
+ keycode = kdb_usb_infos.buffer[2];
+ kdb_usb_infos.buffer[0] = (char)0;
+ kdb_usb_infos.buffer[2] = (char)0;
+
+ if(kdb_usb_infos.buffer[3])
+ return -1;
+
+ /* A normal key is pressed, decode it */
+ if(keycode)
+ keycode = kdb_usb_keycode[keycode];
+
+ /* 2 Keys pressed at one time ? */
+ if (spec && keycode) {
+ switch(spec)
+ {
+ case 0x2:
+ case 0x20: /* Shift */
+ return shift_map[keycode];
+ case 0x1:
+ case 0x10: /* Ctrl */
+ return ctrl_map[keycode];
+ case 0x4:
+ case 0x40: /* Alt */
+ break;
+ }
+ }
+ else {
+ if(keycode) { /* If only one key pressed */
+ switch(keycode)
+ {
+ case 0x1C: /* Enter */
+ return 13;
+
+ case 0x3A: /* Capslock */
+ usb_lock ? (usb_lock = 0) : (usb_lock = 1);
+ break;
+ case 0x0E: /* Backspace */
+ return 8;
+ case 0x0F: /* TAB */
+ return 9;
+ case 0x77: /* Pause */
+ break ;
+ default:
+ if(!usb_lock) {
+ return plain_map[keycode];
+ }
+ else {
+ return shift_map[keycode];
+ }
+ }
+ }
+ }
+ return -1;
+}
+#endif /* CONFIG_KDB_USB */
+
+/*
+ * This module contains code to read characters from the keyboard or a serial
+ * port.
+ *
+ * It is used by the kernel debugger, and is polled, not interrupt driven.
+ *
+ */
+
+#ifdef KDB_BLINK_LED
+/*
+ * send: Send a byte to the keyboard controller. Used primarily to
+ * alter LED settings.
+ */
+
+static void
+kdb_kbdsend(unsigned char byte)
+{
+ int timeout;
+ for (timeout = 200 * 1000; timeout && (inb(KBD_STATUS_REG) & KBD_STAT_IBF); timeout--);
+ outb(byte, KBD_DATA_REG);
+ udelay(40);
+ for (timeout = 200 * 1000; timeout && (~inb(KBD_STATUS_REG) & KBD_STAT_OBF); timeout--);
+ inb(KBD_DATA_REG);
+ udelay(40);
+}
+
+static void
+kdb_toggleled(int led)
+{
+ static int leds;
+
+ leds ^= led;
+
+ kdb_kbdsend(KBD_CMD_SET_LEDS);
+ kdb_kbdsend((unsigned char)leds);
+}
+#endif /* KDB_BLINK_LED */
+
+#if defined(CONFIG_SERIAL_8250_CONSOLE) || defined(CONFIG_SERIAL_CORE_CONSOLE)
+#define CONFIG_SERIAL_CONSOLE
+#endif
+
+#if defined(CONFIG_SERIAL_CONSOLE)
+
+struct kdb_serial kdb_serial;
+
+static unsigned int
+serial_inp(struct kdb_serial *kdb_serial, unsigned long offset)
+{
+ offset <<= kdb_serial->ioreg_shift;
+
+ switch (kdb_serial->io_type) {
+ case SERIAL_IO_MEM:
+ return readb((void __iomem *)(kdb_serial->iobase + offset));
+ break;
+ default:
+ return inb(kdb_serial->iobase + offset);
+ break;
+ }
+}
+
+/* Check if there is a byte ready at the serial port */
+static int get_serial_char(void)
+{
+ unsigned char ch;
+
+ if (kdb_serial.iobase == 0)
+ return -1;
+
+ if (serial_inp(&kdb_serial, UART_LSR) & UART_LSR_DR) {
+ ch = serial_inp(&kdb_serial, UART_RX);
+ if (ch == 0x7f)
+ ch = 8;
+ return ch;
+ }
+ return -1;
+}
+#endif /* CONFIG_SERIAL_CONSOLE */
+
+#ifdef CONFIG_VT_CONSOLE
+
+static int kbd_exists = -1;
+
+/*
+ * Check if the keyboard controller has a keypress for us.
+ * Some parts (Enter Release, LED change) are still blocking polled here,
+ * but hopefully they are all short.
+ */
+static int get_kbd_char(void)
+{
+ int scancode, scanstatus;
+ static int shift_lock; /* CAPS LOCK state (0-off, 1-on) */
+ static int shift_key; /* Shift next keypress */
+ static int ctrl_key;
+ u_short keychar;
+ extern u_short plain_map[], shift_map[], ctrl_map[];
+
+ if (kbd_exists <= 0) {
+ if (kbd_exists == 0)
+ return -1;
+
+ if (inb(KBD_STATUS_REG) == 0xff && inb(KBD_DATA_REG) == 0xff) {
+ kbd_exists = 0;
+ return -1;
+ }
+ kbd_exists = 1;
+ }
+
+ if ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0)
+ return -1;
+
+ /*
+ * Fetch the scancode
+ */
+ scancode = inb(KBD_DATA_REG);
+ scanstatus = inb(KBD_STATUS_REG);
+
+ /*
+ * Ignore mouse events.
+ */
+ if (scanstatus & KBD_STAT_MOUSE_OBF)
+ return -1;
+
+ /*
+ * Ignore release, trigger on make
+ * (except for shift keys, where we want to
+ * keep the shift state so long as the key is
+ * held down).
+ */
+
+ if (((scancode&0x7f) == 0x2a) || ((scancode&0x7f) == 0x36)) {
+ /*
+ * Next key may use shift table
+ */
+ if ((scancode & 0x80) == 0) {
+ shift_key=1;
+ } else {
+ shift_key=0;
+ }
+ return -1;
+ }
+
+ if ((scancode&0x7f) == 0x1d) {
+ /*
+ * Left ctrl key
+ */
+ if ((scancode & 0x80) == 0) {
+ ctrl_key = 1;
+ } else {
+ ctrl_key = 0;
+ }
+ return -1;
+ }
+
+ if ((scancode & 0x80) != 0)
+ return -1;
+
+ scancode &= 0x7f;
+
+ /*
+ * Translate scancode
+ */
+
+ if (scancode == 0x3a) {
+ /*
+ * Toggle caps lock
+ */
+ shift_lock ^= 1;
+
+#ifdef KDB_BLINK_LED
+ kdb_toggleled(0x4);
+#endif
+ return -1;
+ }
+
+ if (scancode == 0x0e) {
+ /*
+ * Backspace
+ */
+ return 8;
+ }
+
+ /* Special Key */
+ switch (scancode) {
+ case 0xF: /* Tab */
+ return 9;
+ case 0x53: /* Del */
+ return 4;
+ case 0x47: /* Home */
+ return 1;
+ case 0x4F: /* End */
+ return 5;
+ case 0x4B: /* Left */
+ return 2;
+ case 0x48: /* Up */
+ return 16;
+ case 0x50: /* Down */
+ return 14;
+ case 0x4D: /* Right */
+ return 6;
+ }
+
+ if (scancode == 0xe0) {
+ return -1;
+ }
+
+ /*
+ * For Japanese 86/106 keyboards
+ * See comment in drivers/char/pc_keyb.c.
+ * - Masahiro Adegawa
+ */
+ if (scancode == 0x73) {
+ scancode = 0x59;
+ } else if (scancode == 0x7d) {
+ scancode = 0x7c;
+ }
+
+ if (!shift_lock && !shift_key && !ctrl_key) {
+ keychar = plain_map[scancode];
+ } else if (shift_lock || shift_key) {
+ keychar = shift_map[scancode];
+ } else if (ctrl_key) {
+ keychar = ctrl_map[scancode];
+ } else {
+ keychar = 0x0020;
+ kdb_printf("Unknown state/scancode (%d)\n", scancode);
+ }
+ keychar &= 0x0fff;
+ if (keychar == '\t')
+ keychar = ' ';
+ switch (KTYP(keychar)) {
+ case KT_LETTER:
+ case KT_LATIN:
+ if (isprint(keychar))
+ break; /* printable characters */
+ /* drop through */
+ case KT_SPEC:
+ if (keychar == K_ENTER)
+ break;
+ /* drop through */
+ default:
+ return(-1); /* ignore unprintables */
+ }
+
+ if ((scancode & 0x7f) == 0x1c) {
+ /*
+ * enter key. All done. Absorb the release scancode.
+ */
+ while ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0)
+ ;
+
+ /*
+ * Fetch the scancode
+ */
+ scancode = inb(KBD_DATA_REG);
+ scanstatus = inb(KBD_STATUS_REG);
+
+ while (scanstatus & KBD_STAT_MOUSE_OBF) {
+ scancode = inb(KBD_DATA_REG);
+ scanstatus = inb(KBD_STATUS_REG);
+ }
+ return 13;
+ }
+
+ return keychar & 0xff;
+}
+#endif /* CONFIG_VT_CONSOLE */
+
+#ifdef KDB_BLINK_LED
+
+/* Leave numlock alone, setting it messes up laptop keyboards with the keypad
+ * mapped over normal keys.
+ */
+static int kdba_blink_mask = 0x1 | 0x4;
+
+#define BOGOMIPS (boot_cpu_data.loops_per_jiffy/(500000/HZ))
+static int blink_led(void)
+{
+ static long delay;
+
+ if (kbd_exists == 0)
+ return -1;
+
+ if (--delay < 0) {
+ if (BOGOMIPS == 0) /* early kdb */
+ delay = 150000000/1000; /* arbitrary bogomips */
+ else
+ delay = 150000000/BOGOMIPS; /* Roughly 1 second when polling */
+ kdb_toggleled(kdba_blink_mask);
+ }
+ return -1;
+}
+#endif
+
+get_char_func poll_funcs[] = {
+#if defined(CONFIG_VT_CONSOLE)
+ get_kbd_char,
+#endif
+#if defined(CONFIG_SERIAL_CONSOLE)
+ get_serial_char,
+#endif
+#ifdef KDB_BLINK_LED
+ blink_led,
+#endif
+#ifdef CONFIG_KDB_USB
+ get_usb_char,
+#endif
+ NULL
+};
+
+/*
+ * On some Compaq Deskpro's, there is a keyboard freeze many times after
+ * exiting from the kdb. As kdb's keyboard handler is not interrupt-driven and
+ * uses a polled interface, it makes more sense to disable motherboard keyboard
+ * controller's OBF interrupts during kdb's polling.In case, of interrupts
+ * remaining enabled during kdb's polling, it may cause un-necessary
+ * interrupts being signalled during keypresses, which are also sometimes seen
+ * as spurious interrupts after exiting from kdb. This hack to disable OBF
+ * interrupts before entry to kdb and re-enabling them at kdb exit point also
+ * solves the keyboard freeze issue. These functions are called from
+ * kdb_local(), hence these are arch. specific setup and cleanup functions
+ * executing only on the local processor - ashishk@sco.com
+ */
+
+void kdba_local_arch_setup(void)
+{
+#ifdef CONFIG_VT_CONSOLE
+ unsigned char c;
+
+ while (kbd_read_status() & KBD_STAT_IBF);
+ kbd_write_command(KBD_CCMD_READ_MODE);
+ udelay(1000);
+ while (kbd_read_status() & KBD_STAT_IBF);
+ while ( !(kbd_read_status() & KBD_STAT_OBF) );
+ c = kbd_read_input();
+ c &= ~KBD_MODE_KBD_INT;
+ while (kbd_read_status() & KBD_STAT_IBF);
+ kbd_write_command(KBD_CCMD_WRITE_MODE);
+ udelay(1000);
+ while (kbd_read_status() & KBD_STAT_IBF);
+ kbd_write_output(c);
+ udelay(1000);
+ while (kbd_read_status() & KBD_STAT_IBF);
+ udelay(1000);
+#endif /* CONFIG_VT_CONSOLE */
+}
+
+void kdba_local_arch_cleanup(void)
+{
+#ifdef CONFIG_VT_CONSOLE
+ unsigned char c;
+
+ while (kbd_read_status() & KBD_STAT_IBF);
+ kbd_write_command(KBD_CCMD_READ_MODE);
+ udelay(1000);
+ while (kbd_read_status() & KBD_STAT_IBF);
+ while ( !(kbd_read_status() & KBD_STAT_OBF) );
+ c = kbd_read_input();
+ c |= KBD_MODE_KBD_INT;
+ while (kbd_read_status() & KBD_STAT_IBF);
+ kbd_write_command(KBD_CCMD_WRITE_MODE);
+ udelay(1000);
+ while (kbd_read_status() & KBD_STAT_IBF);
+ kbd_write_output(c);
+ udelay(1000);
+ while (kbd_read_status() & KBD_STAT_IBF);
+ udelay(1000);
+#endif /* CONFIG_VT_CONSOLE */
+}
--- /dev/null
+/*
+ * Kernel Debugger Architecture Dependent Support Functions
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/string.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ptrace.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/hardirq.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <asm/kdebug.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
+#include <asm/uaccess.h>
+#include <asm/mach_apic.h>
+#include <asm/hw_irq.h>
+#include <asm/desc.h>
+
+kdb_machreg_t
+kdba_getdr6(void)
+{
+ return kdba_getdr(6);
+}
+
+kdb_machreg_t
+kdba_getdr7(void)
+{
+ return kdba_getdr(7);
+}
+
+void
+kdba_putdr6(kdb_machreg_t contents)
+{
+ kdba_putdr(6, contents);
+}
+
+static void
+kdba_putdr7(kdb_machreg_t contents)
+{
+ kdba_putdr(7, contents);
+}
+
+void
+kdba_installdbreg(kdb_bp_t *bp)
+{
+ kdb_machreg_t dr7;
+
+ dr7 = kdba_getdr7();
+
+ kdba_putdr(bp->bp_hard->bph_reg, bp->bp_addr);
+
+ dr7 |= DR7_GE;
+ if (cpu_has_de)
+ set_in_cr4(X86_CR4_DE);
+
+ switch (bp->bp_hard->bph_reg){
+ case 0:
+ DR7_RW0SET(dr7,bp->bp_hard->bph_mode);
+ DR7_LEN0SET(dr7,bp->bp_hard->bph_length);
+ DR7_G0SET(dr7);
+ break;
+ case 1:
+ DR7_RW1SET(dr7,bp->bp_hard->bph_mode);
+ DR7_LEN1SET(dr7,bp->bp_hard->bph_length);
+ DR7_G1SET(dr7);
+ break;
+ case 2:
+ DR7_RW2SET(dr7,bp->bp_hard->bph_mode);
+ DR7_LEN2SET(dr7,bp->bp_hard->bph_length);
+ DR7_G2SET(dr7);
+ break;
+ case 3:
+ DR7_RW3SET(dr7,bp->bp_hard->bph_mode);
+ DR7_LEN3SET(dr7,bp->bp_hard->bph_length);
+ DR7_G3SET(dr7);
+ break;
+ default:
+ kdb_printf("kdb: Bad debug register!! %ld\n",
+ bp->bp_hard->bph_reg);
+ break;
+ }
+
+ kdba_putdr7(dr7);
+ return;
+}
+
+void
+kdba_removedbreg(kdb_bp_t *bp)
+{
+ int regnum;
+ kdb_machreg_t dr7;
+
+ if (!bp->bp_hard)
+ return;
+
+ regnum = bp->bp_hard->bph_reg;
+
+ dr7 = kdba_getdr7();
+
+ kdba_putdr(regnum, 0);
+
+ switch (regnum) {
+ case 0:
+ DR7_G0CLR(dr7);
+ DR7_L0CLR(dr7);
+ break;
+ case 1:
+ DR7_G1CLR(dr7);
+ DR7_L1CLR(dr7);
+ break;
+ case 2:
+ DR7_G2CLR(dr7);
+ DR7_L2CLR(dr7);
+ break;
+ case 3:
+ DR7_G3CLR(dr7);
+ DR7_L3CLR(dr7);
+ break;
+ default:
+ kdb_printf("kdb: Bad debug register!! %d\n", regnum);
+ break;
+ }
+
+ kdba_putdr7(dr7);
+}
+
+kdb_machreg_t
+kdba_getdr(int regnum)
+{
+ kdb_machreg_t contents = 0;
+ switch(regnum) {
+ case 0:
+ __asm__ ("movq %%db0,%0\n\t":"=r"(contents));
+ break;
+ case 1:
+ __asm__ ("movq %%db1,%0\n\t":"=r"(contents));
+ break;
+ case 2:
+ __asm__ ("movq %%db2,%0\n\t":"=r"(contents));
+ break;
+ case 3:
+ __asm__ ("movq %%db3,%0\n\t":"=r"(contents));
+ break;
+ case 4:
+ case 5:
+ break;
+ case 6:
+ __asm__ ("movq %%db6,%0\n\t":"=r"(contents));
+ break;
+ case 7:
+ __asm__ ("movq %%db7,%0\n\t":"=r"(contents));
+ break;
+ default:
+ break;
+ }
+
+ return contents;
+}
+
+
+kdb_machreg_t
+kdb_getcr(int regnum)
+{
+ kdb_machreg_t contents = 0;
+ switch(regnum) {
+ case 0:
+ __asm__ ("movq %%cr0,%0\n\t":"=r"(contents));
+ break;
+ case 1:
+ break;
+ case 2:
+ __asm__ ("movq %%cr2,%0\n\t":"=r"(contents));
+ break;
+ case 3:
+ __asm__ ("movq %%cr3,%0\n\t":"=r"(contents));
+ break;
+ case 4:
+ __asm__ ("movq %%cr4,%0\n\t":"=r"(contents));
+ break;
+ default:
+ break;
+ }
+
+ return contents;
+}
+
+void
+kdba_putdr(int regnum, kdb_machreg_t contents)
+{
+ switch(regnum) {
+ case 0:
+ __asm__ ("movq %0,%%db0\n\t"::"r"(contents));
+ break;
+ case 1:
+ __asm__ ("movq %0,%%db1\n\t"::"r"(contents));
+ break;
+ case 2:
+ __asm__ ("movq %0,%%db2\n\t"::"r"(contents));
+ break;
+ case 3:
+ __asm__ ("movq %0,%%db3\n\t"::"r"(contents));
+ break;
+ case 4:
+ case 5:
+ break;
+ case 6:
+ __asm__ ("movq %0,%%db6\n\t"::"r"(contents));
+ break;
+ case 7:
+ __asm__ ("movq %0,%%db7\n\t"::"r"(contents));
+ break;
+ default:
+ break;
+ }
+}
+
+/*
+ * kdba_getregcontents
+ *
+ * Return the contents of the register specified by the
+ * input string argument. Return an error if the string
+ * does not match a machine register.
+ *
+ * The following pseudo register names are supported:
+ * ®s - Prints address of exception frame
+ * krsp - Prints kernel stack pointer at time of fault
+ * crsp - Prints current kernel stack pointer, inside kdb
+ * ceflags - Prints current flags, inside kdb
+ * %<regname> - Uses the value of the registers at the
+ * last time the user process entered kernel
+ * mode, instead of the registers at the time
+ * kdb was entered.
+ *
+ * Parameters:
+ * regname Pointer to string naming register
+ * regs Pointer to structure containing registers.
+ * Outputs:
+ * *contents Pointer to unsigned long to recieve register contents
+ * Returns:
+ * 0 Success
+ * KDB_BADREG Invalid register name
+ * Locking:
+ * None.
+ * Remarks:
+ * If kdb was entered via an interrupt from the kernel itself then
+ * ss and rsp are *not* on the stack.
+ */
+
+static struct kdbregs {
+ char *reg_name;
+ size_t reg_offset;
+} kdbreglist[] = {
+ { "r15", offsetof(struct pt_regs, r15) },
+ { "r14", offsetof(struct pt_regs, r14) },
+ { "r13", offsetof(struct pt_regs, r13) },
+ { "r12", offsetof(struct pt_regs, r12) },
+ { "rbp", offsetof(struct pt_regs, rbp) },
+ { "rbx", offsetof(struct pt_regs, rbx) },
+ { "r11", offsetof(struct pt_regs, r11) },
+ { "r10", offsetof(struct pt_regs, r10) },
+ { "r9", offsetof(struct pt_regs, r9) },
+ { "r8", offsetof(struct pt_regs, r8) },
+ { "rax", offsetof(struct pt_regs, rax) },
+ { "rcx", offsetof(struct pt_regs, rcx) },
+ { "rdx", offsetof(struct pt_regs, rdx) },
+ { "rsi", offsetof(struct pt_regs, rsi) },
+ { "rdi", offsetof(struct pt_regs, rdi) },
+ { "orig_rax", offsetof(struct pt_regs, orig_rax) },
+ { "rip", offsetof(struct pt_regs, rip) },
+ { "cs", offsetof(struct pt_regs, cs) },
+ { "eflags", offsetof(struct pt_regs, eflags) },
+ { "rsp", offsetof(struct pt_regs, rsp) },
+ { "ss", offsetof(struct pt_regs, ss) },
+};
+
+static const int nkdbreglist = sizeof(kdbreglist) / sizeof(struct kdbregs);
+
+static struct kdbregs dbreglist[] = {
+ { "dr0", 0 },
+ { "dr1", 1 },
+ { "dr2", 2 },
+ { "dr3", 3 },
+ { "dr6", 6 },
+ { "dr7", 7 },
+};
+
+static const int ndbreglist = sizeof(dbreglist) / sizeof(struct kdbregs);
+
+int
+kdba_getregcontents(const char *regname,
+ struct pt_regs *regs,
+ kdb_machreg_t *contents)
+{
+ int i;
+
+ if (strcmp(regname, "®s") == 0) {
+ *contents = (unsigned long)regs;
+ return 0;
+ }
+
+ if (strcmp(regname, "krsp") == 0) {
+ *contents = (unsigned long)regs + sizeof(struct pt_regs);
+ if ((regs->cs & 0xffff) == __KERNEL_CS) {
+ /* rsp and ss are not on stack */
+ *contents -= 2*4;
+ }
+ return 0;
+ }
+
+ if (strcmp(regname, "crsp") == 0) {
+ asm volatile("movq %%rsp,%0":"=m" (*contents));
+ return 0;
+ }
+
+ if (strcmp(regname, "ceflags") == 0) {
+ unsigned long flags;
+ local_save_flags(flags);
+ *contents = flags;
+ return 0;
+ }
+
+ if (regname[0] == '%') {
+ /* User registers: %%r[a-c]x, etc */
+ regname++;
+ regs = (struct pt_regs *)
+ (current->thread.rsp0 - sizeof(struct pt_regs));
+ }
+
+ for (i=0; i<nkdbreglist; i++) {
+ if (strnicmp(kdbreglist[i].reg_name,
+ regname,
+ strlen(regname)) == 0)
+ break;
+ }
+
+ if ((i < nkdbreglist)
+ && (strlen(kdbreglist[i].reg_name) == strlen(regname))) {
+ if ((regs->cs & 0xffff) == __KERNEL_CS) {
+ /* No cpl switch, rsp is not on stack */
+ if (strcmp(kdbreglist[i].reg_name, "rsp") == 0) {
+ *contents = (kdb_machreg_t)regs +
+ sizeof(struct pt_regs) - 2*8;
+ return(0);
+ }
+#if 0 /* FIXME */
+ if (strcmp(kdbreglist[i].reg_name, "ss") == 0) {
+ kdb_machreg_t r;
+
+ r = (kdb_machreg_t)regs +
+ sizeof(struct pt_regs) - 2*8;
+ *contents = (kdb_machreg_t)SS(r); /* XXX */
+ return(0);
+ }
+#endif
+ }
+ *contents = *(unsigned long *)((unsigned long)regs +
+ kdbreglist[i].reg_offset);
+ return(0);
+ }
+
+ for (i=0; i<ndbreglist; i++) {
+ if (strnicmp(dbreglist[i].reg_name,
+ regname,
+ strlen(regname)) == 0)
+ break;
+ }
+
+ if ((i < ndbreglist)
+ && (strlen(dbreglist[i].reg_name) == strlen(regname))) {
+ *contents = kdba_getdr(dbreglist[i].reg_offset);
+ return 0;
+ }
+ return KDB_BADREG;
+}
+
+/*
+ * kdba_setregcontents
+ *
+ * Set the contents of the register specified by the
+ * input string argument. Return an error if the string
+ * does not match a machine register.
+ *
+ * Supports modification of user-mode registers via
+ * %<register-name>
+ *
+ * Parameters:
+ * regname Pointer to string naming register
+ * regs Pointer to structure containing registers.
+ * contents Unsigned long containing new register contents
+ * Outputs:
+ * Returns:
+ * 0 Success
+ * KDB_BADREG Invalid register name
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+int
+kdba_setregcontents(const char *regname,
+ struct pt_regs *regs,
+ unsigned long contents)
+{
+ int i;
+
+ if (regname[0] == '%') {
+ regname++;
+ regs = (struct pt_regs *)
+ (current->thread.rsp0 - sizeof(struct pt_regs));
+ }
+
+ for (i=0; i<nkdbreglist; i++) {
+ if (strnicmp(kdbreglist[i].reg_name,
+ regname,
+ strlen(regname)) == 0)
+ break;
+ }
+
+ if ((i < nkdbreglist)
+ && (strlen(kdbreglist[i].reg_name) == strlen(regname))) {
+ *(unsigned long *)((unsigned long)regs
+ + kdbreglist[i].reg_offset) = contents;
+ return 0;
+ }
+
+ for (i=0; i<ndbreglist; i++) {
+ if (strnicmp(dbreglist[i].reg_name,
+ regname,
+ strlen(regname)) == 0)
+ break;
+ }
+
+ if ((i < ndbreglist)
+ && (strlen(dbreglist[i].reg_name) == strlen(regname))) {
+ kdba_putdr(dbreglist[i].reg_offset, contents);
+ return 0;
+ }
+
+ return KDB_BADREG;
+}
+
+/*
+ * kdba_dumpregs
+ *
+ * Dump the specified register set to the display.
+ *
+ * Parameters:
+ * regs Pointer to structure containing registers.
+ * type Character string identifying register set to dump
+ * extra string further identifying register (optional)
+ * Outputs:
+ * Returns:
+ * 0 Success
+ * Locking:
+ * None.
+ * Remarks:
+ * This function will dump the general register set if the type
+ * argument is NULL (struct pt_regs). The alternate register
+ * set types supported by this function:
+ *
+ * d Debug registers
+ * c Control registers
+ * u User registers at most recent entry to kernel
+ * Following not yet implemented:
+ * m Model Specific Registers (extra defines register #)
+ * r Memory Type Range Registers (extra defines register)
+ */
+
+int
+kdba_dumpregs(struct pt_regs *regs,
+ const char *type,
+ const char *extra)
+{
+ int i;
+ int count = 0;
+
+ if (type
+ && (type[0] == 'u')) {
+ type = NULL;
+ regs = (struct pt_regs *)
+ (current->thread.rsp0 - sizeof(struct pt_regs));
+ }
+
+ if (type == NULL) {
+ struct kdbregs *rlp;
+ kdb_machreg_t contents;
+
+ for (i=0, rlp=kdbreglist; i<nkdbreglist; i++,rlp++) {
+ kdb_printf("%8s = ", rlp->reg_name);
+ kdba_getregcontents(rlp->reg_name, regs, &contents);
+ kdb_printf("0x%016lx ", contents);
+ if ((++count % 2) == 0)
+ kdb_printf("\n");
+ }
+
+ kdb_printf(" ®s = 0x%p\n", regs);
+
+ return 0;
+ }
+
+ switch (type[0]) {
+ case 'd':
+ {
+ unsigned long dr[8];
+
+ for(i=0; i<8; i++) {
+ if ((i == 4) || (i == 5)) continue;
+ dr[i] = kdba_getdr(i);
+ }
+ kdb_printf("dr0 = 0x%08lx dr1 = 0x%08lx dr2 = 0x%08lx dr3 = 0x%08lx\n",
+ dr[0], dr[1], dr[2], dr[3]);
+ kdb_printf("dr6 = 0x%08lx dr7 = 0x%08lx\n",
+ dr[6], dr[7]);
+ return 0;
+ }
+ case 'c':
+ {
+ unsigned long cr[5];
+
+ for (i=0; i<5; i++) {
+ cr[i] = kdb_getcr(i);
+ }
+ kdb_printf("cr0 = 0x%08lx cr1 = 0x%08lx cr2 = 0x%08lx cr3 = 0x%08lx\ncr4 = 0x%08lx\n",
+ cr[0], cr[1], cr[2], cr[3], cr[4]);
+ return 0;
+ }
+ case 'm':
+ break;
+ case 'r':
+ break;
+ default:
+ return KDB_BADREG;
+ }
+
+ /* NOTREACHED */
+ return 0;
+}
+
+kdb_machreg_t
+kdba_getpc(struct pt_regs *regs)
+{
+ return regs->rip;
+}
+
+int
+kdba_setpc(struct pt_regs *regs, kdb_machreg_t newpc)
+{
+ if (KDB_NULL_REGS(regs))
+ return KDB_BADREG;
+ regs->rip = newpc;
+ KDB_STATE_SET(IP_ADJUSTED);
+ return 0;
+}
+
+/*
+ * kdba_main_loop
+ *
+ * Do any architecture specific set up before entering the main kdb loop.
+ * The primary function of this routine is to make all processes look the
+ * same to kdb, kdb must be able to list a process without worrying if the
+ * process is running or blocked, so make all process look as though they
+ * are blocked.
+ *
+ * Inputs:
+ * reason The reason KDB was invoked
+ * error The hardware-defined error code
+ * error2 kdb's current reason code. Initially error but can change
+ * acording to kdb state.
+ * db_result Result from break or debug point.
+ * ef The exception frame at time of fault/breakpoint. If reason
+ * is SILENT or CPU_UP then regs is NULL, otherwise it should
+ * always be valid.
+ * Returns:
+ * 0 KDB was invoked for an event which it wasn't responsible
+ * 1 KDB handled the event for which it was invoked.
+ * Outputs:
+ * Sets rip and rsp in current->thread.
+ * Locking:
+ * None.
+ * Remarks:
+ * none.
+ */
+
+int
+kdba_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error,
+ kdb_dbtrap_t db_result, struct pt_regs *regs)
+{
+ int ret;
+
+ if (regs)
+ kdba_getregcontents("rsp", regs, &(current->thread.rsp));
+ kdb_save_running(regs);
+ ret = kdb_main_loop(reason, reason2, error, db_result, regs);
+ kdb_unsave_running(regs);
+ return ret;
+}
+
+void
+kdba_disableint(kdb_intstate_t *state)
+{
+ unsigned long *fp = (unsigned long *)state;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ *fp = flags;
+}
+
+void
+kdba_restoreint(kdb_intstate_t *state)
+{
+ unsigned long flags = *(unsigned long *)state;
+ local_irq_restore(flags);
+}
+
+void
+kdba_setsinglestep(struct pt_regs *regs)
+{
+ if (KDB_NULL_REGS(regs))
+ return;
+ if (regs->eflags & EF_IE)
+ KDB_STATE_SET(A_IF);
+ else
+ KDB_STATE_CLEAR(A_IF);
+ regs->eflags = (regs->eflags | EF_TF) & ~EF_IE;
+}
+
+void
+kdba_clearsinglestep(struct pt_regs *regs)
+{
+ if (KDB_NULL_REGS(regs))
+ return;
+ if (KDB_STATE(A_IF))
+ regs->eflags |= EF_IE;
+ else
+ regs->eflags &= ~EF_IE;
+}
+
+int asmlinkage
+kdba_setjmp(kdb_jmp_buf *jb)
+{
+#if defined(CONFIG_FRAME_POINTER)
+ __asm__("movq %rbx, (0*8)(%rdi);"
+ "movq (%rsp), %rax;"
+ "movq %rax, (1*8)(%rdi);"
+ "movq %r12, (2*8)(%rdi);"
+ "movq %r13, (3*8)(%rdi);"
+ "movq %r14, (4*8)(%rdi);"
+ "movq %r15, (5*8)(%rdi);"
+ "leaq 16(%rsp), %rdx;"
+ "movq %rdx, (6*8)(%rdi);"
+ "movq 8(%rsp), %rax;"
+ "movq %rax, (7*8)(%rdi)");
+#else /* CONFIG_FRAME_POINTER */
+ __asm__("movq %rbx, (0*8)(%rdi);"
+ "movq %rbp, (1*8)(%rdi);"
+ "movq %r12, (2*8)(%rdi);"
+ "movq %r13, (3*8)(%rdi);"
+ "movq %r14, (4*8)(%rdi);"
+ "movq %r15, (5*8)(%rdi);"
+ "leaq 8(%rsp), %rdx;"
+ "movq %rdx, (6*8)(%rdi);"
+ "movq (%rsp), %rax;"
+ "movq %rax, (7*8)(%rdi)");
+#endif /* CONFIG_FRAME_POINTER */
+ return 0;
+}
+
+void asmlinkage
+kdba_longjmp(kdb_jmp_buf *jb, int reason)
+{
+#if defined(CONFIG_FRAME_POINTER)
+ __asm__("movq (0*8)(%rdi),%rbx;"
+ "movq (1*8)(%rdi),%rbp;"
+ "movq (2*8)(%rdi),%r12;"
+ "movq (3*8)(%rdi),%r13;"
+ "movq (4*8)(%rdi),%r14;"
+ "movq (5*8)(%rdi),%r15;"
+ "test %esi,%esi;"
+ "mov $01,%eax;"
+ "cmove %eax,%esi;"
+ "mov %esi, %eax;"
+ "movq (7*8)(%rdi),%rdx;"
+ "movq (6*8)(%rdi),%rsp;"
+ "jmpq *%rdx");
+#else /* CONFIG_FRAME_POINTER */
+ __asm__("movq (0*8)(%rdi),%rbx;"
+ "movq (1*8)(%rdi),%rbp;"
+ "movq (2*8)(%rdi),%r12;"
+ "movq (3*8)(%rdi),%r13;"
+ "movq (4*8)(%rdi),%r14;"
+ "movq (5*8)(%rdi),%r15;"
+ "test %esi,%esi;"
+ "mov $01,%eax;"
+ "cmove %eax,%esi;"
+ "mov %esi, %eax;"
+ "movq (7*8)(%rdi),%rdx;"
+ "movq (6*8)(%rdi),%rsp;"
+ "jmpq *%rdx");
+#endif /* CONFIG_FRAME_POINTER */
+}
+
+/*
+ * kdba_pt_regs
+ *
+ * Format a struct pt_regs
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * If no address is supplied, it uses regs.
+ */
+
+static int
+kdba_pt_regs(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int diag;
+ kdb_machreg_t addr;
+ long offset = 0;
+ int nextarg;
+ struct pt_regs *p;
+ static const char *fmt = " %-11.11s 0x%lx\n";
+ static int first_time = 1;
+
+ if (argc == 0) {
+ addr = (kdb_machreg_t) regs;
+ } else if (argc == 1) {
+ nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
+ if (diag)
+ return diag;
+ } else {
+ return KDB_ARGCOUNT;
+ }
+
+ p = (struct pt_regs *) addr;
+ if (first_time) {
+ first_time = 0;
+ kdb_printf("\n+++ Warning: x86_64 pt_regs are not always "
+ "completely defined, r15-rbx may be invalid\n\n");
+ }
+ kdb_printf("struct pt_regs 0x%p-0x%p\n", p, (unsigned char *)p + sizeof(*p) - 1);
+ kdb_print_nameval("r15", p->r15);
+ kdb_print_nameval("r14", p->r14);
+ kdb_print_nameval("r13", p->r13);
+ kdb_print_nameval("r12", p->r12);
+ kdb_print_nameval("rbp", p->rbp);
+ kdb_print_nameval("rbx", p->rbx);
+ kdb_print_nameval("r11", p->r11);
+ kdb_print_nameval("r10", p->r10);
+ kdb_print_nameval("r9", p->r9);
+ kdb_print_nameval("r8", p->r8);
+ kdb_print_nameval("rax", p->rax);
+ kdb_print_nameval("rcx", p->rcx);
+ kdb_print_nameval("rdx", p->rdx);
+ kdb_print_nameval("rsi", p->rsi);
+ kdb_print_nameval("rdi", p->rdi);
+ kdb_print_nameval("orig_rax", p->orig_rax);
+ kdb_print_nameval("rip", p->rip);
+ kdb_printf(fmt, "cs", p->cs);
+ kdb_printf(fmt, "eflags", p->eflags);
+ kdb_printf(fmt, "rsp", p->rsp);
+ kdb_printf(fmt, "ss", p->ss);
+ return 0;
+}
+
+/*
+ * kdba_cpu_pda
+ *
+ * Format a struct cpu_pda
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * If no cpu is supplied, it prints the current cpu. If the cpu is '*'
+ * then it prints all cpus.
+ */
+
+static int
+kdba_cpu_pda(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int diag, nextarg, all_cpus = 0;
+ long cpu, offset = 0;
+ struct x8664_pda *c;
+ static const char *fmtl = " %-17.17s 0x%lx\n";
+ static const char *fmtd = " %-17.17s %d\n";
+ static const char *fmtp = " %-17.17s 0x%p\n";
+
+ if (argc == 0) {
+ cpu = smp_processor_id();
+ } else if (argc == 1) {
+ if (strcmp(argv[1], "*") == 0) {
+ all_cpus = 1;
+ cpu = 0;
+ } else {
+ nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &cpu, &offset, NULL, regs);
+ if (diag)
+ return diag;
+ }
+ } else {
+ return KDB_ARGCOUNT;
+ }
+
+ for (; cpu < NR_CPUS; ++cpu) {
+ if (cpu_online(cpu)) {
+ c = cpu_pda(cpu);
+ kdb_printf("struct cpu_pda 0x%p-0x%p\n", c, (unsigned char *)c + sizeof(*c) - 1);
+ kdb_printf(fmtp, "pcurrent", c->pcurrent);
+ kdb_printf(fmtl, "data_offset", c->data_offset);
+ kdb_printf(fmtl, "kernelstack", c->kernelstack);
+ kdb_printf(fmtl, "oldrsp", c->oldrsp);
+ kdb_printf(fmtd, "irqcount", c->irqcount);
+ kdb_printf(fmtd, "cpunumber", c->cpunumber);
+ kdb_printf(fmtp, "irqstackptr", c->irqstackptr);
+ kdb_printf(fmtd, "nodenumber", c->nodenumber);
+ kdb_printf(fmtd, "__softirq_pending", c->__softirq_pending);
+ kdb_printf(fmtd, "__nmi_count", c->__nmi_count);
+ kdb_printf(fmtd, "mmu_state", c->mmu_state);
+ kdb_printf(fmtp, "active_mm", c->active_mm);
+ kdb_printf(fmtd, "apic_timer_irqs", c->apic_timer_irqs);
+ }
+ if (!all_cpus)
+ break;
+ }
+ return 0;
+}
+
+/*
+ * kdba_entry
+ *
+ * This is the interface routine between
+ * the notifier die_chain and kdb
+ */
+static int kdba_entry( struct notifier_block *b, unsigned long val, void *v)
+{
+ struct die_args *args = v;
+ int err, trap, ret = 0;
+ struct pt_regs *regs;
+
+ regs = args->regs;
+ err = args->err;
+ trap = args->trapnr;
+ switch (val){
+#ifdef CONFIG_SMP
+ case DIE_NMI_IPI:
+ ret = kdb_ipi(regs, NULL);
+ break;
+#endif /* CONFIG_SMP */
+ case DIE_OOPS:
+ ret = kdb(KDB_REASON_OOPS, err, regs);
+ break;
+ case DIE_CALL:
+ ret = kdb(KDB_REASON_ENTER, err, regs);
+ break;
+ case DIE_DEBUG:
+ ret = kdb(KDB_REASON_DEBUG, err, regs);
+ break;
+ case DIE_INT3:
+ ret = kdb(KDB_REASON_BREAK, err, regs);
+ // falls thru
+ default:
+ break;
+ }
+ return (ret ? NOTIFY_STOP : NOTIFY_DONE);
+}
+
+/*
+ * notifier block for kdb entry
+ */
+static struct notifier_block kdba_notifier = {
+ .notifier_call = kdba_entry,
+ .priority = 1,
+};
+
+static inline void set_trap_gate(int nr, void *func)
+{
+ _set_gate(&idt_table[nr], GATE_TRAP, (unsigned long) func, 0, 0);
+}
+
+asmlinkage int kdb_call(void);
+
+/* Executed once on each cpu at startup. */
+void
+kdba_cpu_up(void)
+{
+}
+
+/*
+ * kdba_init
+ *
+ * Architecture specific initialization.
+ *
+ * Parameters:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ * None.
+ */
+
+void __init
+kdba_init(void)
+{
+ kdb_register("pt_regs", kdba_pt_regs, "address", "Format struct pt_regs", 0);
+ kdb_register("cpu_pda", kdba_cpu_pda, "<cpu>", "Format struct cpu_pda", 0);
+ atomic_notifier_chain_register(&die_chain, &kdba_notifier);
+ return;
+}
+
+static int __init
+kdba_late_init(void)
+{
+#ifdef CONFIG_SMP
+ set_intr_gate(KDB_VECTOR, kdb_interrupt);
+#endif
+ set_trap_gate(KDBENTER_VECTOR, kdb_call);
+ return 0;
+}
+
+__initcall(kdba_late_init);
+
+/*
+ * kdba_adjust_ip
+ *
+ * Architecture specific adjustment of instruction pointer before leaving
+ * kdb.
+ *
+ * Parameters:
+ * reason The reason KDB was invoked
+ * error The hardware-defined error code
+ * ef The exception frame at time of fault/breakpoint. If reason
+ * is SILENT or CPU_UP then regs is NULL, otherwise it should
+ * always be valid.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ * noop on ix86.
+ */
+
+void
+kdba_adjust_ip(kdb_reason_t reason, int error, struct pt_regs *ef)
+{
+ return;
+}
+
+void
+kdba_set_current_task(const struct task_struct *p)
+{
+ kdb_current_task = p;
+ if (task_curr(p)) {
+ struct kdb_running_process *krp = kdb_running_process + kdb_process_cpu(p);
+ kdb_current_regs = krp->regs;
+ return;
+ }
+ kdb_current_regs = NULL;
+}
+
+int
+kdba_putarea_size(unsigned long to_xxx, void *from, size_t size)
+{
+ mm_segment_t oldfs = get_fs();
+ int r;
+
+ if (to_xxx < PAGE_OFFSET)
+ return kdb_putuserarea_size(to_xxx, from, size);
+
+ set_fs(KERNEL_DS);
+ r = __copy_to_user_inatomic((void __user *)to_xxx, from, size);
+ set_fs(oldfs);
+ return r;
+}
+
+int
+kdba_getarea_size(void *to, unsigned long from_xxx, size_t size)
+{
+ mm_segment_t oldfs = get_fs();
+ int r;
+
+ if (from_xxx < PAGE_OFFSET)
+ return kdb_getuserarea_size(to, from_xxx, size);
+
+ set_fs(KERNEL_DS);
+ r = __copy_from_user_inatomic(to, (void __user *)from_xxx, size);
+ set_fs(oldfs);
+ return r;
+}
+
+int
+kdba_verify_rw(unsigned long addr, size_t size)
+{
+ unsigned char data[size];
+ return(kdba_getarea_size(data, addr, size) || kdba_putarea_size(addr, data, size));
+}
+
+#ifdef CONFIG_SMP
+
+/* When first entering KDB, try a normal IPI. That reduces backtrace problems
+ * on the other cpus.
+ */
+void
+smp_kdb_stop(void)
+{
+ /*
+ * Using send_IPI_mask below rather than send_IPI_allbutself
+ * allows kdb to work with "maxcpus=N" on a machine with more.
+ * However, it broke kdb(KDB_REASON_SILENT,,) in smpboot.c.
+ */
+ if (!KDB_FLAG(NOIPI)) {
+ cpumask_t cpu_mask = cpu_online_map;
+ cpu_clear(smp_processor_id(), cpu_mask);
+ send_IPI_mask(cpu_mask, KDB_VECTOR);
+ }
+}
+
+/* The normal KDB IPI handler */
+asmlinkage void
+smp_kdb_interrupt(struct pt_regs *regs)
+{
+ irq_enter();
+ ack_APIC_irq();
+ kdb_ipi(regs, NULL);
+ irq_exit();
+}
+
+/* Invoked once from kdb_wait_for_cpus when waiting for cpus. For those cpus
+ * that have not responded to the normal KDB interrupt yet, hit them with an
+ * NMI event.
+ */
+void
+kdba_wait_for_cpus(void)
+{
+ int c;
+ if (KDB_FLAG(CATASTROPHIC))
+ return;
+ kdb_printf(" Sending NMI to cpus that have not responded yet\n");
+ for_each_online_cpu(c)
+ if (kdb_running_process[c].seqno < kdb_seqno - 1)
+ send_IPI_mask(cpumask_of_cpu(c), NMI_VECTOR);
+}
+
+#endif /* CONFIG_SMP */
--- /dev/null
+/* Print i386 instructions for GDB, the GNU debugger.
+ Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use.
+ * Run through col -b to remove trailing whitespace and various #ifdef/ifndef
+ * __KERNEL__ added.
+ * Keith Owens <kaos@sgi.com> 15 May 2006
+ */
+
+/* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
+ July 1988
+ modified by John Hassey (hassey@dg-rtp.dg.com)
+ x86-64 support added by Jan Hubicka (jh@suse.cz)
+ VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
+
+/* The main tables describing the instructions is essentially a copy
+ of the "Opcode Map" chapter (Appendix A) of the Intel 80386
+ Programmers Manual. Usually, there is a capital letter, followed
+ by a small letter. The capital letter tell the addressing mode,
+ and the small letter tells about the operand size. Refer to
+ the Intel manual for details. */
+
+#ifdef __KERNEL__
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/dis-asm.h>
+#include <linux/kdb.h>
+#define abort() BUG()
+#else /* __KERNEL__ */
+#include "dis-asm.h"
+#include "sysdep.h"
+#include "opintl.h"
+#endif /* __KERNEL__ */
+
+#define MAXLEN 20
+
+#ifndef __KERNEL__
+#include <setjmp.h>
+#endif /* __KERNEL__ */
+
+#ifndef UNIXWARE_COMPAT
+/* Set non-zero for broken, compatible instructions. Set to zero for
+ non-broken opcodes. */
+#define UNIXWARE_COMPAT 1
+#endif
+
+static int fetch_data (struct disassemble_info *, bfd_byte *);
+static void ckprefix (void);
+static const char *prefix_name (int, int);
+static int print_insn (bfd_vma, disassemble_info *);
+static void dofloat (int);
+static void OP_ST (int, int);
+static void OP_STi (int, int);
+static int putop (const char *, int);
+static void oappend (const char *);
+static void append_seg (void);
+static void OP_indirE (int, int);
+static void print_operand_value (char *, int, bfd_vma);
+static void OP_E (int, int);
+static void OP_G (int, int);
+static bfd_vma get64 (void);
+static bfd_signed_vma get32 (void);
+static bfd_signed_vma get32s (void);
+static int get16 (void);
+static void set_op (bfd_vma, int);
+static void OP_REG (int, int);
+static void OP_IMREG (int, int);
+static void OP_I (int, int);
+static void OP_I64 (int, int);
+static void OP_sI (int, int);
+static void OP_J (int, int);
+static void OP_SEG (int, int);
+static void OP_DIR (int, int);
+static void OP_OFF (int, int);
+static void OP_OFF64 (int, int);
+static void ptr_reg (int, int);
+static void OP_ESreg (int, int);
+static void OP_DSreg (int, int);
+static void OP_C (int, int);
+static void OP_D (int, int);
+static void OP_T (int, int);
+static void OP_Rd (int, int);
+static void OP_MMX (int, int);
+static void OP_XMM (int, int);
+static void OP_EM (int, int);
+static void OP_EX (int, int);
+static void OP_MS (int, int);
+static void OP_XS (int, int);
+static void OP_M (int, int);
+static void OP_VMX (int, int);
+static void OP_0fae (int, int);
+static void OP_0f07 (int, int);
+static void NOP_Fixup (int, int);
+static void OP_3DNowSuffix (int, int);
+static void OP_SIMD_Suffix (int, int);
+static void SIMD_Fixup (int, int);
+static void PNI_Fixup (int, int);
+static void SVME_Fixup (int, int);
+static void INVLPG_Fixup (int, int);
+static void BadOp (void);
+static void SEG_Fixup (int, int);
+static void VMX_Fixup (int, int);
+
+struct dis_private {
+ /* Points to first byte not fetched. */
+ bfd_byte *max_fetched;
+ bfd_byte the_buffer[MAXLEN];
+ bfd_vma insn_start;
+ int orig_sizeflag;
+#ifndef __KERNEL__
+ jmp_buf bailout;
+#endif /* __KERNEL__ */
+};
+
+/* The opcode for the fwait instruction, which we treat as a prefix
+ when we can. */
+#define FWAIT_OPCODE (0x9b)
+
+/* Set to 1 for 64bit mode disassembly. */
+static int mode_64bit;
+
+/* Flags for the prefixes for the current instruction. See below. */
+static int prefixes;
+
+/* REX prefix the current instruction. See below. */
+static int rex;
+/* Bits of REX we've already used. */
+static int rex_used;
+#define REX_MODE64 8
+#define REX_EXTX 4
+#define REX_EXTY 2
+#define REX_EXTZ 1
+/* Mark parts used in the REX prefix. When we are testing for
+ empty prefix (for 8bit register REX extension), just mask it
+ out. Otherwise test for REX bit is excuse for existence of REX
+ only in case value is nonzero. */
+#define USED_REX(value) \
+ { \
+ if (value) \
+ rex_used |= (rex & value) ? (value) | 0x40 : 0; \
+ else \
+ rex_used |= 0x40; \
+ }
+
+/* Flags for prefixes which we somehow handled when printing the
+ current instruction. */
+static int used_prefixes;
+
+/* Flags stored in PREFIXES. */
+#define PREFIX_REPZ 1
+#define PREFIX_REPNZ 2
+#define PREFIX_LOCK 4
+#define PREFIX_CS 8
+#define PREFIX_SS 0x10
+#define PREFIX_DS 0x20
+#define PREFIX_ES 0x40
+#define PREFIX_FS 0x80
+#define PREFIX_GS 0x100
+#define PREFIX_DATA 0x200
+#define PREFIX_ADDR 0x400
+#define PREFIX_FWAIT 0x800
+
+/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
+ to ADDR (exclusive) are valid. Returns 1 for success, longjmps
+ on error. */
+#define FETCH_DATA(info, addr) \
+ ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
+ ? 1 : fetch_data ((info), (addr)))
+
+static int
+fetch_data (struct disassemble_info *info, bfd_byte *addr)
+{
+ int status;
+ struct dis_private *priv = (struct dis_private *) info->private_data;
+ bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
+
+ status = (*info->read_memory_func) (start,
+ priv->max_fetched,
+ addr - priv->max_fetched,
+ info);
+ if (status != 0)
+ {
+ /* If we did manage to read at least one byte, then
+ print_insn_i386 will do something sensible. Otherwise, print
+ an error. We do that here because this is where we know
+ STATUS. */
+ if (priv->max_fetched == priv->the_buffer)
+ (*info->memory_error_func) (status, start, info);
+#ifndef __KERNEL__
+ longjmp (priv->bailout, 1);
+#else /* __KERNEL__ */
+ /* XXX - what to do? */
+ kdb_printf("Hmm. longjmp.\n");
+#endif /* __KERNEL__ */
+ }
+ else
+ priv->max_fetched = addr;
+ return 1;
+}
+
+#define XX NULL, 0
+
+#define Eb OP_E, b_mode
+#define Ev OP_E, v_mode
+#define Ed OP_E, d_mode
+#define Eq OP_E, q_mode
+#define Edq OP_E, dq_mode
+#define Edqw OP_E, dqw_mode
+#define indirEv OP_indirE, branch_v_mode
+#define indirEp OP_indirE, f_mode
+#define Em OP_E, m_mode
+#define Ew OP_E, w_mode
+#define Ma OP_E, v_mode
+#define M OP_M, 0 /* lea, lgdt, etc. */
+#define Mp OP_M, f_mode /* 32 or 48 bit memory operand for LDS, LES etc */
+#define Gb OP_G, b_mode
+#define Gv OP_G, v_mode
+#define Gd OP_G, d_mode
+#define Gdq OP_G, dq_mode
+#define Gm OP_G, m_mode
+#define Gw OP_G, w_mode
+#define Rd OP_Rd, d_mode
+#define Rm OP_Rd, m_mode
+#define Ib OP_I, b_mode
+#define sIb OP_sI, b_mode /* sign extened byte */
+#define Iv OP_I, v_mode
+#define Iq OP_I, q_mode
+#define Iv64 OP_I64, v_mode
+#define Iw OP_I, w_mode
+#define I1 OP_I, const_1_mode
+#define Jb OP_J, b_mode
+#define Jv OP_J, v_mode
+#define Cm OP_C, m_mode
+#define Dm OP_D, m_mode
+#define Td OP_T, d_mode
+#define Sv SEG_Fixup, v_mode
+
+#define RMeAX OP_REG, eAX_reg
+#define RMeBX OP_REG, eBX_reg
+#define RMeCX OP_REG, eCX_reg
+#define RMeDX OP_REG, eDX_reg
+#define RMeSP OP_REG, eSP_reg
+#define RMeBP OP_REG, eBP_reg
+#define RMeSI OP_REG, eSI_reg
+#define RMeDI OP_REG, eDI_reg
+#define RMrAX OP_REG, rAX_reg
+#define RMrBX OP_REG, rBX_reg
+#define RMrCX OP_REG, rCX_reg
+#define RMrDX OP_REG, rDX_reg
+#define RMrSP OP_REG, rSP_reg
+#define RMrBP OP_REG, rBP_reg
+#define RMrSI OP_REG, rSI_reg
+#define RMrDI OP_REG, rDI_reg
+#define RMAL OP_REG, al_reg
+#define RMAL OP_REG, al_reg
+#define RMCL OP_REG, cl_reg
+#define RMDL OP_REG, dl_reg
+#define RMBL OP_REG, bl_reg
+#define RMAH OP_REG, ah_reg
+#define RMCH OP_REG, ch_reg
+#define RMDH OP_REG, dh_reg
+#define RMBH OP_REG, bh_reg
+#define RMAX OP_REG, ax_reg
+#define RMDX OP_REG, dx_reg
+
+#define eAX OP_IMREG, eAX_reg
+#define eBX OP_IMREG, eBX_reg
+#define eCX OP_IMREG, eCX_reg
+#define eDX OP_IMREG, eDX_reg
+#define eSP OP_IMREG, eSP_reg
+#define eBP OP_IMREG, eBP_reg
+#define eSI OP_IMREG, eSI_reg
+#define eDI OP_IMREG, eDI_reg
+#define AL OP_IMREG, al_reg
+#define AL OP_IMREG, al_reg
+#define CL OP_IMREG, cl_reg
+#define DL OP_IMREG, dl_reg
+#define BL OP_IMREG, bl_reg
+#define AH OP_IMREG, ah_reg
+#define CH OP_IMREG, ch_reg
+#define DH OP_IMREG, dh_reg
+#define BH OP_IMREG, bh_reg
+#define AX OP_IMREG, ax_reg
+#define DX OP_IMREG, dx_reg
+#define indirDX OP_IMREG, indir_dx_reg
+
+#define Sw OP_SEG, w_mode
+#define Ap OP_DIR, 0
+#define Ob OP_OFF, b_mode
+#define Ob64 OP_OFF64, b_mode
+#define Ov OP_OFF, v_mode
+#define Ov64 OP_OFF64, v_mode
+#define Xb OP_DSreg, eSI_reg
+#define Xv OP_DSreg, eSI_reg
+#define Yb OP_ESreg, eDI_reg
+#define Yv OP_ESreg, eDI_reg
+#define DSBX OP_DSreg, eBX_reg
+
+#define es OP_REG, es_reg
+#define ss OP_REG, ss_reg
+#define cs OP_REG, cs_reg
+#define ds OP_REG, ds_reg
+#define fs OP_REG, fs_reg
+#define gs OP_REG, gs_reg
+
+#define MX OP_MMX, 0
+#define XM OP_XMM, 0
+#define EM OP_EM, v_mode
+#define EX OP_EX, v_mode
+#define MS OP_MS, v_mode
+#define XS OP_XS, v_mode
+#define VM OP_VMX, q_mode
+#define OPSUF OP_3DNowSuffix, 0
+#define OPSIMD OP_SIMD_Suffix, 0
+
+#define cond_jump_flag NULL, cond_jump_mode
+#define loop_jcxz_flag NULL, loop_jcxz_mode
+
+/* bits in sizeflag */
+#define SUFFIX_ALWAYS 4
+#define AFLAG 2
+#define DFLAG 1
+
+#define b_mode 1 /* byte operand */
+#define v_mode 2 /* operand size depends on prefixes */
+#define w_mode 3 /* word operand */
+#define d_mode 4 /* double word operand */
+#define q_mode 5 /* quad word operand */
+#define t_mode 6 /* ten-byte operand */
+#define x_mode 7 /* 16-byte XMM operand */
+#define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
+#define cond_jump_mode 9
+#define loop_jcxz_mode 10
+#define dq_mode 11 /* operand size depends on REX prefixes. */
+#define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
+#define f_mode 13 /* 4- or 6-byte pointer operand */
+#define const_1_mode 14
+#define branch_v_mode 15 /* v_mode for branch. */
+
+#define es_reg 100
+#define cs_reg 101
+#define ss_reg 102
+#define ds_reg 103
+#define fs_reg 104
+#define gs_reg 105
+
+#define eAX_reg 108
+#define eCX_reg 109
+#define eDX_reg 110
+#define eBX_reg 111
+#define eSP_reg 112
+#define eBP_reg 113
+#define eSI_reg 114
+#define eDI_reg 115
+
+#define al_reg 116
+#define cl_reg 117
+#define dl_reg 118
+#define bl_reg 119
+#define ah_reg 120
+#define ch_reg 121
+#define dh_reg 122
+#define bh_reg 123
+
+#define ax_reg 124
+#define cx_reg 125
+#define dx_reg 126
+#define bx_reg 127
+#define sp_reg 128
+#define bp_reg 129
+#define si_reg 130
+#define di_reg 131
+
+#define rAX_reg 132
+#define rCX_reg 133
+#define rDX_reg 134
+#define rBX_reg 135
+#define rSP_reg 136
+#define rBP_reg 137
+#define rSI_reg 138
+#define rDI_reg 139
+
+#define indir_dx_reg 150
+
+#define FLOATCODE 1
+#define USE_GROUPS 2
+#define USE_PREFIX_USER_TABLE 3
+#define X86_64_SPECIAL 4
+
+#define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
+
+#define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0
+#define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0
+#define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0
+#define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0
+#define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0
+#define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0
+#define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0
+#define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0
+#define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0
+#define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0
+#define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
+#define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
+#define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
+#define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
+#define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
+#define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
+#define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
+#define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
+#define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
+#define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
+#define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
+#define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
+#define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
+#define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0
+#define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0
+
+#define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0
+#define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0
+#define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0
+#define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0
+#define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0
+#define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0
+#define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0
+#define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0
+#define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0
+#define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0
+#define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
+#define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
+#define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
+#define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
+#define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
+#define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
+#define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
+#define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
+#define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
+#define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
+#define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
+#define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
+#define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
+#define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
+#define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
+#define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
+#define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
+#define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0
+#define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0
+#define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0
+#define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0
+#define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0
+#define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0
+
+#define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
+
+typedef void (*op_rtn) (int bytemode, int sizeflag);
+
+struct dis386 {
+ const char *name;
+ op_rtn op1;
+ int bytemode1;
+ op_rtn op2;
+ int bytemode2;
+ op_rtn op3;
+ int bytemode3;
+};
+
+/* Upper case letters in the instruction names here are macros.
+ 'A' => print 'b' if no register operands or suffix_always is true
+ 'B' => print 'b' if suffix_always is true
+ 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
+ . size prefix
+ 'E' => print 'e' if 32-bit form of jcxz
+ 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
+ 'H' => print ",pt" or ",pn" branch hint
+ 'I' => honor following macro letter even in Intel mode (implemented only
+ . for some of the macro letters)
+ 'J' => print 'l'
+ 'L' => print 'l' if suffix_always is true
+ 'N' => print 'n' if instruction has no wait "prefix"
+ 'O' => print 'd', or 'o'
+ 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
+ . or suffix_always is true. print 'q' if rex prefix is present.
+ 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
+ . is true
+ 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
+ 'S' => print 'w', 'l' or 'q' if suffix_always is true
+ 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
+ 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
+ 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
+ 'X' => print 's', 'd' depending on data16 prefix (for XMM)
+ 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
+
+ Many of the above letters print nothing in Intel mode. See "putop"
+ for the details.
+
+ Braces '{' and '}', and vertical bars '|', indicate alternative
+ mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
+ modes. In cases where there are only two alternatives, the X86_64
+ instruction is reserved, and "(bad)" is printed.
+*/
+
+static const struct dis386 dis386[] = {
+ /* 00 */
+ { "addB", Eb, Gb, XX },
+ { "addS", Ev, Gv, XX },
+ { "addB", Gb, Eb, XX },
+ { "addS", Gv, Ev, XX },
+ { "addB", AL, Ib, XX },
+ { "addS", eAX, Iv, XX },
+ { "push{T|}", es, XX, XX },
+ { "pop{T|}", es, XX, XX },
+ /* 08 */
+ { "orB", Eb, Gb, XX },
+ { "orS", Ev, Gv, XX },
+ { "orB", Gb, Eb, XX },
+ { "orS", Gv, Ev, XX },
+ { "orB", AL, Ib, XX },
+ { "orS", eAX, Iv, XX },
+ { "push{T|}", cs, XX, XX },
+ { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */
+ /* 10 */
+ { "adcB", Eb, Gb, XX },
+ { "adcS", Ev, Gv, XX },
+ { "adcB", Gb, Eb, XX },
+ { "adcS", Gv, Ev, XX },
+ { "adcB", AL, Ib, XX },
+ { "adcS", eAX, Iv, XX },
+ { "push{T|}", ss, XX, XX },
+ { "popT|}", ss, XX, XX },
+ /* 18 */
+ { "sbbB", Eb, Gb, XX },
+ { "sbbS", Ev, Gv, XX },
+ { "sbbB", Gb, Eb, XX },
+ { "sbbS", Gv, Ev, XX },
+ { "sbbB", AL, Ib, XX },
+ { "sbbS", eAX, Iv, XX },
+ { "push{T|}", ds, XX, XX },
+ { "pop{T|}", ds, XX, XX },
+ /* 20 */
+ { "andB", Eb, Gb, XX },
+ { "andS", Ev, Gv, XX },
+ { "andB", Gb, Eb, XX },
+ { "andS", Gv, Ev, XX },
+ { "andB", AL, Ib, XX },
+ { "andS", eAX, Iv, XX },
+ { "(bad)", XX, XX, XX }, /* SEG ES prefix */
+ { "daa{|}", XX, XX, XX },
+ /* 28 */
+ { "subB", Eb, Gb, XX },
+ { "subS", Ev, Gv, XX },
+ { "subB", Gb, Eb, XX },
+ { "subS", Gv, Ev, XX },
+ { "subB", AL, Ib, XX },
+ { "subS", eAX, Iv, XX },
+ { "(bad)", XX, XX, XX }, /* SEG CS prefix */
+ { "das{|}", XX, XX, XX },
+ /* 30 */
+ { "xorB", Eb, Gb, XX },
+ { "xorS", Ev, Gv, XX },
+ { "xorB", Gb, Eb, XX },
+ { "xorS", Gv, Ev, XX },
+ { "xorB", AL, Ib, XX },
+ { "xorS", eAX, Iv, XX },
+ { "(bad)", XX, XX, XX }, /* SEG SS prefix */
+ { "aaa{|}", XX, XX, XX },
+ /* 38 */
+ { "cmpB", Eb, Gb, XX },
+ { "cmpS", Ev, Gv, XX },
+ { "cmpB", Gb, Eb, XX },
+ { "cmpS", Gv, Ev, XX },
+ { "cmpB", AL, Ib, XX },
+ { "cmpS", eAX, Iv, XX },
+ { "(bad)", XX, XX, XX }, /* SEG DS prefix */
+ { "aas{|}", XX, XX, XX },
+ /* 40 */
+ { "inc{S|}", RMeAX, XX, XX },
+ { "inc{S|}", RMeCX, XX, XX },
+ { "inc{S|}", RMeDX, XX, XX },
+ { "inc{S|}", RMeBX, XX, XX },
+ { "inc{S|}", RMeSP, XX, XX },
+ { "inc{S|}", RMeBP, XX, XX },
+ { "inc{S|}", RMeSI, XX, XX },
+ { "inc{S|}", RMeDI, XX, XX },
+ /* 48 */
+ { "dec{S|}", RMeAX, XX, XX },
+ { "dec{S|}", RMeCX, XX, XX },
+ { "dec{S|}", RMeDX, XX, XX },
+ { "dec{S|}", RMeBX, XX, XX },
+ { "dec{S|}", RMeSP, XX, XX },
+ { "dec{S|}", RMeBP, XX, XX },
+ { "dec{S|}", RMeSI, XX, XX },
+ { "dec{S|}", RMeDI, XX, XX },
+ /* 50 */
+ { "pushS", RMrAX, XX, XX },
+ { "pushS", RMrCX, XX, XX },
+ { "pushS", RMrDX, XX, XX },
+ { "pushS", RMrBX, XX, XX },
+ { "pushS", RMrSP, XX, XX },
+ { "pushS", RMrBP, XX, XX },
+ { "pushS", RMrSI, XX, XX },
+ { "pushS", RMrDI, XX, XX },
+ /* 58 */
+ { "popS", RMrAX, XX, XX },
+ { "popS", RMrCX, XX, XX },
+ { "popS", RMrDX, XX, XX },
+ { "popS", RMrBX, XX, XX },
+ { "popS", RMrSP, XX, XX },
+ { "popS", RMrBP, XX, XX },
+ { "popS", RMrSI, XX, XX },
+ { "popS", RMrDI, XX, XX },
+ /* 60 */
+ { "pusha{P|}", XX, XX, XX },
+ { "popa{P|}", XX, XX, XX },
+ { "bound{S|}", Gv, Ma, XX },
+ { X86_64_0 },
+ { "(bad)", XX, XX, XX }, /* seg fs */
+ { "(bad)", XX, XX, XX }, /* seg gs */
+ { "(bad)", XX, XX, XX }, /* op size prefix */
+ { "(bad)", XX, XX, XX }, /* adr size prefix */
+ /* 68 */
+ { "pushT", Iq, XX, XX },
+ { "imulS", Gv, Ev, Iv },
+ { "pushT", sIb, XX, XX },
+ { "imulS", Gv, Ev, sIb },
+ { "ins{b||b|}", Yb, indirDX, XX },
+ { "ins{R||R|}", Yv, indirDX, XX },
+ { "outs{b||b|}", indirDX, Xb, XX },
+ { "outs{R||R|}", indirDX, Xv, XX },
+ /* 70 */
+ { "joH", Jb, XX, cond_jump_flag },
+ { "jnoH", Jb, XX, cond_jump_flag },
+ { "jbH", Jb, XX, cond_jump_flag },
+ { "jaeH", Jb, XX, cond_jump_flag },
+ { "jeH", Jb, XX, cond_jump_flag },
+ { "jneH", Jb, XX, cond_jump_flag },
+ { "jbeH", Jb, XX, cond_jump_flag },
+ { "jaH", Jb, XX, cond_jump_flag },
+ /* 78 */
+ { "jsH", Jb, XX, cond_jump_flag },
+ { "jnsH", Jb, XX, cond_jump_flag },
+ { "jpH", Jb, XX, cond_jump_flag },
+ { "jnpH", Jb, XX, cond_jump_flag },
+ { "jlH", Jb, XX, cond_jump_flag },
+ { "jgeH", Jb, XX, cond_jump_flag },
+ { "jleH", Jb, XX, cond_jump_flag },
+ { "jgH", Jb, XX, cond_jump_flag },
+ /* 80 */
+ { GRP1b },
+ { GRP1S },
+ { "(bad)", XX, XX, XX },
+ { GRP1Ss },
+ { "testB", Eb, Gb, XX },
+ { "testS", Ev, Gv, XX },
+ { "xchgB", Eb, Gb, XX },
+ { "xchgS", Ev, Gv, XX },
+ /* 88 */
+ { "movB", Eb, Gb, XX },
+ { "movS", Ev, Gv, XX },
+ { "movB", Gb, Eb, XX },
+ { "movS", Gv, Ev, XX },
+ { "movQ", Sv, Sw, XX },
+ { "leaS", Gv, M, XX },
+ { "movQ", Sw, Sv, XX },
+ { "popU", Ev, XX, XX },
+ /* 90 */
+ { "nop", NOP_Fixup, 0, XX, XX },
+ { "xchgS", RMeCX, eAX, XX },
+ { "xchgS", RMeDX, eAX, XX },
+ { "xchgS", RMeBX, eAX, XX },
+ { "xchgS", RMeSP, eAX, XX },
+ { "xchgS", RMeBP, eAX, XX },
+ { "xchgS", RMeSI, eAX, XX },
+ { "xchgS", RMeDI, eAX, XX },
+ /* 98 */
+ { "cW{tR||tR|}", XX, XX, XX },
+ { "cR{tO||tO|}", XX, XX, XX },
+ { "Jcall{T|}", Ap, XX, XX },
+ { "(bad)", XX, XX, XX }, /* fwait */
+ { "pushfT", XX, XX, XX },
+ { "popfT", XX, XX, XX },
+ { "sahf{|}", XX, XX, XX },
+ { "lahf{|}", XX, XX, XX },
+ /* a0 */
+ { "movB", AL, Ob64, XX },
+ { "movS", eAX, Ov64, XX },
+ { "movB", Ob64, AL, XX },
+ { "movS", Ov64, eAX, XX },
+ { "movs{b||b|}", Yb, Xb, XX },
+ { "movs{R||R|}", Yv, Xv, XX },
+ { "cmps{b||b|}", Xb, Yb, XX },
+ { "cmps{R||R|}", Xv, Yv, XX },
+ /* a8 */
+ { "testB", AL, Ib, XX },
+ { "testS", eAX, Iv, XX },
+ { "stosB", Yb, AL, XX },
+ { "stosS", Yv, eAX, XX },
+ { "lodsB", AL, Xb, XX },
+ { "lodsS", eAX, Xv, XX },
+ { "scasB", AL, Yb, XX },
+ { "scasS", eAX, Yv, XX },
+ /* b0 */
+ { "movB", RMAL, Ib, XX },
+ { "movB", RMCL, Ib, XX },
+ { "movB", RMDL, Ib, XX },
+ { "movB", RMBL, Ib, XX },
+ { "movB", RMAH, Ib, XX },
+ { "movB", RMCH, Ib, XX },
+ { "movB", RMDH, Ib, XX },
+ { "movB", RMBH, Ib, XX },
+ /* b8 */
+ { "movS", RMeAX, Iv64, XX },
+ { "movS", RMeCX, Iv64, XX },
+ { "movS", RMeDX, Iv64, XX },
+ { "movS", RMeBX, Iv64, XX },
+ { "movS", RMeSP, Iv64, XX },
+ { "movS", RMeBP, Iv64, XX },
+ { "movS", RMeSI, Iv64, XX },
+ { "movS", RMeDI, Iv64, XX },
+ /* c0 */
+ { GRP2b },
+ { GRP2S },
+ { "retT", Iw, XX, XX },
+ { "retT", XX, XX, XX },
+ { "les{S|}", Gv, Mp, XX },
+ { "ldsS", Gv, Mp, XX },
+ { "movA", Eb, Ib, XX },
+ { "movQ", Ev, Iv, XX },
+ /* c8 */
+ { "enterT", Iw, Ib, XX },
+ { "leaveT", XX, XX, XX },
+ { "lretP", Iw, XX, XX },
+ { "lretP", XX, XX, XX },
+ { "int3", XX, XX, XX },
+ { "int", Ib, XX, XX },
+ { "into{|}", XX, XX, XX },
+ { "iretP", XX, XX, XX },
+ /* d0 */
+ { GRP2b_one },
+ { GRP2S_one },
+ { GRP2b_cl },
+ { GRP2S_cl },
+ { "aam{|}", sIb, XX, XX },
+ { "aad{|}", sIb, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "xlat", DSBX, XX, XX },
+ /* d8 */
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ { FLOAT },
+ /* e0 */
+ { "loopneFH", Jb, XX, loop_jcxz_flag },
+ { "loopeFH", Jb, XX, loop_jcxz_flag },
+ { "loopFH", Jb, XX, loop_jcxz_flag },
+ { "jEcxzH", Jb, XX, loop_jcxz_flag },
+ { "inB", AL, Ib, XX },
+ { "inS", eAX, Ib, XX },
+ { "outB", Ib, AL, XX },
+ { "outS", Ib, eAX, XX },
+ /* e8 */
+ { "callT", Jv, XX, XX },
+ { "jmpT", Jv, XX, XX },
+ { "Jjmp{T|}", Ap, XX, XX },
+ { "jmp", Jb, XX, XX },
+ { "inB", AL, indirDX, XX },
+ { "inS", eAX, indirDX, XX },
+ { "outB", indirDX, AL, XX },
+ { "outS", indirDX, eAX, XX },
+ /* f0 */
+ { "(bad)", XX, XX, XX }, /* lock prefix */
+ { "icebp", XX, XX, XX },
+ { "(bad)", XX, XX, XX }, /* repne */
+ { "(bad)", XX, XX, XX }, /* repz */
+ { "hlt", XX, XX, XX },
+ { "cmc", XX, XX, XX },
+ { GRP3b },
+ { GRP3S },
+ /* f8 */
+ { "clc", XX, XX, XX },
+ { "stc", XX, XX, XX },
+ { "cli", XX, XX, XX },
+ { "sti", XX, XX, XX },
+ { "cld", XX, XX, XX },
+ { "std", XX, XX, XX },
+ { GRP4 },
+ { GRP5 },
+};
+
+static const struct dis386 dis386_twobyte[] = {
+ /* 00 */
+ { GRP6 },
+ { GRP7 },
+ { "larS", Gv, Ew, XX },
+ { "lslS", Gv, Ew, XX },
+ { "(bad)", XX, XX, XX },
+ { "syscall", XX, XX, XX },
+ { "clts", XX, XX, XX },
+ { "sysretP", XX, XX, XX },
+ /* 08 */
+ { "invd", XX, XX, XX },
+ { "wbinvd", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "ud2a", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { GRPAMD },
+ { "femms", XX, XX, XX },
+ { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix. */
+ /* 10 */
+ { PREGRP8 },
+ { PREGRP9 },
+ { PREGRP30 },
+ { "movlpX", EX, XM, SIMD_Fixup, 'h' },
+ { "unpcklpX", XM, EX, XX },
+ { "unpckhpX", XM, EX, XX },
+ { PREGRP31 },
+ { "movhpX", EX, XM, SIMD_Fixup, 'l' },
+ /* 18 */
+ { GRP14 },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ /* 20 */
+ { "movL", Rm, Cm, XX },
+ { "movL", Rm, Dm, XX },
+ { "movL", Cm, Rm, XX },
+ { "movL", Dm, Rm, XX },
+ { "movL", Rd, Td, XX },
+ { "(bad)", XX, XX, XX },
+ { "movL", Td, Rd, XX },
+ { "(bad)", XX, XX, XX },
+ /* 28 */
+ { "movapX", XM, EX, XX },
+ { "movapX", EX, XM, XX },
+ { PREGRP2 },
+ { "movntpX", Ev, XM, XX },
+ { PREGRP4 },
+ { PREGRP3 },
+ { "ucomisX", XM,EX, XX },
+ { "comisX", XM,EX, XX },
+ /* 30 */
+ { "wrmsr", XX, XX, XX },
+ { "rdtsc", XX, XX, XX },
+ { "rdmsr", XX, XX, XX },
+ { "rdpmc", XX, XX, XX },
+ { "sysenter", XX, XX, XX },
+ { "sysexit", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ /* 38 */
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ /* 40 */
+ { "cmovo", Gv, Ev, XX },
+ { "cmovno", Gv, Ev, XX },
+ { "cmovb", Gv, Ev, XX },
+ { "cmovae", Gv, Ev, XX },
+ { "cmove", Gv, Ev, XX },
+ { "cmovne", Gv, Ev, XX },
+ { "cmovbe", Gv, Ev, XX },
+ { "cmova", Gv, Ev, XX },
+ /* 48 */
+ { "cmovs", Gv, Ev, XX },
+ { "cmovns", Gv, Ev, XX },
+ { "cmovp", Gv, Ev, XX },
+ { "cmovnp", Gv, Ev, XX },
+ { "cmovl", Gv, Ev, XX },
+ { "cmovge", Gv, Ev, XX },
+ { "cmovle", Gv, Ev, XX },
+ { "cmovg", Gv, Ev, XX },
+ /* 50 */
+ { "movmskpX", Gdq, XS, XX },
+ { PREGRP13 },
+ { PREGRP12 },
+ { PREGRP11 },
+ { "andpX", XM, EX, XX },
+ { "andnpX", XM, EX, XX },
+ { "orpX", XM, EX, XX },
+ { "xorpX", XM, EX, XX },
+ /* 58 */
+ { PREGRP0 },
+ { PREGRP10 },
+ { PREGRP17 },
+ { PREGRP16 },
+ { PREGRP14 },
+ { PREGRP7 },
+ { PREGRP5 },
+ { PREGRP6 },
+ /* 60 */
+ { "punpcklbw", MX, EM, XX },
+ { "punpcklwd", MX, EM, XX },
+ { "punpckldq", MX, EM, XX },
+ { "packsswb", MX, EM, XX },
+ { "pcmpgtb", MX, EM, XX },
+ { "pcmpgtw", MX, EM, XX },
+ { "pcmpgtd", MX, EM, XX },
+ { "packuswb", MX, EM, XX },
+ /* 68 */
+ { "punpckhbw", MX, EM, XX },
+ { "punpckhwd", MX, EM, XX },
+ { "punpckhdq", MX, EM, XX },
+ { "packssdw", MX, EM, XX },
+ { PREGRP26 },
+ { PREGRP24 },
+ { "movd", MX, Edq, XX },
+ { PREGRP19 },
+ /* 70 */
+ { PREGRP22 },
+ { GRP10 },
+ { GRP11 },
+ { GRP12 },
+ { "pcmpeqb", MX, EM, XX },
+ { "pcmpeqw", MX, EM, XX },
+ { "pcmpeqd", MX, EM, XX },
+ { "emms", XX, XX, XX },
+ /* 78 */
+ { "vmread", Em, Gm, XX },
+ { "vmwrite", Gm, Em, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { PREGRP28 },
+ { PREGRP29 },
+ { PREGRP23 },
+ { PREGRP20 },
+ /* 80 */
+ { "joH", Jv, XX, cond_jump_flag },
+ { "jnoH", Jv, XX, cond_jump_flag },
+ { "jbH", Jv, XX, cond_jump_flag },
+ { "jaeH", Jv, XX, cond_jump_flag },
+ { "jeH", Jv, XX, cond_jump_flag },
+ { "jneH", Jv, XX, cond_jump_flag },
+ { "jbeH", Jv, XX, cond_jump_flag },
+ { "jaH", Jv, XX, cond_jump_flag },
+ /* 88 */
+ { "jsH", Jv, XX, cond_jump_flag },
+ { "jnsH", Jv, XX, cond_jump_flag },
+ { "jpH", Jv, XX, cond_jump_flag },
+ { "jnpH", Jv, XX, cond_jump_flag },
+ { "jlH", Jv, XX, cond_jump_flag },
+ { "jgeH", Jv, XX, cond_jump_flag },
+ { "jleH", Jv, XX, cond_jump_flag },
+ { "jgH", Jv, XX, cond_jump_flag },
+ /* 90 */
+ { "seto", Eb, XX, XX },
+ { "setno", Eb, XX, XX },
+ { "setb", Eb, XX, XX },
+ { "setae", Eb, XX, XX },
+ { "sete", Eb, XX, XX },
+ { "setne", Eb, XX, XX },
+ { "setbe", Eb, XX, XX },
+ { "seta", Eb, XX, XX },
+ /* 98 */
+ { "sets", Eb, XX, XX },
+ { "setns", Eb, XX, XX },
+ { "setp", Eb, XX, XX },
+ { "setnp", Eb, XX, XX },
+ { "setl", Eb, XX, XX },
+ { "setge", Eb, XX, XX },
+ { "setle", Eb, XX, XX },
+ { "setg", Eb, XX, XX },
+ /* a0 */
+ { "pushT", fs, XX, XX },
+ { "popT", fs, XX, XX },
+ { "cpuid", XX, XX, XX },
+ { "btS", Ev, Gv, XX },
+ { "shldS", Ev, Gv, Ib },
+ { "shldS", Ev, Gv, CL },
+ { GRPPADLCK2 },
+ { GRPPADLCK1 },
+ /* a8 */
+ { "pushT", gs, XX, XX },
+ { "popT", gs, XX, XX },
+ { "rsm", XX, XX, XX },
+ { "btsS", Ev, Gv, XX },
+ { "shrdS", Ev, Gv, Ib },
+ { "shrdS", Ev, Gv, CL },
+ { GRP13 },
+ { "imulS", Gv, Ev, XX },
+ /* b0 */
+ { "cmpxchgB", Eb, Gb, XX },
+ { "cmpxchgS", Ev, Gv, XX },
+ { "lssS", Gv, Mp, XX },
+ { "btrS", Ev, Gv, XX },
+ { "lfsS", Gv, Mp, XX },
+ { "lgsS", Gv, Mp, XX },
+ { "movz{bR|x|bR|x}", Gv, Eb, XX },
+ { "movz{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movzww ! */
+ /* b8 */
+ { "(bad)", XX, XX, XX },
+ { "ud2b", XX, XX, XX },
+ { GRP8 },
+ { "btcS", Ev, Gv, XX },
+ { "bsfS", Gv, Ev, XX },
+ { "bsrS", Gv, Ev, XX },
+ { "movs{bR|x|bR|x}", Gv, Eb, XX },
+ { "movs{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movsww ! */
+ /* c0 */
+ { "xaddB", Eb, Gb, XX },
+ { "xaddS", Ev, Gv, XX },
+ { PREGRP1 },
+ { "movntiS", Ev, Gv, XX },
+ { "pinsrw", MX, Edqw, Ib },
+ { "pextrw", Gdq, MS, Ib },
+ { "shufpX", XM, EX, Ib },
+ { GRP9 },
+ /* c8 */
+ { "bswap", RMeAX, XX, XX },
+ { "bswap", RMeCX, XX, XX },
+ { "bswap", RMeDX, XX, XX },
+ { "bswap", RMeBX, XX, XX },
+ { "bswap", RMeSP, XX, XX },
+ { "bswap", RMeBP, XX, XX },
+ { "bswap", RMeSI, XX, XX },
+ { "bswap", RMeDI, XX, XX },
+ /* d0 */
+ { PREGRP27 },
+ { "psrlw", MX, EM, XX },
+ { "psrld", MX, EM, XX },
+ { "psrlq", MX, EM, XX },
+ { "paddq", MX, EM, XX },
+ { "pmullw", MX, EM, XX },
+ { PREGRP21 },
+ { "pmovmskb", Gdq, MS, XX },
+ /* d8 */
+ { "psubusb", MX, EM, XX },
+ { "psubusw", MX, EM, XX },
+ { "pminub", MX, EM, XX },
+ { "pand", MX, EM, XX },
+ { "paddusb", MX, EM, XX },
+ { "paddusw", MX, EM, XX },
+ { "pmaxub", MX, EM, XX },
+ { "pandn", MX, EM, XX },
+ /* e0 */
+ { "pavgb", MX, EM, XX },
+ { "psraw", MX, EM, XX },
+ { "psrad", MX, EM, XX },
+ { "pavgw", MX, EM, XX },
+ { "pmulhuw", MX, EM, XX },
+ { "pmulhw", MX, EM, XX },
+ { PREGRP15 },
+ { PREGRP25 },
+ /* e8 */
+ { "psubsb", MX, EM, XX },
+ { "psubsw", MX, EM, XX },
+ { "pminsw", MX, EM, XX },
+ { "por", MX, EM, XX },
+ { "paddsb", MX, EM, XX },
+ { "paddsw", MX, EM, XX },
+ { "pmaxsw", MX, EM, XX },
+ { "pxor", MX, EM, XX },
+ /* f0 */
+ { PREGRP32 },
+ { "psllw", MX, EM, XX },
+ { "pslld", MX, EM, XX },
+ { "psllq", MX, EM, XX },
+ { "pmuludq", MX, EM, XX },
+ { "pmaddwd", MX, EM, XX },
+ { "psadbw", MX, EM, XX },
+ { PREGRP18 },
+ /* f8 */
+ { "psubb", MX, EM, XX },
+ { "psubw", MX, EM, XX },
+ { "psubd", MX, EM, XX },
+ { "psubq", MX, EM, XX },
+ { "paddb", MX, EM, XX },
+ { "paddw", MX, EM, XX },
+ { "paddd", MX, EM, XX },
+ { "(bad)", XX, XX, XX }
+};
+
+static const unsigned char onebyte_has_modrm[256] = {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* ------------------------------- */
+ /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
+ /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
+ /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
+ /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
+ /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
+ /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
+ /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
+ /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
+ /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
+ /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
+ /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
+ /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
+ /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
+ /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
+ /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
+ /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
+ /* ------------------------------- */
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+};
+
+static const unsigned char twobyte_has_modrm[256] = {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* ------------------------------- */
+ /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
+ /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
+ /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
+ /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
+ /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
+ /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
+ /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
+ /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
+ /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
+ /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
+ /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
+ /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
+ /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
+ /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
+ /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
+ /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
+ /* ------------------------------- */
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+};
+
+static const unsigned char twobyte_uses_SSE_prefix[256] = {
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ /* ------------------------------- */
+ /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
+ /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
+ /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
+ /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
+ /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
+ /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
+ /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
+ /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, /* 7f */
+ /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
+ /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
+ /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
+ /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
+ /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
+ /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
+ /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
+ /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
+ /* ------------------------------- */
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+};
+
+static char obuf[100];
+static char *obufp;
+static char scratchbuf[100];
+static unsigned char *start_codep;
+static unsigned char *insn_codep;
+static unsigned char *codep;
+static disassemble_info *the_info;
+static int mod;
+static int rm;
+static int reg;
+static unsigned char need_modrm;
+
+/* If we are accessing mod/rm/reg without need_modrm set, then the
+ values are stale. Hitting this abort likely indicates that you
+ need to update onebyte_has_modrm or twobyte_has_modrm. */
+#define MODRM_CHECK if (!need_modrm) abort ()
+
+static const char **names64;
+static const char **names32;
+static const char **names16;
+static const char **names8;
+static const char **names8rex;
+static const char **names_seg;
+static const char **index16;
+
+static const char *intel_names64[] = {
+ "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
+};
+static const char *intel_names32[] = {
+ "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
+ "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
+};
+static const char *intel_names16[] = {
+ "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
+ "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
+};
+static const char *intel_names8[] = {
+ "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
+};
+static const char *intel_names8rex[] = {
+ "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
+ "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
+};
+static const char *intel_names_seg[] = {
+ "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
+};
+static const char *intel_index16[] = {
+ "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
+};
+
+static const char *att_names64[] = {
+ "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
+ "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
+};
+static const char *att_names32[] = {
+ "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
+ "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
+};
+static const char *att_names16[] = {
+ "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
+ "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
+};
+static const char *att_names8[] = {
+ "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
+};
+static const char *att_names8rex[] = {
+ "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
+ "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
+};
+static const char *att_names_seg[] = {
+ "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
+};
+static const char *att_index16[] = {
+ "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
+};
+
+static const struct dis386 grps[][8] = {
+ /* GRP1b */
+ {
+ { "addA", Eb, Ib, XX },
+ { "orA", Eb, Ib, XX },
+ { "adcA", Eb, Ib, XX },
+ { "sbbA", Eb, Ib, XX },
+ { "andA", Eb, Ib, XX },
+ { "subA", Eb, Ib, XX },
+ { "xorA", Eb, Ib, XX },
+ { "cmpA", Eb, Ib, XX }
+ },
+ /* GRP1S */
+ {
+ { "addQ", Ev, Iv, XX },
+ { "orQ", Ev, Iv, XX },
+ { "adcQ", Ev, Iv, XX },
+ { "sbbQ", Ev, Iv, XX },
+ { "andQ", Ev, Iv, XX },
+ { "subQ", Ev, Iv, XX },
+ { "xorQ", Ev, Iv, XX },
+ { "cmpQ", Ev, Iv, XX }
+ },
+ /* GRP1Ss */
+ {
+ { "addQ", Ev, sIb, XX },
+ { "orQ", Ev, sIb, XX },
+ { "adcQ", Ev, sIb, XX },
+ { "sbbQ", Ev, sIb, XX },
+ { "andQ", Ev, sIb, XX },
+ { "subQ", Ev, sIb, XX },
+ { "xorQ", Ev, sIb, XX },
+ { "cmpQ", Ev, sIb, XX }
+ },
+ /* GRP2b */
+ {
+ { "rolA", Eb, Ib, XX },
+ { "rorA", Eb, Ib, XX },
+ { "rclA", Eb, Ib, XX },
+ { "rcrA", Eb, Ib, XX },
+ { "shlA", Eb, Ib, XX },
+ { "shrA", Eb, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "sarA", Eb, Ib, XX },
+ },
+ /* GRP2S */
+ {
+ { "rolQ", Ev, Ib, XX },
+ { "rorQ", Ev, Ib, XX },
+ { "rclQ", Ev, Ib, XX },
+ { "rcrQ", Ev, Ib, XX },
+ { "shlQ", Ev, Ib, XX },
+ { "shrQ", Ev, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "sarQ", Ev, Ib, XX },
+ },
+ /* GRP2b_one */
+ {
+ { "rolA", Eb, I1, XX },
+ { "rorA", Eb, I1, XX },
+ { "rclA", Eb, I1, XX },
+ { "rcrA", Eb, I1, XX },
+ { "shlA", Eb, I1, XX },
+ { "shrA", Eb, I1, XX },
+ { "(bad)", XX, XX, XX },
+ { "sarA", Eb, I1, XX },
+ },
+ /* GRP2S_one */
+ {
+ { "rolQ", Ev, I1, XX },
+ { "rorQ", Ev, I1, XX },
+ { "rclQ", Ev, I1, XX },
+ { "rcrQ", Ev, I1, XX },
+ { "shlQ", Ev, I1, XX },
+ { "shrQ", Ev, I1, XX },
+ { "(bad)", XX, XX, XX},
+ { "sarQ", Ev, I1, XX },
+ },
+ /* GRP2b_cl */
+ {
+ { "rolA", Eb, CL, XX },
+ { "rorA", Eb, CL, XX },
+ { "rclA", Eb, CL, XX },
+ { "rcrA", Eb, CL, XX },
+ { "shlA", Eb, CL, XX },
+ { "shrA", Eb, CL, XX },
+ { "(bad)", XX, XX, XX },
+ { "sarA", Eb, CL, XX },
+ },
+ /* GRP2S_cl */
+ {
+ { "rolQ", Ev, CL, XX },
+ { "rorQ", Ev, CL, XX },
+ { "rclQ", Ev, CL, XX },
+ { "rcrQ", Ev, CL, XX },
+ { "shlQ", Ev, CL, XX },
+ { "shrQ", Ev, CL, XX },
+ { "(bad)", XX, XX, XX },
+ { "sarQ", Ev, CL, XX }
+ },
+ /* GRP3b */
+ {
+ { "testA", Eb, Ib, XX },
+ { "(bad)", Eb, XX, XX },
+ { "notA", Eb, XX, XX },
+ { "negA", Eb, XX, XX },
+ { "mulA", Eb, XX, XX }, /* Don't print the implicit %al register, */
+ { "imulA", Eb, XX, XX }, /* to distinguish these opcodes from other */
+ { "divA", Eb, XX, XX }, /* mul/imul opcodes. Do the same for div */
+ { "idivA", Eb, XX, XX } /* and idiv for consistency. */
+ },
+ /* GRP3S */
+ {
+ { "testQ", Ev, Iv, XX },
+ { "(bad)", XX, XX, XX },
+ { "notQ", Ev, XX, XX },
+ { "negQ", Ev, XX, XX },
+ { "mulQ", Ev, XX, XX }, /* Don't print the implicit register. */
+ { "imulQ", Ev, XX, XX },
+ { "divQ", Ev, XX, XX },
+ { "idivQ", Ev, XX, XX },
+ },
+ /* GRP4 */
+ {
+ { "incA", Eb, XX, XX },
+ { "decA", Eb, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ },
+ /* GRP5 */
+ {
+ { "incQ", Ev, XX, XX },
+ { "decQ", Ev, XX, XX },
+ { "callT", indirEv, XX, XX },
+ { "JcallT", indirEp, XX, XX },
+ { "jmpT", indirEv, XX, XX },
+ { "JjmpT", indirEp, XX, XX },
+ { "pushU", Ev, XX, XX },
+ { "(bad)", XX, XX, XX },
+ },
+ /* GRP6 */
+ {
+ { "sldtQ", Ev, XX, XX },
+ { "strQ", Ev, XX, XX },
+ { "lldt", Ew, XX, XX },
+ { "ltr", Ew, XX, XX },
+ { "verr", Ew, XX, XX },
+ { "verw", Ew, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX }
+ },
+ /* GRP7 */
+ {
+ { "sgdtIQ", VMX_Fixup, 0, XX, XX },
+ { "sidtIQ", PNI_Fixup, 0, XX, XX },
+ { "lgdt{Q|Q||}", M, XX, XX },
+ { "lidt{Q|Q||}", SVME_Fixup, 0, XX, XX },
+ { "smswQ", Ev, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "lmsw", Ew, XX, XX },
+ { "invlpg", INVLPG_Fixup, w_mode, XX, XX },
+ },
+ /* GRP8 */
+ {
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "btQ", Ev, Ib, XX },
+ { "btsQ", Ev, Ib, XX },
+ { "btrQ", Ev, Ib, XX },
+ { "btcQ", Ev, Ib, XX },
+ },
+ /* GRP9 */
+ {
+ { "(bad)", XX, XX, XX },
+ { "cmpxchg8b", Eq, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "", VM, XX, XX }, /* See OP_VMX. */
+ { "vmptrst", Eq, XX, XX },
+ },
+ /* GRP10 */
+ {
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "psrlw", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "psraw", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "psllw", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ },
+ /* GRP11 */
+ {
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "psrld", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "psrad", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "pslld", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ },
+ /* GRP12 */
+ {
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "psrlq", MS, Ib, XX },
+ { "psrldq", MS, Ib, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "psllq", MS, Ib, XX },
+ { "pslldq", MS, Ib, XX },
+ },
+ /* GRP13 */
+ {
+ { "fxsave", Ev, XX, XX },
+ { "fxrstor", Ev, XX, XX },
+ { "ldmxcsr", Ev, XX, XX },
+ { "stmxcsr", Ev, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "lfence", OP_0fae, 0, XX, XX },
+ { "mfence", OP_0fae, 0, XX, XX },
+ { "clflush", OP_0fae, 0, XX, XX },
+ },
+ /* GRP14 */
+ {
+ { "prefetchnta", Ev, XX, XX },
+ { "prefetcht0", Ev, XX, XX },
+ { "prefetcht1", Ev, XX, XX },
+ { "prefetcht2", Ev, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ },
+ /* GRPAMD */
+ {
+ { "prefetch", Eb, XX, XX },
+ { "prefetchw", Eb, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ },
+ /* GRPPADLCK1 */
+ {
+ { "xstore-rng", OP_0f07, 0, XX, XX },
+ { "xcrypt-ecb", OP_0f07, 0, XX, XX },
+ { "xcrypt-cbc", OP_0f07, 0, XX, XX },
+ { "xcrypt-ctr", OP_0f07, 0, XX, XX },
+ { "xcrypt-cfb", OP_0f07, 0, XX, XX },
+ { "xcrypt-ofb", OP_0f07, 0, XX, XX },
+ { "(bad)", OP_0f07, 0, XX, XX },
+ { "(bad)", OP_0f07, 0, XX, XX },
+ },
+ /* GRPPADLCK2 */
+ {
+ { "montmul", OP_0f07, 0, XX, XX },
+ { "xsha1", OP_0f07, 0, XX, XX },
+ { "xsha256", OP_0f07, 0, XX, XX },
+ { "(bad)", OP_0f07, 0, XX, XX },
+ { "(bad)", OP_0f07, 0, XX, XX },
+ { "(bad)", OP_0f07, 0, XX, XX },
+ { "(bad)", OP_0f07, 0, XX, XX },
+ { "(bad)", OP_0f07, 0, XX, XX },
+ }
+};
+
+static const struct dis386 prefix_user_table[][4] = {
+ /* PREGRP0 */
+ {
+ { "addps", XM, EX, XX },
+ { "addss", XM, EX, XX },
+ { "addpd", XM, EX, XX },
+ { "addsd", XM, EX, XX },
+ },
+ /* PREGRP1 */
+ {
+ { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX. */
+ { "", XM, EX, OPSIMD },
+ { "", XM, EX, OPSIMD },
+ { "", XM, EX, OPSIMD },
+ },
+ /* PREGRP2 */
+ {
+ { "cvtpi2ps", XM, EM, XX },
+ { "cvtsi2ssY", XM, Ev, XX },
+ { "cvtpi2pd", XM, EM, XX },
+ { "cvtsi2sdY", XM, Ev, XX },
+ },
+ /* PREGRP3 */
+ {
+ { "cvtps2pi", MX, EX, XX },
+ { "cvtss2siY", Gv, EX, XX },
+ { "cvtpd2pi", MX, EX, XX },
+ { "cvtsd2siY", Gv, EX, XX },
+ },
+ /* PREGRP4 */
+ {
+ { "cvttps2pi", MX, EX, XX },
+ { "cvttss2siY", Gv, EX, XX },
+ { "cvttpd2pi", MX, EX, XX },
+ { "cvttsd2siY", Gv, EX, XX },
+ },
+ /* PREGRP5 */
+ {
+ { "divps", XM, EX, XX },
+ { "divss", XM, EX, XX },
+ { "divpd", XM, EX, XX },
+ { "divsd", XM, EX, XX },
+ },
+ /* PREGRP6 */
+ {
+ { "maxps", XM, EX, XX },
+ { "maxss", XM, EX, XX },
+ { "maxpd", XM, EX, XX },
+ { "maxsd", XM, EX, XX },
+ },
+ /* PREGRP7 */
+ {
+ { "minps", XM, EX, XX },
+ { "minss", XM, EX, XX },
+ { "minpd", XM, EX, XX },
+ { "minsd", XM, EX, XX },
+ },
+ /* PREGRP8 */
+ {
+ { "movups", XM, EX, XX },
+ { "movss", XM, EX, XX },
+ { "movupd", XM, EX, XX },
+ { "movsd", XM, EX, XX },
+ },
+ /* PREGRP9 */
+ {
+ { "movups", EX, XM, XX },
+ { "movss", EX, XM, XX },
+ { "movupd", EX, XM, XX },
+ { "movsd", EX, XM, XX },
+ },
+ /* PREGRP10 */
+ {
+ { "mulps", XM, EX, XX },
+ { "mulss", XM, EX, XX },
+ { "mulpd", XM, EX, XX },
+ { "mulsd", XM, EX, XX },
+ },
+ /* PREGRP11 */
+ {
+ { "rcpps", XM, EX, XX },
+ { "rcpss", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ },
+ /* PREGRP12 */
+ {
+ { "rsqrtps", XM, EX, XX },
+ { "rsqrtss", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ },
+ /* PREGRP13 */
+ {
+ { "sqrtps", XM, EX, XX },
+ { "sqrtss", XM, EX, XX },
+ { "sqrtpd", XM, EX, XX },
+ { "sqrtsd", XM, EX, XX },
+ },
+ /* PREGRP14 */
+ {
+ { "subps", XM, EX, XX },
+ { "subss", XM, EX, XX },
+ { "subpd", XM, EX, XX },
+ { "subsd", XM, EX, XX },
+ },
+ /* PREGRP15 */
+ {
+ { "(bad)", XM, EX, XX },
+ { "cvtdq2pd", XM, EX, XX },
+ { "cvttpd2dq", XM, EX, XX },
+ { "cvtpd2dq", XM, EX, XX },
+ },
+ /* PREGRP16 */
+ {
+ { "cvtdq2ps", XM, EX, XX },
+ { "cvttps2dq",XM, EX, XX },
+ { "cvtps2dq",XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ },
+ /* PREGRP17 */
+ {
+ { "cvtps2pd", XM, EX, XX },
+ { "cvtss2sd", XM, EX, XX },
+ { "cvtpd2ps", XM, EX, XX },
+ { "cvtsd2ss", XM, EX, XX },
+ },
+ /* PREGRP18 */
+ {
+ { "maskmovq", MX, MS, XX },
+ { "(bad)", XM, EX, XX },
+ { "maskmovdqu", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ },
+ /* PREGRP19 */
+ {
+ { "movq", MX, EM, XX },
+ { "movdqu", XM, EX, XX },
+ { "movdqa", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ },
+ /* PREGRP20 */
+ {
+ { "movq", EM, MX, XX },
+ { "movdqu", EX, XM, XX },
+ { "movdqa", EX, XM, XX },
+ { "(bad)", EX, XM, XX },
+ },
+ /* PREGRP21 */
+ {
+ { "(bad)", EX, XM, XX },
+ { "movq2dq", XM, MS, XX },
+ { "movq", EX, XM, XX },
+ { "movdq2q", MX, XS, XX },
+ },
+ /* PREGRP22 */
+ {
+ { "pshufw", MX, EM, Ib },
+ { "pshufhw", XM, EX, Ib },
+ { "pshufd", XM, EX, Ib },
+ { "pshuflw", XM, EX, Ib },
+ },
+ /* PREGRP23 */
+ {
+ { "movd", Edq, MX, XX },
+ { "movq", XM, EX, XX },
+ { "movd", Edq, XM, XX },
+ { "(bad)", Ed, XM, XX },
+ },
+ /* PREGRP24 */
+ {
+ { "(bad)", MX, EX, XX },
+ { "(bad)", XM, EX, XX },
+ { "punpckhqdq", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ },
+ /* PREGRP25 */
+ {
+ { "movntq", EM, MX, XX },
+ { "(bad)", EM, XM, XX },
+ { "movntdq", EM, XM, XX },
+ { "(bad)", EM, XM, XX },
+ },
+ /* PREGRP26 */
+ {
+ { "(bad)", MX, EX, XX },
+ { "(bad)", XM, EX, XX },
+ { "punpcklqdq", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ },
+ /* PREGRP27 */
+ {
+ { "(bad)", MX, EX, XX },
+ { "(bad)", XM, EX, XX },
+ { "addsubpd", XM, EX, XX },
+ { "addsubps", XM, EX, XX },
+ },
+ /* PREGRP28 */
+ {
+ { "(bad)", MX, EX, XX },
+ { "(bad)", XM, EX, XX },
+ { "haddpd", XM, EX, XX },
+ { "haddps", XM, EX, XX },
+ },
+ /* PREGRP29 */
+ {
+ { "(bad)", MX, EX, XX },
+ { "(bad)", XM, EX, XX },
+ { "hsubpd", XM, EX, XX },
+ { "hsubps", XM, EX, XX },
+ },
+ /* PREGRP30 */
+ {
+ { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
+ { "movsldup", XM, EX, XX },
+ { "movlpd", XM, EX, XX },
+ { "movddup", XM, EX, XX },
+ },
+ /* PREGRP31 */
+ {
+ { "movhpX", XM, EX, SIMD_Fixup, 'l' },
+ { "movshdup", XM, EX, XX },
+ { "movhpd", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ },
+ /* PREGRP32 */
+ {
+ { "(bad)", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ { "(bad)", XM, EX, XX },
+ { "lddqu", XM, M, XX },
+ },
+};
+
+static const struct dis386 x86_64_table[][2] = {
+ {
+ { "arpl", Ew, Gw, XX },
+ { "movs{||lq|xd}", Gv, Ed, XX },
+ },
+};
+
+#ifdef __KERNEL__
+#define INTERNAL_DISASSEMBLER_ERROR "<internal disassembler error>"
+#else /* __KERNEL__ */
+#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
+#endif /* __KERNEL__ */
+
+static void
+ckprefix (void)
+{
+ int newrex;
+ rex = 0;
+ prefixes = 0;
+ used_prefixes = 0;
+ rex_used = 0;
+ while (1)
+ {
+ FETCH_DATA (the_info, codep + 1);
+ newrex = 0;
+ switch (*codep)
+ {
+ /* REX prefixes family. */
+ case 0x40:
+ case 0x41:
+ case 0x42:
+ case 0x43:
+ case 0x44:
+ case 0x45:
+ case 0x46:
+ case 0x47:
+ case 0x48:
+ case 0x49:
+ case 0x4a:
+ case 0x4b:
+ case 0x4c:
+ case 0x4d:
+ case 0x4e:
+ case 0x4f:
+ if (mode_64bit)
+ newrex = *codep;
+ else
+ return;
+ break;
+ case 0xf3:
+ prefixes |= PREFIX_REPZ;
+ break;
+ case 0xf2:
+ prefixes |= PREFIX_REPNZ;
+ break;
+ case 0xf0:
+ prefixes |= PREFIX_LOCK;
+ break;
+ case 0x2e:
+ prefixes |= PREFIX_CS;
+ break;
+ case 0x36:
+ prefixes |= PREFIX_SS;
+ break;
+ case 0x3e:
+ prefixes |= PREFIX_DS;
+ break;
+ case 0x26:
+ prefixes |= PREFIX_ES;
+ break;
+ case 0x64:
+ prefixes |= PREFIX_FS;
+ break;
+ case 0x65:
+ prefixes |= PREFIX_GS;
+ break;
+ case 0x66:
+ prefixes |= PREFIX_DATA;
+ break;
+ case 0x67:
+ prefixes |= PREFIX_ADDR;
+ break;
+ case FWAIT_OPCODE:
+ /* fwait is really an instruction. If there are prefixes
+ before the fwait, they belong to the fwait, *not* to the
+ following instruction. */
+ if (prefixes)
+ {
+ prefixes |= PREFIX_FWAIT;
+ codep++;
+ return;
+ }
+ prefixes = PREFIX_FWAIT;
+ break;
+ default:
+ return;
+ }
+ /* Rex is ignored when followed by another prefix. */
+ if (rex)
+ {
+ oappend (prefix_name (rex, 0));
+ oappend (" ");
+ }
+ rex = newrex;
+ codep++;
+ }
+}
+
+/* Return the name of the prefix byte PREF, or NULL if PREF is not a
+ prefix byte. */
+
+static const char *
+prefix_name (int pref, int sizeflag)
+{
+ switch (pref)
+ {
+ /* REX prefixes family. */
+ case 0x40:
+ return "rex";
+ case 0x41:
+ return "rexZ";
+ case 0x42:
+ return "rexY";
+ case 0x43:
+ return "rexYZ";
+ case 0x44:
+ return "rexX";
+ case 0x45:
+ return "rexXZ";
+ case 0x46:
+ return "rexXY";
+ case 0x47:
+ return "rexXYZ";
+ case 0x48:
+ return "rex64";
+ case 0x49:
+ return "rex64Z";
+ case 0x4a:
+ return "rex64Y";
+ case 0x4b:
+ return "rex64YZ";
+ case 0x4c:
+ return "rex64X";
+ case 0x4d:
+ return "rex64XZ";
+ case 0x4e:
+ return "rex64XY";
+ case 0x4f:
+ return "rex64XYZ";
+ case 0xf3:
+ return "repz";
+ case 0xf2:
+ return "repnz";
+ case 0xf0:
+ return "lock";
+ case 0x2e:
+ return "cs";
+ case 0x36:
+ return "ss";
+ case 0x3e:
+ return "ds";
+ case 0x26:
+ return "es";
+ case 0x64:
+ return "fs";
+ case 0x65:
+ return "gs";
+ case 0x66:
+ return (sizeflag & DFLAG) ? "data16" : "data32";
+ case 0x67:
+ if (mode_64bit)
+ return (sizeflag & AFLAG) ? "addr32" : "addr64";
+ else
+ return (sizeflag & AFLAG) ? "addr16" : "addr32";
+ case FWAIT_OPCODE:
+ return "fwait";
+ default:
+ return NULL;
+ }
+}
+
+static char op1out[100], op2out[100], op3out[100];
+static int op_ad, op_index[3];
+static int two_source_ops;
+static bfd_vma op_address[3];
+static bfd_vma op_riprel[3];
+static bfd_vma start_pc;
+
+/*
+ * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
+ * (see topic "Redundant prefixes" in the "Differences from 8086"
+ * section of the "Virtual 8086 Mode" chapter.)
+ * 'pc' should be the address of this instruction, it will
+ * be used to print the target address if this is a relative jump or call
+ * The function returns the length of this instruction in bytes.
+ */
+
+static char intel_syntax;
+static char open_char;
+static char close_char;
+static char separator_char;
+static char scale_char;
+
+/* Here for backwards compatibility. When gdb stops using
+ print_insn_i386_att and print_insn_i386_intel these functions can
+ disappear, and print_insn_i386 be merged into print_insn. */
+int
+print_insn_i386_att (bfd_vma pc, disassemble_info *info)
+{
+ intel_syntax = 0;
+
+ return print_insn (pc, info);
+}
+
+int
+print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
+{
+ intel_syntax = 1;
+
+ return print_insn (pc, info);
+}
+
+int
+print_insn_i386 (bfd_vma pc, disassemble_info *info)
+{
+ intel_syntax = -1;
+
+ return print_insn (pc, info);
+}
+
+static int
+print_insn (bfd_vma pc, disassemble_info *info)
+{
+ const struct dis386 *dp;
+ int i;
+ char *first, *second, *third;
+ int needcomma;
+ unsigned char uses_SSE_prefix, uses_LOCK_prefix;
+ int sizeflag;
+ const char *p;
+ struct dis_private priv;
+
+ mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
+ || info->mach == bfd_mach_x86_64);
+
+ if (intel_syntax == (char) -1)
+ intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
+ || info->mach == bfd_mach_x86_64_intel_syntax);
+
+ if (info->mach == bfd_mach_i386_i386
+ || info->mach == bfd_mach_x86_64
+ || info->mach == bfd_mach_i386_i386_intel_syntax
+ || info->mach == bfd_mach_x86_64_intel_syntax)
+ priv.orig_sizeflag = AFLAG | DFLAG;
+ else if (info->mach == bfd_mach_i386_i8086)
+ priv.orig_sizeflag = 0;
+ else
+ abort ();
+
+ for (p = info->disassembler_options; p != NULL; )
+ {
+ if (strncmp (p, "x86-64", 6) == 0)
+ {
+ mode_64bit = 1;
+ priv.orig_sizeflag = AFLAG | DFLAG;
+ }
+ else if (strncmp (p, "i386", 4) == 0)
+ {
+ mode_64bit = 0;
+ priv.orig_sizeflag = AFLAG | DFLAG;
+ }
+ else if (strncmp (p, "i8086", 5) == 0)
+ {
+ mode_64bit = 0;
+ priv.orig_sizeflag = 0;
+ }
+ else if (strncmp (p, "intel", 5) == 0)
+ {
+ intel_syntax = 1;
+ }
+ else if (strncmp (p, "att", 3) == 0)
+ {
+ intel_syntax = 0;
+ }
+ else if (strncmp (p, "addr", 4) == 0)
+ {
+ if (p[4] == '1' && p[5] == '6')
+ priv.orig_sizeflag &= ~AFLAG;
+ else if (p[4] == '3' && p[5] == '2')
+ priv.orig_sizeflag |= AFLAG;
+ }
+ else if (strncmp (p, "data", 4) == 0)
+ {
+ if (p[4] == '1' && p[5] == '6')
+ priv.orig_sizeflag &= ~DFLAG;
+ else if (p[4] == '3' && p[5] == '2')
+ priv.orig_sizeflag |= DFLAG;
+ }
+ else if (strncmp (p, "suffix", 6) == 0)
+ priv.orig_sizeflag |= SUFFIX_ALWAYS;
+
+ p = strchr (p, ',');
+ if (p != NULL)
+ p++;
+ }
+
+ if (intel_syntax)
+ {
+ names64 = intel_names64;
+ names32 = intel_names32;
+ names16 = intel_names16;
+ names8 = intel_names8;
+ names8rex = intel_names8rex;
+ names_seg = intel_names_seg;
+ index16 = intel_index16;
+ open_char = '[';
+ close_char = ']';
+ separator_char = '+';
+ scale_char = '*';
+ }
+ else
+ {
+ names64 = att_names64;
+ names32 = att_names32;
+ names16 = att_names16;
+ names8 = att_names8;
+ names8rex = att_names8rex;
+ names_seg = att_names_seg;
+ index16 = att_index16;
+ open_char = '(';
+ close_char = ')';
+ separator_char = ',';
+ scale_char = ',';
+ }
+
+ /* The output looks better if we put 7 bytes on a line, since that
+ puts most long word instructions on a single line. */
+ info->bytes_per_line = 7;
+
+ info->private_data = &priv;
+ priv.max_fetched = priv.the_buffer;
+ priv.insn_start = pc;
+
+ obuf[0] = 0;
+ op1out[0] = 0;
+ op2out[0] = 0;
+ op3out[0] = 0;
+
+ op_index[0] = op_index[1] = op_index[2] = -1;
+
+ the_info = info;
+ start_pc = pc;
+ start_codep = priv.the_buffer;
+ codep = priv.the_buffer;
+
+#ifndef __KERNEL__
+ if (setjmp (priv.bailout) != 0)
+ {
+ const char *name;
+
+ /* Getting here means we tried for data but didn't get it. That
+ means we have an incomplete instruction of some sort. Just
+ print the first byte as a prefix or a .byte pseudo-op. */
+ if (codep > priv.the_buffer)
+ {
+ name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
+ if (name != NULL)
+ (*info->fprintf_func) (info->stream, "%s", name);
+ else
+ {
+ /* Just print the first byte as a .byte instruction. */
+ (*info->fprintf_func) (info->stream, ".byte 0x%x",
+ (unsigned int) priv.the_buffer[0]);
+ }
+
+ return 1;
+ }
+
+ return -1;
+ }
+#endif /* __KERNEL__ */
+
+ obufp = obuf;
+ ckprefix ();
+
+ insn_codep = codep;
+ sizeflag = priv.orig_sizeflag;
+
+ FETCH_DATA (info, codep + 1);
+ two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
+
+ if ((prefixes & PREFIX_FWAIT)
+ && ((*codep < 0xd8) || (*codep > 0xdf)))
+ {
+ const char *name;
+
+ /* fwait not followed by floating point instruction. Print the
+ first prefix, which is probably fwait itself. */
+ name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
+ if (name == NULL)
+ name = INTERNAL_DISASSEMBLER_ERROR;
+ (*info->fprintf_func) (info->stream, "%s", name);
+ return 1;
+ }
+
+ if (*codep == 0x0f)
+ {
+ FETCH_DATA (info, codep + 2);
+ dp = &dis386_twobyte[*++codep];
+ need_modrm = twobyte_has_modrm[*codep];
+ uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
+ uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
+ }
+ else
+ {
+ dp = &dis386[*codep];
+ need_modrm = onebyte_has_modrm[*codep];
+ uses_SSE_prefix = 0;
+ uses_LOCK_prefix = 0;
+ }
+ codep++;
+
+ if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))
+ {
+ oappend ("repz ");
+ used_prefixes |= PREFIX_REPZ;
+ }
+ if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))
+ {
+ oappend ("repnz ");
+ used_prefixes |= PREFIX_REPNZ;
+ }
+ if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
+ {
+ oappend ("lock ");
+ used_prefixes |= PREFIX_LOCK;
+ }
+
+ if (prefixes & PREFIX_ADDR)
+ {
+ sizeflag ^= AFLAG;
+ if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
+ {
+ if ((sizeflag & AFLAG) || mode_64bit)
+ oappend ("addr32 ");
+ else
+ oappend ("addr16 ");
+ used_prefixes |= PREFIX_ADDR;
+ }
+ }
+
+ if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
+ {
+ sizeflag ^= DFLAG;
+ if (dp->bytemode3 == cond_jump_mode
+ && dp->bytemode1 == v_mode
+ && !intel_syntax)
+ {
+ if (sizeflag & DFLAG)
+ oappend ("data32 ");
+ else
+ oappend ("data16 ");
+ used_prefixes |= PREFIX_DATA;
+ }
+ }
+
+ if (need_modrm)
+ {
+ FETCH_DATA (info, codep + 1);
+ mod = (*codep >> 6) & 3;
+ reg = (*codep >> 3) & 7;
+ rm = *codep & 7;
+ }
+
+ if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
+ {
+ dofloat (sizeflag);
+ }
+ else
+ {
+ int index;
+ if (dp->name == NULL)
+ {
+ switch (dp->bytemode1)
+ {
+ case USE_GROUPS:
+ dp = &grps[dp->bytemode2][reg];
+ break;
+
+ case USE_PREFIX_USER_TABLE:
+ index = 0;
+ used_prefixes |= (prefixes & PREFIX_REPZ);
+ if (prefixes & PREFIX_REPZ)
+ index = 1;
+ else
+ {
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ if (prefixes & PREFIX_DATA)
+ index = 2;
+ else
+ {
+ used_prefixes |= (prefixes & PREFIX_REPNZ);
+ if (prefixes & PREFIX_REPNZ)
+ index = 3;
+ }
+ }
+ dp = &prefix_user_table[dp->bytemode2][index];
+ break;
+
+ case X86_64_SPECIAL:
+ dp = &x86_64_table[dp->bytemode2][mode_64bit];
+ break;
+
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ break;
+ }
+ }
+
+ if (putop (dp->name, sizeflag) == 0)
+ {
+ obufp = op1out;
+ op_ad = 2;
+ if (dp->op1)
+ (*dp->op1) (dp->bytemode1, sizeflag);
+
+ obufp = op2out;
+ op_ad = 1;
+ if (dp->op2)
+ (*dp->op2) (dp->bytemode2, sizeflag);
+
+ obufp = op3out;
+ op_ad = 0;
+ if (dp->op3)
+ (*dp->op3) (dp->bytemode3, sizeflag);
+ }
+ }
+
+ /* See if any prefixes were not used. If so, print the first one
+ separately. If we don't do this, we'll wind up printing an
+ instruction stream which does not precisely correspond to the
+ bytes we are disassembling. */
+ if ((prefixes & ~used_prefixes) != 0)
+ {
+ const char *name;
+
+ name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
+ if (name == NULL)
+ name = INTERNAL_DISASSEMBLER_ERROR;
+ (*info->fprintf_func) (info->stream, "%s", name);
+ return 1;
+ }
+ if (rex & ~rex_used)
+ {
+ const char *name;
+ name = prefix_name (rex | 0x40, priv.orig_sizeflag);
+ if (name == NULL)
+ name = INTERNAL_DISASSEMBLER_ERROR;
+ (*info->fprintf_func) (info->stream, "%s ", name);
+ }
+
+ obufp = obuf + strlen (obuf);
+ for (i = strlen (obuf); i < 6; i++)
+ oappend (" ");
+ oappend (" ");
+ (*info->fprintf_func) (info->stream, "%s", obuf);
+
+ /* The enter and bound instructions are printed with operands in the same
+ order as the intel book; everything else is printed in reverse order. */
+ if (intel_syntax || two_source_ops)
+ {
+ first = op1out;
+ second = op2out;
+ third = op3out;
+ op_ad = op_index[0];
+ op_index[0] = op_index[2];
+ op_index[2] = op_ad;
+ }
+ else
+ {
+ first = op3out;
+ second = op2out;
+ third = op1out;
+ }
+ needcomma = 0;
+ if (*first)
+ {
+ if (op_index[0] != -1 && !op_riprel[0])
+ (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
+ else
+ (*info->fprintf_func) (info->stream, "%s", first);
+ needcomma = 1;
+ }
+ if (*second)
+ {
+ if (needcomma)
+ (*info->fprintf_func) (info->stream, ",");
+ if (op_index[1] != -1 && !op_riprel[1])
+ (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
+ else
+ (*info->fprintf_func) (info->stream, "%s", second);
+ needcomma = 1;
+ }
+ if (*third)
+ {
+ if (needcomma)
+ (*info->fprintf_func) (info->stream, ",");
+ if (op_index[2] != -1 && !op_riprel[2])
+ (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
+ else
+ (*info->fprintf_func) (info->stream, "%s", third);
+ }
+ for (i = 0; i < 3; i++)
+ if (op_index[i] != -1 && op_riprel[i])
+ {
+ (*info->fprintf_func) (info->stream, " # ");
+ (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
+ + op_address[op_index[i]]), info);
+ }
+ return codep - priv.the_buffer;
+}
+
+static const char *float_mem[] = {
+ /* d8 */
+ "fadd{s||s|}",
+ "fmul{s||s|}",
+ "fcom{s||s|}",
+ "fcomp{s||s|}",
+ "fsub{s||s|}",
+ "fsubr{s||s|}",
+ "fdiv{s||s|}",
+ "fdivr{s||s|}",
+ /* d9 */
+ "fld{s||s|}",
+ "(bad)",
+ "fst{s||s|}",
+ "fstp{s||s|}",
+ "fldenvIC",
+ "fldcw",
+ "fNstenvIC",
+ "fNstcw",
+ /* da */
+ "fiadd{l||l|}",
+ "fimul{l||l|}",
+ "ficom{l||l|}",
+ "ficomp{l||l|}",
+ "fisub{l||l|}",
+ "fisubr{l||l|}",
+ "fidiv{l||l|}",
+ "fidivr{l||l|}",
+ /* db */
+ "fild{l||l|}",
+ "fisttp{l||l|}",
+ "fist{l||l|}",
+ "fistp{l||l|}",
+ "(bad)",
+ "fld{t||t|}",
+ "(bad)",
+ "fstp{t||t|}",
+ /* dc */
+ "fadd{l||l|}",
+ "fmul{l||l|}",
+ "fcom{l||l|}",
+ "fcomp{l||l|}",
+ "fsub{l||l|}",
+ "fsubr{l||l|}",
+ "fdiv{l||l|}",
+ "fdivr{l||l|}",
+ /* dd */
+ "fld{l||l|}",
+ "fisttp{ll||ll|}",
+ "fst{l||l|}",
+ "fstp{l||l|}",
+ "frstorIC",
+ "(bad)",
+ "fNsaveIC",
+ "fNstsw",
+ /* de */
+ "fiadd",
+ "fimul",
+ "ficom",
+ "ficomp",
+ "fisub",
+ "fisubr",
+ "fidiv",
+ "fidivr",
+ /* df */
+ "fild",
+ "fisttp",
+ "fist",
+ "fistp",
+ "fbld",
+ "fild{ll||ll|}",
+ "fbstp",
+ "fistp{ll||ll|}",
+};
+
+static const unsigned char float_mem_mode[] = {
+ /* d8 */
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ /* d9 */
+ d_mode,
+ 0,
+ d_mode,
+ d_mode,
+ 0,
+ w_mode,
+ 0,
+ w_mode,
+ /* da */
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ /* db */
+ d_mode,
+ d_mode,
+ d_mode,
+ d_mode,
+ 0,
+ t_mode,
+ 0,
+ t_mode,
+ /* dc */
+ q_mode,
+ q_mode,
+ q_mode,
+ q_mode,
+ q_mode,
+ q_mode,
+ q_mode,
+ q_mode,
+ /* dd */
+ q_mode,
+ q_mode,
+ q_mode,
+ q_mode,
+ 0,
+ 0,
+ 0,
+ w_mode,
+ /* de */
+ w_mode,
+ w_mode,
+ w_mode,
+ w_mode,
+ w_mode,
+ w_mode,
+ w_mode,
+ w_mode,
+ /* df */
+ w_mode,
+ w_mode,
+ w_mode,
+ w_mode,
+ t_mode,
+ q_mode,
+ t_mode,
+ q_mode
+};
+
+#define ST OP_ST, 0
+#define STi OP_STi, 0
+
+#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
+#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
+#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
+#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
+#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
+#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
+#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
+#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
+#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
+
+static const struct dis386 float_reg[][8] = {
+ /* d8 */
+ {
+ { "fadd", ST, STi, XX },
+ { "fmul", ST, STi, XX },
+ { "fcom", STi, XX, XX },
+ { "fcomp", STi, XX, XX },
+ { "fsub", ST, STi, XX },
+ { "fsubr", ST, STi, XX },
+ { "fdiv", ST, STi, XX },
+ { "fdivr", ST, STi, XX },
+ },
+ /* d9 */
+ {
+ { "fld", STi, XX, XX },
+ { "fxch", STi, XX, XX },
+ { FGRPd9_2 },
+ { "(bad)", XX, XX, XX },
+ { FGRPd9_4 },
+ { FGRPd9_5 },
+ { FGRPd9_6 },
+ { FGRPd9_7 },
+ },
+ /* da */
+ {
+ { "fcmovb", ST, STi, XX },
+ { "fcmove", ST, STi, XX },
+ { "fcmovbe",ST, STi, XX },
+ { "fcmovu", ST, STi, XX },
+ { "(bad)", XX, XX, XX },
+ { FGRPda_5 },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ },
+ /* db */
+ {
+ { "fcmovnb",ST, STi, XX },
+ { "fcmovne",ST, STi, XX },
+ { "fcmovnbe",ST, STi, XX },
+ { "fcmovnu",ST, STi, XX },
+ { FGRPdb_4 },
+ { "fucomi", ST, STi, XX },
+ { "fcomi", ST, STi, XX },
+ { "(bad)", XX, XX, XX },
+ },
+ /* dc */
+ {
+ { "fadd", STi, ST, XX },
+ { "fmul", STi, ST, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+#if UNIXWARE_COMPAT
+ { "fsub", STi, ST, XX },
+ { "fsubr", STi, ST, XX },
+ { "fdiv", STi, ST, XX },
+ { "fdivr", STi, ST, XX },
+#else
+ { "fsubr", STi, ST, XX },
+ { "fsub", STi, ST, XX },
+ { "fdivr", STi, ST, XX },
+ { "fdiv", STi, ST, XX },
+#endif
+ },
+ /* dd */
+ {
+ { "ffree", STi, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "fst", STi, XX, XX },
+ { "fstp", STi, XX, XX },
+ { "fucom", STi, XX, XX },
+ { "fucomp", STi, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ },
+ /* de */
+ {
+ { "faddp", STi, ST, XX },
+ { "fmulp", STi, ST, XX },
+ { "(bad)", XX, XX, XX },
+ { FGRPde_3 },
+#if UNIXWARE_COMPAT
+ { "fsubp", STi, ST, XX },
+ { "fsubrp", STi, ST, XX },
+ { "fdivp", STi, ST, XX },
+ { "fdivrp", STi, ST, XX },
+#else
+ { "fsubrp", STi, ST, XX },
+ { "fsubp", STi, ST, XX },
+ { "fdivrp", STi, ST, XX },
+ { "fdivp", STi, ST, XX },
+#endif
+ },
+ /* df */
+ {
+ { "ffreep", STi, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { "(bad)", XX, XX, XX },
+ { FGRPdf_4 },
+ { "fucomip",ST, STi, XX },
+ { "fcomip", ST, STi, XX },
+ { "(bad)", XX, XX, XX },
+ },
+};
+
+static char *fgrps[][8] = {
+ /* d9_2 0 */
+ {
+ "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+ },
+
+ /* d9_4 1 */
+ {
+ "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
+ },
+
+ /* d9_5 2 */
+ {
+ "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
+ },
+
+ /* d9_6 3 */
+ {
+ "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
+ },
+
+ /* d9_7 4 */
+ {
+ "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
+ },
+
+ /* da_5 5 */
+ {
+ "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+ },
+
+ /* db_4 6 */
+ {
+ "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
+ "fNsetpm(287 only)","(bad)","(bad)","(bad)",
+ },
+
+ /* de_3 7 */
+ {
+ "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+ },
+
+ /* df_4 8 */
+ {
+ "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
+ },
+};
+
+static void
+dofloat (int sizeflag)
+{
+ const struct dis386 *dp;
+ unsigned char floatop;
+
+ floatop = codep[-1];
+
+ if (mod != 3)
+ {
+ int fp_indx = (floatop - 0xd8) * 8 + reg;
+
+ putop (float_mem[fp_indx], sizeflag);
+ obufp = op1out;
+ OP_E (float_mem_mode[fp_indx], sizeflag);
+ return;
+ }
+ /* Skip mod/rm byte. */
+ MODRM_CHECK;
+ codep++;
+
+ dp = &float_reg[floatop - 0xd8][reg];
+ if (dp->name == NULL)
+ {
+ putop (fgrps[dp->bytemode1][rm], sizeflag);
+
+ /* Instruction fnstsw is only one with strange arg. */
+ if (floatop == 0xdf && codep[-1] == 0xe0)
+ strcpy (op1out, names16[0]);
+ }
+ else
+ {
+ putop (dp->name, sizeflag);
+
+ obufp = op1out;
+ if (dp->op1)
+ (*dp->op1) (dp->bytemode1, sizeflag);
+ obufp = op2out;
+ if (dp->op2)
+ (*dp->op2) (dp->bytemode2, sizeflag);
+ }
+}
+
+static void
+OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ oappend ("%st");
+}
+
+static void
+OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ sprintf (scratchbuf, "%%st(%d)", rm);
+ oappend (scratchbuf + intel_syntax);
+}
+
+/* Capital letters in template are macros. */
+static int
+putop (const char *template, int sizeflag)
+{
+ const char *p;
+ int alt = 0;
+
+ for (p = template; *p; p++)
+ {
+ switch (*p)
+ {
+ default:
+ *obufp++ = *p;
+ break;
+ case '{':
+ alt = 0;
+ if (intel_syntax)
+ alt += 1;
+ if (mode_64bit)
+ alt += 2;
+ while (alt != 0)
+ {
+ while (*++p != '|')
+ {
+ if (*p == '}')
+ {
+ /* Alternative not valid. */
+ strcpy (obuf, "(bad)");
+ obufp = obuf + 5;
+ return 1;
+ }
+ else if (*p == '\0')
+ abort ();
+ }
+ alt--;
+ }
+ /* Fall through. */
+ case 'I':
+ alt = 1;
+ continue;
+ case '|':
+ while (*++p != '}')
+ {
+ if (*p == '\0')
+ abort ();
+ }
+ break;
+ case '}':
+ break;
+ case 'A':
+ if (intel_syntax)
+ break;
+ if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
+ *obufp++ = 'b';
+ break;
+ case 'B':
+ if (intel_syntax)
+ break;
+ if (sizeflag & SUFFIX_ALWAYS)
+ *obufp++ = 'b';
+ break;
+ case 'C':
+ if (intel_syntax && !alt)
+ break;
+ if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
+ {
+ if (sizeflag & DFLAG)
+ *obufp++ = intel_syntax ? 'd' : 'l';
+ else
+ *obufp++ = intel_syntax ? 'w' : 's';
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
+ break;
+ case 'E': /* For jcxz/jecxz */
+ if (mode_64bit)
+ {
+ if (sizeflag & AFLAG)
+ *obufp++ = 'r';
+ else
+ *obufp++ = 'e';
+ }
+ else
+ if (sizeflag & AFLAG)
+ *obufp++ = 'e';
+ used_prefixes |= (prefixes & PREFIX_ADDR);
+ break;
+ case 'F':
+ if (intel_syntax)
+ break;
+ if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
+ {
+ if (sizeflag & AFLAG)
+ *obufp++ = mode_64bit ? 'q' : 'l';
+ else
+ *obufp++ = mode_64bit ? 'l' : 'w';
+ used_prefixes |= (prefixes & PREFIX_ADDR);
+ }
+ break;
+ case 'H':
+ if (intel_syntax)
+ break;
+ if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
+ || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
+ {
+ used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
+ *obufp++ = ',';
+ *obufp++ = 'p';
+ if (prefixes & PREFIX_DS)
+ *obufp++ = 't';
+ else
+ *obufp++ = 'n';
+ }
+ break;
+ case 'J':
+ if (intel_syntax)
+ break;
+ *obufp++ = 'l';
+ break;
+ case 'L':
+ if (intel_syntax)
+ break;
+ if (sizeflag & SUFFIX_ALWAYS)
+ *obufp++ = 'l';
+ break;
+ case 'N':
+ if ((prefixes & PREFIX_FWAIT) == 0)
+ *obufp++ = 'n';
+ else
+ used_prefixes |= PREFIX_FWAIT;
+ break;
+ case 'O':
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ *obufp++ = 'o';
+ else
+ *obufp++ = 'd';
+ break;
+ case 'T':
+ if (intel_syntax)
+ break;
+ if (mode_64bit)
+ {
+ *obufp++ = 'q';
+ break;
+ }
+ /* Fall through. */
+ case 'P':
+ if (intel_syntax)
+ break;
+ if ((prefixes & PREFIX_DATA)
+ || (rex & REX_MODE64)
+ || (sizeflag & SUFFIX_ALWAYS))
+ {
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ *obufp++ = 'q';
+ else
+ {
+ if (sizeflag & DFLAG)
+ *obufp++ = 'l';
+ else
+ *obufp++ = 'w';
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
+ }
+ break;
+ case 'U':
+ if (intel_syntax)
+ break;
+ if (mode_64bit)
+ {
+ *obufp++ = 'q';
+ break;
+ }
+ /* Fall through. */
+ case 'Q':
+ if (intel_syntax && !alt)
+ break;
+ USED_REX (REX_MODE64);
+ if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
+ {
+ if (rex & REX_MODE64)
+ *obufp++ = 'q';
+ else
+ {
+ if (sizeflag & DFLAG)
+ *obufp++ = intel_syntax ? 'd' : 'l';
+ else
+ *obufp++ = 'w';
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
+ }
+ break;
+ case 'R':
+ USED_REX (REX_MODE64);
+ if (intel_syntax)
+ {
+ if (rex & REX_MODE64)
+ {
+ *obufp++ = 'q';
+ *obufp++ = 't';
+ }
+ else if (sizeflag & DFLAG)
+ {
+ *obufp++ = 'd';
+ *obufp++ = 'q';
+ }
+ else
+ {
+ *obufp++ = 'w';
+ *obufp++ = 'd';
+ }
+ }
+ else
+ {
+ if (rex & REX_MODE64)
+ *obufp++ = 'q';
+ else if (sizeflag & DFLAG)
+ *obufp++ = 'l';
+ else
+ *obufp++ = 'w';
+ }
+ if (!(rex & REX_MODE64))
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ case 'S':
+ if (intel_syntax)
+ break;
+ if (sizeflag & SUFFIX_ALWAYS)
+ {
+ if (rex & REX_MODE64)
+ *obufp++ = 'q';
+ else
+ {
+ if (sizeflag & DFLAG)
+ *obufp++ = 'l';
+ else
+ *obufp++ = 'w';
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
+ }
+ break;
+ case 'X':
+ if (prefixes & PREFIX_DATA)
+ *obufp++ = 'd';
+ else
+ *obufp++ = 's';
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ case 'Y':
+ if (intel_syntax)
+ break;
+ if (rex & REX_MODE64)
+ {
+ USED_REX (REX_MODE64);
+ *obufp++ = 'q';
+ }
+ break;
+ /* implicit operand size 'l' for i386 or 'q' for x86-64 */
+ case 'W':
+ /* operand size flag for cwtl, cbtw */
+ USED_REX (0);
+ if (rex)
+ *obufp++ = 'l';
+ else if (sizeflag & DFLAG)
+ *obufp++ = 'w';
+ else
+ *obufp++ = 'b';
+ if (intel_syntax)
+ {
+ if (rex)
+ {
+ *obufp++ = 'q';
+ *obufp++ = 'e';
+ }
+ if (sizeflag & DFLAG)
+ {
+ *obufp++ = 'd';
+ *obufp++ = 'e';
+ }
+ else
+ {
+ *obufp++ = 'w';
+ }
+ }
+ if (!rex)
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ }
+ alt = 0;
+ }
+ *obufp = 0;
+ return 0;
+}
+
+static void
+oappend (const char *s)
+{
+ strcpy (obufp, s);
+ obufp += strlen (s);
+}
+
+static void
+append_seg (void)
+{
+ if (prefixes & PREFIX_CS)
+ {
+ used_prefixes |= PREFIX_CS;
+ oappend ("%cs:" + intel_syntax);
+ }
+ if (prefixes & PREFIX_DS)
+ {
+ used_prefixes |= PREFIX_DS;
+ oappend ("%ds:" + intel_syntax);
+ }
+ if (prefixes & PREFIX_SS)
+ {
+ used_prefixes |= PREFIX_SS;
+ oappend ("%ss:" + intel_syntax);
+ }
+ if (prefixes & PREFIX_ES)
+ {
+ used_prefixes |= PREFIX_ES;
+ oappend ("%es:" + intel_syntax);
+ }
+ if (prefixes & PREFIX_FS)
+ {
+ used_prefixes |= PREFIX_FS;
+ oappend ("%fs:" + intel_syntax);
+ }
+ if (prefixes & PREFIX_GS)
+ {
+ used_prefixes |= PREFIX_GS;
+ oappend ("%gs:" + intel_syntax);
+ }
+}
+
+static void
+OP_indirE (int bytemode, int sizeflag)
+{
+ if (!intel_syntax)
+ oappend ("*");
+ OP_E (bytemode, sizeflag);
+}
+
+static void
+print_operand_value (char *buf, int hex, bfd_vma disp)
+{
+ if (mode_64bit)
+ {
+ if (hex)
+ {
+ char tmp[30];
+ int i;
+ buf[0] = '0';
+ buf[1] = 'x';
+ sprintf_vma (tmp, disp);
+ for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
+ strcpy (buf + 2, tmp + i);
+ }
+ else
+ {
+ bfd_signed_vma v = disp;
+ char tmp[30];
+ int i;
+ if (v < 0)
+ {
+ *(buf++) = '-';
+ v = -disp;
+ /* Check for possible overflow on 0x8000000000000000. */
+ if (v < 0)
+ {
+ strcpy (buf, "9223372036854775808");
+ return;
+ }
+ }
+ if (!v)
+ {
+ strcpy (buf, "0");
+ return;
+ }
+
+ i = 0;
+ tmp[29] = 0;
+ while (v)
+ {
+ tmp[28 - i] = (v % 10) + '0';
+ v /= 10;
+ i++;
+ }
+ strcpy (buf, tmp + 29 - i);
+ }
+ }
+ else
+ {
+ if (hex)
+ sprintf (buf, "0x%x", (unsigned int) disp);
+ else
+ sprintf (buf, "%d", (int) disp);
+ }
+}
+
+static void
+OP_E (int bytemode, int sizeflag)
+{
+ bfd_vma disp;
+ int add = 0;
+ int riprel = 0;
+ USED_REX (REX_EXTZ);
+ if (rex & REX_EXTZ)
+ add += 8;
+
+ /* Skip mod/rm byte. */
+ MODRM_CHECK;
+ codep++;
+
+ if (mod == 3)
+ {
+ switch (bytemode)
+ {
+ case b_mode:
+ USED_REX (0);
+ if (rex)
+ oappend (names8rex[rm + add]);
+ else
+ oappend (names8[rm + add]);
+ break;
+ case w_mode:
+ oappend (names16[rm + add]);
+ break;
+ case d_mode:
+ oappend (names32[rm + add]);
+ break;
+ case q_mode:
+ oappend (names64[rm + add]);
+ break;
+ case m_mode:
+ if (mode_64bit)
+ oappend (names64[rm + add]);
+ else
+ oappend (names32[rm + add]);
+ break;
+ case branch_v_mode:
+ if (mode_64bit)
+ oappend (names64[rm + add]);
+ else
+ {
+ if ((sizeflag & DFLAG) || bytemode != branch_v_mode)
+ oappend (names32[rm + add]);
+ else
+ oappend (names16[rm + add]);
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
+ break;
+ case v_mode:
+ case dq_mode:
+ case dqw_mode:
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ oappend (names64[rm + add]);
+ else if ((sizeflag & DFLAG) || bytemode != v_mode)
+ oappend (names32[rm + add]);
+ else
+ oappend (names16[rm + add]);
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ case 0:
+ break;
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ break;
+ }
+ return;
+ }
+
+ disp = 0;
+ append_seg ();
+
+ if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
+ {
+ int havesib;
+ int havebase;
+ int base;
+ int index = 0;
+ int scale = 0;
+
+ havesib = 0;
+ havebase = 1;
+ base = rm;
+
+ if (base == 4)
+ {
+ havesib = 1;
+ FETCH_DATA (the_info, codep + 1);
+ index = (*codep >> 3) & 7;
+ if (mode_64bit || index != 0x4)
+ /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
+ scale = (*codep >> 6) & 3;
+ base = *codep & 7;
+ USED_REX (REX_EXTY);
+ if (rex & REX_EXTY)
+ index += 8;
+ codep++;
+ }
+ base += add;
+
+ switch (mod)
+ {
+ case 0:
+ if ((base & 7) == 5)
+ {
+ havebase = 0;
+ if (mode_64bit && !havesib)
+ riprel = 1;
+ disp = get32s ();
+ }
+ break;
+ case 1:
+ FETCH_DATA (the_info, codep + 1);
+ disp = *codep++;
+ if ((disp & 0x80) != 0)
+ disp -= 0x100;
+ break;
+ case 2:
+ disp = get32s ();
+ break;
+ }
+
+ if (!intel_syntax)
+ if (mod != 0 || (base & 7) == 5)
+ {
+ print_operand_value (scratchbuf, !riprel, disp);
+ oappend (scratchbuf);
+ if (riprel)
+ {
+ set_op (disp, 1);
+ oappend ("(%rip)");
+ }
+ }
+
+ if (havebase || (havesib && (index != 4 || scale != 0)))
+ {
+ if (intel_syntax)
+ {
+ switch (bytemode)
+ {
+ case b_mode:
+ oappend ("BYTE PTR ");
+ break;
+ case w_mode:
+ case dqw_mode:
+ oappend ("WORD PTR ");
+ break;
+ case branch_v_mode:
+ case v_mode:
+ case dq_mode:
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ oappend ("QWORD PTR ");
+ else if ((sizeflag & DFLAG) || bytemode == dq_mode)
+ oappend ("DWORD PTR ");
+ else
+ oappend ("WORD PTR ");
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ case d_mode:
+ oappend ("DWORD PTR ");
+ break;
+ case q_mode:
+ oappend ("QWORD PTR ");
+ break;
+ case m_mode:
+ if (mode_64bit)
+ oappend ("QWORD PTR ");
+ else
+ oappend ("DWORD PTR ");
+ break;
+ case f_mode:
+ if (sizeflag & DFLAG)
+ {
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ oappend ("FWORD PTR ");
+ }
+ else
+ oappend ("DWORD PTR ");
+ break;
+ case t_mode:
+ oappend ("TBYTE PTR ");
+ break;
+ case x_mode:
+ oappend ("XMMWORD PTR ");
+ break;
+ default:
+ break;
+ }
+ }
+ *obufp++ = open_char;
+ if (intel_syntax && riprel)
+ oappend ("rip + ");
+ *obufp = '\0';
+ if (havebase)
+ oappend (mode_64bit && (sizeflag & AFLAG)
+ ? names64[base] : names32[base]);
+ if (havesib)
+ {
+ if (index != 4)
+ {
+ if (!intel_syntax || havebase)
+ {
+ *obufp++ = separator_char;
+ *obufp = '\0';
+ }
+ oappend (mode_64bit && (sizeflag & AFLAG)
+ ? names64[index] : names32[index]);
+ }
+ if (scale != 0 || (!intel_syntax && index != 4))
+ {
+ *obufp++ = scale_char;
+ *obufp = '\0';
+ sprintf (scratchbuf, "%d", 1 << scale);
+ oappend (scratchbuf);
+ }
+ }
+ if (intel_syntax && disp)
+ {
+ if ((bfd_signed_vma) disp > 0)
+ {
+ *obufp++ = '+';
+ *obufp = '\0';
+ }
+ else if (mod != 1)
+ {
+ *obufp++ = '-';
+ *obufp = '\0';
+ disp = - (bfd_signed_vma) disp;
+ }
+
+ print_operand_value (scratchbuf, mod != 1, disp);
+ oappend (scratchbuf);
+ }
+
+ *obufp++ = close_char;
+ *obufp = '\0';
+ }
+ else if (intel_syntax)
+ {
+ if (mod != 0 || (base & 7) == 5)
+ {
+ if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
+ | PREFIX_ES | PREFIX_FS | PREFIX_GS))
+ ;
+ else
+ {
+ oappend (names_seg[ds_reg - es_reg]);
+ oappend (":");
+ }
+ print_operand_value (scratchbuf, 1, disp);
+ oappend (scratchbuf);
+ }
+ }
+ }
+ else
+ { /* 16 bit address mode */
+ switch (mod)
+ {
+ case 0:
+ if (rm == 6)
+ {
+ disp = get16 ();
+ if ((disp & 0x8000) != 0)
+ disp -= 0x10000;
+ }
+ break;
+ case 1:
+ FETCH_DATA (the_info, codep + 1);
+ disp = *codep++;
+ if ((disp & 0x80) != 0)
+ disp -= 0x100;
+ break;
+ case 2:
+ disp = get16 ();
+ if ((disp & 0x8000) != 0)
+ disp -= 0x10000;
+ break;
+ }
+
+ if (!intel_syntax)
+ if (mod != 0 || rm == 6)
+ {
+ print_operand_value (scratchbuf, 0, disp);
+ oappend (scratchbuf);
+ }
+
+ if (mod != 0 || rm != 6)
+ {
+ *obufp++ = open_char;
+ *obufp = '\0';
+ oappend (index16[rm]);
+ if (intel_syntax && disp)
+ {
+ if ((bfd_signed_vma) disp > 0)
+ {
+ *obufp++ = '+';
+ *obufp = '\0';
+ }
+ else if (mod != 1)
+ {
+ *obufp++ = '-';
+ *obufp = '\0';
+ disp = - (bfd_signed_vma) disp;
+ }
+
+ print_operand_value (scratchbuf, mod != 1, disp);
+ oappend (scratchbuf);
+ }
+
+ *obufp++ = close_char;
+ *obufp = '\0';
+ }
+ else if (intel_syntax)
+ {
+ if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
+ | PREFIX_ES | PREFIX_FS | PREFIX_GS))
+ ;
+ else
+ {
+ oappend (names_seg[ds_reg - es_reg]);
+ oappend (":");
+ }
+ print_operand_value (scratchbuf, 1, disp & 0xffff);
+ oappend (scratchbuf);
+ }
+ }
+}
+
+static void
+OP_G (int bytemode, int sizeflag)
+{
+ int add = 0;
+ USED_REX (REX_EXTX);
+ if (rex & REX_EXTX)
+ add += 8;
+ switch (bytemode)
+ {
+ case b_mode:
+ USED_REX (0);
+ if (rex)
+ oappend (names8rex[reg + add]);
+ else
+ oappend (names8[reg + add]);
+ break;
+ case w_mode:
+ oappend (names16[reg + add]);
+ break;
+ case d_mode:
+ oappend (names32[reg + add]);
+ break;
+ case q_mode:
+ oappend (names64[reg + add]);
+ break;
+ case v_mode:
+ case dq_mode:
+ case dqw_mode:
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ oappend (names64[reg + add]);
+ else if ((sizeflag & DFLAG) || bytemode != v_mode)
+ oappend (names32[reg + add]);
+ else
+ oappend (names16[reg + add]);
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ case m_mode:
+ if (mode_64bit)
+ oappend (names64[reg + add]);
+ else
+ oappend (names32[reg + add]);
+ break;
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ break;
+ }
+}
+
+static bfd_vma
+get64 (void)
+{
+ bfd_vma x;
+#ifdef BFD64
+ unsigned int a;
+ unsigned int b;
+
+ FETCH_DATA (the_info, codep + 8);
+ a = *codep++ & 0xff;
+ a |= (*codep++ & 0xff) << 8;
+ a |= (*codep++ & 0xff) << 16;
+ a |= (*codep++ & 0xff) << 24;
+ b = *codep++ & 0xff;
+ b |= (*codep++ & 0xff) << 8;
+ b |= (*codep++ & 0xff) << 16;
+ b |= (*codep++ & 0xff) << 24;
+ x = a + ((bfd_vma) b << 32);
+#else
+ abort ();
+ x = 0;
+#endif
+ return x;
+}
+
+static bfd_signed_vma
+get32 (void)
+{
+ bfd_signed_vma x = 0;
+
+ FETCH_DATA (the_info, codep + 4);
+ x = *codep++ & (bfd_signed_vma) 0xff;
+ x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
+ x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
+ x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
+ return x;
+}
+
+static bfd_signed_vma
+get32s (void)
+{
+ bfd_signed_vma x = 0;
+
+ FETCH_DATA (the_info, codep + 4);
+ x = *codep++ & (bfd_signed_vma) 0xff;
+ x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
+ x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
+ x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
+
+ x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
+
+ return x;
+}
+
+static int
+get16 (void)
+{
+ int x = 0;
+
+ FETCH_DATA (the_info, codep + 2);
+ x = *codep++ & 0xff;
+ x |= (*codep++ & 0xff) << 8;
+ return x;
+}
+
+static void
+set_op (bfd_vma op, int riprel)
+{
+ op_index[op_ad] = op_ad;
+ if (mode_64bit)
+ {
+ op_address[op_ad] = op;
+ op_riprel[op_ad] = riprel;
+ }
+ else
+ {
+ /* Mask to get a 32-bit address. */
+ op_address[op_ad] = op & 0xffffffff;
+ op_riprel[op_ad] = riprel & 0xffffffff;
+ }
+}
+
+static void
+OP_REG (int code, int sizeflag)
+{
+ const char *s;
+ int add = 0;
+ USED_REX (REX_EXTZ);
+ if (rex & REX_EXTZ)
+ add = 8;
+
+ switch (code)
+ {
+ case indir_dx_reg:
+ if (intel_syntax)
+ s = "[dx]";
+ else
+ s = "(%dx)";
+ break;
+ case ax_reg: case cx_reg: case dx_reg: case bx_reg:
+ case sp_reg: case bp_reg: case si_reg: case di_reg:
+ s = names16[code - ax_reg + add];
+ break;
+ case es_reg: case ss_reg: case cs_reg:
+ case ds_reg: case fs_reg: case gs_reg:
+ s = names_seg[code - es_reg + add];
+ break;
+ case al_reg: case ah_reg: case cl_reg: case ch_reg:
+ case dl_reg: case dh_reg: case bl_reg: case bh_reg:
+ USED_REX (0);
+ if (rex)
+ s = names8rex[code - al_reg + add];
+ else
+ s = names8[code - al_reg];
+ break;
+ case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
+ case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
+ if (mode_64bit)
+ {
+ s = names64[code - rAX_reg + add];
+ break;
+ }
+ code += eAX_reg - rAX_reg;
+ /* Fall through. */
+ case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
+ case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ s = names64[code - eAX_reg + add];
+ else if (sizeflag & DFLAG)
+ s = names32[code - eAX_reg + add];
+ else
+ s = names16[code - eAX_reg + add];
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ default:
+ s = INTERNAL_DISASSEMBLER_ERROR;
+ break;
+ }
+ oappend (s);
+}
+
+static void
+OP_IMREG (int code, int sizeflag)
+{
+ const char *s;
+
+ switch (code)
+ {
+ case indir_dx_reg:
+ if (intel_syntax)
+ s = "[dx]";
+ else
+ s = "(%dx)";
+ break;
+ case ax_reg: case cx_reg: case dx_reg: case bx_reg:
+ case sp_reg: case bp_reg: case si_reg: case di_reg:
+ s = names16[code - ax_reg];
+ break;
+ case es_reg: case ss_reg: case cs_reg:
+ case ds_reg: case fs_reg: case gs_reg:
+ s = names_seg[code - es_reg];
+ break;
+ case al_reg: case ah_reg: case cl_reg: case ch_reg:
+ case dl_reg: case dh_reg: case bl_reg: case bh_reg:
+ USED_REX (0);
+ if (rex)
+ s = names8rex[code - al_reg];
+ else
+ s = names8[code - al_reg];
+ break;
+ case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
+ case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ s = names64[code - eAX_reg];
+ else if (sizeflag & DFLAG)
+ s = names32[code - eAX_reg];
+ else
+ s = names16[code - eAX_reg];
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ default:
+ s = INTERNAL_DISASSEMBLER_ERROR;
+ break;
+ }
+ oappend (s);
+}
+
+static void
+OP_I (int bytemode, int sizeflag)
+{
+ bfd_signed_vma op;
+ bfd_signed_vma mask = -1;
+
+ switch (bytemode)
+ {
+ case b_mode:
+ FETCH_DATA (the_info, codep + 1);
+ op = *codep++;
+ mask = 0xff;
+ break;
+ case q_mode:
+ if (mode_64bit)
+ {
+ op = get32s ();
+ break;
+ }
+ /* Fall through. */
+ case v_mode:
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ op = get32s ();
+ else if (sizeflag & DFLAG)
+ {
+ op = get32 ();
+ mask = 0xffffffff;
+ }
+ else
+ {
+ op = get16 ();
+ mask = 0xfffff;
+ }
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ case w_mode:
+ mask = 0xfffff;
+ op = get16 ();
+ break;
+ case const_1_mode:
+ if (intel_syntax)
+ oappend ("1");
+ return;
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ return;
+ }
+
+ op &= mask;
+ scratchbuf[0] = '$';
+ print_operand_value (scratchbuf + 1, 1, op);
+ oappend (scratchbuf + intel_syntax);
+ scratchbuf[0] = '\0';
+}
+
+static void
+OP_I64 (int bytemode, int sizeflag)
+{
+ bfd_signed_vma op;
+ bfd_signed_vma mask = -1;
+
+ if (!mode_64bit)
+ {
+ OP_I (bytemode, sizeflag);
+ return;
+ }
+
+ switch (bytemode)
+ {
+ case b_mode:
+ FETCH_DATA (the_info, codep + 1);
+ op = *codep++;
+ mask = 0xff;
+ break;
+ case v_mode:
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ op = get64 ();
+ else if (sizeflag & DFLAG)
+ {
+ op = get32 ();
+ mask = 0xffffffff;
+ }
+ else
+ {
+ op = get16 ();
+ mask = 0xfffff;
+ }
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ case w_mode:
+ mask = 0xfffff;
+ op = get16 ();
+ break;
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ return;
+ }
+
+ op &= mask;
+ scratchbuf[0] = '$';
+ print_operand_value (scratchbuf + 1, 1, op);
+ oappend (scratchbuf + intel_syntax);
+ scratchbuf[0] = '\0';
+}
+
+static void
+OP_sI (int bytemode, int sizeflag)
+{
+ bfd_signed_vma op;
+ bfd_signed_vma mask = -1;
+
+ switch (bytemode)
+ {
+ case b_mode:
+ FETCH_DATA (the_info, codep + 1);
+ op = *codep++;
+ if ((op & 0x80) != 0)
+ op -= 0x100;
+ mask = 0xffffffff;
+ break;
+ case v_mode:
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ op = get32s ();
+ else if (sizeflag & DFLAG)
+ {
+ op = get32s ();
+ mask = 0xffffffff;
+ }
+ else
+ {
+ mask = 0xffffffff;
+ op = get16 ();
+ if ((op & 0x8000) != 0)
+ op -= 0x10000;
+ }
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ break;
+ case w_mode:
+ op = get16 ();
+ mask = 0xffffffff;
+ if ((op & 0x8000) != 0)
+ op -= 0x10000;
+ break;
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ return;
+ }
+
+ scratchbuf[0] = '$';
+ print_operand_value (scratchbuf + 1, 1, op);
+ oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_J (int bytemode, int sizeflag)
+{
+ bfd_vma disp;
+ bfd_vma mask = -1;
+
+ switch (bytemode)
+ {
+ case b_mode:
+ FETCH_DATA (the_info, codep + 1);
+ disp = *codep++;
+ if ((disp & 0x80) != 0)
+ disp -= 0x100;
+ break;
+ case v_mode:
+ if (sizeflag & DFLAG)
+ disp = get32s ();
+ else
+ {
+ disp = get16 ();
+ /* For some reason, a data16 prefix on a jump instruction
+ means that the pc is masked to 16 bits after the
+ displacement is added! */
+ mask = 0xffff;
+ }
+ break;
+ default:
+ oappend (INTERNAL_DISASSEMBLER_ERROR);
+ return;
+ }
+ disp = (start_pc + codep - start_codep + disp) & mask;
+ set_op (disp, 0);
+ print_operand_value (scratchbuf, 1, disp);
+ oappend (scratchbuf);
+}
+
+static void
+OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ oappend (names_seg[reg]);
+}
+
+static void
+OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
+{
+ int seg, offset;
+
+ if (sizeflag & DFLAG)
+ {
+ offset = get32 ();
+ seg = get16 ();
+ }
+ else
+ {
+ offset = get16 ();
+ seg = get16 ();
+ }
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ if (intel_syntax)
+ sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
+ else
+ sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
+ oappend (scratchbuf);
+}
+
+static void
+OP_OFF (int bytemode ATTRIBUTE_UNUSED, int sizeflag)
+{
+ bfd_vma off;
+
+ append_seg ();
+
+ if ((sizeflag & AFLAG) || mode_64bit)
+ off = get32 ();
+ else
+ off = get16 ();
+
+ if (intel_syntax)
+ {
+ if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
+ | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
+ {
+ oappend (names_seg[ds_reg - es_reg]);
+ oappend (":");
+ }
+ }
+ print_operand_value (scratchbuf, 1, off);
+ oappend (scratchbuf);
+}
+
+static void
+OP_OFF64 (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ bfd_vma off;
+
+ if (!mode_64bit)
+ {
+ OP_OFF (bytemode, sizeflag);
+ return;
+ }
+
+ append_seg ();
+
+ off = get64 ();
+
+ if (intel_syntax)
+ {
+ if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
+ | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
+ {
+ oappend (names_seg[ds_reg - es_reg]);
+ oappend (":");
+ }
+ }
+ print_operand_value (scratchbuf, 1, off);
+ oappend (scratchbuf);
+}
+
+static void
+ptr_reg (int code, int sizeflag)
+{
+ const char *s;
+
+ *obufp++ = open_char;
+ used_prefixes |= (prefixes & PREFIX_ADDR);
+ if (mode_64bit)
+ {
+ if (!(sizeflag & AFLAG))
+ s = names32[code - eAX_reg];
+ else
+ s = names64[code - eAX_reg];
+ }
+ else if (sizeflag & AFLAG)
+ s = names32[code - eAX_reg];
+ else
+ s = names16[code - eAX_reg];
+ oappend (s);
+ *obufp++ = close_char;
+ *obufp = 0;
+}
+
+static void
+OP_ESreg (int code, int sizeflag)
+{
+ if (intel_syntax)
+ {
+ if (codep[-1] & 1)
+ {
+ USED_REX (REX_MODE64);
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ if (rex & REX_MODE64)
+ oappend ("QWORD PTR ");
+ else if ((sizeflag & DFLAG))
+ oappend ("DWORD PTR ");
+ else
+ oappend ("WORD PTR ");
+ }
+ else
+ oappend ("BYTE PTR ");
+ }
+
+ oappend ("%es:" + intel_syntax);
+ ptr_reg (code, sizeflag);
+}
+
+static void
+OP_DSreg (int code, int sizeflag)
+{
+ if (intel_syntax)
+ {
+ if (codep[-1] != 0xd7 && (codep[-1] & 1))
+ {
+ USED_REX (REX_MODE64);
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ if (rex & REX_MODE64)
+ oappend ("QWORD PTR ");
+ else if ((sizeflag & DFLAG))
+ oappend ("DWORD PTR ");
+ else
+ oappend ("WORD PTR ");
+ }
+ else
+ oappend ("BYTE PTR ");
+ }
+
+ if ((prefixes
+ & (PREFIX_CS
+ | PREFIX_DS
+ | PREFIX_SS
+ | PREFIX_ES
+ | PREFIX_FS
+ | PREFIX_GS)) == 0)
+ prefixes |= PREFIX_DS;
+ append_seg ();
+ ptr_reg (code, sizeflag);
+}
+
+static void
+OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ int add = 0;
+ if (rex & REX_EXTX)
+ {
+ USED_REX (REX_EXTX);
+ add = 8;
+ }
+ else if (!mode_64bit && (prefixes & PREFIX_LOCK))
+ {
+ used_prefixes |= PREFIX_LOCK;
+ add = 8;
+ }
+ sprintf (scratchbuf, "%%cr%d", reg + add);
+ oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ int add = 0;
+ USED_REX (REX_EXTX);
+ if (rex & REX_EXTX)
+ add = 8;
+ if (intel_syntax)
+ sprintf (scratchbuf, "db%d", reg + add);
+ else
+ sprintf (scratchbuf, "%%db%d", reg + add);
+ oappend (scratchbuf);
+}
+
+static void
+OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ sprintf (scratchbuf, "%%tr%d", reg);
+ oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_Rd (int bytemode, int sizeflag)
+{
+ if (mod == 3)
+ OP_E (bytemode, sizeflag);
+ else
+ BadOp ();
+}
+
+static void
+OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ if (prefixes & PREFIX_DATA)
+ {
+ int add = 0;
+ USED_REX (REX_EXTX);
+ if (rex & REX_EXTX)
+ add = 8;
+ sprintf (scratchbuf, "%%xmm%d", reg + add);
+ }
+ else
+ sprintf (scratchbuf, "%%mm%d", reg);
+ oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ int add = 0;
+ USED_REX (REX_EXTX);
+ if (rex & REX_EXTX)
+ add = 8;
+ sprintf (scratchbuf, "%%xmm%d", reg + add);
+ oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_EM (int bytemode, int sizeflag)
+{
+ if (mod != 3)
+ {
+ if (intel_syntax && bytemode == v_mode)
+ {
+ bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
+ OP_E (bytemode, sizeflag);
+ return;
+ }
+
+ /* Skip mod/rm byte. */
+ MODRM_CHECK;
+ codep++;
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ if (prefixes & PREFIX_DATA)
+ {
+ int add = 0;
+
+ USED_REX (REX_EXTZ);
+ if (rex & REX_EXTZ)
+ add = 8;
+ sprintf (scratchbuf, "%%xmm%d", rm + add);
+ }
+ else
+ sprintf (scratchbuf, "%%mm%d", rm);
+ oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_EX (int bytemode, int sizeflag)
+{
+ int add = 0;
+ if (mod != 3)
+ {
+ if (intel_syntax && bytemode == v_mode)
+ {
+ switch (prefixes & (PREFIX_DATA|PREFIX_REPZ|PREFIX_REPNZ))
+ {
+ case 0: bytemode = x_mode; break;
+ case PREFIX_REPZ: bytemode = d_mode; used_prefixes |= PREFIX_REPZ; break;
+ case PREFIX_DATA: bytemode = x_mode; used_prefixes |= PREFIX_DATA; break;
+ case PREFIX_REPNZ: bytemode = q_mode; used_prefixes |= PREFIX_REPNZ; break;
+ default: bytemode = 0; break;
+ }
+ }
+ OP_E (bytemode, sizeflag);
+ return;
+ }
+ USED_REX (REX_EXTZ);
+ if (rex & REX_EXTZ)
+ add = 8;
+
+ /* Skip mod/rm byte. */
+ MODRM_CHECK;
+ codep++;
+ sprintf (scratchbuf, "%%xmm%d", rm + add);
+ oappend (scratchbuf + intel_syntax);
+}
+
+static void
+OP_MS (int bytemode, int sizeflag)
+{
+ if (mod == 3)
+ OP_EM (bytemode, sizeflag);
+ else
+ BadOp ();
+}
+
+static void
+OP_XS (int bytemode, int sizeflag)
+{
+ if (mod == 3)
+ OP_EX (bytemode, sizeflag);
+ else
+ BadOp ();
+}
+
+static void
+OP_M (int bytemode, int sizeflag)
+{
+ if (mod == 3)
+ BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */
+ else
+ OP_E (bytemode, sizeflag);
+}
+
+static void
+OP_0f07 (int bytemode, int sizeflag)
+{
+ if (mod != 3 || rm != 0)
+ BadOp ();
+ else
+ OP_E (bytemode, sizeflag);
+}
+
+static void
+OP_0fae (int bytemode, int sizeflag)
+{
+ if (mod == 3)
+ {
+ if (reg == 7)
+ strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
+
+ if (reg < 5 || rm != 0)
+ {
+ BadOp (); /* bad sfence, mfence, or lfence */
+ return;
+ }
+ }
+ else if (reg != 7)
+ {
+ BadOp (); /* bad clflush */
+ return;
+ }
+
+ OP_E (bytemode, sizeflag);
+}
+
+static void
+NOP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ /* NOP with REPZ prefix is called PAUSE. */
+ if (prefixes == PREFIX_REPZ)
+ strcpy (obuf, "pause");
+}
+
+static const char *const Suffix3DNow[] = {
+/* 00 */ NULL, NULL, NULL, NULL,
+/* 04 */ NULL, NULL, NULL, NULL,
+/* 08 */ NULL, NULL, NULL, NULL,
+/* 0C */ "pi2fw", "pi2fd", NULL, NULL,
+/* 10 */ NULL, NULL, NULL, NULL,
+/* 14 */ NULL, NULL, NULL, NULL,
+/* 18 */ NULL, NULL, NULL, NULL,
+/* 1C */ "pf2iw", "pf2id", NULL, NULL,
+/* 20 */ NULL, NULL, NULL, NULL,
+/* 24 */ NULL, NULL, NULL, NULL,
+/* 28 */ NULL, NULL, NULL, NULL,
+/* 2C */ NULL, NULL, NULL, NULL,
+/* 30 */ NULL, NULL, NULL, NULL,
+/* 34 */ NULL, NULL, NULL, NULL,
+/* 38 */ NULL, NULL, NULL, NULL,
+/* 3C */ NULL, NULL, NULL, NULL,
+/* 40 */ NULL, NULL, NULL, NULL,
+/* 44 */ NULL, NULL, NULL, NULL,
+/* 48 */ NULL, NULL, NULL, NULL,
+/* 4C */ NULL, NULL, NULL, NULL,
+/* 50 */ NULL, NULL, NULL, NULL,
+/* 54 */ NULL, NULL, NULL, NULL,
+/* 58 */ NULL, NULL, NULL, NULL,
+/* 5C */ NULL, NULL, NULL, NULL,
+/* 60 */ NULL, NULL, NULL, NULL,
+/* 64 */ NULL, NULL, NULL, NULL,
+/* 68 */ NULL, NULL, NULL, NULL,
+/* 6C */ NULL, NULL, NULL, NULL,
+/* 70 */ NULL, NULL, NULL, NULL,
+/* 74 */ NULL, NULL, NULL, NULL,
+/* 78 */ NULL, NULL, NULL, NULL,
+/* 7C */ NULL, NULL, NULL, NULL,
+/* 80 */ NULL, NULL, NULL, NULL,
+/* 84 */ NULL, NULL, NULL, NULL,
+/* 88 */ NULL, NULL, "pfnacc", NULL,
+/* 8C */ NULL, NULL, "pfpnacc", NULL,
+/* 90 */ "pfcmpge", NULL, NULL, NULL,
+/* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
+/* 98 */ NULL, NULL, "pfsub", NULL,
+/* 9C */ NULL, NULL, "pfadd", NULL,
+/* A0 */ "pfcmpgt", NULL, NULL, NULL,
+/* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
+/* A8 */ NULL, NULL, "pfsubr", NULL,
+/* AC */ NULL, NULL, "pfacc", NULL,
+/* B0 */ "pfcmpeq", NULL, NULL, NULL,
+/* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
+/* B8 */ NULL, NULL, NULL, "pswapd",
+/* BC */ NULL, NULL, NULL, "pavgusb",
+/* C0 */ NULL, NULL, NULL, NULL,
+/* C4 */ NULL, NULL, NULL, NULL,
+/* C8 */ NULL, NULL, NULL, NULL,
+/* CC */ NULL, NULL, NULL, NULL,
+/* D0 */ NULL, NULL, NULL, NULL,
+/* D4 */ NULL, NULL, NULL, NULL,
+/* D8 */ NULL, NULL, NULL, NULL,
+/* DC */ NULL, NULL, NULL, NULL,
+/* E0 */ NULL, NULL, NULL, NULL,
+/* E4 */ NULL, NULL, NULL, NULL,
+/* E8 */ NULL, NULL, NULL, NULL,
+/* EC */ NULL, NULL, NULL, NULL,
+/* F0 */ NULL, NULL, NULL, NULL,
+/* F4 */ NULL, NULL, NULL, NULL,
+/* F8 */ NULL, NULL, NULL, NULL,
+/* FC */ NULL, NULL, NULL, NULL,
+};
+
+static void
+OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ const char *mnemonic;
+
+ FETCH_DATA (the_info, codep + 1);
+ /* AMD 3DNow! instructions are specified by an opcode suffix in the
+ place where an 8-bit immediate would normally go. ie. the last
+ byte of the instruction. */
+ obufp = obuf + strlen (obuf);
+ mnemonic = Suffix3DNow[*codep++ & 0xff];
+ if (mnemonic)
+ oappend (mnemonic);
+ else
+ {
+ /* Since a variable sized modrm/sib chunk is between the start
+ of the opcode (0x0f0f) and the opcode suffix, we need to do
+ all the modrm processing first, and don't know until now that
+ we have a bad opcode. This necessitates some cleaning up. */
+ op1out[0] = '\0';
+ op2out[0] = '\0';
+ BadOp ();
+ }
+}
+
+static const char *simd_cmp_op[] = {
+ "eq",
+ "lt",
+ "le",
+ "unord",
+ "neq",
+ "nlt",
+ "nle",
+ "ord"
+};
+
+static void
+OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
+{
+ unsigned int cmp_type;
+
+ FETCH_DATA (the_info, codep + 1);
+ obufp = obuf + strlen (obuf);
+ cmp_type = *codep++ & 0xff;
+ if (cmp_type < 8)
+ {
+ char suffix1 = 'p', suffix2 = 's';
+ used_prefixes |= (prefixes & PREFIX_REPZ);
+ if (prefixes & PREFIX_REPZ)
+ suffix1 = 's';
+ else
+ {
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ if (prefixes & PREFIX_DATA)
+ suffix2 = 'd';
+ else
+ {
+ used_prefixes |= (prefixes & PREFIX_REPNZ);
+ if (prefixes & PREFIX_REPNZ)
+ suffix1 = 's', suffix2 = 'd';
+ }
+ }
+ sprintf (scratchbuf, "cmp%s%c%c",
+ simd_cmp_op[cmp_type], suffix1, suffix2);
+ used_prefixes |= (prefixes & PREFIX_REPZ);
+ oappend (scratchbuf);
+ }
+ else
+ {
+ /* We have a bad extension byte. Clean up. */
+ op1out[0] = '\0';
+ op2out[0] = '\0';
+ BadOp ();
+ }
+}
+
+static void
+SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
+{
+ /* Change movlps/movhps to movhlps/movlhps for 2 register operand
+ forms of these instructions. */
+ if (mod == 3)
+ {
+ char *p = obuf + strlen (obuf);
+ *(p + 1) = '\0';
+ *p = *(p - 1);
+ *(p - 1) = *(p - 2);
+ *(p - 2) = *(p - 3);
+ *(p - 3) = extrachar;
+ }
+}
+
+static void
+PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
+{
+ if (mod == 3 && reg == 1 && rm <= 1)
+ {
+ /* Override "sidt". */
+ char *p = obuf + strlen (obuf) - 4;
+
+ /* We might have a suffix when disassembling with -Msuffix. */
+ if (*p == 'i')
+ --p;
+
+ if (rm)
+ {
+ /* mwait %eax,%ecx */
+ strcpy (p, "mwait");
+ if (!intel_syntax)
+ strcpy (op1out, names32[0]);
+ }
+ else
+ {
+ /* monitor %eax,%ecx,%edx" */
+ strcpy (p, "monitor");
+ if (!intel_syntax)
+ {
+ if (!mode_64bit)
+ strcpy (op1out, names32[0]);
+ else if (!(prefixes & PREFIX_ADDR))
+ strcpy (op1out, names64[0]);
+ else
+ {
+ strcpy (op1out, names32[0]);
+ used_prefixes |= PREFIX_ADDR;
+ }
+ strcpy (op3out, names32[2]);
+ }
+ }
+ if (!intel_syntax)
+ {
+ strcpy (op2out, names32[1]);
+ two_source_ops = 1;
+ }
+
+ codep++;
+ }
+ else
+ OP_M (0, sizeflag);
+}
+
+static void
+SVME_Fixup (int bytemode, int sizeflag)
+{
+ const char *alt;
+ char *p;
+
+ switch (*codep)
+ {
+ case 0xd8:
+ alt = "vmrun";
+ break;
+ case 0xd9:
+ alt = "vmmcall";
+ break;
+ case 0xda:
+ alt = "vmload";
+ break;
+ case 0xdb:
+ alt = "vmsave";
+ break;
+ case 0xdc:
+ alt = "stgi";
+ break;
+ case 0xdd:
+ alt = "clgi";
+ break;
+ case 0xde:
+ alt = "skinit";
+ break;
+ case 0xdf:
+ alt = "invlpga";
+ break;
+ default:
+ OP_M (bytemode, sizeflag);
+ return;
+ }
+ /* Override "lidt". */
+ p = obuf + strlen (obuf) - 4;
+ /* We might have a suffix. */
+ if (*p == 'i')
+ --p;
+ strcpy (p, alt);
+ if (!(prefixes & PREFIX_ADDR))
+ {
+ ++codep;
+ return;
+ }
+ used_prefixes |= PREFIX_ADDR;
+ switch (*codep++)
+ {
+ case 0xdf:
+ strcpy (op2out, names32[1]);
+ two_source_ops = 1;
+ /* Fall through. */
+ case 0xd8:
+ case 0xda:
+ case 0xdb:
+ *obufp++ = open_char;
+ if (mode_64bit || (sizeflag & AFLAG))
+ alt = names32[0];
+ else
+ alt = names16[0];
+ strcpy (obufp, alt);
+ obufp += strlen (alt);
+ *obufp++ = close_char;
+ *obufp = '\0';
+ break;
+ }
+}
+
+static void
+INVLPG_Fixup (int bytemode, int sizeflag)
+{
+ const char *alt;
+
+ switch (*codep)
+ {
+ case 0xf8:
+ alt = "swapgs";
+ break;
+ case 0xf9:
+ alt = "rdtscp";
+ break;
+ default:
+ OP_M (bytemode, sizeflag);
+ return;
+ }
+ /* Override "invlpg". */
+ strcpy (obuf + strlen (obuf) - 6, alt);
+ codep++;
+}
+
+static void
+BadOp (void)
+{
+ /* Throw away prefixes and 1st. opcode byte. */
+ codep = insn_codep + 1;
+ oappend ("(bad)");
+}
+
+static void
+SEG_Fixup (int extrachar, int sizeflag)
+{
+ if (mod == 3)
+ {
+ /* We need to add a proper suffix with
+
+ movw %ds,%ax
+ movl %ds,%eax
+ movq %ds,%rax
+ movw %ax,%ds
+ movl %eax,%ds
+ movq %rax,%ds
+ */
+ const char *suffix;
+
+ if (prefixes & PREFIX_DATA)
+ suffix = "w";
+ else
+ {
+ USED_REX (REX_MODE64);
+ if (rex & REX_MODE64)
+ suffix = "q";
+ else
+ suffix = "l";
+ }
+ strcat (obuf, suffix);
+ }
+ else
+ {
+ /* We need to fix the suffix for
+
+ movw %ds,(%eax)
+ movw %ds,(%rax)
+ movw (%eax),%ds
+ movw (%rax),%ds
+
+ Override "mov[l|q]". */
+ char *p = obuf + strlen (obuf) - 1;
+
+ /* We might not have a suffix. */
+ if (*p == 'v')
+ ++p;
+ *p = 'w';
+ }
+
+ OP_E (extrachar, sizeflag);
+}
+
+static void
+VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
+{
+ if (mod == 3 && reg == 0 && rm >=1 && rm <= 4)
+ {
+ /* Override "sgdt". */
+ char *p = obuf + strlen (obuf) - 4;
+
+ /* We might have a suffix when disassembling with -Msuffix. */
+ if (*p == 'g')
+ --p;
+
+ switch (rm)
+ {
+ case 1:
+ strcpy (p, "vmcall");
+ break;
+ case 2:
+ strcpy (p, "vmlaunch");
+ break;
+ case 3:
+ strcpy (p, "vmresume");
+ break;
+ case 4:
+ strcpy (p, "vmxoff");
+ break;
+ }
+
+ codep++;
+ }
+ else
+ OP_E (0, sizeflag);
+}
+
+static void
+OP_VMX (int bytemode, int sizeflag)
+{
+ used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
+ if (prefixes & PREFIX_DATA)
+ strcpy (obuf, "vmclear");
+ else if (prefixes & PREFIX_REPZ)
+ strcpy (obuf, "vmxon");
+ else
+ strcpy (obuf, "vmptrld");
+ OP_E (bytemode, sizeflag);
+}
CFI_ENDPROC
ENDPROC(call_softirq)
+
+#ifdef CONFIG_KDB
+
+#ifdef CONFIG_SMP
+ENTRY(kdb_interrupt)
+ apicinterrupt KDB_VECTOR,smp_kdb_interrupt
+END(kdb_interrupt)
+#endif /* CONFIG_SMP */
+
+ENTRY(kdb_call)
+ INTR_FRAME
+ cld
+ pushq $-1 # orig_eax
+ CFI_ADJUST_CFA_OFFSET 8
+ SAVE_ALL
+ movq $1,%rdi # KDB_REASON_ENTER
+ movq $0,%rsi # error_code
+ movq %rsp,%rdx # struct pt_regs
+ call kdb
+ RESTORE_ALL
+ addq $8,%rsp # forget orig_eax
+ CFI_ADJUST_CFA_OFFSET -8
+ iretq
+ CFI_ENDPROC
+END(kdb_call)
+
+#endif /* CONFIG_KDB */
+
+
+
+
#include <linux/sysrq.h>
#include <linux/input.h>
#include <linux/reboot.h>
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#endif /* CONFIG_KDB */
static void kbd_disconnect(struct input_handle *handle);
extern void ctrl_alt_del(void);
if (keycode < BTN_MISC)
printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode);
+#ifdef CONFIG_PPC_PMAC /* hacks for hugh */
+#undef KEY_SYSRQ /* from 99 */
+#define KEY_SYSRQ 184 /* F14 */
+#undef KEY_PAUSE /* from 119 */
+#define KEY_PAUSE 186 /* F16 */
+#define DOWN down
+#else
+#define DOWN 1
+#endif
+
+#ifdef CONFIG_KDB
+ if (keycode == KEY_PAUSE && DOWN && !rep && kdb_on == 1) {
+ kdb(KDB_REASON_KEYBOARD, 0, regs);
+ return;
+ }
+#endif /* CONFIG_KDB */
+
#ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */
if (keycode == KEY_SYSRQ && (sysrq_down || (down == 1 && sysrq_alt))) {
if (!sysrq_down) {
case TIOCMBIC:
case TIOCMBIS:
return tty_tiocmset(tty, file, cmd, p);
+ /*
+ * Without the real device to which /dev/console is connected,
+ * blogd can not work.
+ * blogd spawns a pty/tty pair,
+ * set /dev/console to the tty of that pair (ioctl TIOCCONS),
+ * then reads in all input from the current /dev/console,
+ * buffer or write the readed data to /var/log/boot.msg
+ * _and_ to the original real device.
+ */
+#define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get real dev no below /dev/console */
+ case TIOCGDEV:
+ {
+ unsigned int ret = new_encode_dev(tty_devnum(real_tty));
+ return put_user(ret, (unsigned int __user *)p);
+ }
+
}
if (tty->driver->ioctl) {
retval = (tty->driver->ioctl)(tty, file, cmd, arg);
add_release_event = 1;
break;
case ATKBD_RET_ERR:
-// printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
+#ifdef ATKBD_DEBUG
+ printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
+#endif
goto out;
}
case ATKBD_KEY_NULL:
break;
case ATKBD_KEY_UNKNOWN:
+#ifdef ATKBD_DEBUG
printk(KERN_WARNING
"atkbd.c: Unknown key %s (%s set %d, code %#x on %s).\n",
atkbd->release ? "released" : "pressed",
printk(KERN_WARNING
"atkbd.c: Use 'setkeycodes %s%02x <keycode>' to make it known.\n",
code & 0x80 ? "e0" : "", code & 0x7f);
+#endif
input_sync(dev);
break;
case ATKBD_SCR_1:
#include <asm/irq.h>
#include "8250.h"
+#include <linux/kdb.h>
+#ifdef CONFIG_KDB
+/*
+ * kdb_serial_line records the serial line number of the first serial console.
+ * NOTE: The kernel ignores characters on the serial line unless a user space
+ * program has opened the line first. To enter kdb before user space has opened
+ * the serial line, you can use the 'kdb=early' flag to lilo and set the
+ * appropriate breakpoints.
+ */
+
+static int kdb_serial_line = -1;
+static const char *kdb_serial_ptr = kdb_serial_str;
+#endif /* CONFIG_KDB */
/*
* Configuration:
int max_count = 256;
char flag;
+
do {
if (likely(lsr & UART_LSR_DR))
ch = serial_inp(up, UART_RX);
* the read character to be 0
*/
ch = 0;
-
+#ifdef CONFIG_KDB
+ if ((up->port.line == kdb_serial_line) && kdb_on == 1) {
+ if (ch == *kdb_serial_ptr) {
+ if (!(*++kdb_serial_ptr)) {
+ atomic_inc(&kdb_8250);
+ kdb(KDB_REASON_KEYBOARD, 0, regs);
+ atomic_dec(&kdb_8250);
+ kdb_serial_ptr = kdb_serial_str;
+ break;
+ }
+ } else
+ kdb_serial_ptr = kdb_serial_str;
+ }
+#endif /* CONFIG_KDB */
flag = TTY_NORMAL;
up->port.icount.rx++;
if (up->port.sysrq) {
/* serial8250_handle_port() already took the lock */
locked = 0;
- } else if (oops_in_progress) {
+ } else if (oops_in_progress || KDB_8250()) {
locked = spin_trylock(&up->port.lock);
} else
spin_lock(&up->port.lock);
if (!port->iobase && !port->membase)
return -ENODEV;
+#ifdef CONFIG_KDB
+ /*
+ * Remember the line number of the first serial
+ * console. We'll make this the kdb serial console too.
+ */
+ if (co && kdb_serial_line == -1) {
+ kdb_serial_line = co->index;
+ kdb_serial.io_type = port->iotype;
+ switch (port->iotype) {
+ case SERIAL_IO_MEM:
+#ifdef SERIAL_IO_MEM32
+ case SERIAL_IO_MEM32:
+#endif
+ kdb_serial.iobase = (unsigned long)(port->membase);
+ kdb_serial.ioreg_shift = port->regshift;
+ break;
+ default:
+ kdb_serial.iobase = port->iobase;
+ kdb_serial.ioreg_shift = 0;
+ break;
+ }
+ }
+#endif /* CONFIG_KDB */
+
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
#include <asm/io.h>
#include <asm/serial.h>
+
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+
+static int kdb_serial_line = -1;
+#endif /* CONFIG_KDB */
+
struct early_uart_device {
struct uart_port port;
char options[16]; /* e.g., 115200n8 */
if ((err = parse_options(device, options)) < 0)
return err;
+
+#ifdef CONFIG_KDB
+ /*
+ * Remember the line number of the first serial
+ * console. We'll make this the kdb serial console too.
+ */
+ if (console && kdb_serial_line == -1) {
+ kdb_serial_line = console->index;
+ kdb_serial.io_type = device->port.iotype;
+ switch (device->port.iotype) {
+ case SERIAL_IO_MEM:
+#ifdef SERIAL_IO_MEM32
+ case SERIAL_IO_MEM32:
+#endif
+ kdb_serial.iobase = (unsigned long)(device->port.membase);
+ kdb_serial.ioreg_shift = device->port.regshift;
+ break;
+ default:
+ kdb_serial.iobase = device->port.iobase;
+ kdb_serial.ioreg_shift = 0;
+ break;
+ }
+ }
+#endif /* CONFIG_KDB */
+
init_port(device);
return 0;
}
return -ENODEV;
options = strchr(cmdline, ',') + 1;
- if ((err = early_uart_setup(NULL, options)) < 0)
+ if ((err = early_uart_setup(&early_uart_console, options)) < 0)
return err;
return early_uart_console_init();
}
#include <linux/delay.h> /* for mdelay */
#include <linux/miscdevice.h>
#include <linux/serial_core.h>
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <linux/serial_reg.h>
+/*
+ * kdb_serial_line records the serial line number of the first serial console.
+ * NOTE: The kernel ignores characters on the serial line unless a user space
+ * program has opened the line first. To enter kdb before user space has opened
+ * the serial line, you can use the 'kdb=early' flag to lilo and set the
+ * appropriate breakpoints.
+ */
+
+static int kdb_serial_line = -1;
+static char *kdb_serial_ptr = (char *)kdb_serial_str;
+#endif /* CONFIG_KDB */
+
#include <asm/io.h>
#include <asm/sn/simulator.h>
"obtaining data from the console (0x%0x)\n", ch);
break;
}
+#ifdef CONFIG_KDB
+ if (kdb_on == 1) {
+ if (ch == *kdb_serial_ptr) {
+ if (!(*++kdb_serial_ptr)) {
+ spin_unlock_irqrestore(&port->sc_port.lock, flags);
+ if (!regs) {
+ KDB_STATE_SET(KEYBOARD);
+ KDB_ENTER(); /* to get some registers */
+ } else
+ kdb(KDB_REASON_KEYBOARD, 0, regs);
+ kdb_serial_ptr = (char *)kdb_serial_str;
+ spin_lock_irqsave(&port->sc_port.lock, flags);
+ break;
+ }
+ }
+ else
+ kdb_serial_ptr = (char *)kdb_serial_str;
+ }
+#endif /* CONFIG_KDB */
+
#ifdef CONFIG_MAGIC_SYSRQ
if (sysrq_requested) {
unsigned long sysrq_timeout = sysrq_requested + HZ*5;
*/
static int __init sn_sal_console_setup(struct console *co, char *options)
{
+#ifdef CONFIG_KDB
+ /*
+ * Remember the line number of the first serial
+ * console. We'll make this the kdb serial console too.
+ */
+ if (kdb_serial_line == -1) {
+ kdb_serial_line = co->index;
+ }
+#endif /* CONFIG_KDB */
return 0;
}
}
console_initcall(sn_sal_serial_console_init);
+
+#ifdef CONFIG_KDB
+int
+l1_control_in_polled(int offset)
+{
+ int sal_call_status = 0, input;
+ int ret = 0;
+ if (offset == UART_LSR) {
+ ret = (UART_LSR_THRE | UART_LSR_TEMT); /* can send anytime */
+ sal_call_status = ia64_sn_console_check(&input);
+ if (!sal_call_status && input) {
+ /* input pending */
+ ret |= UART_LSR_DR;
+ }
+ }
+ return ret;
+}
+
+int
+l1_serial_in_polled(void)
+{
+ int ch;
+ if (!ia64_sn_console_getc(&ch))
+ return ch;
+ else
+ return 0;
+}
+#endif /* CONFIG_KDB */
goto fail;
}
+#ifndef CONFIG_KDB
dev_info (&udev->dev,
"%s %s speed USB device using %s and address %d\n",
(udev->config) ? "reset" : "new",
}; speed;}),
udev->bus->controller->driver->name,
udev->devnum);
+#endif
/* Set up TT records, if needed */
if (hdev->tt) {
*
* History:
*
+ * 2005/06/23 CONFIG_KDB_USB support. (ayoung@sgi.com)
* 2004/03/24 LH7A404 support (Durgesh Pattamatta & Marc Singer)
* 2004/02/04 use generic dma_* functions instead of pci_* (dsaxena@plexity.net)
* 2003/02/24 show registers in sysfs (Kevin Brosius)
/*-------------------------------------------------------------------------*/
+#ifdef CONFIG_KDB_USB
+
+static void
+ohci_kdb_poll (void * __ohci, struct urb *urb)
+{
+ struct ohci_hcd *ohci;
+ struct ohci_regs * regs;
+
+ /*
+ * NOTE - we use the ohci_hcd from the urb rather than the
+ * __ohci parameter (which is NULL anyway). This ensures
+ * that we will process the proper controller for the urb.
+ */
+
+ if (!urb) /* can happen if no keyboard attached */
+ return;
+
+ ohci = (struct ohci_hcd *) hcd_to_ohci(urb->dev->bus->hcpriv);
+ regs = ohci->regs;
+
+ /* if the urb is not currently in progress resubmit it */
+ if (urb->status != -EINPROGRESS) {
+
+ if (usb_submit_urb (urb, SLAB_ATOMIC))
+ return;
+
+ /* make sure the HC registers are set correctly */
+ writel (OHCI_INTR_WDH, ®s->intrenable);
+ writel (OHCI_INTR_WDH, ®s->intrstatus);
+ writel (OHCI_INTR_MIE, ®s->intrenable);
+
+ // flush those pci writes
+ (void) readl (&ohci->regs->control);
+ }
+
+ if (ohci->hcca->done_head) {
+ dl_done_list_kdb (ohci, urb);
+ writel (OHCI_INTR_WDH, ®s->intrstatus);
+ // flush the pci write
+ (void) readl (&ohci->regs->control);
+ }
+}
+
+#endif /* CONFIG_KDB_USB */
+
+/*-------------------------------------------------------------------------*/
+
#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
MODULE_AUTHOR (DRIVER_AUTHOR);
#error "This file is PCI bus glue. CONFIG_PCI must be defined."
#endif
+#ifdef CONFIG_KDB_USB
+#include <linux/kdb.h>
+#endif
+
/*-------------------------------------------------------------------------*/
static int
ohci_stop (hcd);
return ret;
}
+
+#ifdef CONFIG_KDB_USB
+ kdb_usb_infos.poll_func = ohci_kdb_poll;
+ kdb_usb_infos.uhci = NULL; /* not used */
+#endif
return 0;
}
td = td_next;
}
}
+
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef CONFIG_KDB_USB
+static void
+dl_done_list_kdb (struct ohci_hcd *ohci, struct urb *kdburb)
+{
+ struct td *td = dl_reverse_done_list (ohci);
+
+ while (td) {
+ struct td *td_next = td->next_dl_td;
+ struct urb *urb = td->urb;
+ urb_priv_t *urb_priv = urb->hcpriv;
+ struct ed *ed = td->ed;
+
+ if (urb != kdburb) {
+ td = td_next;
+ continue;
+ }
+
+ /* update URB's length and status from TD */
+ td_done (ohci, urb, td);
+ urb_priv->td_cnt++;
+
+ /* If all this urb's TDs are done, just resubmit it */
+ if (urb_priv->td_cnt == urb_priv->length) {
+ urb->actual_length = 0;
+ urb->status = -EINPROGRESS;
+ list_del(&urb_priv->pending);
+ td_submit_urb (ohci, urb);
+ }
+
+ /* clean schedule: unlink EDs that are no longer busy */
+ if (list_empty (&ed->td_list)) {
+ if (ed->state == ED_OPER)
+ start_ed_unlink (ohci, ed);
+
+ /* ... reenabling halted EDs only after fault cleanup */
+ } else if ((ed->hwINFO & cpu_to_hc32 (ohci, ED_SKIP | ED_DEQUEUE))
+ == cpu_to_hc32 (ohci, ED_SKIP)) {
+ td = list_entry (ed->td_list.next, struct td, td_list);
+ if (!(td->hwINFO & cpu_to_hc32 (ohci, TD_DONE))) {
+ ed->hwINFO &= ~cpu_to_hc32 (ohci, ED_SKIP);
+ /* ... hc may need waking-up */
+ switch (ed->type) {
+ case PIPE_CONTROL:
+ ohci_writel (ohci, OHCI_CLF,
+ &ohci->regs->cmdstatus);
+ break;
+ case PIPE_BULK:
+ ohci_writel (ohci, OHCI_BLF,
+ &ohci->regs->cmdstatus);
+ break;
+ }
+ }
+ }
+
+ td = td_next;
+ }
+}
+
+#endif /* CONFIG_KDB_USB */
#define DRIVER_DESC "USB HID core driver"
#define DRIVER_LICENSE "GPL"
+#ifdef CONFIG_KDB_USB
+#include <linux/kdb.h>
+#endif
+
static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick",
"Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"};
/*
if (status) {
clear_bit(HID_IN_RUNNING, &hid->iofl);
if (status != -EPERM) {
+#ifndef CONFIG_KDB
err("can't resubmit intr, %s-%s/input%d, status %d",
hid->dev->bus->bus_name,
hid->dev->devpath,
hid->ifnum, status);
+#endif
hid_io_error(hid);
}
}
if (!hid)
return;
+#ifdef CONFIG_KDB_USB
+ /* Unlink the KDB USB struct */
+ if (hid->urbin == kdb_usb_infos.urb)
+ memset(&kdb_usb_infos, 0, sizeof(kdb_usb_infos));
+#endif
+
spin_lock_irq(&hid->inlock); /* Sync with error handler */
usb_set_intfdata(intf, NULL);
spin_unlock_irq(&hid->inlock);
printk(": USB HID v%x.%02x %s [%s] on %s\n",
hid->version >> 8, hid->version & 0xff, c, hid->name, path);
+#ifdef CONFIG_KDB_USB
+ /* Initialization of the KDB structure */
+ if (!strcmp(c, "Keyboard")) {
+ kdb_usb_infos.urb = hid->urbin;
+ kdb_usb_infos.buffer = hid->inbuf;
+ kdb_usb_infos.reset_timer = NULL;
+ }
+#endif
+
return 0;
}
dma_addr_t leds_dma;
};
+#ifdef CONFIG_KDB_USB
+#include <linux/kdb.h>
+#endif
+
static void usb_kbd_irq(struct urb *urb, struct pt_regs *regs)
{
struct usb_kbd *kbd = urb->context;
usb_fill_int_urb(kbd->irq, dev, pipe,
kbd->new, (maxp > 8 ? 8 : maxp),
usb_kbd_irq, kbd, endpoint->bInterval);
+
+#ifdef CONFIG_KDB_USB
+ /* Init the KDB structure */
+ kdb_usb_infos.urb = kbd->irq;
+ kdb_usb_infos.buffer = kbd->new;
+ kdb_usb_infos.reset_timer = NULL;
+#endif
kbd->irq->transfer_dma = kbd->new_dma;
kbd->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
struct usb_kbd *kbd = usb_get_intfdata (intf);
usb_set_intfdata(intf, NULL);
+#ifdef CONFIG_KDB_USB
+ /* Unlink the KDB USB struct */
+ if (kbd && kbd->irq == kdb_usb_infos.urb)
+ memset(&kdb_usb_infos, 0, sizeof(kdb_usb_infos));
+#endif /* CONFIG_KDB_USB */
if (kbd) {
usb_kill_urb(kbd->irq);
input_unregister_device(kbd->dev);
--- /dev/null
+/* Cut down version, enough for KDB */
+/* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically
+ generated from "bfd-in.h", "init.c", "opncls.c", "libbfd.c",
+ "bfdio.c", "bfdwin.c", "section.c", "archures.c", "reloc.c",
+ "syms.c", "bfd.c", "archive.c", "corefile.c", "targets.c", "format.c",
+ "linker.c" and "simple.c".
+ Run "make headers" in your build bfd/ to regenerate. */
+
+/* Main header file for the bfd library -- portable access to object files.
+
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Support.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use.
+ * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as
+ * required.
+ * Keith Owens <kaos@sgi.com> 15 May 2006
+ */
+
+#ifndef __BFD_H_SEEN__
+#define __BFD_H_SEEN__
+
+#ifdef __KERNEL__
+#include <linux/ansidecl.h>
+#else /* __KERNEL__ */
+#include "ansidecl.h"
+#include "symcat.h"
+#endif /* __KERNEL__ */
+
+/* The word size used by BFD on the host. This may be 64 with a 32
+ bit target if the host is 64 bit, or if other 64 bit targets have
+ been selected with --enable-targets, or if --enable-64-bit-bfd. */
+#define BFD_ARCH_SIZE 32
+
+/* The word size of the default bfd target. */
+#define BFD_DEFAULT_TARGET_SIZE 32
+
+#define BFD_HOST_64BIT_LONG 0
+#define BFD_HOST_LONG_LONG 1
+#if 1
+#define BFD_HOST_64_BIT long long
+#define BFD_HOST_U_64_BIT unsigned long long
+typedef BFD_HOST_64_BIT bfd_int64_t;
+typedef BFD_HOST_U_64_BIT bfd_uint64_t;
+#endif
+
+#if BFD_ARCH_SIZE >= 64
+#define BFD64
+#endif
+
+#ifndef INLINE
+#if __GNUC__ >= 2
+#define INLINE __inline__
+#else
+#define INLINE
+#endif
+#endif
+
+/* Forward declaration. */
+typedef struct bfd bfd;
+
+/* Boolean type used in bfd. Too many systems define their own
+ versions of "boolean" for us to safely typedef a "boolean" of
+ our own. Using an enum for "bfd_boolean" has its own set of
+ problems, with strange looking casts required to avoid warnings
+ on some older compilers. Thus we just use an int.
+
+ General rule: Functions which are bfd_boolean return TRUE on
+ success and FALSE on failure (unless they're a predicate). */
+
+typedef int bfd_boolean;
+#undef FALSE
+#undef TRUE
+#define FALSE 0
+#define TRUE 1
+
+#ifdef BFD64
+
+#ifndef BFD_HOST_64_BIT
+ #error No 64 bit integer type available
+#endif /* ! defined (BFD_HOST_64_BIT) */
+
+typedef BFD_HOST_U_64_BIT bfd_vma;
+typedef BFD_HOST_64_BIT bfd_signed_vma;
+typedef BFD_HOST_U_64_BIT bfd_size_type;
+typedef BFD_HOST_U_64_BIT symvalue;
+
+#ifndef fprintf_vma
+#if BFD_HOST_64BIT_LONG
+#define sprintf_vma(s,x) sprintf (s, "%016lx", x)
+#define fprintf_vma(f,x) fprintf (f, "%016lx", x)
+#else
+#define _bfd_int64_low(x) ((unsigned long) (((x) & 0xffffffff)))
+#define _bfd_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff))
+#define fprintf_vma(s,x) \
+ fprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x))
+#define sprintf_vma(s,x) \
+ sprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x))
+#endif
+#endif
+
+#else /* not BFD64 */
+
+/* Represent a target address. Also used as a generic unsigned type
+ which is guaranteed to be big enough to hold any arithmetic types
+ we need to deal with. */
+typedef unsigned long bfd_vma;
+
+/* A generic signed type which is guaranteed to be big enough to hold any
+ arithmetic types we need to deal with. Can be assumed to be compatible
+ with bfd_vma in the same way that signed and unsigned ints are compatible
+ (as parameters, in assignment, etc). */
+typedef long bfd_signed_vma;
+
+typedef unsigned long symvalue;
+typedef unsigned long bfd_size_type;
+
+/* Print a bfd_vma x on stream s. */
+#define fprintf_vma(s,x) fprintf (s, "%08lx", x)
+#define sprintf_vma(s,x) sprintf (s, "%08lx", x)
+
+#endif /* not BFD64 */
+
+#define HALF_BFD_SIZE_TYPE \
+ (((bfd_size_type) 1) << (8 * sizeof (bfd_size_type) / 2))
+
+#ifndef BFD_HOST_64_BIT
+/* Fall back on a 32 bit type. The idea is to make these types always
+ available for function return types, but in the case that
+ BFD_HOST_64_BIT is undefined such a function should abort or
+ otherwise signal an error. */
+typedef bfd_signed_vma bfd_int64_t;
+typedef bfd_vma bfd_uint64_t;
+#endif
+
+/* An offset into a file. BFD always uses the largest possible offset
+ based on the build time availability of fseek, fseeko, or fseeko64. */
+typedef BFD_HOST_64_BIT file_ptr;
+typedef unsigned BFD_HOST_64_BIT ufile_ptr;
+
+extern void bfd_sprintf_vma (bfd *, char *, bfd_vma);
+extern void bfd_fprintf_vma (bfd *, void *, bfd_vma);
+
+#define printf_vma(x) fprintf_vma(stdout,x)
+#define bfd_printf_vma(abfd,x) bfd_fprintf_vma (abfd,stdout,x)
+
+typedef unsigned int flagword; /* 32 bits of flags */
+typedef unsigned char bfd_byte;
+
+/* Extracted from archures.c. */
+enum bfd_architecture
+{
+ bfd_arch_unknown, /* File arch not known. */
+ bfd_arch_obscure, /* Arch known, not one of these. */
+ bfd_arch_m68k, /* Motorola 68xxx */
+#define bfd_mach_m68000 1
+#define bfd_mach_m68008 2
+#define bfd_mach_m68010 3
+#define bfd_mach_m68020 4
+#define bfd_mach_m68030 5
+#define bfd_mach_m68040 6
+#define bfd_mach_m68060 7
+#define bfd_mach_cpu32 8
+#define bfd_mach_mcf5200 9
+#define bfd_mach_mcf5206e 10
+#define bfd_mach_mcf5307 11
+#define bfd_mach_mcf5407 12
+#define bfd_mach_mcf528x 13
+#define bfd_mach_mcfv4e 14
+#define bfd_mach_mcf521x 15
+#define bfd_mach_mcf5249 16
+#define bfd_mach_mcf547x 17
+#define bfd_mach_mcf548x 18
+ bfd_arch_vax, /* DEC Vax */
+ bfd_arch_i960, /* Intel 960 */
+ /* The order of the following is important.
+ lower number indicates a machine type that
+ only accepts a subset of the instructions
+ available to machines with higher numbers.
+ The exception is the "ca", which is
+ incompatible with all other machines except
+ "core". */
+
+#define bfd_mach_i960_core 1
+#define bfd_mach_i960_ka_sa 2
+#define bfd_mach_i960_kb_sb 3
+#define bfd_mach_i960_mc 4
+#define bfd_mach_i960_xa 5
+#define bfd_mach_i960_ca 6
+#define bfd_mach_i960_jx 7
+#define bfd_mach_i960_hx 8
+
+ bfd_arch_or32, /* OpenRISC 32 */
+
+ bfd_arch_a29k, /* AMD 29000 */
+ bfd_arch_sparc, /* SPARC */
+#define bfd_mach_sparc 1
+/* The difference between v8plus and v9 is that v9 is a true 64 bit env. */
+#define bfd_mach_sparc_sparclet 2
+#define bfd_mach_sparc_sparclite 3
+#define bfd_mach_sparc_v8plus 4
+#define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns. */
+#define bfd_mach_sparc_sparclite_le 6
+#define bfd_mach_sparc_v9 7
+#define bfd_mach_sparc_v9a 8 /* with ultrasparc add'ns. */
+#define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */
+#define bfd_mach_sparc_v9b 10 /* with cheetah add'ns. */
+/* Nonzero if MACH has the v9 instruction set. */
+#define bfd_mach_sparc_v9_p(mach) \
+ ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9b \
+ && (mach) != bfd_mach_sparc_sparclite_le)
+/* Nonzero if MACH is a 64 bit sparc architecture. */
+#define bfd_mach_sparc_64bit_p(mach) \
+ ((mach) >= bfd_mach_sparc_v9 && (mach) != bfd_mach_sparc_v8plusb)
+ bfd_arch_mips, /* MIPS Rxxxx */
+#define bfd_mach_mips3000 3000
+#define bfd_mach_mips3900 3900
+#define bfd_mach_mips4000 4000
+#define bfd_mach_mips4010 4010
+#define bfd_mach_mips4100 4100
+#define bfd_mach_mips4111 4111
+#define bfd_mach_mips4120 4120
+#define bfd_mach_mips4300 4300
+#define bfd_mach_mips4400 4400
+#define bfd_mach_mips4600 4600
+#define bfd_mach_mips4650 4650
+#define bfd_mach_mips5000 5000
+#define bfd_mach_mips5400 5400
+#define bfd_mach_mips5500 5500
+#define bfd_mach_mips6000 6000
+#define bfd_mach_mips7000 7000
+#define bfd_mach_mips8000 8000
+#define bfd_mach_mips9000 9000
+#define bfd_mach_mips10000 10000
+#define bfd_mach_mips12000 12000
+#define bfd_mach_mips16 16
+#define bfd_mach_mips5 5
+#define bfd_mach_mips_sb1 12310201 /* octal 'SB', 01 */
+#define bfd_mach_mipsisa32 32
+#define bfd_mach_mipsisa32r2 33
+#define bfd_mach_mipsisa64 64
+#define bfd_mach_mipsisa64r2 65
+ bfd_arch_i386, /* Intel 386 */
+#define bfd_mach_i386_i386 1
+#define bfd_mach_i386_i8086 2
+#define bfd_mach_i386_i386_intel_syntax 3
+#define bfd_mach_x86_64 64
+#define bfd_mach_x86_64_intel_syntax 65
+ bfd_arch_we32k, /* AT&T WE32xxx */
+ bfd_arch_tahoe, /* CCI/Harris Tahoe */
+ bfd_arch_i860, /* Intel 860 */
+ bfd_arch_i370, /* IBM 360/370 Mainframes */
+ bfd_arch_romp, /* IBM ROMP PC/RT */
+ bfd_arch_alliant, /* Alliant */
+ bfd_arch_convex, /* Convex */
+ bfd_arch_m88k, /* Motorola 88xxx */
+ bfd_arch_m98k, /* Motorola 98xxx */
+ bfd_arch_pyramid, /* Pyramid Technology */
+ bfd_arch_h8300, /* Renesas H8/300 (formerly Hitachi H8/300) */
+#define bfd_mach_h8300 1
+#define bfd_mach_h8300h 2
+#define bfd_mach_h8300s 3
+#define bfd_mach_h8300hn 4
+#define bfd_mach_h8300sn 5
+#define bfd_mach_h8300sx 6
+#define bfd_mach_h8300sxn 7
+ bfd_arch_pdp11, /* DEC PDP-11 */
+ bfd_arch_powerpc, /* PowerPC */
+#define bfd_mach_ppc 32
+#define bfd_mach_ppc64 64
+#define bfd_mach_ppc_403 403
+#define bfd_mach_ppc_403gc 4030
+#define bfd_mach_ppc_505 505
+#define bfd_mach_ppc_601 601
+#define bfd_mach_ppc_602 602
+#define bfd_mach_ppc_603 603
+#define bfd_mach_ppc_ec603e 6031
+#define bfd_mach_ppc_604 604
+#define bfd_mach_ppc_620 620
+#define bfd_mach_ppc_630 630
+#define bfd_mach_ppc_750 750
+#define bfd_mach_ppc_860 860
+#define bfd_mach_ppc_a35 35
+#define bfd_mach_ppc_rs64ii 642
+#define bfd_mach_ppc_rs64iii 643
+#define bfd_mach_ppc_7400 7400
+#define bfd_mach_ppc_e500 500
+ bfd_arch_rs6000, /* IBM RS/6000 */
+#define bfd_mach_rs6k 6000
+#define bfd_mach_rs6k_rs1 6001
+#define bfd_mach_rs6k_rsc 6003
+#define bfd_mach_rs6k_rs2 6002
+ bfd_arch_hppa, /* HP PA RISC */
+#define bfd_mach_hppa10 10
+#define bfd_mach_hppa11 11
+#define bfd_mach_hppa20 20
+#define bfd_mach_hppa20w 25
+ bfd_arch_d10v, /* Mitsubishi D10V */
+#define bfd_mach_d10v 1
+#define bfd_mach_d10v_ts2 2
+#define bfd_mach_d10v_ts3 3
+ bfd_arch_d30v, /* Mitsubishi D30V */
+ bfd_arch_dlx, /* DLX */
+ bfd_arch_m68hc11, /* Motorola 68HC11 */
+ bfd_arch_m68hc12, /* Motorola 68HC12 */
+#define bfd_mach_m6812_default 0
+#define bfd_mach_m6812 1
+#define bfd_mach_m6812s 2
+ bfd_arch_z8k, /* Zilog Z8000 */
+#define bfd_mach_z8001 1
+#define bfd_mach_z8002 2
+ bfd_arch_h8500, /* Renesas H8/500 (formerly Hitachi H8/500) */
+ bfd_arch_sh, /* Renesas / SuperH SH (formerly Hitachi SH) */
+#define bfd_mach_sh 1
+#define bfd_mach_sh2 0x20
+#define bfd_mach_sh_dsp 0x2d
+#define bfd_mach_sh2a 0x2a
+#define bfd_mach_sh2a_nofpu 0x2b
+#define bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu 0x2a1
+#define bfd_mach_sh2a_nofpu_or_sh3_nommu 0x2a2
+#define bfd_mach_sh2a_or_sh4 0x2a3
+#define bfd_mach_sh2a_or_sh3e 0x2a4
+#define bfd_mach_sh2e 0x2e
+#define bfd_mach_sh3 0x30
+#define bfd_mach_sh3_nommu 0x31
+#define bfd_mach_sh3_dsp 0x3d
+#define bfd_mach_sh3e 0x3e
+#define bfd_mach_sh4 0x40
+#define bfd_mach_sh4_nofpu 0x41
+#define bfd_mach_sh4_nommu_nofpu 0x42
+#define bfd_mach_sh4a 0x4a
+#define bfd_mach_sh4a_nofpu 0x4b
+#define bfd_mach_sh4al_dsp 0x4d
+#define bfd_mach_sh5 0x50
+ bfd_arch_alpha, /* Dec Alpha */
+#define bfd_mach_alpha_ev4 0x10
+#define bfd_mach_alpha_ev5 0x20
+#define bfd_mach_alpha_ev6 0x30
+ bfd_arch_arm, /* Advanced Risc Machines ARM. */
+#define bfd_mach_arm_unknown 0
+#define bfd_mach_arm_2 1
+#define bfd_mach_arm_2a 2
+#define bfd_mach_arm_3 3
+#define bfd_mach_arm_3M 4
+#define bfd_mach_arm_4 5
+#define bfd_mach_arm_4T 6
+#define bfd_mach_arm_5 7
+#define bfd_mach_arm_5T 8
+#define bfd_mach_arm_5TE 9
+#define bfd_mach_arm_XScale 10
+#define bfd_mach_arm_ep9312 11
+#define bfd_mach_arm_iWMMXt 12
+ bfd_arch_ns32k, /* National Semiconductors ns32000 */
+ bfd_arch_w65, /* WDC 65816 */
+ bfd_arch_tic30, /* Texas Instruments TMS320C30 */
+ bfd_arch_tic4x, /* Texas Instruments TMS320C3X/4X */
+#define bfd_mach_tic3x 30
+#define bfd_mach_tic4x 40
+ bfd_arch_tic54x, /* Texas Instruments TMS320C54X */
+ bfd_arch_tic80, /* TI TMS320c80 (MVP) */
+ bfd_arch_v850, /* NEC V850 */
+#define bfd_mach_v850 1
+#define bfd_mach_v850e 'E'
+#define bfd_mach_v850e1 '1'
+ bfd_arch_arc, /* ARC Cores */
+#define bfd_mach_arc_5 5
+#define bfd_mach_arc_6 6
+#define bfd_mach_arc_7 7
+#define bfd_mach_arc_8 8
+ bfd_arch_m32c, /* Renesas M16C/M32C. */
+#define bfd_mach_m16c 0x75
+#define bfd_mach_m32c 0x78
+ bfd_arch_m32r, /* Renesas M32R (formerly Mitsubishi M32R/D) */
+#define bfd_mach_m32r 1 /* For backwards compatibility. */
+#define bfd_mach_m32rx 'x'
+#define bfd_mach_m32r2 '2'
+ bfd_arch_mn10200, /* Matsushita MN10200 */
+ bfd_arch_mn10300, /* Matsushita MN10300 */
+#define bfd_mach_mn10300 300
+#define bfd_mach_am33 330
+#define bfd_mach_am33_2 332
+ bfd_arch_fr30,
+#define bfd_mach_fr30 0x46523330
+ bfd_arch_frv,
+#define bfd_mach_frv 1
+#define bfd_mach_frvsimple 2
+#define bfd_mach_fr300 300
+#define bfd_mach_fr400 400
+#define bfd_mach_fr450 450
+#define bfd_mach_frvtomcat 499 /* fr500 prototype */
+#define bfd_mach_fr500 500
+#define bfd_mach_fr550 550
+ bfd_arch_mcore,
+ bfd_arch_ia64, /* HP/Intel ia64 */
+#define bfd_mach_ia64_elf64 64
+#define bfd_mach_ia64_elf32 32
+ bfd_arch_ip2k, /* Ubicom IP2K microcontrollers. */
+#define bfd_mach_ip2022 1
+#define bfd_mach_ip2022ext 2
+ bfd_arch_iq2000, /* Vitesse IQ2000. */
+#define bfd_mach_iq2000 1
+#define bfd_mach_iq10 2
+ bfd_arch_ms1,
+#define bfd_mach_ms1 1
+#define bfd_mach_mrisc2 2
+ bfd_arch_pj,
+ bfd_arch_avr, /* Atmel AVR microcontrollers. */
+#define bfd_mach_avr1 1
+#define bfd_mach_avr2 2
+#define bfd_mach_avr3 3
+#define bfd_mach_avr4 4
+#define bfd_mach_avr5 5
+ bfd_arch_cr16c, /* National Semiconductor CompactRISC. */
+#define bfd_mach_cr16c 1
+ bfd_arch_crx, /* National Semiconductor CRX. */
+#define bfd_mach_crx 1
+ bfd_arch_cris, /* Axis CRIS */
+#define bfd_mach_cris_v0_v10 255
+#define bfd_mach_cris_v32 32
+#define bfd_mach_cris_v10_v32 1032
+ bfd_arch_s390, /* IBM s390 */
+#define bfd_mach_s390_31 31
+#define bfd_mach_s390_64 64
+ bfd_arch_openrisc, /* OpenRISC */
+ bfd_arch_mmix, /* Donald Knuth's educational processor. */
+ bfd_arch_xstormy16,
+#define bfd_mach_xstormy16 1
+ bfd_arch_msp430, /* Texas Instruments MSP430 architecture. */
+#define bfd_mach_msp11 11
+#define bfd_mach_msp110 110
+#define bfd_mach_msp12 12
+#define bfd_mach_msp13 13
+#define bfd_mach_msp14 14
+#define bfd_mach_msp15 15
+#define bfd_mach_msp16 16
+#define bfd_mach_msp31 31
+#define bfd_mach_msp32 32
+#define bfd_mach_msp33 33
+#define bfd_mach_msp41 41
+#define bfd_mach_msp42 42
+#define bfd_mach_msp43 43
+#define bfd_mach_msp44 44
+ bfd_arch_xtensa, /* Tensilica's Xtensa cores. */
+#define bfd_mach_xtensa 1
+ bfd_arch_maxq, /* Dallas MAXQ 10/20 */
+#define bfd_mach_maxq10 10
+#define bfd_mach_maxq20 20
+ bfd_arch_last
+ };
+
+enum bfd_flavour
+{
+ bfd_target_unknown_flavour,
+ bfd_target_aout_flavour,
+ bfd_target_coff_flavour,
+ bfd_target_ecoff_flavour,
+ bfd_target_xcoff_flavour,
+ bfd_target_elf_flavour,
+ bfd_target_ieee_flavour,
+ bfd_target_nlm_flavour,
+ bfd_target_oasys_flavour,
+ bfd_target_tekhex_flavour,
+ bfd_target_srec_flavour,
+ bfd_target_ihex_flavour,
+ bfd_target_som_flavour,
+ bfd_target_os9k_flavour,
+ bfd_target_versados_flavour,
+ bfd_target_msdos_flavour,
+ bfd_target_ovax_flavour,
+ bfd_target_evax_flavour,
+ bfd_target_mmo_flavour,
+ bfd_target_mach_o_flavour,
+ bfd_target_pef_flavour,
+ bfd_target_pef_xlib_flavour,
+ bfd_target_sym_flavour
+};
+
+enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
+
+#endif
#ifdef CONFIG_DEBUG_BUGVERBOSE
#define BUG() \
__asm__ __volatile__( "ud2\n" \
- "\t.word %c0\n" \
- "\t.long %c1\n" \
- : : "i" (__LINE__), "i" (__FILE__))
+ "\t.byte 0xea\n" \
+ "\t.long %c0\n" \
+ "\t.word %c1\n" \
+ : : "i" (__FILE__), "i" (__LINE__))
+ /* "ljmp long short" so disassemblers can make sense of it */
#else
#define BUG() __asm__ __volatile__("ud2\n")
#endif
--- /dev/null
+#ifndef _ASM_KDB_H
+#define _ASM_KDB_H
+
+/*
+ * Kernel Debugger Architecture Dependent Global Headers
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * KDB_ENTER() is a macro which causes entry into the kernel
+ * debugger from any point in the kernel code stream. If it
+ * is intended to be used from interrupt level, it must use
+ * a non-maskable entry method. The vector is KDBENTER_VECTOR.
+ */
+#define KDB_ENTER() do {if (kdb_on && !KDB_IS_RUNNING()) { asm("\tint $129\n"); }} while(0)
+
+/*
+ * Needed for exported symbols.
+ */
+typedef unsigned long kdb_machreg_t;
+
+#define kdb_machreg_fmt "0x%lx"
+#define kdb_machreg_fmt0 "%08lx"
+#define kdb_bfd_vma_fmt "0x%lx"
+#define kdb_bfd_vma_fmt0 "0x%08lx"
+#define kdb_elfw_addr_fmt "0x%x"
+#define kdb_elfw_addr_fmt0 "0x%08x"
+
+/*
+ * Per cpu arch specific kdb state. Must be in range 0xff000000.
+ */
+#define KDB_STATE_A_IF 0x01000000 /* Saved IF flag */
+
+static inline unsigned long
+kdba_funcptr_value(void *fp)
+{
+ return (unsigned long)fp;
+}
+
+#endif /* !_ASM_KDB_H */
--- /dev/null
+#ifndef _ASM_KDBPRIVATE_H
+#define _ASM_KDBPRIVATE_H
+
+/*
+ * Kernel Debugger Architecture Dependent Private Headers
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2006 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+typedef unsigned char kdb_machinst_t;
+
+/*
+ * KDB_MAXBPT describes the total number of breakpoints
+ * supported by this architecure.
+ */
+#define KDB_MAXBPT 16
+
+/*
+ * KDB_MAXHARDBPT describes the total number of hardware
+ * breakpoint registers that exist.
+ */
+#define KDB_MAXHARDBPT 4
+
+/* Maximum number of arguments to a function */
+#define KDBA_MAXARGS 16
+
+/*
+ * Platform specific environment entries
+ */
+#define KDB_PLATFORM_ENV "IDMODE=x86", "BYTESPERWORD=4", "IDCOUNT=16"
+
+/*
+ * Support for ia32 debug registers
+ */
+typedef struct _kdbhard_bp {
+ kdb_machreg_t bph_reg; /* Register this breakpoint uses */
+
+ unsigned int bph_free:1; /* Register available for use */
+ unsigned int bph_data:1; /* Data Access breakpoint */
+
+ unsigned int bph_write:1; /* Write Data breakpoint */
+ unsigned int bph_mode:2; /* 0=inst, 1=write, 2=io, 3=read */
+ unsigned int bph_length:2; /* 0=1, 1=2, 2=BAD, 3=4 (bytes) */
+} kdbhard_bp_t;
+
+#define IA32_BREAKPOINT_INSTRUCTION 0xcc
+
+#define DR6_BT 0x00008000
+#define DR6_BS 0x00004000
+#define DR6_BD 0x00002000
+
+#define DR6_B3 0x00000008
+#define DR6_B2 0x00000004
+#define DR6_B1 0x00000002
+#define DR6_B0 0x00000001
+#define DR6_DR_MASK 0x0000000F
+
+#define DR7_RW_VAL(dr, drnum) \
+ (((dr) >> (16 + (4 * (drnum)))) & 0x3)
+
+#define DR7_RW_SET(dr, drnum, rw) \
+ do { \
+ (dr) &= ~(0x3 << (16 + (4 * (drnum)))); \
+ (dr) |= (((rw) & 0x3) << (16 + (4 * (drnum)))); \
+ } while (0)
+
+#define DR7_RW0(dr) DR7_RW_VAL(dr, 0)
+#define DR7_RW0SET(dr,rw) DR7_RW_SET(dr, 0, rw)
+#define DR7_RW1(dr) DR7_RW_VAL(dr, 1)
+#define DR7_RW1SET(dr,rw) DR7_RW_SET(dr, 1, rw)
+#define DR7_RW2(dr) DR7_RW_VAL(dr, 2)
+#define DR7_RW2SET(dr,rw) DR7_RW_SET(dr, 2, rw)
+#define DR7_RW3(dr) DR7_RW_VAL(dr, 3)
+#define DR7_RW3SET(dr,rw) DR7_RW_SET(dr, 3, rw)
+
+
+#define DR7_LEN_VAL(dr, drnum) \
+ (((dr) >> (18 + (4 * (drnum)))) & 0x3)
+
+#define DR7_LEN_SET(dr, drnum, rw) \
+ do { \
+ (dr) &= ~(0x3 << (18 + (4 * (drnum)))); \
+ (dr) |= (((rw) & 0x3) << (18 + (4 * (drnum)))); \
+ } while (0)
+
+#define DR7_LEN0(dr) DR7_LEN_VAL(dr, 0)
+#define DR7_LEN0SET(dr,len) DR7_LEN_SET(dr, 0, len)
+#define DR7_LEN1(dr) DR7_LEN_VAL(dr, 1)
+#define DR7_LEN1SET(dr,len) DR7_LEN_SET(dr, 1, len)
+#define DR7_LEN2(dr) DR7_LEN_VAL(dr, 2)
+#define DR7_LEN2SET(dr,len) DR7_LEN_SET(dr, 2, len)
+#define DR7_LEN3(dr) DR7_LEN_VAL(dr, 3)
+#define DR7_LEN3SET(dr,len) DR7_LEN_SET(dr, 3, len)
+
+#define DR7_G0(dr) (((dr)>>1)&0x1)
+#define DR7_G0SET(dr) ((dr) |= 0x2)
+#define DR7_G0CLR(dr) ((dr) &= ~0x2)
+#define DR7_G1(dr) (((dr)>>3)&0x1)
+#define DR7_G1SET(dr) ((dr) |= 0x8)
+#define DR7_G1CLR(dr) ((dr) &= ~0x8)
+#define DR7_G2(dr) (((dr)>>5)&0x1)
+#define DR7_G2SET(dr) ((dr) |= 0x20)
+#define DR7_G2CLR(dr) ((dr) &= ~0x20)
+#define DR7_G3(dr) (((dr)>>7)&0x1)
+#define DR7_G3SET(dr) ((dr) |= 0x80)
+#define DR7_G3CLR(dr) ((dr) &= ~0x80)
+
+#define DR7_L0(dr) (((dr))&0x1)
+#define DR7_L0SET(dr) ((dr) |= 0x1)
+#define DR7_L0CLR(dr) ((dr) &= ~0x1)
+#define DR7_L1(dr) (((dr)>>2)&0x1)
+#define DR7_L1SET(dr) ((dr) |= 0x4)
+#define DR7_L1CLR(dr) ((dr) &= ~0x4)
+#define DR7_L2(dr) (((dr)>>4)&0x1)
+#define DR7_L2SET(dr) ((dr) |= 0x10)
+#define DR7_L2CLR(dr) ((dr) &= ~0x10)
+#define DR7_L3(dr) (((dr)>>6)&0x1)
+#define DR7_L3SET(dr) ((dr) |= 0x40)
+#define DR7_L3CLR(dr) ((dr) &= ~0x40)
+
+#define DR7_GD 0x00002000 /* General Detect Enable */
+#define DR7_GE 0x00000200 /* Global exact */
+#define DR7_LE 0x00000100 /* Local exact */
+
+#define DR_TYPE_EXECUTE 0x0
+#define DR_TYPE_WRITE 0x1
+#define DR_TYPE_IO 0x2
+#define DR_TYPE_RW 0x3
+
+extern kdb_machreg_t kdba_getdr6(void);
+extern void kdba_putdr6(kdb_machreg_t);
+
+extern kdb_machreg_t kdba_getdr7(void);
+
+/*
+ * Support for setjmp/longjmp
+ */
+#define JB_BX 0
+#define JB_SI 1
+#define JB_DI 2
+#define JB_BP 3
+#define JB_SP 4
+#define JB_PC 5
+
+typedef struct __kdb_jmp_buf {
+ unsigned long regs[6]; /* kdba_setjmp assumes fixed offsets here */
+} kdb_jmp_buf;
+
+extern int asmlinkage kdba_setjmp(kdb_jmp_buf *);
+extern void asmlinkage kdba_longjmp(kdb_jmp_buf *, int);
+#define kdba_setjmp kdba_setjmp
+
+extern kdb_jmp_buf *kdbjmpbuf;
+
+/* Arch specific data saved for running processes */
+
+struct kdba_running_process {
+ long esp; /* CONFIG_4KSTACKS may be on a different stack */
+};
+
+static inline
+void kdba_save_running(struct kdba_running_process *k, struct pt_regs *regs)
+{
+ k->esp = current_stack_pointer;
+}
+
+static inline
+void kdba_unsave_running(struct kdba_running_process *k, struct pt_regs *regs)
+{
+}
+
+struct kdb_activation_record;
+extern void kdba_get_stack_info_alternate(kdb_machreg_t addr, int cpu,
+ struct kdb_activation_record *ar);
+
+extern void kdba_wait_for_cpus(void);
+
+extern fastcall void kdb_interrupt(void);
+
+#endif /* !_ASM_KDBPRIVATE_H */
DIE_DIE,
DIE_NMIWATCHDOG,
DIE_KERNELDEBUG,
+ DIE_KDEBUG_ENTER,
+ DIE_KDEBUG_LEAVE,
DIE_TRAP,
DIE_GPF,
DIE_CALL,
#define INVALIDATE_TLB_VECTOR 0xfd
#define RESCHEDULE_VECTOR 0xfc
#define CALL_FUNCTION_VECTOR 0xfb
-
+#define KDB_VECTOR 0xf9
+#define KDBENTER_VECTOR 0x81
#define THERMAL_APIC_VECTOR 0xf0
/*
* Local APIC timer IRQ vector is on a different priority level,
* something other than this.
*/
extern struct desc_struct default_ldt[];
-extern void set_intr_gate(unsigned int irq, void * addr);
+/* extern void set_intr_gate(unsigned int irq, void * addr); */
#define _set_tssldt_desc(n,addr,limit,type) \
__asm__ __volatile__ ("movw %w3,0(%2)\n\t" \
--- /dev/null
+/*
+ * include/linux/pc_keyb.h
+ *
+ * PC Keyboard And Keyboard Controller
+ *
+ * (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ */
+
+/*
+ * Configuration Switches
+ */
+
+#undef KBD_REPORT_ERR /* Report keyboard errors */
+#define KBD_REPORT_UNKN /* Report unknown scan codes */
+#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */
+#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */
+#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */
+
+
+
+#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */
+#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */
+#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */
+
+/*
+ * Internal variables of the driver
+ */
+
+extern unsigned char pckbd_read_mask;
+extern unsigned char aux_device_present;
+
+/*
+ * Keyboard Controller Registers on normal PCs.
+ */
+
+#define KBD_STATUS_REG 0x64 /* Status register (R) */
+#define KBD_CNTL_REG 0x64 /* Controller command register (W) */
+#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */
+
+/*
+ * Keyboard Controller Commands
+ */
+
+#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
+#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
+#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
+#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
+#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
+#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
+#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
+#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
+#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
+#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
+#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if
+ initiated by the auxiliary device */
+#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
+
+/*
+ * Keyboard Commands
+ */
+
+#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
+#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
+#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
+#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */
+#define KBD_CMD_RESET 0xFF /* Reset */
+
+/*
+ * Keyboard Replies
+ */
+
+#define KBD_REPLY_POR 0xAA /* Power on reset */
+#define KBD_REPLY_ACK 0xFA /* Command ACK */
+#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
+
+/*
+ * Status Register Bits
+ */
+
+#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
+#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
+#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
+#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
+#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
+#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
+#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
+#define KBD_STAT_PERR 0x80 /* Parity error */
+
+#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
+
+/*
+ * Controller Mode Register Bits
+ */
+
+#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */
+#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
+#define KBD_MODE_SYS 0x04 /* The system flag (?) */
+#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
+#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
+#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
+#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
+#define KBD_MODE_RFU 0x80
+
+/*
+ * Mouse Commands
+ */
+
+#define AUX_SET_RES 0xE8 /* Set resolution */
+#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
+#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
+#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
+#define AUX_SET_STREAM 0xEA /* Set stream mode */
+#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
+#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
+#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
+#define AUX_RESET 0xFF /* Reset aux device */
+#define AUX_ACK 0xFA /* Command byte ACK. */
+
+#define AUX_BUF_SIZE 2048 /* This might be better divisible by
+ three to make overruns stay in sync
+ but then the read function would need
+ a lock etc - ick */
+
+struct aux_queue {
+ unsigned long head;
+ unsigned long tail;
+ wait_queue_head_t proc_list;
+ struct fasync_struct *fasync;
+ unsigned char buf[AUX_BUF_SIZE];
+};
+
+
+/* How to access the keyboard macros on this platform. */
+#define kbd_read_input() inb(KBD_DATA_REG)
+#define kbd_read_status() inb(KBD_STATUS_REG)
+#define kbd_write_output(val) outb(val, KBD_DATA_REG)
+#define kbd_write_command(val) outb(val, KBD_CNTL_REG)
#define PTRACE_SYSEMU 31
#define PTRACE_SYSEMU_SINGLESTEP 32
+enum EFLAGS {
+ EF_CF = 0x00000001,
+ EF_PF = 0x00000004,
+ EF_AF = 0x00000010,
+ EF_ZF = 0x00000040,
+ EF_SF = 0x00000080,
+ EF_TF = 0x00000100,
+ EF_IE = 0x00000200,
+ EF_DF = 0x00000400,
+ EF_OF = 0x00000800,
+ EF_IOPL = 0x00003000,
+ EF_IOPL_RING0 = 0x00000000,
+ EF_IOPL_RING1 = 0x00001000,
+ EF_IOPL_RING2 = 0x00002000,
+ EF_NT = 0x00004000, /* nested task */
+ EF_RF = 0x00010000, /* resume */
+ EF_VM = 0x00020000, /* virtual mode */
+ EF_AC = 0x00040000, /* alignment */
+ EF_VIF = 0x00080000, /* virtual interrupt */
+ EF_VIP = 0x00100000, /* virtual interrupt pending */
+ EF_ID = 0x00200000, /* id */
+};
+
#ifdef __KERNEL__
#include <asm/vm86.h>
--- /dev/null
+/* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically
+ generated from "bfd-in.h", "init.c", "opncls.c", "libbfd.c",
+ "bfdio.c", "bfdwin.c", "section.c", "archures.c", "reloc.c",
+ "syms.c", "bfd.c", "archive.c", "corefile.c", "targets.c", "format.c",
+ "linker.c" and "simple.c".
+ Run "make headers" in your build bfd/ to regenerate. */
+
+/* Main header file for the bfd library -- portable access to object files.
+
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Support.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use.
+ * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as
+ * required.
+ * Keith Owens <kaos@sgi.com> 15 May 2006
+ */
+
+#ifndef __BFD_H_SEEN__
+#define __BFD_H_SEEN__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __KERNEL__
+#include <linux/ansidecl.h>
+#else /* __KERNEL__ */
+#include "ansidecl.h"
+#include "symcat.h"
+#endif /* __KERNEL__ */
+#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
+#ifndef SABER
+/* This hack is to avoid a problem with some strict ANSI C preprocessors.
+ The problem is, "32_" is not a valid preprocessing token, and we don't
+ want extra underscores (e.g., "nlm_32_"). The XCONCAT2 macro will
+ cause the inner CONCAT2 macros to be evaluated first, producing
+ still-valid pp-tokens. Then the final concatenation can be done. */
+#undef CONCAT4
+#define CONCAT4(a,b,c,d) XCONCAT2(CONCAT2(a,b),CONCAT2(c,d))
+#endif
+#endif
+
+/* The word size used by BFD on the host. This may be 64 with a 32
+ bit target if the host is 64 bit, or if other 64 bit targets have
+ been selected with --enable-targets, or if --enable-64-bit-bfd. */
+#define BFD_ARCH_SIZE 64
+
+/* The word size of the default bfd target. */
+#define BFD_DEFAULT_TARGET_SIZE 64
+
+#define BFD_HOST_64BIT_LONG 1
+#define BFD_HOST_LONG_LONG 1
+#if 1
+#define BFD_HOST_64_BIT long
+#define BFD_HOST_U_64_BIT unsigned long
+typedef BFD_HOST_64_BIT bfd_int64_t;
+typedef BFD_HOST_U_64_BIT bfd_uint64_t;
+#endif
+
+#if BFD_ARCH_SIZE >= 64
+#define BFD64
+#endif
+
+#ifndef INLINE
+#if __GNUC__ >= 2
+#define INLINE __inline__
+#else
+#define INLINE
+#endif
+#endif
+
+/* Forward declaration. */
+typedef struct bfd bfd;
+
+/* Boolean type used in bfd. Too many systems define their own
+ versions of "boolean" for us to safely typedef a "boolean" of
+ our own. Using an enum for "bfd_boolean" has its own set of
+ problems, with strange looking casts required to avoid warnings
+ on some older compilers. Thus we just use an int.
+
+ General rule: Functions which are bfd_boolean return TRUE on
+ success and FALSE on failure (unless they're a predicate). */
+
+typedef int bfd_boolean;
+#undef FALSE
+#undef TRUE
+#define FALSE 0
+#define TRUE 1
+
+#ifdef BFD64
+
+#ifndef BFD_HOST_64_BIT
+ #error No 64 bit integer type available
+#endif /* ! defined (BFD_HOST_64_BIT) */
+
+typedef BFD_HOST_U_64_BIT bfd_vma;
+typedef BFD_HOST_64_BIT bfd_signed_vma;
+typedef BFD_HOST_U_64_BIT bfd_size_type;
+typedef BFD_HOST_U_64_BIT symvalue;
+
+#ifndef fprintf_vma
+#if BFD_HOST_64BIT_LONG
+#define sprintf_vma(s,x) sprintf (s, "%016lx", x)
+#define fprintf_vma(f,x) fprintf (f, "%016lx", x)
+#else
+#define _bfd_int64_low(x) ((unsigned long) (((x) & 0xffffffff)))
+#define _bfd_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff))
+#define fprintf_vma(s,x) \
+ fprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x))
+#define sprintf_vma(s,x) \
+ sprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x))
+#endif
+#endif
+
+#else /* not BFD64 */
+
+/* Represent a target address. Also used as a generic unsigned type
+ which is guaranteed to be big enough to hold any arithmetic types
+ we need to deal with. */
+typedef unsigned long bfd_vma;
+
+/* A generic signed type which is guaranteed to be big enough to hold any
+ arithmetic types we need to deal with. Can be assumed to be compatible
+ with bfd_vma in the same way that signed and unsigned ints are compatible
+ (as parameters, in assignment, etc). */
+typedef long bfd_signed_vma;
+
+typedef unsigned long symvalue;
+typedef unsigned long bfd_size_type;
+
+/* Print a bfd_vma x on stream s. */
+#define fprintf_vma(s,x) fprintf (s, "%08lx", x)
+#define sprintf_vma(s,x) sprintf (s, "%08lx", x)
+
+#endif /* not BFD64 */
+
+#define HALF_BFD_SIZE_TYPE \
+ (((bfd_size_type) 1) << (8 * sizeof (bfd_size_type) / 2))
+
+#ifndef BFD_HOST_64_BIT
+/* Fall back on a 32 bit type. The idea is to make these types always
+ available for function return types, but in the case that
+ BFD_HOST_64_BIT is undefined such a function should abort or
+ otherwise signal an error. */
+typedef bfd_signed_vma bfd_int64_t;
+typedef bfd_vma bfd_uint64_t;
+#endif
+
+/* An offset into a file. BFD always uses the largest possible offset
+ based on the build time availability of fseek, fseeko, or fseeko64. */
+typedef BFD_HOST_64_BIT file_ptr;
+typedef unsigned BFD_HOST_64_BIT ufile_ptr;
+
+extern void bfd_sprintf_vma (bfd *, char *, bfd_vma);
+extern void bfd_fprintf_vma (bfd *, void *, bfd_vma);
+
+#define printf_vma(x) fprintf_vma(stdout,x)
+#define bfd_printf_vma(abfd,x) bfd_fprintf_vma (abfd,stdout,x)
+
+typedef unsigned int flagword; /* 32 bits of flags */
+typedef unsigned char bfd_byte;
+
+typedef int (*bfd_qsort_closure_func) (const void *, const void *, const void *);
+extern void bfd_qsort (void *base, bfd_size_type nmemb, bfd_size_type size,
+ bfd_qsort_closure_func cmp, void *closure);
+\f
+/* File formats. */
+
+typedef enum bfd_format
+{
+ bfd_unknown = 0, /* File format is unknown. */
+ bfd_object, /* Linker/assembler/compiler output. */
+ bfd_archive, /* Object archive file. */
+ bfd_core, /* Core dump. */
+ bfd_type_end /* Marks the end; don't use it! */
+}
+bfd_format;
+
+/* Values that may appear in the flags field of a BFD. These also
+ appear in the object_flags field of the bfd_target structure, where
+ they indicate the set of flags used by that backend (not all flags
+ are meaningful for all object file formats) (FIXME: at the moment,
+ the object_flags values have mostly just been copied from backend
+ to another, and are not necessarily correct). */
+
+/* No flags. */
+#define BFD_NO_FLAGS 0x00
+
+/* BFD contains relocation entries. */
+#define HAS_RELOC 0x01
+
+/* BFD is directly executable. */
+#define EXEC_P 0x02
+
+/* BFD has line number information (basically used for F_LNNO in a
+ COFF header). */
+#define HAS_LINENO 0x04
+
+/* BFD has debugging information. */
+#define HAS_DEBUG 0x08
+
+/* BFD has symbols. */
+#define HAS_SYMS 0x10
+
+/* BFD has local symbols (basically used for F_LSYMS in a COFF
+ header). */
+#define HAS_LOCALS 0x20
+
+/* BFD is a dynamic object. */
+#define DYNAMIC 0x40
+
+/* Text section is write protected (if D_PAGED is not set, this is
+ like an a.out NMAGIC file) (the linker sets this by default, but
+ clears it for -r or -N). */
+#define WP_TEXT 0x80
+
+/* BFD is dynamically paged (this is like an a.out ZMAGIC file) (the
+ linker sets this by default, but clears it for -r or -n or -N). */
+#define D_PAGED 0x100
+
+/* BFD is relaxable (this means that bfd_relax_section may be able to
+ do something) (sometimes bfd_relax_section can do something even if
+ this is not set). */
+#define BFD_IS_RELAXABLE 0x200
+
+/* This may be set before writing out a BFD to request using a
+ traditional format. For example, this is used to request that when
+ writing out an a.out object the symbols not be hashed to eliminate
+ duplicates. */
+#define BFD_TRADITIONAL_FORMAT 0x400
+
+/* This flag indicates that the BFD contents are actually cached in
+ memory. If this is set, iostream points to a bfd_in_memory struct. */
+#define BFD_IN_MEMORY 0x800
+
+/* The sections in this BFD specify a memory page. */
+#define HAS_LOAD_PAGE 0x1000
+
+/* This BFD has been created by the linker and doesn't correspond
+ to any input file. */
+#define BFD_LINKER_CREATED 0x2000
+\f
+/* Symbols and relocation. */
+
+/* A count of carsyms (canonical archive symbols). */
+typedef unsigned long symindex;
+
+/* How to perform a relocation. */
+typedef const struct reloc_howto_struct reloc_howto_type;
+
+#define BFD_NO_MORE_SYMBOLS ((symindex) ~0)
+
+/* General purpose part of a symbol X;
+ target specific parts are in libcoff.h, libaout.h, etc. */
+
+#define bfd_get_section(x) ((x)->section)
+#define bfd_get_output_section(x) ((x)->section->output_section)
+#define bfd_set_section(x,y) ((x)->section) = (y)
+#define bfd_asymbol_base(x) ((x)->section->vma)
+#define bfd_asymbol_value(x) (bfd_asymbol_base(x) + (x)->value)
+#define bfd_asymbol_name(x) ((x)->name)
+/*Perhaps future: #define bfd_asymbol_bfd(x) ((x)->section->owner)*/
+#define bfd_asymbol_bfd(x) ((x)->the_bfd)
+#define bfd_asymbol_flavour(x) (bfd_asymbol_bfd(x)->xvec->flavour)
+
+/* A canonical archive symbol. */
+/* This is a type pun with struct ranlib on purpose! */
+typedef struct carsym
+{
+ char *name;
+ file_ptr file_offset; /* Look here to find the file. */
+}
+carsym; /* To make these you call a carsymogen. */
+
+/* Used in generating armaps (archive tables of contents).
+ Perhaps just a forward definition would do? */
+struct orl /* Output ranlib. */
+{
+ char **name; /* Symbol name. */
+ union
+ {
+ file_ptr pos;
+ bfd *abfd;
+ } u; /* bfd* or file position. */
+ int namidx; /* Index into string table. */
+};
+\f
+/* Linenumber stuff. */
+typedef struct lineno_cache_entry
+{
+ unsigned int line_number; /* Linenumber from start of function. */
+ union
+ {
+ struct bfd_symbol *sym; /* Function name. */
+ bfd_vma offset; /* Offset into section. */
+ } u;
+}
+alent;
+\f
+/* Object and core file sections. */
+
+#define align_power(addr, align) \
+ (((addr) + ((bfd_vma) 1 << (align)) - 1) & ((bfd_vma) -1 << (align)))
+
+typedef struct bfd_section *sec_ptr;
+
+#define bfd_get_section_name(bfd, ptr) ((ptr)->name + 0)
+#define bfd_get_section_vma(bfd, ptr) ((ptr)->vma + 0)
+#define bfd_get_section_lma(bfd, ptr) ((ptr)->lma + 0)
+#define bfd_get_section_alignment(bfd, ptr) ((ptr)->alignment_power + 0)
+#define bfd_section_name(bfd, ptr) ((ptr)->name)
+#define bfd_section_size(bfd, ptr) ((ptr)->size)
+#define bfd_get_section_size(ptr) ((ptr)->size)
+#define bfd_section_vma(bfd, ptr) ((ptr)->vma)
+#define bfd_section_lma(bfd, ptr) ((ptr)->lma)
+#define bfd_section_alignment(bfd, ptr) ((ptr)->alignment_power)
+#define bfd_get_section_flags(bfd, ptr) ((ptr)->flags + 0)
+#define bfd_get_section_userdata(bfd, ptr) ((ptr)->userdata)
+
+#define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0)
+
+#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma = (val)), ((ptr)->user_set_vma = TRUE), TRUE)
+#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),TRUE)
+#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE)
+/* Find the address one past the end of SEC. */
+#define bfd_get_section_limit(bfd, sec) \
+ (((sec)->rawsize ? (sec)->rawsize : (sec)->size) \
+ / bfd_octets_per_byte (bfd))
+
+typedef struct stat stat_type;
+\f
+typedef enum bfd_print_symbol
+{
+ bfd_print_symbol_name,
+ bfd_print_symbol_more,
+ bfd_print_symbol_all
+} bfd_print_symbol_type;
+
+/* Information about a symbol that nm needs. */
+
+typedef struct _symbol_info
+{
+ symvalue value;
+ char type;
+ const char *name; /* Symbol name. */
+ unsigned char stab_type; /* Stab type. */
+ char stab_other; /* Stab other. */
+ short stab_desc; /* Stab desc. */
+ const char *stab_name; /* String for stab type. */
+} symbol_info;
+
+/* Get the name of a stabs type code. */
+
+extern const char *bfd_get_stab_name (int);
+\f
+/* Hash table routines. There is no way to free up a hash table. */
+
+/* An element in the hash table. Most uses will actually use a larger
+ structure, and an instance of this will be the first field. */
+
+struct bfd_hash_entry
+{
+ /* Next entry for this hash code. */
+ struct bfd_hash_entry *next;
+ /* String being hashed. */
+ const char *string;
+ /* Hash code. This is the full hash code, not the index into the
+ table. */
+ unsigned long hash;
+};
+
+/* A hash table. */
+
+struct bfd_hash_table
+{
+ /* The hash array. */
+ struct bfd_hash_entry **table;
+ /* The number of slots in the hash table. */
+ unsigned int size;
+ /* A function used to create new elements in the hash table. The
+ first entry is itself a pointer to an element. When this
+ function is first invoked, this pointer will be NULL. However,
+ having the pointer permits a hierarchy of method functions to be
+ built each of which calls the function in the superclass. Thus
+ each function should be written to allocate a new block of memory
+ only if the argument is NULL. */
+ struct bfd_hash_entry *(*newfunc)
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
+ /* An objalloc for this hash table. This is a struct objalloc *,
+ but we use void * to avoid requiring the inclusion of objalloc.h. */
+ void *memory;
+};
+
+/* Initialize a hash table. */
+extern bfd_boolean bfd_hash_table_init
+ (struct bfd_hash_table *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *));
+
+/* Initialize a hash table specifying a size. */
+extern bfd_boolean bfd_hash_table_init_n
+ (struct bfd_hash_table *,
+ struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
+ struct bfd_hash_table *,
+ const char *),
+ unsigned int size);
+
+/* Free up a hash table. */
+extern void bfd_hash_table_free
+ (struct bfd_hash_table *);
+
+/* Look up a string in a hash table. If CREATE is TRUE, a new entry
+ will be created for this string if one does not already exist. The
+ COPY argument must be TRUE if this routine should copy the string
+ into newly allocated memory when adding an entry. */
+extern struct bfd_hash_entry *bfd_hash_lookup
+ (struct bfd_hash_table *, const char *, bfd_boolean create,
+ bfd_boolean copy);
+
+/* Replace an entry in a hash table. */
+extern void bfd_hash_replace
+ (struct bfd_hash_table *, struct bfd_hash_entry *old,
+ struct bfd_hash_entry *nw);
+
+/* Base method for creating a hash table entry. */
+extern struct bfd_hash_entry *bfd_hash_newfunc
+ (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
+
+/* Grab some space for a hash table entry. */
+extern void *bfd_hash_allocate
+ (struct bfd_hash_table *, unsigned int);
+
+/* Traverse a hash table in a random order, calling a function on each
+ element. If the function returns FALSE, the traversal stops. The
+ INFO argument is passed to the function. */
+extern void bfd_hash_traverse
+ (struct bfd_hash_table *,
+ bfd_boolean (*) (struct bfd_hash_entry *, void *),
+ void *info);
+
+/* Allows the default size of a hash table to be configured. New hash
+ tables allocated using bfd_hash_table_init will be created with
+ this size. */
+extern void bfd_hash_set_default_size (bfd_size_type);
+
+/* This structure is used to keep track of stabs in sections
+ information while linking. */
+
+struct stab_info
+{
+ /* A hash table used to hold stabs strings. */
+ struct bfd_strtab_hash *strings;
+ /* The header file hash table. */
+ struct bfd_hash_table includes;
+ /* The first .stabstr section. */
+ struct bfd_section *stabstr;
+};
+
+#define COFF_SWAP_TABLE (void *) &bfd_coff_std_swap_table
+
+/* User program access to BFD facilities. */
+
+/* Direct I/O routines, for programs which know more about the object
+ file than BFD does. Use higher level routines if possible. */
+
+extern bfd_size_type bfd_bread (void *, bfd_size_type, bfd *);
+extern bfd_size_type bfd_bwrite (const void *, bfd_size_type, bfd *);
+extern int bfd_seek (bfd *, file_ptr, int);
+extern file_ptr bfd_tell (bfd *);
+extern int bfd_flush (bfd *);
+extern int bfd_stat (bfd *, struct stat *);
+
+/* Deprecated old routines. */
+#if __GNUC__
+#define bfd_read(BUF, ELTSIZE, NITEMS, ABFD) \
+ (warn_deprecated ("bfd_read", __FILE__, __LINE__, __FUNCTION__), \
+ bfd_bread ((BUF), (ELTSIZE) * (NITEMS), (ABFD)))
+#define bfd_write(BUF, ELTSIZE, NITEMS, ABFD) \
+ (warn_deprecated ("bfd_write", __FILE__, __LINE__, __FUNCTION__), \
+ bfd_bwrite ((BUF), (ELTSIZE) * (NITEMS), (ABFD)))
+#else
+#define bfd_read(BUF, ELTSIZE, NITEMS, ABFD) \
+ (warn_deprecated ("bfd_read", (const char *) 0, 0, (const char *) 0), \
+ bfd_bread ((BUF), (ELTSIZE) * (NITEMS), (ABFD)))
+#define bfd_write(BUF, ELTSIZE, NITEMS, ABFD) \
+ (warn_deprecated ("bfd_write", (const char *) 0, 0, (const char *) 0),\
+ bfd_bwrite ((BUF), (ELTSIZE) * (NITEMS), (ABFD)))
+#endif
+extern void warn_deprecated (const char *, const char *, int, const char *);
+
+/* Cast from const char * to char * so that caller can assign to
+ a char * without a warning. */
+#define bfd_get_filename(abfd) ((char *) (abfd)->filename)
+#define bfd_get_cacheable(abfd) ((abfd)->cacheable)
+#define bfd_get_format(abfd) ((abfd)->format)
+#define bfd_get_target(abfd) ((abfd)->xvec->name)
+#define bfd_get_flavour(abfd) ((abfd)->xvec->flavour)
+#define bfd_family_coff(abfd) \
+ (bfd_get_flavour (abfd) == bfd_target_coff_flavour || \
+ bfd_get_flavour (abfd) == bfd_target_xcoff_flavour)
+#define bfd_big_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_BIG)
+#define bfd_little_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_LITTLE)
+#define bfd_header_big_endian(abfd) \
+ ((abfd)->xvec->header_byteorder == BFD_ENDIAN_BIG)
+#define bfd_header_little_endian(abfd) \
+ ((abfd)->xvec->header_byteorder == BFD_ENDIAN_LITTLE)
+#define bfd_get_file_flags(abfd) ((abfd)->flags)
+#define bfd_applicable_file_flags(abfd) ((abfd)->xvec->object_flags)
+#define bfd_applicable_section_flags(abfd) ((abfd)->xvec->section_flags)
+#define bfd_my_archive(abfd) ((abfd)->my_archive)
+#define bfd_has_map(abfd) ((abfd)->has_armap)
+
+#define bfd_valid_reloc_types(abfd) ((abfd)->xvec->valid_reloc_types)
+#define bfd_usrdata(abfd) ((abfd)->usrdata)
+
+#define bfd_get_start_address(abfd) ((abfd)->start_address)
+#define bfd_get_symcount(abfd) ((abfd)->symcount)
+#define bfd_get_outsymbols(abfd) ((abfd)->outsymbols)
+#define bfd_count_sections(abfd) ((abfd)->section_count)
+
+#define bfd_get_dynamic_symcount(abfd) ((abfd)->dynsymcount)
+
+#define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char)
+
+#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE)
+
+extern bfd_boolean bfd_cache_close
+ (bfd *abfd);
+/* NB: This declaration should match the autogenerated one in libbfd.h. */
+
+extern bfd_boolean bfd_cache_close_all (void);
+
+extern bfd_boolean bfd_record_phdr
+ (bfd *, unsigned long, bfd_boolean, flagword, bfd_boolean, bfd_vma,
+ bfd_boolean, bfd_boolean, unsigned int, struct bfd_section **);
+
+/* Byte swapping routines. */
+
+bfd_uint64_t bfd_getb64 (const void *);
+bfd_uint64_t bfd_getl64 (const void *);
+bfd_int64_t bfd_getb_signed_64 (const void *);
+bfd_int64_t bfd_getl_signed_64 (const void *);
+bfd_vma bfd_getb32 (const void *);
+bfd_vma bfd_getl32 (const void *);
+bfd_signed_vma bfd_getb_signed_32 (const void *);
+bfd_signed_vma bfd_getl_signed_32 (const void *);
+bfd_vma bfd_getb16 (const void *);
+bfd_vma bfd_getl16 (const void *);
+bfd_signed_vma bfd_getb_signed_16 (const void *);
+bfd_signed_vma bfd_getl_signed_16 (const void *);
+void bfd_putb64 (bfd_uint64_t, void *);
+void bfd_putl64 (bfd_uint64_t, void *);
+void bfd_putb32 (bfd_vma, void *);
+void bfd_putl32 (bfd_vma, void *);
+void bfd_putb16 (bfd_vma, void *);
+void bfd_putl16 (bfd_vma, void *);
+
+/* Byte swapping routines which take size and endiannes as arguments. */
+
+bfd_uint64_t bfd_get_bits (const void *, int, bfd_boolean);
+void bfd_put_bits (bfd_uint64_t, void *, int, bfd_boolean);
+
+extern bfd_boolean bfd_section_already_linked_table_init (void);
+extern void bfd_section_already_linked_table_free (void);
+\f
+/* Externally visible ECOFF routines. */
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
+struct ecoff_debug_info;
+struct ecoff_debug_swap;
+struct ecoff_extr;
+struct bfd_symbol;
+struct bfd_link_info;
+struct bfd_link_hash_entry;
+struct bfd_elf_version_tree;
+#endif
+extern bfd_vma bfd_ecoff_get_gp_value
+ (bfd * abfd);
+extern bfd_boolean bfd_ecoff_set_gp_value
+ (bfd *abfd, bfd_vma gp_value);
+extern bfd_boolean bfd_ecoff_set_regmasks
+ (bfd *abfd, unsigned long gprmask, unsigned long fprmask,
+ unsigned long *cprmask);
+extern void *bfd_ecoff_debug_init
+ (bfd *output_bfd, struct ecoff_debug_info *output_debug,
+ const struct ecoff_debug_swap *output_swap, struct bfd_link_info *);
+extern void bfd_ecoff_debug_free
+ (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug,
+ const struct ecoff_debug_swap *output_swap, struct bfd_link_info *);
+extern bfd_boolean bfd_ecoff_debug_accumulate
+ (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug,
+ const struct ecoff_debug_swap *output_swap, bfd *input_bfd,
+ struct ecoff_debug_info *input_debug,
+ const struct ecoff_debug_swap *input_swap, struct bfd_link_info *);
+extern bfd_boolean bfd_ecoff_debug_accumulate_other
+ (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug,
+ const struct ecoff_debug_swap *output_swap, bfd *input_bfd,
+ struct bfd_link_info *);
+extern bfd_boolean bfd_ecoff_debug_externals
+ (bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap, bfd_boolean relocatable,
+ bfd_boolean (*get_extr) (struct bfd_symbol *, struct ecoff_extr *),
+ void (*set_index) (struct bfd_symbol *, bfd_size_type));
+extern bfd_boolean bfd_ecoff_debug_one_external
+ (bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap, const char *name,
+ struct ecoff_extr *esym);
+extern bfd_size_type bfd_ecoff_debug_size
+ (bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap);
+extern bfd_boolean bfd_ecoff_write_debug
+ (bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap, file_ptr where);
+extern bfd_boolean bfd_ecoff_write_accumulated_debug
+ (void *handle, bfd *abfd, struct ecoff_debug_info *debug,
+ const struct ecoff_debug_swap *swap,
+ struct bfd_link_info *info, file_ptr where);
+
+/* Externally visible ELF routines. */
+
+struct bfd_link_needed_list
+{
+ struct bfd_link_needed_list *next;
+ bfd *by;
+ const char *name;
+};
+
+enum dynamic_lib_link_class {
+ DYN_NORMAL = 0,
+ DYN_AS_NEEDED = 1,
+ DYN_DT_NEEDED = 2,
+ DYN_NO_ADD_NEEDED = 4,
+ DYN_NO_NEEDED = 8
+};
+
+extern bfd_boolean bfd_elf_record_link_assignment
+ (bfd *, struct bfd_link_info *, const char *, bfd_boolean,
+ bfd_boolean);
+extern struct bfd_link_needed_list *bfd_elf_get_needed_list
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean bfd_elf_get_bfd_needed_list
+ (bfd *, struct bfd_link_needed_list **);
+extern bfd_boolean bfd_elf_size_dynamic_sections
+ (bfd *, const char *, const char *, const char *, const char * const *,
+ struct bfd_link_info *, struct bfd_section **,
+ struct bfd_elf_version_tree *);
+extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr
+ (bfd *, struct bfd_link_info *);
+extern void bfd_elf_set_dt_needed_name
+ (bfd *, const char *);
+extern const char *bfd_elf_get_dt_soname
+ (bfd *);
+extern void bfd_elf_set_dyn_lib_class
+ (bfd *, int);
+extern int bfd_elf_get_dyn_lib_class
+ (bfd *);
+extern struct bfd_link_needed_list *bfd_elf_get_runpath_list
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean bfd_elf_discard_info
+ (bfd *, struct bfd_link_info *);
+extern unsigned int _bfd_elf_default_action_discarded
+ (struct bfd_section *);
+
+/* Return an upper bound on the number of bytes required to store a
+ copy of ABFD's program header table entries. Return -1 if an error
+ occurs; bfd_get_error will return an appropriate code. */
+extern long bfd_get_elf_phdr_upper_bound
+ (bfd *abfd);
+
+/* Copy ABFD's program header table entries to *PHDRS. The entries
+ will be stored as an array of Elf_Internal_Phdr structures, as
+ defined in include/elf/internal.h. To find out how large the
+ buffer needs to be, call bfd_get_elf_phdr_upper_bound.
+
+ Return the number of program header table entries read, or -1 if an
+ error occurs; bfd_get_error will return an appropriate code. */
+extern int bfd_get_elf_phdrs
+ (bfd *abfd, void *phdrs);
+
+/* Create a new BFD as if by bfd_openr. Rather than opening a file,
+ reconstruct an ELF file by reading the segments out of remote memory
+ based on the ELF file header at EHDR_VMA and the ELF program headers it
+ points to. If not null, *LOADBASEP is filled in with the difference
+ between the VMAs from which the segments were read, and the VMAs the
+ file headers (and hence BFD's idea of each section's VMA) put them at.
+
+ The function TARGET_READ_MEMORY is called to copy LEN bytes from the
+ remote memory at target address VMA into the local buffer at MYADDR; it
+ should return zero on success or an `errno' code on failure. TEMPL must
+ be a BFD for an ELF target with the word size and byte order found in
+ the remote memory. */
+extern bfd *bfd_elf_bfd_from_remote_memory
+ (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
+ int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr, int len));
+
+/* Return the arch_size field of an elf bfd, or -1 if not elf. */
+extern int bfd_get_arch_size
+ (bfd *);
+
+/* Return TRUE if address "naturally" sign extends, or -1 if not elf. */
+extern int bfd_get_sign_extend_vma
+ (bfd *);
+
+extern struct bfd_section *_bfd_elf_tls_setup
+ (bfd *, struct bfd_link_info *);
+
+extern void _bfd_fix_excluded_sec_syms
+ (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean bfd_m68k_elf32_create_embedded_relocs
+ (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *,
+ char **);
+
+extern bfd_boolean bfd_bfin_elf32_create_embedded_relocs
+ (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *,
+ char **);
+
+/* SunOS shared library support routines for the linker. */
+
+extern struct bfd_link_needed_list *bfd_sunos_get_needed_list
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean bfd_sunos_record_link_assignment
+ (bfd *, struct bfd_link_info *, const char *);
+extern bfd_boolean bfd_sunos_size_dynamic_sections
+ (bfd *, struct bfd_link_info *, struct bfd_section **,
+ struct bfd_section **, struct bfd_section **);
+
+/* Linux shared library support routines for the linker. */
+
+extern bfd_boolean bfd_i386linux_size_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean bfd_m68klinux_size_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+extern bfd_boolean bfd_sparclinux_size_dynamic_sections
+ (bfd *, struct bfd_link_info *);
+
+/* mmap hacks */
+
+struct _bfd_window_internal;
+typedef struct _bfd_window_internal bfd_window_internal;
+
+typedef struct _bfd_window
+{
+ /* What the user asked for. */
+ void *data;
+ bfd_size_type size;
+ /* The actual window used by BFD. Small user-requested read-only
+ regions sharing a page may share a single window into the object
+ file. Read-write versions shouldn't until I've fixed things to
+ keep track of which portions have been claimed by the
+ application; don't want to give the same region back when the
+ application wants two writable copies! */
+ struct _bfd_window_internal *i;
+}
+bfd_window;
+
+extern void bfd_init_window
+ (bfd_window *);
+extern void bfd_free_window
+ (bfd_window *);
+extern bfd_boolean bfd_get_file_window
+ (bfd *, file_ptr, bfd_size_type, bfd_window *, bfd_boolean);
+
+/* XCOFF support routines for the linker. */
+
+extern bfd_boolean bfd_xcoff_link_record_set
+ (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, bfd_size_type);
+extern bfd_boolean bfd_xcoff_import_symbol
+ (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, bfd_vma,
+ const char *, const char *, const char *, unsigned int);
+extern bfd_boolean bfd_xcoff_export_symbol
+ (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *);
+extern bfd_boolean bfd_xcoff_link_count_reloc
+ (bfd *, struct bfd_link_info *, const char *);
+extern bfd_boolean bfd_xcoff_record_link_assignment
+ (bfd *, struct bfd_link_info *, const char *);
+extern bfd_boolean bfd_xcoff_size_dynamic_sections
+ (bfd *, struct bfd_link_info *, const char *, const char *,
+ unsigned long, unsigned long, unsigned long, bfd_boolean,
+ int, bfd_boolean, bfd_boolean, struct bfd_section **, bfd_boolean);
+extern bfd_boolean bfd_xcoff_link_generate_rtinit
+ (bfd *, const char *, const char *, bfd_boolean);
+
+/* XCOFF support routines for ar. */
+extern bfd_boolean bfd_xcoff_ar_archive_set_magic
+ (bfd *, char *);
+
+/* Externally visible COFF routines. */
+
+#if defined(__STDC__) || defined(ALMOST_STDC)
+struct internal_syment;
+union internal_auxent;
+#endif
+
+extern bfd_boolean bfd_coff_get_syment
+ (bfd *, struct bfd_symbol *, struct internal_syment *);
+
+extern bfd_boolean bfd_coff_get_auxent
+ (bfd *, struct bfd_symbol *, int, union internal_auxent *);
+
+extern bfd_boolean bfd_coff_set_symbol_class
+ (bfd *, struct bfd_symbol *, unsigned int);
+
+extern bfd_boolean bfd_m68k_coff_create_embedded_relocs
+ (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, char **);
+
+/* ARM Interworking support. Called from linker. */
+extern bfd_boolean bfd_arm_allocate_interworking_sections
+ (struct bfd_link_info *);
+
+extern bfd_boolean bfd_arm_process_before_allocation
+ (bfd *, struct bfd_link_info *, int);
+
+extern bfd_boolean bfd_arm_get_bfd_for_interworking
+ (bfd *, struct bfd_link_info *);
+
+/* PE ARM Interworking support. Called from linker. */
+extern bfd_boolean bfd_arm_pe_allocate_interworking_sections
+ (struct bfd_link_info *);
+
+extern bfd_boolean bfd_arm_pe_process_before_allocation
+ (bfd *, struct bfd_link_info *, int);
+
+extern bfd_boolean bfd_arm_pe_get_bfd_for_interworking
+ (bfd *, struct bfd_link_info *);
+
+/* ELF ARM Interworking support. Called from linker. */
+extern bfd_boolean bfd_elf32_arm_allocate_interworking_sections
+ (struct bfd_link_info *);
+
+extern bfd_boolean bfd_elf32_arm_process_before_allocation
+ (bfd *, struct bfd_link_info *, int);
+
+void bfd_elf32_arm_set_target_relocs
+ (struct bfd_link_info *, int, char *, int, int);
+
+extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
+ (bfd *, struct bfd_link_info *);
+
+extern bfd_boolean bfd_elf32_arm_add_glue_sections_to_bfd
+ (bfd *, struct bfd_link_info *);
+
+/* ELF ARM mapping symbol support */
+extern bfd_boolean bfd_is_arm_mapping_symbol_name
+ (const char * name);
+
+/* ARM Note section processing. */
+extern bfd_boolean bfd_arm_merge_machines
+ (bfd *, bfd *);
+
+extern bfd_boolean bfd_arm_update_notes
+ (bfd *, const char *);
+
+extern unsigned int bfd_arm_get_mach_from_notes
+ (bfd *, const char *);
+
+/* TI COFF load page support. */
+extern void bfd_ticoff_set_section_load_page
+ (struct bfd_section *, int);
+
+extern int bfd_ticoff_get_section_load_page
+ (struct bfd_section *);
+
+/* H8/300 functions. */
+extern bfd_vma bfd_h8300_pad_address
+ (bfd *, bfd_vma);
+
+/* IA64 Itanium code generation. Called from linker. */
+extern void bfd_elf32_ia64_after_parse
+ (int);
+
+extern void bfd_elf64_ia64_after_parse
+ (int);
+
+/* This structure is used for a comdat section, as in PE. A comdat
+ section is associated with a particular symbol. When the linker
+ sees a comdat section, it keeps only one of the sections with a
+ given name and associated with a given symbol. */
+
+struct coff_comdat_info
+{
+ /* The name of the symbol associated with a comdat section. */
+ const char *name;
+
+ /* The local symbol table index of the symbol associated with a
+ comdat section. This is only meaningful to the object file format
+ specific code; it is not an index into the list returned by
+ bfd_canonicalize_symtab. */
+ long symbol;
+};
+
+extern struct coff_comdat_info *bfd_coff_get_comdat_section
+ (bfd *, struct bfd_section *);
+
+/* Extracted from init.c. */
+void bfd_init (void);
+
+/* Extracted from opncls.c. */
+bfd *bfd_fopen (const char *filename, const char *target,
+ const char *mode, int fd);
+
+bfd *bfd_openr (const char *filename, const char *target);
+
+bfd *bfd_fdopenr (const char *filename, const char *target, int fd);
+
+bfd *bfd_openstreamr (const char *, const char *, void *);
+
+bfd *bfd_openr_iovec (const char *filename, const char *target,
+ void *(*open) (struct bfd *nbfd,
+ void *open_closure),
+ void *open_closure,
+ file_ptr (*pread) (struct bfd *nbfd,
+ void *stream,
+ void *buf,
+ file_ptr nbytes,
+ file_ptr offset),
+ int (*close) (struct bfd *nbfd,
+ void *stream));
+
+bfd *bfd_openw (const char *filename, const char *target);
+
+bfd_boolean bfd_close (bfd *abfd);
+
+bfd_boolean bfd_close_all_done (bfd *);
+
+bfd *bfd_create (const char *filename, bfd *templ);
+
+bfd_boolean bfd_make_writable (bfd *abfd);
+
+bfd_boolean bfd_make_readable (bfd *abfd);
+
+unsigned long bfd_calc_gnu_debuglink_crc32
+ (unsigned long crc, const unsigned char *buf, bfd_size_type len);
+
+char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir);
+
+struct bfd_section *bfd_create_gnu_debuglink_section
+ (bfd *abfd, const char *filename);
+
+bfd_boolean bfd_fill_in_gnu_debuglink_section
+ (bfd *abfd, struct bfd_section *sect, const char *filename);
+
+/* Extracted from libbfd.c. */
+
+/* Byte swapping macros for user section data. */
+
+#define bfd_put_8(abfd, val, ptr) \
+ ((void) (*((unsigned char *) (ptr)) = (val) & 0xff))
+#define bfd_put_signed_8 \
+ bfd_put_8
+#define bfd_get_8(abfd, ptr) \
+ (*(unsigned char *) (ptr) & 0xff)
+#define bfd_get_signed_8(abfd, ptr) \
+ (((*(unsigned char *) (ptr) & 0xff) ^ 0x80) - 0x80)
+
+#define bfd_put_16(abfd, val, ptr) \
+ BFD_SEND (abfd, bfd_putx16, ((val),(ptr)))
+#define bfd_put_signed_16 \
+ bfd_put_16
+#define bfd_get_16(abfd, ptr) \
+ BFD_SEND (abfd, bfd_getx16, (ptr))
+#define bfd_get_signed_16(abfd, ptr) \
+ BFD_SEND (abfd, bfd_getx_signed_16, (ptr))
+
+#define bfd_put_32(abfd, val, ptr) \
+ BFD_SEND (abfd, bfd_putx32, ((val),(ptr)))
+#define bfd_put_signed_32 \
+ bfd_put_32
+#define bfd_get_32(abfd, ptr) \
+ BFD_SEND (abfd, bfd_getx32, (ptr))
+#define bfd_get_signed_32(abfd, ptr) \
+ BFD_SEND (abfd, bfd_getx_signed_32, (ptr))
+
+#define bfd_put_64(abfd, val, ptr) \
+ BFD_SEND (abfd, bfd_putx64, ((val), (ptr)))
+#define bfd_put_signed_64 \
+ bfd_put_64
+#define bfd_get_64(abfd, ptr) \
+ BFD_SEND (abfd, bfd_getx64, (ptr))
+#define bfd_get_signed_64(abfd, ptr) \
+ BFD_SEND (abfd, bfd_getx_signed_64, (ptr))
+
+#define bfd_get(bits, abfd, ptr) \
+ ((bits) == 8 ? (bfd_vma) bfd_get_8 (abfd, ptr) \
+ : (bits) == 16 ? bfd_get_16 (abfd, ptr) \
+ : (bits) == 32 ? bfd_get_32 (abfd, ptr) \
+ : (bits) == 64 ? bfd_get_64 (abfd, ptr) \
+ : (abort (), (bfd_vma) - 1))
+
+#define bfd_put(bits, abfd, val, ptr) \
+ ((bits) == 8 ? bfd_put_8 (abfd, val, ptr) \
+ : (bits) == 16 ? bfd_put_16 (abfd, val, ptr) \
+ : (bits) == 32 ? bfd_put_32 (abfd, val, ptr) \
+ : (bits) == 64 ? bfd_put_64 (abfd, val, ptr) \
+ : (abort (), (void) 0))
+
+
+/* Byte swapping macros for file header data. */
+
+#define bfd_h_put_8(abfd, val, ptr) \
+ bfd_put_8 (abfd, val, ptr)
+#define bfd_h_put_signed_8(abfd, val, ptr) \
+ bfd_put_8 (abfd, val, ptr)
+#define bfd_h_get_8(abfd, ptr) \
+ bfd_get_8 (abfd, ptr)
+#define bfd_h_get_signed_8(abfd, ptr) \
+ bfd_get_signed_8 (abfd, ptr)
+
+#define bfd_h_put_16(abfd, val, ptr) \
+ BFD_SEND (abfd, bfd_h_putx16, (val, ptr))
+#define bfd_h_put_signed_16 \
+ bfd_h_put_16
+#define bfd_h_get_16(abfd, ptr) \
+ BFD_SEND (abfd, bfd_h_getx16, (ptr))
+#define bfd_h_get_signed_16(abfd, ptr) \
+ BFD_SEND (abfd, bfd_h_getx_signed_16, (ptr))
+
+#define bfd_h_put_32(abfd, val, ptr) \
+ BFD_SEND (abfd, bfd_h_putx32, (val, ptr))
+#define bfd_h_put_signed_32 \
+ bfd_h_put_32
+#define bfd_h_get_32(abfd, ptr) \
+ BFD_SEND (abfd, bfd_h_getx32, (ptr))
+#define bfd_h_get_signed_32(abfd, ptr) \
+ BFD_SEND (abfd, bfd_h_getx_signed_32, (ptr))
+
+#define bfd_h_put_64(abfd, val, ptr) \
+ BFD_SEND (abfd, bfd_h_putx64, (val, ptr))
+#define bfd_h_put_signed_64 \
+ bfd_h_put_64
+#define bfd_h_get_64(abfd, ptr) \
+ BFD_SEND (abfd, bfd_h_getx64, (ptr))
+#define bfd_h_get_signed_64(abfd, ptr) \
+ BFD_SEND (abfd, bfd_h_getx_signed_64, (ptr))
+
+/* Aliases for the above, which should eventually go away. */
+
+#define H_PUT_64 bfd_h_put_64
+#define H_PUT_32 bfd_h_put_32
+#define H_PUT_16 bfd_h_put_16
+#define H_PUT_8 bfd_h_put_8
+#define H_PUT_S64 bfd_h_put_signed_64
+#define H_PUT_S32 bfd_h_put_signed_32
+#define H_PUT_S16 bfd_h_put_signed_16
+#define H_PUT_S8 bfd_h_put_signed_8
+#define H_GET_64 bfd_h_get_64
+#define H_GET_32 bfd_h_get_32
+#define H_GET_16 bfd_h_get_16
+#define H_GET_8 bfd_h_get_8
+#define H_GET_S64 bfd_h_get_signed_64
+#define H_GET_S32 bfd_h_get_signed_32
+#define H_GET_S16 bfd_h_get_signed_16
+#define H_GET_S8 bfd_h_get_signed_8
+
+
+/* Extracted from bfdio.c. */
+long bfd_get_mtime (bfd *abfd);
+
+long bfd_get_size (bfd *abfd);
+
+/* Extracted from bfdwin.c. */
+/* Extracted from section.c. */
+typedef struct bfd_section
+{
+ /* The name of the section; the name isn't a copy, the pointer is
+ the same as that passed to bfd_make_section. */
+ const char *name;
+
+ /* A unique sequence number. */
+ int id;
+
+ /* Which section in the bfd; 0..n-1 as sections are created in a bfd. */
+ int index;
+
+ /* The next section in the list belonging to the BFD, or NULL. */
+ struct bfd_section *next;
+
+ /* The previous section in the list belonging to the BFD, or NULL. */
+ struct bfd_section *prev;
+
+ /* The field flags contains attributes of the section. Some
+ flags are read in from the object file, and some are
+ synthesized from other information. */
+ flagword flags;
+
+#define SEC_NO_FLAGS 0x000
+
+ /* Tells the OS to allocate space for this section when loading.
+ This is clear for a section containing debug information only. */
+#define SEC_ALLOC 0x001
+
+ /* Tells the OS to load the section from the file when loading.
+ This is clear for a .bss section. */
+#define SEC_LOAD 0x002
+
+ /* The section contains data still to be relocated, so there is
+ some relocation information too. */
+#define SEC_RELOC 0x004
+
+ /* A signal to the OS that the section contains read only data. */
+#define SEC_READONLY 0x008
+
+ /* The section contains code only. */
+#define SEC_CODE 0x010
+
+ /* The section contains data only. */
+#define SEC_DATA 0x020
+
+ /* The section will reside in ROM. */
+#define SEC_ROM 0x040
+
+ /* The section contains constructor information. This section
+ type is used by the linker to create lists of constructors and
+ destructors used by <<g++>>. When a back end sees a symbol
+ which should be used in a constructor list, it creates a new
+ section for the type of name (e.g., <<__CTOR_LIST__>>), attaches
+ the symbol to it, and builds a relocation. To build the lists
+ of constructors, all the linker has to do is catenate all the
+ sections called <<__CTOR_LIST__>> and relocate the data
+ contained within - exactly the operations it would peform on
+ standard data. */
+#define SEC_CONSTRUCTOR 0x080
+
+ /* The section has contents - a data section could be
+ <<SEC_ALLOC>> | <<SEC_HAS_CONTENTS>>; a debug section could be
+ <<SEC_HAS_CONTENTS>> */
+#define SEC_HAS_CONTENTS 0x100
+
+ /* An instruction to the linker to not output the section
+ even if it has information which would normally be written. */
+#define SEC_NEVER_LOAD 0x200
+
+ /* The section contains thread local data. */
+#define SEC_THREAD_LOCAL 0x400
+
+ /* The section has GOT references. This flag is only for the
+ linker, and is currently only used by the elf32-hppa back end.
+ It will be set if global offset table references were detected
+ in this section, which indicate to the linker that the section
+ contains PIC code, and must be handled specially when doing a
+ static link. */
+#define SEC_HAS_GOT_REF 0x800
+
+ /* The section contains common symbols (symbols may be defined
+ multiple times, the value of a symbol is the amount of
+ space it requires, and the largest symbol value is the one
+ used). Most targets have exactly one of these (which we
+ translate to bfd_com_section_ptr), but ECOFF has two. */
+#define SEC_IS_COMMON 0x1000
+
+ /* The section contains only debugging information. For
+ example, this is set for ELF .debug and .stab sections.
+ strip tests this flag to see if a section can be
+ discarded. */
+#define SEC_DEBUGGING 0x2000
+
+ /* The contents of this section are held in memory pointed to
+ by the contents field. This is checked by bfd_get_section_contents,
+ and the data is retrieved from memory if appropriate. */
+#define SEC_IN_MEMORY 0x4000
+
+ /* The contents of this section are to be excluded by the
+ linker for executable and shared objects unless those
+ objects are to be further relocated. */
+#define SEC_EXCLUDE 0x8000
+
+ /* The contents of this section are to be sorted based on the sum of
+ the symbol and addend values specified by the associated relocation
+ entries. Entries without associated relocation entries will be
+ appended to the end of the section in an unspecified order. */
+#define SEC_SORT_ENTRIES 0x10000
+
+ /* When linking, duplicate sections of the same name should be
+ discarded, rather than being combined into a single section as
+ is usually done. This is similar to how common symbols are
+ handled. See SEC_LINK_DUPLICATES below. */
+#define SEC_LINK_ONCE 0x20000
+
+ /* If SEC_LINK_ONCE is set, this bitfield describes how the linker
+ should handle duplicate sections. */
+#define SEC_LINK_DUPLICATES 0x40000
+
+ /* This value for SEC_LINK_DUPLICATES means that duplicate
+ sections with the same name should simply be discarded. */
+#define SEC_LINK_DUPLICATES_DISCARD 0x0
+
+ /* This value for SEC_LINK_DUPLICATES means that the linker
+ should warn if there are any duplicate sections, although
+ it should still only link one copy. */
+#define SEC_LINK_DUPLICATES_ONE_ONLY 0x80000
+
+ /* This value for SEC_LINK_DUPLICATES means that the linker
+ should warn if any duplicate sections are a different size. */
+#define SEC_LINK_DUPLICATES_SAME_SIZE 0x100000
+
+ /* This value for SEC_LINK_DUPLICATES means that the linker
+ should warn if any duplicate sections contain different
+ contents. */
+#define SEC_LINK_DUPLICATES_SAME_CONTENTS \
+ (SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE)
+
+ /* This section was created by the linker as part of dynamic
+ relocation or other arcane processing. It is skipped when
+ going through the first-pass output, trusting that someone
+ else up the line will take care of it later. */
+#define SEC_LINKER_CREATED 0x200000
+
+ /* This section should not be subject to garbage collection. */
+#define SEC_KEEP 0x400000
+
+ /* This section contains "short" data, and should be placed
+ "near" the GP. */
+#define SEC_SMALL_DATA 0x800000
+
+ /* Attempt to merge identical entities in the section.
+ Entity size is given in the entsize field. */
+#define SEC_MERGE 0x1000000
+
+ /* If given with SEC_MERGE, entities to merge are zero terminated
+ strings where entsize specifies character size instead of fixed
+ size entries. */
+#define SEC_STRINGS 0x2000000
+
+ /* This section contains data about section groups. */
+#define SEC_GROUP 0x4000000
+
+ /* The section is a COFF shared library section. This flag is
+ only for the linker. If this type of section appears in
+ the input file, the linker must copy it to the output file
+ without changing the vma or size. FIXME: Although this
+ was originally intended to be general, it really is COFF
+ specific (and the flag was renamed to indicate this). It
+ might be cleaner to have some more general mechanism to
+ allow the back end to control what the linker does with
+ sections. */
+#define SEC_COFF_SHARED_LIBRARY 0x10000000
+
+ /* This section contains data which may be shared with other
+ executables or shared objects. This is for COFF only. */
+#define SEC_COFF_SHARED 0x20000000
+
+ /* When a section with this flag is being linked, then if the size of
+ the input section is less than a page, it should not cross a page
+ boundary. If the size of the input section is one page or more,
+ it should be aligned on a page boundary. This is for TI
+ TMS320C54X only. */
+#define SEC_TIC54X_BLOCK 0x40000000
+
+ /* Conditionally link this section; do not link if there are no
+ references found to any symbol in the section. This is for TI
+ TMS320C54X only. */
+#define SEC_TIC54X_CLINK 0x80000000
+
+ /* End of section flags. */
+
+ /* Some internal packed boolean fields. */
+
+ /* See the vma field. */
+ unsigned int user_set_vma : 1;
+
+ /* A mark flag used by some of the linker backends. */
+ unsigned int linker_mark : 1;
+
+ /* Another mark flag used by some of the linker backends. Set for
+ output sections that have an input section. */
+ unsigned int linker_has_input : 1;
+
+ /* Mark flags used by some linker backends for garbage collection. */
+ unsigned int gc_mark : 1;
+ unsigned int gc_mark_from_eh : 1;
+
+ /* The following flags are used by the ELF linker. */
+
+ /* Mark sections which have been allocated to segments. */
+ unsigned int segment_mark : 1;
+
+ /* Type of sec_info information. */
+ unsigned int sec_info_type:3;
+#define ELF_INFO_TYPE_NONE 0
+#define ELF_INFO_TYPE_STABS 1
+#define ELF_INFO_TYPE_MERGE 2
+#define ELF_INFO_TYPE_EH_FRAME 3
+#define ELF_INFO_TYPE_JUST_SYMS 4
+
+ /* Nonzero if this section uses RELA relocations, rather than REL. */
+ unsigned int use_rela_p:1;
+
+ /* Bits used by various backends. The generic code doesn't touch
+ these fields. */
+
+ /* Nonzero if this section has TLS related relocations. */
+ unsigned int has_tls_reloc:1;
+
+ /* Nonzero if this section has a gp reloc. */
+ unsigned int has_gp_reloc:1;
+
+ /* Nonzero if this section needs the relax finalize pass. */
+ unsigned int need_finalize_relax:1;
+
+ /* Whether relocations have been processed. */
+ unsigned int reloc_done : 1;
+
+ /* End of internal packed boolean fields. */
+
+ /* The virtual memory address of the section - where it will be
+ at run time. The symbols are relocated against this. The
+ user_set_vma flag is maintained by bfd; if it's not set, the
+ backend can assign addresses (for example, in <<a.out>>, where
+ the default address for <<.data>> is dependent on the specific
+ target and various flags). */
+ bfd_vma vma;
+
+ /* The load address of the section - where it would be in a
+ rom image; really only used for writing section header
+ information. */
+ bfd_vma lma;
+
+ /* The size of the section in octets, as it will be output.
+ Contains a value even if the section has no contents (e.g., the
+ size of <<.bss>>). */
+ bfd_size_type size;
+
+ /* For input sections, the original size on disk of the section, in
+ octets. This field is used by the linker relaxation code. It is
+ currently only set for sections where the linker relaxation scheme
+ doesn't cache altered section and reloc contents (stabs, eh_frame,
+ SEC_MERGE, some coff relaxing targets), and thus the original size
+ needs to be kept to read the section multiple times.
+ For output sections, rawsize holds the section size calculated on
+ a previous linker relaxation pass. */
+ bfd_size_type rawsize;
+
+ /* If this section is going to be output, then this value is the
+ offset in *bytes* into the output section of the first byte in the
+ input section (byte ==> smallest addressable unit on the
+ target). In most cases, if this was going to start at the
+ 100th octet (8-bit quantity) in the output section, this value
+ would be 100. However, if the target byte size is 16 bits
+ (bfd_octets_per_byte is "2"), this value would be 50. */
+ bfd_vma output_offset;
+
+ /* The output section through which to map on output. */
+ struct bfd_section *output_section;
+
+ /* The alignment requirement of the section, as an exponent of 2 -
+ e.g., 3 aligns to 2^3 (or 8). */
+ unsigned int alignment_power;
+
+ /* If an input section, a pointer to a vector of relocation
+ records for the data in this section. */
+ struct reloc_cache_entry *relocation;
+
+ /* If an output section, a pointer to a vector of pointers to
+ relocation records for the data in this section. */
+ struct reloc_cache_entry **orelocation;
+
+ /* The number of relocation records in one of the above. */
+ unsigned reloc_count;
+
+ /* Information below is back end specific - and not always used
+ or updated. */
+
+ /* File position of section data. */
+ file_ptr filepos;
+
+ /* File position of relocation info. */
+ file_ptr rel_filepos;
+
+ /* File position of line data. */
+ file_ptr line_filepos;
+
+ /* Pointer to data for applications. */
+ void *userdata;
+
+ /* If the SEC_IN_MEMORY flag is set, this points to the actual
+ contents. */
+ unsigned char *contents;
+
+ /* Attached line number information. */
+ alent *lineno;
+
+ /* Number of line number records. */
+ unsigned int lineno_count;
+
+ /* Entity size for merging purposes. */
+ unsigned int entsize;
+
+ /* Points to the kept section if this section is a link-once section,
+ and is discarded. */
+ struct bfd_section *kept_section;
+
+ /* When a section is being output, this value changes as more
+ linenumbers are written out. */
+ file_ptr moving_line_filepos;
+
+ /* What the section number is in the target world. */
+ int target_index;
+
+ void *used_by_bfd;
+
+ /* If this is a constructor section then here is a list of the
+ relocations created to relocate items within it. */
+ struct relent_chain *constructor_chain;
+
+ /* The BFD which owns the section. */
+ bfd *owner;
+
+ /* A symbol which points at this section only. */
+ struct bfd_symbol *symbol;
+ struct bfd_symbol **symbol_ptr_ptr;
+
+ /* Early in the link process, map_head and map_tail are used to build
+ a list of input sections attached to an output section. Later,
+ output sections use these fields for a list of bfd_link_order
+ structs. */
+ union {
+ struct bfd_link_order *link_order;
+ struct bfd_section *s;
+ } map_head, map_tail;
+} asection;
+
+/* These sections are global, and are managed by BFD. The application
+ and target back end are not permitted to change the values in
+ these sections. New code should use the section_ptr macros rather
+ than referring directly to the const sections. The const sections
+ may eventually vanish. */
+#define BFD_ABS_SECTION_NAME "*ABS*"
+#define BFD_UND_SECTION_NAME "*UND*"
+#define BFD_COM_SECTION_NAME "*COM*"
+#define BFD_IND_SECTION_NAME "*IND*"
+
+/* The absolute section. */
+extern asection bfd_abs_section;
+#define bfd_abs_section_ptr ((asection *) &bfd_abs_section)
+#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr)
+/* Pointer to the undefined section. */
+extern asection bfd_und_section;
+#define bfd_und_section_ptr ((asection *) &bfd_und_section)
+#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr)
+/* Pointer to the common section. */
+extern asection bfd_com_section;
+#define bfd_com_section_ptr ((asection *) &bfd_com_section)
+/* Pointer to the indirect section. */
+extern asection bfd_ind_section;
+#define bfd_ind_section_ptr ((asection *) &bfd_ind_section)
+#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr)
+
+#define bfd_is_const_section(SEC) \
+ ( ((SEC) == bfd_abs_section_ptr) \
+ || ((SEC) == bfd_und_section_ptr) \
+ || ((SEC) == bfd_com_section_ptr) \
+ || ((SEC) == bfd_ind_section_ptr))
+
+extern const struct bfd_symbol * const bfd_abs_symbol;
+extern const struct bfd_symbol * const bfd_com_symbol;
+extern const struct bfd_symbol * const bfd_und_symbol;
+extern const struct bfd_symbol * const bfd_ind_symbol;
+
+/* Macros to handle insertion and deletion of a bfd's sections. These
+ only handle the list pointers, ie. do not adjust section_count,
+ target_index etc. */
+#define bfd_section_list_remove(ABFD, S) \
+ do \
+ { \
+ asection *_s = S; \
+ asection *_next = _s->next; \
+ asection *_prev = _s->prev; \
+ if (_prev) \
+ _prev->next = _next; \
+ else \
+ (ABFD)->sections = _next; \
+ if (_next) \
+ _next->prev = _prev; \
+ else \
+ (ABFD)->section_last = _prev; \
+ } \
+ while (0)
+#define bfd_section_list_append(ABFD, S) \
+ do \
+ { \
+ asection *_s = S; \
+ bfd *_abfd = ABFD; \
+ _s->next = NULL; \
+ if (_abfd->section_last) \
+ { \
+ _s->prev = _abfd->section_last; \
+ _abfd->section_last->next = _s; \
+ } \
+ else \
+ { \
+ _s->prev = NULL; \
+ _abfd->sections = _s; \
+ } \
+ _abfd->section_last = _s; \
+ } \
+ while (0)
+#define bfd_section_list_prepend(ABFD, S) \
+ do \
+ { \
+ asection *_s = S; \
+ bfd *_abfd = ABFD; \
+ _s->prev = NULL; \
+ if (_abfd->sections) \
+ { \
+ _s->next = _abfd->sections; \
+ _abfd->sections->prev = _s; \
+ } \
+ else \
+ { \
+ _s->next = NULL; \
+ _abfd->section_last = _s; \
+ } \
+ _abfd->sections = _s; \
+ } \
+ while (0)
+#define bfd_section_list_insert_after(ABFD, A, S) \
+ do \
+ { \
+ asection *_a = A; \
+ asection *_s = S; \
+ asection *_next = _a->next; \
+ _s->next = _next; \
+ _s->prev = _a; \
+ _a->next = _s; \
+ if (_next) \
+ _next->prev = _s; \
+ else \
+ (ABFD)->section_last = _s; \
+ } \
+ while (0)
+#define bfd_section_list_insert_before(ABFD, B, S) \
+ do \
+ { \
+ asection *_b = B; \
+ asection *_s = S; \
+ asection *_prev = _b->prev; \
+ _s->prev = _prev; \
+ _s->next = _b; \
+ _b->prev = _s; \
+ if (_prev) \
+ _prev->next = _s; \
+ else \
+ (ABFD)->sections = _s; \
+ } \
+ while (0)
+#define bfd_section_removed_from_list(ABFD, S) \
+ ((S)->next == NULL ? (ABFD)->section_last != (S) : (S)->next->prev != (S))
+
+#define BFD_FAKE_SECTION(SEC, FLAGS, SYM, SYM_PTR, NAME, IDX) \
+ /* name, id, index, next, prev, flags, user_set_vma, */ \
+ { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \
+ \
+ /* linker_mark, linker_has_input, gc_mark, gc_mark_from_eh, */ \
+ 0, 0, 1, 0, \
+ \
+ /* segment_mark, sec_info_type, use_rela_p, has_tls_reloc, */ \
+ 0, 0, 0, 0, \
+ \
+ /* has_gp_reloc, need_finalize_relax, reloc_done, */ \
+ 0, 0, 0, \
+ \
+ /* vma, lma, size, rawsize */ \
+ 0, 0, 0, 0, \
+ \
+ /* output_offset, output_section, alignment_power, */ \
+ 0, (struct bfd_section *) &SEC, 0, \
+ \
+ /* relocation, orelocation, reloc_count, filepos, rel_filepos, */ \
+ NULL, NULL, 0, 0, 0, \
+ \
+ /* line_filepos, userdata, contents, lineno, lineno_count, */ \
+ 0, NULL, NULL, NULL, 0, \
+ \
+ /* entsize, kept_section, moving_line_filepos, */ \
+ 0, NULL, 0, \
+ \
+ /* target_index, used_by_bfd, constructor_chain, owner, */ \
+ 0, NULL, NULL, NULL, \
+ \
+ /* symbol, */ \
+ (struct bfd_symbol *) SYM, \
+ \
+ /* symbol_ptr_ptr, */ \
+ (struct bfd_symbol **) SYM_PTR, \
+ \
+ /* map_head, map_tail */ \
+ { NULL }, { NULL } \
+ }
+
+void bfd_section_list_clear (bfd *);
+
+asection *bfd_get_section_by_name (bfd *abfd, const char *name);
+
+asection *bfd_get_section_by_name_if
+ (bfd *abfd,
+ const char *name,
+ bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj),
+ void *obj);
+
+char *bfd_get_unique_section_name
+ (bfd *abfd, const char *templat, int *count);
+
+asection *bfd_make_section_old_way (bfd *abfd, const char *name);
+
+asection *bfd_make_section_anyway_with_flags
+ (bfd *abfd, const char *name, flagword flags);
+
+asection *bfd_make_section_anyway (bfd *abfd, const char *name);
+
+asection *bfd_make_section_with_flags
+ (bfd *, const char *name, flagword flags);
+
+asection *bfd_make_section (bfd *, const char *name);
+
+bfd_boolean bfd_set_section_flags
+ (bfd *abfd, asection *sec, flagword flags);
+
+void bfd_map_over_sections
+ (bfd *abfd,
+ void (*func) (bfd *abfd, asection *sect, void *obj),
+ void *obj);
+
+asection *bfd_sections_find_if
+ (bfd *abfd,
+ bfd_boolean (*operation) (bfd *abfd, asection *sect, void *obj),
+ void *obj);
+
+bfd_boolean bfd_set_section_size
+ (bfd *abfd, asection *sec, bfd_size_type val);
+
+bfd_boolean bfd_set_section_contents
+ (bfd *abfd, asection *section, const void *data,
+ file_ptr offset, bfd_size_type count);
+
+bfd_boolean bfd_get_section_contents
+ (bfd *abfd, asection *section, void *location, file_ptr offset,
+ bfd_size_type count);
+
+bfd_boolean bfd_malloc_and_get_section
+ (bfd *abfd, asection *section, bfd_byte **buf);
+
+bfd_boolean bfd_copy_private_section_data
+ (bfd *ibfd, asection *isec, bfd *obfd, asection *osec);
+
+#define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \
+ BFD_SEND (obfd, _bfd_copy_private_section_data, \
+ (ibfd, isection, obfd, osection))
+bfd_boolean bfd_generic_is_group_section (bfd *, const asection *sec);
+
+bfd_boolean bfd_generic_discard_group (bfd *abfd, asection *group);
+
+/* Extracted from archures.c. */
+enum bfd_architecture
+{
+ bfd_arch_unknown, /* File arch not known. */
+ bfd_arch_obscure, /* Arch known, not one of these. */
+ bfd_arch_m68k, /* Motorola 68xxx */
+#define bfd_mach_m68000 1
+#define bfd_mach_m68008 2
+#define bfd_mach_m68010 3
+#define bfd_mach_m68020 4
+#define bfd_mach_m68030 5
+#define bfd_mach_m68040 6
+#define bfd_mach_m68060 7
+#define bfd_mach_cpu32 8
+#define bfd_mach_mcf5200 9
+#define bfd_mach_mcf5206e 10
+#define bfd_mach_mcf5307 11
+#define bfd_mach_mcf5407 12
+#define bfd_mach_mcf528x 13
+#define bfd_mach_mcfv4e 14
+#define bfd_mach_mcf521x 15
+#define bfd_mach_mcf5249 16
+#define bfd_mach_mcf547x 17
+#define bfd_mach_mcf548x 18
+ bfd_arch_vax, /* DEC Vax */
+ bfd_arch_i960, /* Intel 960 */
+ /* The order of the following is important.
+ lower number indicates a machine type that
+ only accepts a subset of the instructions
+ available to machines with higher numbers.
+ The exception is the "ca", which is
+ incompatible with all other machines except
+ "core". */
+
+#define bfd_mach_i960_core 1
+#define bfd_mach_i960_ka_sa 2
+#define bfd_mach_i960_kb_sb 3
+#define bfd_mach_i960_mc 4
+#define bfd_mach_i960_xa 5
+#define bfd_mach_i960_ca 6
+#define bfd_mach_i960_jx 7
+#define bfd_mach_i960_hx 8
+
+ bfd_arch_or32, /* OpenRISC 32 */
+
+ bfd_arch_sparc, /* SPARC */
+#define bfd_mach_sparc 1
+/* The difference between v8plus and v9 is that v9 is a true 64 bit env. */
+#define bfd_mach_sparc_sparclet 2
+#define bfd_mach_sparc_sparclite 3
+#define bfd_mach_sparc_v8plus 4
+#define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns. */
+#define bfd_mach_sparc_sparclite_le 6
+#define bfd_mach_sparc_v9 7
+#define bfd_mach_sparc_v9a 8 /* with ultrasparc add'ns. */
+#define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */
+#define bfd_mach_sparc_v9b 10 /* with cheetah add'ns. */
+/* Nonzero if MACH has the v9 instruction set. */
+#define bfd_mach_sparc_v9_p(mach) \
+ ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9b \
+ && (mach) != bfd_mach_sparc_sparclite_le)
+/* Nonzero if MACH is a 64 bit sparc architecture. */
+#define bfd_mach_sparc_64bit_p(mach) \
+ ((mach) >= bfd_mach_sparc_v9 && (mach) != bfd_mach_sparc_v8plusb)
+ bfd_arch_mips, /* MIPS Rxxxx */
+#define bfd_mach_mips3000 3000
+#define bfd_mach_mips3900 3900
+#define bfd_mach_mips4000 4000
+#define bfd_mach_mips4010 4010
+#define bfd_mach_mips4100 4100
+#define bfd_mach_mips4111 4111
+#define bfd_mach_mips4120 4120
+#define bfd_mach_mips4300 4300
+#define bfd_mach_mips4400 4400
+#define bfd_mach_mips4600 4600
+#define bfd_mach_mips4650 4650
+#define bfd_mach_mips5000 5000
+#define bfd_mach_mips5400 5400
+#define bfd_mach_mips5500 5500
+#define bfd_mach_mips6000 6000
+#define bfd_mach_mips7000 7000
+#define bfd_mach_mips8000 8000
+#define bfd_mach_mips9000 9000
+#define bfd_mach_mips10000 10000
+#define bfd_mach_mips12000 12000
+#define bfd_mach_mips16 16
+#define bfd_mach_mips5 5
+#define bfd_mach_mips_sb1 12310201 /* octal 'SB', 01 */
+#define bfd_mach_mipsisa32 32
+#define bfd_mach_mipsisa32r2 33
+#define bfd_mach_mipsisa64 64
+#define bfd_mach_mipsisa64r2 65
+ bfd_arch_i386, /* Intel 386 */
+#define bfd_mach_i386_i386 1
+#define bfd_mach_i386_i8086 2
+#define bfd_mach_i386_i386_intel_syntax 3
+#define bfd_mach_x86_64 64
+#define bfd_mach_x86_64_intel_syntax 65
+ bfd_arch_we32k, /* AT&T WE32xxx */
+ bfd_arch_tahoe, /* CCI/Harris Tahoe */
+ bfd_arch_i860, /* Intel 860 */
+ bfd_arch_i370, /* IBM 360/370 Mainframes */
+ bfd_arch_romp, /* IBM ROMP PC/RT */
+ bfd_arch_convex, /* Convex */
+ bfd_arch_m88k, /* Motorola 88xxx */
+ bfd_arch_m98k, /* Motorola 98xxx */
+ bfd_arch_pyramid, /* Pyramid Technology */
+ bfd_arch_h8300, /* Renesas H8/300 (formerly Hitachi H8/300) */
+#define bfd_mach_h8300 1
+#define bfd_mach_h8300h 2
+#define bfd_mach_h8300s 3
+#define bfd_mach_h8300hn 4
+#define bfd_mach_h8300sn 5
+#define bfd_mach_h8300sx 6
+#define bfd_mach_h8300sxn 7
+ bfd_arch_pdp11, /* DEC PDP-11 */
+ bfd_arch_powerpc, /* PowerPC */
+#define bfd_mach_ppc 32
+#define bfd_mach_ppc64 64
+#define bfd_mach_ppc_403 403
+#define bfd_mach_ppc_403gc 4030
+#define bfd_mach_ppc_505 505
+#define bfd_mach_ppc_601 601
+#define bfd_mach_ppc_602 602
+#define bfd_mach_ppc_603 603
+#define bfd_mach_ppc_ec603e 6031
+#define bfd_mach_ppc_604 604
+#define bfd_mach_ppc_620 620
+#define bfd_mach_ppc_630 630
+#define bfd_mach_ppc_750 750
+#define bfd_mach_ppc_860 860
+#define bfd_mach_ppc_a35 35
+#define bfd_mach_ppc_rs64ii 642
+#define bfd_mach_ppc_rs64iii 643
+#define bfd_mach_ppc_7400 7400
+#define bfd_mach_ppc_e500 500
+ bfd_arch_rs6000, /* IBM RS/6000 */
+#define bfd_mach_rs6k 6000
+#define bfd_mach_rs6k_rs1 6001
+#define bfd_mach_rs6k_rsc 6003
+#define bfd_mach_rs6k_rs2 6002
+ bfd_arch_hppa, /* HP PA RISC */
+#define bfd_mach_hppa10 10
+#define bfd_mach_hppa11 11
+#define bfd_mach_hppa20 20
+#define bfd_mach_hppa20w 25
+ bfd_arch_d10v, /* Mitsubishi D10V */
+#define bfd_mach_d10v 1
+#define bfd_mach_d10v_ts2 2
+#define bfd_mach_d10v_ts3 3
+ bfd_arch_d30v, /* Mitsubishi D30V */
+ bfd_arch_dlx, /* DLX */
+ bfd_arch_m68hc11, /* Motorola 68HC11 */
+ bfd_arch_m68hc12, /* Motorola 68HC12 */
+#define bfd_mach_m6812_default 0
+#define bfd_mach_m6812 1
+#define bfd_mach_m6812s 2
+ bfd_arch_z8k, /* Zilog Z8000 */
+#define bfd_mach_z8001 1
+#define bfd_mach_z8002 2
+ bfd_arch_h8500, /* Renesas H8/500 (formerly Hitachi H8/500) */
+ bfd_arch_sh, /* Renesas / SuperH SH (formerly Hitachi SH) */
+#define bfd_mach_sh 1
+#define bfd_mach_sh2 0x20
+#define bfd_mach_sh_dsp 0x2d
+#define bfd_mach_sh2a 0x2a
+#define bfd_mach_sh2a_nofpu 0x2b
+#define bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu 0x2a1
+#define bfd_mach_sh2a_nofpu_or_sh3_nommu 0x2a2
+#define bfd_mach_sh2a_or_sh4 0x2a3
+#define bfd_mach_sh2a_or_sh3e 0x2a4
+#define bfd_mach_sh2e 0x2e
+#define bfd_mach_sh3 0x30
+#define bfd_mach_sh3_nommu 0x31
+#define bfd_mach_sh3_dsp 0x3d
+#define bfd_mach_sh3e 0x3e
+#define bfd_mach_sh4 0x40
+#define bfd_mach_sh4_nofpu 0x41
+#define bfd_mach_sh4_nommu_nofpu 0x42
+#define bfd_mach_sh4a 0x4a
+#define bfd_mach_sh4a_nofpu 0x4b
+#define bfd_mach_sh4al_dsp 0x4d
+#define bfd_mach_sh5 0x50
+ bfd_arch_alpha, /* Dec Alpha */
+#define bfd_mach_alpha_ev4 0x10
+#define bfd_mach_alpha_ev5 0x20
+#define bfd_mach_alpha_ev6 0x30
+ bfd_arch_arm, /* Advanced Risc Machines ARM. */
+#define bfd_mach_arm_unknown 0
+#define bfd_mach_arm_2 1
+#define bfd_mach_arm_2a 2
+#define bfd_mach_arm_3 3
+#define bfd_mach_arm_3M 4
+#define bfd_mach_arm_4 5
+#define bfd_mach_arm_4T 6
+#define bfd_mach_arm_5 7
+#define bfd_mach_arm_5T 8
+#define bfd_mach_arm_5TE 9
+#define bfd_mach_arm_XScale 10
+#define bfd_mach_arm_ep9312 11
+#define bfd_mach_arm_iWMMXt 12
+ bfd_arch_ns32k, /* National Semiconductors ns32000 */
+ bfd_arch_w65, /* WDC 65816 */
+ bfd_arch_tic30, /* Texas Instruments TMS320C30 */
+ bfd_arch_tic4x, /* Texas Instruments TMS320C3X/4X */
+#define bfd_mach_tic3x 30
+#define bfd_mach_tic4x 40
+ bfd_arch_tic54x, /* Texas Instruments TMS320C54X */
+ bfd_arch_tic80, /* TI TMS320c80 (MVP) */
+ bfd_arch_v850, /* NEC V850 */
+#define bfd_mach_v850 1
+#define bfd_mach_v850e 'E'
+#define bfd_mach_v850e1 '1'
+ bfd_arch_arc, /* ARC Cores */
+#define bfd_mach_arc_5 5
+#define bfd_mach_arc_6 6
+#define bfd_mach_arc_7 7
+#define bfd_mach_arc_8 8
+ bfd_arch_m32c, /* Renesas M16C/M32C. */
+#define bfd_mach_m16c 0x75
+#define bfd_mach_m32c 0x78
+ bfd_arch_m32r, /* Renesas M32R (formerly Mitsubishi M32R/D) */
+#define bfd_mach_m32r 1 /* For backwards compatibility. */
+#define bfd_mach_m32rx 'x'
+#define bfd_mach_m32r2 '2'
+ bfd_arch_mn10200, /* Matsushita MN10200 */
+ bfd_arch_mn10300, /* Matsushita MN10300 */
+#define bfd_mach_mn10300 300
+#define bfd_mach_am33 330
+#define bfd_mach_am33_2 332
+ bfd_arch_fr30,
+#define bfd_mach_fr30 0x46523330
+ bfd_arch_frv,
+#define bfd_mach_frv 1
+#define bfd_mach_frvsimple 2
+#define bfd_mach_fr300 300
+#define bfd_mach_fr400 400
+#define bfd_mach_fr450 450
+#define bfd_mach_frvtomcat 499 /* fr500 prototype */
+#define bfd_mach_fr500 500
+#define bfd_mach_fr550 550
+ bfd_arch_mcore,
+ bfd_arch_ia64, /* HP/Intel ia64 */
+#define bfd_mach_ia64_elf64 64
+#define bfd_mach_ia64_elf32 32
+ bfd_arch_ip2k, /* Ubicom IP2K microcontrollers. */
+#define bfd_mach_ip2022 1
+#define bfd_mach_ip2022ext 2
+ bfd_arch_iq2000, /* Vitesse IQ2000. */
+#define bfd_mach_iq2000 1
+#define bfd_mach_iq10 2
+ bfd_arch_mt,
+#define bfd_mach_ms1 1
+#define bfd_mach_mrisc2 2
+#define bfd_mach_ms2 3
+ bfd_arch_pj,
+ bfd_arch_avr, /* Atmel AVR microcontrollers. */
+#define bfd_mach_avr1 1
+#define bfd_mach_avr2 2
+#define bfd_mach_avr3 3
+#define bfd_mach_avr4 4
+#define bfd_mach_avr5 5
+ bfd_arch_bfin, /* ADI Blackfin */
+#define bfd_mach_bfin 1
+ bfd_arch_cr16c, /* National Semiconductor CompactRISC. */
+#define bfd_mach_cr16c 1
+ bfd_arch_crx, /* National Semiconductor CRX. */
+#define bfd_mach_crx 1
+ bfd_arch_cris, /* Axis CRIS */
+#define bfd_mach_cris_v0_v10 255
+#define bfd_mach_cris_v32 32
+#define bfd_mach_cris_v10_v32 1032
+ bfd_arch_s390, /* IBM s390 */
+#define bfd_mach_s390_31 31
+#define bfd_mach_s390_64 64
+ bfd_arch_openrisc, /* OpenRISC */
+ bfd_arch_mmix, /* Donald Knuth's educational processor. */
+ bfd_arch_xstormy16,
+#define bfd_mach_xstormy16 1
+ bfd_arch_msp430, /* Texas Instruments MSP430 architecture. */
+#define bfd_mach_msp11 11
+#define bfd_mach_msp110 110
+#define bfd_mach_msp12 12
+#define bfd_mach_msp13 13
+#define bfd_mach_msp14 14
+#define bfd_mach_msp15 15
+#define bfd_mach_msp16 16
+#define bfd_mach_msp21 21
+#define bfd_mach_msp31 31
+#define bfd_mach_msp32 32
+#define bfd_mach_msp33 33
+#define bfd_mach_msp41 41
+#define bfd_mach_msp42 42
+#define bfd_mach_msp43 43
+#define bfd_mach_msp44 44
+ bfd_arch_xtensa, /* Tensilica's Xtensa cores. */
+#define bfd_mach_xtensa 1
+ bfd_arch_maxq, /* Dallas MAXQ 10/20 */
+#define bfd_mach_maxq10 10
+#define bfd_mach_maxq20 20
+ bfd_arch_z80,
+#define bfd_mach_z80strict 1 /* No undocumented opcodes. */
+#define bfd_mach_z80 3 /* With ixl, ixh, iyl, and iyh. */
+#define bfd_mach_z80full 7 /* All undocumented instructions. */
+#define bfd_mach_r800 11 /* R800: successor with multiplication. */
+ bfd_arch_last
+ };
+
+typedef struct bfd_arch_info
+{
+ int bits_per_word;
+ int bits_per_address;
+ int bits_per_byte;
+ enum bfd_architecture arch;
+ unsigned long mach;
+ const char *arch_name;
+ const char *printable_name;
+ unsigned int section_align_power;
+ /* TRUE if this is the default machine for the architecture.
+ The default arch should be the first entry for an arch so that
+ all the entries for that arch can be accessed via <<next>>. */
+ bfd_boolean the_default;
+ const struct bfd_arch_info * (*compatible)
+ (const struct bfd_arch_info *a, const struct bfd_arch_info *b);
+
+ bfd_boolean (*scan) (const struct bfd_arch_info *, const char *);
+
+ const struct bfd_arch_info *next;
+}
+bfd_arch_info_type;
+
+const char *bfd_printable_name (bfd *abfd);
+
+const bfd_arch_info_type *bfd_scan_arch (const char *string);
+
+const char **bfd_arch_list (void);
+
+const bfd_arch_info_type *bfd_arch_get_compatible
+ (const bfd *abfd, const bfd *bbfd, bfd_boolean accept_unknowns);
+
+void bfd_set_arch_info (bfd *abfd, const bfd_arch_info_type *arg);
+
+enum bfd_architecture bfd_get_arch (bfd *abfd);
+
+unsigned long bfd_get_mach (bfd *abfd);
+
+unsigned int bfd_arch_bits_per_byte (bfd *abfd);
+
+unsigned int bfd_arch_bits_per_address (bfd *abfd);
+
+const bfd_arch_info_type *bfd_get_arch_info (bfd *abfd);
+
+const bfd_arch_info_type *bfd_lookup_arch
+ (enum bfd_architecture arch, unsigned long machine);
+
+const char *bfd_printable_arch_mach
+ (enum bfd_architecture arch, unsigned long machine);
+
+unsigned int bfd_octets_per_byte (bfd *abfd);
+
+unsigned int bfd_arch_mach_octets_per_byte
+ (enum bfd_architecture arch, unsigned long machine);
+
+/* Extracted from reloc.c. */
+typedef enum bfd_reloc_status
+{
+ /* No errors detected. */
+ bfd_reloc_ok,
+
+ /* The relocation was performed, but there was an overflow. */
+ bfd_reloc_overflow,
+
+ /* The address to relocate was not within the section supplied. */
+ bfd_reloc_outofrange,
+
+ /* Used by special functions. */
+ bfd_reloc_continue,
+
+ /* Unsupported relocation size requested. */
+ bfd_reloc_notsupported,
+
+ /* Unused. */
+ bfd_reloc_other,
+
+ /* The symbol to relocate against was undefined. */
+ bfd_reloc_undefined,
+
+ /* The relocation was performed, but may not be ok - presently
+ generated only when linking i960 coff files with i960 b.out
+ symbols. If this type is returned, the error_message argument
+ to bfd_perform_relocation will be set. */
+ bfd_reloc_dangerous
+ }
+ bfd_reloc_status_type;
+
+
+typedef struct reloc_cache_entry
+{
+ /* A pointer into the canonical table of pointers. */
+ struct bfd_symbol **sym_ptr_ptr;
+
+ /* offset in section. */
+ bfd_size_type address;
+
+ /* addend for relocation value. */
+ bfd_vma addend;
+
+ /* Pointer to how to perform the required relocation. */
+ reloc_howto_type *howto;
+
+}
+arelent;
+
+enum complain_overflow
+{
+ /* Do not complain on overflow. */
+ complain_overflow_dont,
+
+ /* Complain if the value overflows when considered as a signed
+ number one bit larger than the field. ie. A bitfield of N bits
+ is allowed to represent -2**n to 2**n-1. */
+ complain_overflow_bitfield,
+
+ /* Complain if the value overflows when considered as a signed
+ number. */
+ complain_overflow_signed,
+
+ /* Complain if the value overflows when considered as an
+ unsigned number. */
+ complain_overflow_unsigned
+};
+
+struct reloc_howto_struct
+{
+ /* The type field has mainly a documentary use - the back end can
+ do what it wants with it, though normally the back end's
+ external idea of what a reloc number is stored
+ in this field. For example, a PC relative word relocation
+ in a coff environment has the type 023 - because that's
+ what the outside world calls a R_PCRWORD reloc. */
+ unsigned int type;
+
+ /* The value the final relocation is shifted right by. This drops
+ unwanted data from the relocation. */
+ unsigned int rightshift;
+
+ /* The size of the item to be relocated. This is *not* a
+ power-of-two measure. To get the number of bytes operated
+ on by a type of relocation, use bfd_get_reloc_size. */
+ int size;
+
+ /* The number of bits in the item to be relocated. This is used
+ when doing overflow checking. */
+ unsigned int bitsize;
+
+ /* Notes that the relocation is relative to the location in the
+ data section of the addend. The relocation function will
+ subtract from the relocation value the address of the location
+ being relocated. */
+ bfd_boolean pc_relative;
+
+ /* The bit position of the reloc value in the destination.
+ The relocated value is left shifted by this amount. */
+ unsigned int bitpos;
+
+ /* What type of overflow error should be checked for when
+ relocating. */
+ enum complain_overflow complain_on_overflow;
+
+ /* If this field is non null, then the supplied function is
+ called rather than the normal function. This allows really
+ strange relocation methods to be accommodated (e.g., i960 callj
+ instructions). */
+ bfd_reloc_status_type (*special_function)
+ (bfd *, arelent *, struct bfd_symbol *, void *, asection *,
+ bfd *, char **);
+
+ /* The textual name of the relocation type. */
+ char *name;
+
+ /* Some formats record a relocation addend in the section contents
+ rather than with the relocation. For ELF formats this is the
+ distinction between USE_REL and USE_RELA (though the code checks
+ for USE_REL == 1/0). The value of this field is TRUE if the
+ addend is recorded with the section contents; when performing a
+ partial link (ld -r) the section contents (the data) will be
+ modified. The value of this field is FALSE if addends are
+ recorded with the relocation (in arelent.addend); when performing
+ a partial link the relocation will be modified.
+ All relocations for all ELF USE_RELA targets should set this field
+ to FALSE (values of TRUE should be looked on with suspicion).
+ However, the converse is not true: not all relocations of all ELF
+ USE_REL targets set this field to TRUE. Why this is so is peculiar
+ to each particular target. For relocs that aren't used in partial
+ links (e.g. GOT stuff) it doesn't matter what this is set to. */
+ bfd_boolean partial_inplace;
+
+ /* src_mask selects the part of the instruction (or data) to be used
+ in the relocation sum. If the target relocations don't have an
+ addend in the reloc, eg. ELF USE_REL, src_mask will normally equal
+ dst_mask to extract the addend from the section contents. If
+ relocations do have an addend in the reloc, eg. ELF USE_RELA, this
+ field should be zero. Non-zero values for ELF USE_RELA targets are
+ bogus as in those cases the value in the dst_mask part of the
+ section contents should be treated as garbage. */
+ bfd_vma src_mask;
+
+ /* dst_mask selects which parts of the instruction (or data) are
+ replaced with a relocated value. */
+ bfd_vma dst_mask;
+
+ /* When some formats create PC relative instructions, they leave
+ the value of the pc of the place being relocated in the offset
+ slot of the instruction, so that a PC relative relocation can
+ be made just by adding in an ordinary offset (e.g., sun3 a.out).
+ Some formats leave the displacement part of an instruction
+ empty (e.g., m88k bcs); this flag signals the fact. */
+ bfd_boolean pcrel_offset;
+};
+
+#define HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
+ { (unsigned) C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC }
+#define NEWHOWTO(FUNCTION, NAME, SIZE, REL, IN) \
+ HOWTO (0, 0, SIZE, 0, REL, 0, complain_overflow_dont, FUNCTION, \
+ NAME, FALSE, 0, 0, IN)
+
+#define EMPTY_HOWTO(C) \
+ HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \
+ NULL, FALSE, 0, 0, FALSE)
+
+#define HOWTO_PREPARE(relocation, symbol) \
+ { \
+ if (symbol != NULL) \
+ { \
+ if (bfd_is_com_section (symbol->section)) \
+ { \
+ relocation = 0; \
+ } \
+ else \
+ { \
+ relocation = symbol->value; \
+ } \
+ } \
+ }
+
+unsigned int bfd_get_reloc_size (reloc_howto_type *);
+
+typedef struct relent_chain
+{
+ arelent relent;
+ struct relent_chain *next;
+}
+arelent_chain;
+
+bfd_reloc_status_type bfd_check_overflow
+ (enum complain_overflow how,
+ unsigned int bitsize,
+ unsigned int rightshift,
+ unsigned int addrsize,
+ bfd_vma relocation);
+
+bfd_reloc_status_type bfd_perform_relocation
+ (bfd *abfd,
+ arelent *reloc_entry,
+ void *data,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message);
+
+bfd_reloc_status_type bfd_install_relocation
+ (bfd *abfd,
+ arelent *reloc_entry,
+ void *data, bfd_vma data_start,
+ asection *input_section,
+ char **error_message);
+
+enum bfd_reloc_code_real {
+ _dummy_first_bfd_reloc_code_real,
+
+
+/* Basic absolute relocations of N bits. */
+ BFD_RELOC_64,
+ BFD_RELOC_32,
+ BFD_RELOC_26,
+ BFD_RELOC_24,
+ BFD_RELOC_16,
+ BFD_RELOC_14,
+ BFD_RELOC_8,
+
+/* PC-relative relocations. Sometimes these are relative to the address
+of the relocation itself; sometimes they are relative to the start of
+the section containing the relocation. It depends on the specific target.
+
+The 24-bit relocation is used in some Intel 960 configurations. */
+ BFD_RELOC_64_PCREL,
+ BFD_RELOC_32_PCREL,
+ BFD_RELOC_24_PCREL,
+ BFD_RELOC_16_PCREL,
+ BFD_RELOC_12_PCREL,
+ BFD_RELOC_8_PCREL,
+
+/* Section relative relocations. Some targets need this for DWARF2. */
+ BFD_RELOC_32_SECREL,
+
+/* For ELF. */
+ BFD_RELOC_32_GOT_PCREL,
+ BFD_RELOC_16_GOT_PCREL,
+ BFD_RELOC_8_GOT_PCREL,
+ BFD_RELOC_32_GOTOFF,
+ BFD_RELOC_16_GOTOFF,
+ BFD_RELOC_LO16_GOTOFF,
+ BFD_RELOC_HI16_GOTOFF,
+ BFD_RELOC_HI16_S_GOTOFF,
+ BFD_RELOC_8_GOTOFF,
+ BFD_RELOC_64_PLT_PCREL,
+ BFD_RELOC_32_PLT_PCREL,
+ BFD_RELOC_24_PLT_PCREL,
+ BFD_RELOC_16_PLT_PCREL,
+ BFD_RELOC_8_PLT_PCREL,
+ BFD_RELOC_64_PLTOFF,
+ BFD_RELOC_32_PLTOFF,
+ BFD_RELOC_16_PLTOFF,
+ BFD_RELOC_LO16_PLTOFF,
+ BFD_RELOC_HI16_PLTOFF,
+ BFD_RELOC_HI16_S_PLTOFF,
+ BFD_RELOC_8_PLTOFF,
+
+/* Relocations used by 68K ELF. */
+ BFD_RELOC_68K_GLOB_DAT,
+ BFD_RELOC_68K_JMP_SLOT,
+ BFD_RELOC_68K_RELATIVE,
+
+/* Linkage-table relative. */
+ BFD_RELOC_32_BASEREL,
+ BFD_RELOC_16_BASEREL,
+ BFD_RELOC_LO16_BASEREL,
+ BFD_RELOC_HI16_BASEREL,
+ BFD_RELOC_HI16_S_BASEREL,
+ BFD_RELOC_8_BASEREL,
+ BFD_RELOC_RVA,
+
+/* Absolute 8-bit relocation, but used to form an address like 0xFFnn. */
+ BFD_RELOC_8_FFnn,
+
+/* These PC-relative relocations are stored as word displacements --
+i.e., byte displacements shifted right two bits. The 30-bit word
+displacement (<<32_PCREL_S2>> -- 32 bits, shifted 2) is used on the
+SPARC. (SPARC tools generally refer to this as <<WDISP30>>.) The
+signed 16-bit displacement is used on the MIPS, and the 23-bit
+displacement is used on the Alpha. */
+ BFD_RELOC_32_PCREL_S2,
+ BFD_RELOC_16_PCREL_S2,
+ BFD_RELOC_23_PCREL_S2,
+
+/* High 22 bits and low 10 bits of 32-bit value, placed into lower bits of
+the target word. These are used on the SPARC. */
+ BFD_RELOC_HI22,
+ BFD_RELOC_LO10,
+
+/* For systems that allocate a Global Pointer register, these are
+displacements off that register. These relocation types are
+handled specially, because the value the register will have is
+decided relatively late. */
+ BFD_RELOC_GPREL16,
+ BFD_RELOC_GPREL32,
+
+/* Reloc types used for i960/b.out. */
+ BFD_RELOC_I960_CALLJ,
+
+/* SPARC ELF relocations. There is probably some overlap with other
+relocation types already defined. */
+ BFD_RELOC_NONE,
+ BFD_RELOC_SPARC_WDISP22,
+ BFD_RELOC_SPARC22,
+ BFD_RELOC_SPARC13,
+ BFD_RELOC_SPARC_GOT10,
+ BFD_RELOC_SPARC_GOT13,
+ BFD_RELOC_SPARC_GOT22,
+ BFD_RELOC_SPARC_PC10,
+ BFD_RELOC_SPARC_PC22,
+ BFD_RELOC_SPARC_WPLT30,
+ BFD_RELOC_SPARC_COPY,
+ BFD_RELOC_SPARC_GLOB_DAT,
+ BFD_RELOC_SPARC_JMP_SLOT,
+ BFD_RELOC_SPARC_RELATIVE,
+ BFD_RELOC_SPARC_UA16,
+ BFD_RELOC_SPARC_UA32,
+ BFD_RELOC_SPARC_UA64,
+
+/* I think these are specific to SPARC a.out (e.g., Sun 4). */
+ BFD_RELOC_SPARC_BASE13,
+ BFD_RELOC_SPARC_BASE22,
+
+/* SPARC64 relocations */
+#define BFD_RELOC_SPARC_64 BFD_RELOC_64
+ BFD_RELOC_SPARC_10,
+ BFD_RELOC_SPARC_11,
+ BFD_RELOC_SPARC_OLO10,
+ BFD_RELOC_SPARC_HH22,
+ BFD_RELOC_SPARC_HM10,
+ BFD_RELOC_SPARC_LM22,
+ BFD_RELOC_SPARC_PC_HH22,
+ BFD_RELOC_SPARC_PC_HM10,
+ BFD_RELOC_SPARC_PC_LM22,
+ BFD_RELOC_SPARC_WDISP16,
+ BFD_RELOC_SPARC_WDISP19,
+ BFD_RELOC_SPARC_7,
+ BFD_RELOC_SPARC_6,
+ BFD_RELOC_SPARC_5,
+#define BFD_RELOC_SPARC_DISP64 BFD_RELOC_64_PCREL
+ BFD_RELOC_SPARC_PLT32,
+ BFD_RELOC_SPARC_PLT64,
+ BFD_RELOC_SPARC_HIX22,
+ BFD_RELOC_SPARC_LOX10,
+ BFD_RELOC_SPARC_H44,
+ BFD_RELOC_SPARC_M44,
+ BFD_RELOC_SPARC_L44,
+ BFD_RELOC_SPARC_REGISTER,
+
+/* SPARC little endian relocation */
+ BFD_RELOC_SPARC_REV32,
+
+/* SPARC TLS relocations */
+ BFD_RELOC_SPARC_TLS_GD_HI22,
+ BFD_RELOC_SPARC_TLS_GD_LO10,
+ BFD_RELOC_SPARC_TLS_GD_ADD,
+ BFD_RELOC_SPARC_TLS_GD_CALL,
+ BFD_RELOC_SPARC_TLS_LDM_HI22,
+ BFD_RELOC_SPARC_TLS_LDM_LO10,
+ BFD_RELOC_SPARC_TLS_LDM_ADD,
+ BFD_RELOC_SPARC_TLS_LDM_CALL,
+ BFD_RELOC_SPARC_TLS_LDO_HIX22,
+ BFD_RELOC_SPARC_TLS_LDO_LOX10,
+ BFD_RELOC_SPARC_TLS_LDO_ADD,
+ BFD_RELOC_SPARC_TLS_IE_HI22,
+ BFD_RELOC_SPARC_TLS_IE_LO10,
+ BFD_RELOC_SPARC_TLS_IE_LD,
+ BFD_RELOC_SPARC_TLS_IE_LDX,
+ BFD_RELOC_SPARC_TLS_IE_ADD,
+ BFD_RELOC_SPARC_TLS_LE_HIX22,
+ BFD_RELOC_SPARC_TLS_LE_LOX10,
+ BFD_RELOC_SPARC_TLS_DTPMOD32,
+ BFD_RELOC_SPARC_TLS_DTPMOD64,
+ BFD_RELOC_SPARC_TLS_DTPOFF32,
+ BFD_RELOC_SPARC_TLS_DTPOFF64,
+ BFD_RELOC_SPARC_TLS_TPOFF32,
+ BFD_RELOC_SPARC_TLS_TPOFF64,
+
+/* Alpha ECOFF and ELF relocations. Some of these treat the symbol or
+"addend" in some special way.
+For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when
+writing; when reading, it will be the absolute section symbol. The
+addend is the displacement in bytes of the "lda" instruction from
+the "ldah" instruction (which is at the address of this reloc). */
+ BFD_RELOC_ALPHA_GPDISP_HI16,
+
+/* For GPDISP_LO16 ("ignore") relocations, the symbol is handled as
+with GPDISP_HI16 relocs. The addend is ignored when writing the
+relocations out, and is filled in with the file's GP value on
+reading, for convenience. */
+ BFD_RELOC_ALPHA_GPDISP_LO16,
+
+/* The ELF GPDISP relocation is exactly the same as the GPDISP_HI16
+relocation except that there is no accompanying GPDISP_LO16
+relocation. */
+ BFD_RELOC_ALPHA_GPDISP,
+
+/* The Alpha LITERAL/LITUSE relocs are produced by a symbol reference;
+the assembler turns it into a LDQ instruction to load the address of
+the symbol, and then fills in a register in the real instruction.
+
+The LITERAL reloc, at the LDQ instruction, refers to the .lita
+section symbol. The addend is ignored when writing, but is filled
+in with the file's GP value on reading, for convenience, as with the
+GPDISP_LO16 reloc.
+
+The ELF_LITERAL reloc is somewhere between 16_GOTOFF and GPDISP_LO16.
+It should refer to the symbol to be referenced, as with 16_GOTOFF,
+but it generates output not based on the position within the .got
+section, but relative to the GP value chosen for the file during the
+final link stage.
+
+The LITUSE reloc, on the instruction using the loaded address, gives
+information to the linker that it might be able to use to optimize
+away some literal section references. The symbol is ignored (read
+as the absolute section symbol), and the "addend" indicates the type
+of instruction using the register:
+1 - "memory" fmt insn
+2 - byte-manipulation (byte offset reg)
+3 - jsr (target of branch) */
+ BFD_RELOC_ALPHA_LITERAL,
+ BFD_RELOC_ALPHA_ELF_LITERAL,
+ BFD_RELOC_ALPHA_LITUSE,
+
+/* The HINT relocation indicates a value that should be filled into the
+"hint" field of a jmp/jsr/ret instruction, for possible branch-
+prediction logic which may be provided on some processors. */
+ BFD_RELOC_ALPHA_HINT,
+
+/* The LINKAGE relocation outputs a linkage pair in the object file,
+which is filled by the linker. */
+ BFD_RELOC_ALPHA_LINKAGE,
+
+/* The CODEADDR relocation outputs a STO_CA in the object file,
+which is filled by the linker. */
+ BFD_RELOC_ALPHA_CODEADDR,
+
+/* The GPREL_HI/LO relocations together form a 32-bit offset from the
+GP register. */
+ BFD_RELOC_ALPHA_GPREL_HI16,
+ BFD_RELOC_ALPHA_GPREL_LO16,
+
+/* Like BFD_RELOC_23_PCREL_S2, except that the source and target must
+share a common GP, and the target address is adjusted for
+STO_ALPHA_STD_GPLOAD. */
+ BFD_RELOC_ALPHA_BRSGP,
+
+/* Alpha thread-local storage relocations. */
+ BFD_RELOC_ALPHA_TLSGD,
+ BFD_RELOC_ALPHA_TLSLDM,
+ BFD_RELOC_ALPHA_DTPMOD64,
+ BFD_RELOC_ALPHA_GOTDTPREL16,
+ BFD_RELOC_ALPHA_DTPREL64,
+ BFD_RELOC_ALPHA_DTPREL_HI16,
+ BFD_RELOC_ALPHA_DTPREL_LO16,
+ BFD_RELOC_ALPHA_DTPREL16,
+ BFD_RELOC_ALPHA_GOTTPREL16,
+ BFD_RELOC_ALPHA_TPREL64,
+ BFD_RELOC_ALPHA_TPREL_HI16,
+ BFD_RELOC_ALPHA_TPREL_LO16,
+ BFD_RELOC_ALPHA_TPREL16,
+
+/* Bits 27..2 of the relocation address shifted right 2 bits;
+simple reloc otherwise. */
+ BFD_RELOC_MIPS_JMP,
+
+/* The MIPS16 jump instruction. */
+ BFD_RELOC_MIPS16_JMP,
+
+/* MIPS16 GP relative reloc. */
+ BFD_RELOC_MIPS16_GPREL,
+
+/* High 16 bits of 32-bit value; simple reloc. */
+ BFD_RELOC_HI16,
+
+/* High 16 bits of 32-bit value but the low 16 bits will be sign
+extended and added to form the final result. If the low 16
+bits form a negative number, we need to add one to the high value
+to compensate for the borrow when the low bits are added. */
+ BFD_RELOC_HI16_S,
+
+/* Low 16 bits. */
+ BFD_RELOC_LO16,
+
+/* High 16 bits of 32-bit pc-relative value */
+ BFD_RELOC_HI16_PCREL,
+
+/* High 16 bits of 32-bit pc-relative value, adjusted */
+ BFD_RELOC_HI16_S_PCREL,
+
+/* Low 16 bits of pc-relative value */
+ BFD_RELOC_LO16_PCREL,
+
+/* MIPS16 high 16 bits of 32-bit value. */
+ BFD_RELOC_MIPS16_HI16,
+
+/* MIPS16 high 16 bits of 32-bit value but the low 16 bits will be sign
+extended and added to form the final result. If the low 16
+bits form a negative number, we need to add one to the high value
+to compensate for the borrow when the low bits are added. */
+ BFD_RELOC_MIPS16_HI16_S,
+
+/* MIPS16 low 16 bits. */
+ BFD_RELOC_MIPS16_LO16,
+
+/* Relocation against a MIPS literal section. */
+ BFD_RELOC_MIPS_LITERAL,
+
+/* MIPS ELF relocations. */
+ BFD_RELOC_MIPS_GOT16,
+ BFD_RELOC_MIPS_CALL16,
+ BFD_RELOC_MIPS_GOT_HI16,
+ BFD_RELOC_MIPS_GOT_LO16,
+ BFD_RELOC_MIPS_CALL_HI16,
+ BFD_RELOC_MIPS_CALL_LO16,
+ BFD_RELOC_MIPS_SUB,
+ BFD_RELOC_MIPS_GOT_PAGE,
+ BFD_RELOC_MIPS_GOT_OFST,
+ BFD_RELOC_MIPS_GOT_DISP,
+ BFD_RELOC_MIPS_SHIFT5,
+ BFD_RELOC_MIPS_SHIFT6,
+ BFD_RELOC_MIPS_INSERT_A,
+ BFD_RELOC_MIPS_INSERT_B,
+ BFD_RELOC_MIPS_DELETE,
+ BFD_RELOC_MIPS_HIGHEST,
+ BFD_RELOC_MIPS_HIGHER,
+ BFD_RELOC_MIPS_SCN_DISP,
+ BFD_RELOC_MIPS_REL16,
+ BFD_RELOC_MIPS_RELGOT,
+ BFD_RELOC_MIPS_JALR,
+ BFD_RELOC_MIPS_TLS_DTPMOD32,
+ BFD_RELOC_MIPS_TLS_DTPREL32,
+ BFD_RELOC_MIPS_TLS_DTPMOD64,
+ BFD_RELOC_MIPS_TLS_DTPREL64,
+ BFD_RELOC_MIPS_TLS_GD,
+ BFD_RELOC_MIPS_TLS_LDM,
+ BFD_RELOC_MIPS_TLS_DTPREL_HI16,
+ BFD_RELOC_MIPS_TLS_DTPREL_LO16,
+ BFD_RELOC_MIPS_TLS_GOTTPREL,
+ BFD_RELOC_MIPS_TLS_TPREL32,
+ BFD_RELOC_MIPS_TLS_TPREL64,
+ BFD_RELOC_MIPS_TLS_TPREL_HI16,
+ BFD_RELOC_MIPS_TLS_TPREL_LO16,
+
+
+/* Fujitsu Frv Relocations. */
+ BFD_RELOC_FRV_LABEL16,
+ BFD_RELOC_FRV_LABEL24,
+ BFD_RELOC_FRV_LO16,
+ BFD_RELOC_FRV_HI16,
+ BFD_RELOC_FRV_GPREL12,
+ BFD_RELOC_FRV_GPRELU12,
+ BFD_RELOC_FRV_GPREL32,
+ BFD_RELOC_FRV_GPRELHI,
+ BFD_RELOC_FRV_GPRELLO,
+ BFD_RELOC_FRV_GOT12,
+ BFD_RELOC_FRV_GOTHI,
+ BFD_RELOC_FRV_GOTLO,
+ BFD_RELOC_FRV_FUNCDESC,
+ BFD_RELOC_FRV_FUNCDESC_GOT12,
+ BFD_RELOC_FRV_FUNCDESC_GOTHI,
+ BFD_RELOC_FRV_FUNCDESC_GOTLO,
+ BFD_RELOC_FRV_FUNCDESC_VALUE,
+ BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
+ BFD_RELOC_FRV_FUNCDESC_GOTOFFHI,
+ BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
+ BFD_RELOC_FRV_GOTOFF12,
+ BFD_RELOC_FRV_GOTOFFHI,
+ BFD_RELOC_FRV_GOTOFFLO,
+ BFD_RELOC_FRV_GETTLSOFF,
+ BFD_RELOC_FRV_TLSDESC_VALUE,
+ BFD_RELOC_FRV_GOTTLSDESC12,
+ BFD_RELOC_FRV_GOTTLSDESCHI,
+ BFD_RELOC_FRV_GOTTLSDESCLO,
+ BFD_RELOC_FRV_TLSMOFF12,
+ BFD_RELOC_FRV_TLSMOFFHI,
+ BFD_RELOC_FRV_TLSMOFFLO,
+ BFD_RELOC_FRV_GOTTLSOFF12,
+ BFD_RELOC_FRV_GOTTLSOFFHI,
+ BFD_RELOC_FRV_GOTTLSOFFLO,
+ BFD_RELOC_FRV_TLSOFF,
+ BFD_RELOC_FRV_TLSDESC_RELAX,
+ BFD_RELOC_FRV_GETTLSOFF_RELAX,
+ BFD_RELOC_FRV_TLSOFF_RELAX,
+ BFD_RELOC_FRV_TLSMOFF,
+
+
+/* This is a 24bit GOT-relative reloc for the mn10300. */
+ BFD_RELOC_MN10300_GOTOFF24,
+
+/* This is a 32bit GOT-relative reloc for the mn10300, offset by two bytes
+in the instruction. */
+ BFD_RELOC_MN10300_GOT32,
+
+/* This is a 24bit GOT-relative reloc for the mn10300, offset by two bytes
+in the instruction. */
+ BFD_RELOC_MN10300_GOT24,
+
+/* This is a 16bit GOT-relative reloc for the mn10300, offset by two bytes
+in the instruction. */
+ BFD_RELOC_MN10300_GOT16,
+
+/* Copy symbol at runtime. */
+ BFD_RELOC_MN10300_COPY,
+
+/* Create GOT entry. */
+ BFD_RELOC_MN10300_GLOB_DAT,
+
+/* Create PLT entry. */
+ BFD_RELOC_MN10300_JMP_SLOT,
+
+/* Adjust by program base. */
+ BFD_RELOC_MN10300_RELATIVE,
+
+
+/* i386/elf relocations */
+ BFD_RELOC_386_GOT32,
+ BFD_RELOC_386_PLT32,
+ BFD_RELOC_386_COPY,
+ BFD_RELOC_386_GLOB_DAT,
+ BFD_RELOC_386_JUMP_SLOT,
+ BFD_RELOC_386_RELATIVE,
+ BFD_RELOC_386_GOTOFF,
+ BFD_RELOC_386_GOTPC,
+ BFD_RELOC_386_TLS_TPOFF,
+ BFD_RELOC_386_TLS_IE,
+ BFD_RELOC_386_TLS_GOTIE,
+ BFD_RELOC_386_TLS_LE,
+ BFD_RELOC_386_TLS_GD,
+ BFD_RELOC_386_TLS_LDM,
+ BFD_RELOC_386_TLS_LDO_32,
+ BFD_RELOC_386_TLS_IE_32,
+ BFD_RELOC_386_TLS_LE_32,
+ BFD_RELOC_386_TLS_DTPMOD32,
+ BFD_RELOC_386_TLS_DTPOFF32,
+ BFD_RELOC_386_TLS_TPOFF32,
+
+/* x86-64/elf relocations */
+ BFD_RELOC_X86_64_GOT32,
+ BFD_RELOC_X86_64_PLT32,
+ BFD_RELOC_X86_64_COPY,
+ BFD_RELOC_X86_64_GLOB_DAT,
+ BFD_RELOC_X86_64_JUMP_SLOT,
+ BFD_RELOC_X86_64_RELATIVE,
+ BFD_RELOC_X86_64_GOTPCREL,
+ BFD_RELOC_X86_64_32S,
+ BFD_RELOC_X86_64_DTPMOD64,
+ BFD_RELOC_X86_64_DTPOFF64,
+ BFD_RELOC_X86_64_TPOFF64,
+ BFD_RELOC_X86_64_TLSGD,
+ BFD_RELOC_X86_64_TLSLD,
+ BFD_RELOC_X86_64_DTPOFF32,
+ BFD_RELOC_X86_64_GOTTPOFF,
+ BFD_RELOC_X86_64_TPOFF32,
+ BFD_RELOC_X86_64_GOTOFF64,
+ BFD_RELOC_X86_64_GOTPC32,
+ BFD_RELOC_X86_64_GOT64,
+ BFD_RELOC_X86_64_GOTPCREL64,
+ BFD_RELOC_X86_64_GOTPC64,
+ BFD_RELOC_X86_64_GOTPLT64,
+ BFD_RELOC_X86_64_PLTOFF64,
+
+/* ns32k relocations */
+ BFD_RELOC_NS32K_IMM_8,
+ BFD_RELOC_NS32K_IMM_16,
+ BFD_RELOC_NS32K_IMM_32,
+ BFD_RELOC_NS32K_IMM_8_PCREL,
+ BFD_RELOC_NS32K_IMM_16_PCREL,
+ BFD_RELOC_NS32K_IMM_32_PCREL,
+ BFD_RELOC_NS32K_DISP_8,
+ BFD_RELOC_NS32K_DISP_16,
+ BFD_RELOC_NS32K_DISP_32,
+ BFD_RELOC_NS32K_DISP_8_PCREL,
+ BFD_RELOC_NS32K_DISP_16_PCREL,
+ BFD_RELOC_NS32K_DISP_32_PCREL,
+
+/* PDP11 relocations */
+ BFD_RELOC_PDP11_DISP_8_PCREL,
+ BFD_RELOC_PDP11_DISP_6_PCREL,
+
+/* Picojava relocs. Not all of these appear in object files. */
+ BFD_RELOC_PJ_CODE_HI16,
+ BFD_RELOC_PJ_CODE_LO16,
+ BFD_RELOC_PJ_CODE_DIR16,
+ BFD_RELOC_PJ_CODE_DIR32,
+ BFD_RELOC_PJ_CODE_REL16,
+ BFD_RELOC_PJ_CODE_REL32,
+
+/* Power(rs6000) and PowerPC relocations. */
+ BFD_RELOC_PPC_B26,
+ BFD_RELOC_PPC_BA26,
+ BFD_RELOC_PPC_TOC16,
+ BFD_RELOC_PPC_B16,
+ BFD_RELOC_PPC_B16_BRTAKEN,
+ BFD_RELOC_PPC_B16_BRNTAKEN,
+ BFD_RELOC_PPC_BA16,
+ BFD_RELOC_PPC_BA16_BRTAKEN,
+ BFD_RELOC_PPC_BA16_BRNTAKEN,
+ BFD_RELOC_PPC_COPY,
+ BFD_RELOC_PPC_GLOB_DAT,
+ BFD_RELOC_PPC_JMP_SLOT,
+ BFD_RELOC_PPC_RELATIVE,
+ BFD_RELOC_PPC_LOCAL24PC,
+ BFD_RELOC_PPC_EMB_NADDR32,
+ BFD_RELOC_PPC_EMB_NADDR16,
+ BFD_RELOC_PPC_EMB_NADDR16_LO,
+ BFD_RELOC_PPC_EMB_NADDR16_HI,
+ BFD_RELOC_PPC_EMB_NADDR16_HA,
+ BFD_RELOC_PPC_EMB_SDAI16,
+ BFD_RELOC_PPC_EMB_SDA2I16,
+ BFD_RELOC_PPC_EMB_SDA2REL,
+ BFD_RELOC_PPC_EMB_SDA21,
+ BFD_RELOC_PPC_EMB_MRKREF,
+ BFD_RELOC_PPC_EMB_RELSEC16,
+ BFD_RELOC_PPC_EMB_RELST_LO,
+ BFD_RELOC_PPC_EMB_RELST_HI,
+ BFD_RELOC_PPC_EMB_RELST_HA,
+ BFD_RELOC_PPC_EMB_BIT_FLD,
+ BFD_RELOC_PPC_EMB_RELSDA,
+ BFD_RELOC_PPC64_HIGHER,
+ BFD_RELOC_PPC64_HIGHER_S,
+ BFD_RELOC_PPC64_HIGHEST,
+ BFD_RELOC_PPC64_HIGHEST_S,
+ BFD_RELOC_PPC64_TOC16_LO,
+ BFD_RELOC_PPC64_TOC16_HI,
+ BFD_RELOC_PPC64_TOC16_HA,
+ BFD_RELOC_PPC64_TOC,
+ BFD_RELOC_PPC64_PLTGOT16,
+ BFD_RELOC_PPC64_PLTGOT16_LO,
+ BFD_RELOC_PPC64_PLTGOT16_HI,
+ BFD_RELOC_PPC64_PLTGOT16_HA,
+ BFD_RELOC_PPC64_ADDR16_DS,
+ BFD_RELOC_PPC64_ADDR16_LO_DS,
+ BFD_RELOC_PPC64_GOT16_DS,
+ BFD_RELOC_PPC64_GOT16_LO_DS,
+ BFD_RELOC_PPC64_PLT16_LO_DS,
+ BFD_RELOC_PPC64_SECTOFF_DS,
+ BFD_RELOC_PPC64_SECTOFF_LO_DS,
+ BFD_RELOC_PPC64_TOC16_DS,
+ BFD_RELOC_PPC64_TOC16_LO_DS,
+ BFD_RELOC_PPC64_PLTGOT16_DS,
+ BFD_RELOC_PPC64_PLTGOT16_LO_DS,
+
+/* PowerPC and PowerPC64 thread-local storage relocations. */
+ BFD_RELOC_PPC_TLS,
+ BFD_RELOC_PPC_DTPMOD,
+ BFD_RELOC_PPC_TPREL16,
+ BFD_RELOC_PPC_TPREL16_LO,
+ BFD_RELOC_PPC_TPREL16_HI,
+ BFD_RELOC_PPC_TPREL16_HA,
+ BFD_RELOC_PPC_TPREL,
+ BFD_RELOC_PPC_DTPREL16,
+ BFD_RELOC_PPC_DTPREL16_LO,
+ BFD_RELOC_PPC_DTPREL16_HI,
+ BFD_RELOC_PPC_DTPREL16_HA,
+ BFD_RELOC_PPC_DTPREL,
+ BFD_RELOC_PPC_GOT_TLSGD16,
+ BFD_RELOC_PPC_GOT_TLSGD16_LO,
+ BFD_RELOC_PPC_GOT_TLSGD16_HI,
+ BFD_RELOC_PPC_GOT_TLSGD16_HA,
+ BFD_RELOC_PPC_GOT_TLSLD16,
+ BFD_RELOC_PPC_GOT_TLSLD16_LO,
+ BFD_RELOC_PPC_GOT_TLSLD16_HI,
+ BFD_RELOC_PPC_GOT_TLSLD16_HA,
+ BFD_RELOC_PPC_GOT_TPREL16,
+ BFD_RELOC_PPC_GOT_TPREL16_LO,
+ BFD_RELOC_PPC_GOT_TPREL16_HI,
+ BFD_RELOC_PPC_GOT_TPREL16_HA,
+ BFD_RELOC_PPC_GOT_DTPREL16,
+ BFD_RELOC_PPC_GOT_DTPREL16_LO,
+ BFD_RELOC_PPC_GOT_DTPREL16_HI,
+ BFD_RELOC_PPC_GOT_DTPREL16_HA,
+ BFD_RELOC_PPC64_TPREL16_DS,
+ BFD_RELOC_PPC64_TPREL16_LO_DS,
+ BFD_RELOC_PPC64_TPREL16_HIGHER,
+ BFD_RELOC_PPC64_TPREL16_HIGHERA,
+ BFD_RELOC_PPC64_TPREL16_HIGHEST,
+ BFD_RELOC_PPC64_TPREL16_HIGHESTA,
+ BFD_RELOC_PPC64_DTPREL16_DS,
+ BFD_RELOC_PPC64_DTPREL16_LO_DS,
+ BFD_RELOC_PPC64_DTPREL16_HIGHER,
+ BFD_RELOC_PPC64_DTPREL16_HIGHERA,
+ BFD_RELOC_PPC64_DTPREL16_HIGHEST,
+ BFD_RELOC_PPC64_DTPREL16_HIGHESTA,
+
+/* IBM 370/390 relocations */
+ BFD_RELOC_I370_D12,
+
+/* The type of reloc used to build a constructor table - at the moment
+probably a 32 bit wide absolute relocation, but the target can choose.
+It generally does map to one of the other relocation types. */
+ BFD_RELOC_CTOR,
+
+/* ARM 26 bit pc-relative branch. The lowest two bits must be zero and are
+not stored in the instruction. */
+ BFD_RELOC_ARM_PCREL_BRANCH,
+
+/* ARM 26 bit pc-relative branch. The lowest bit must be zero and is
+not stored in the instruction. The 2nd lowest bit comes from a 1 bit
+field in the instruction. */
+ BFD_RELOC_ARM_PCREL_BLX,
+
+/* Thumb 22 bit pc-relative branch. The lowest bit must be zero and is
+not stored in the instruction. The 2nd lowest bit comes from a 1 bit
+field in the instruction. */
+ BFD_RELOC_THUMB_PCREL_BLX,
+
+/* ARM 26-bit pc-relative branch for an unconditional BL or BLX instruction. */
+ BFD_RELOC_ARM_PCREL_CALL,
+
+/* ARM 26-bit pc-relative branch for B or conditional BL instruction. */
+ BFD_RELOC_ARM_PCREL_JUMP,
+
+/* Thumb 7-, 9-, 12-, 20-, 23-, and 25-bit pc-relative branches.
+The lowest bit must be zero and is not stored in the instruction.
+Note that the corresponding ELF R_ARM_THM_JUMPnn constant has an
+"nn" one smaller in all cases. Note further that BRANCH23
+corresponds to R_ARM_THM_CALL. */
+ BFD_RELOC_THUMB_PCREL_BRANCH7,
+ BFD_RELOC_THUMB_PCREL_BRANCH9,
+ BFD_RELOC_THUMB_PCREL_BRANCH12,
+ BFD_RELOC_THUMB_PCREL_BRANCH20,
+ BFD_RELOC_THUMB_PCREL_BRANCH23,
+ BFD_RELOC_THUMB_PCREL_BRANCH25,
+
+/* 12-bit immediate offset, used in ARM-format ldr and str instructions. */
+ BFD_RELOC_ARM_OFFSET_IMM,
+
+/* 5-bit immediate offset, used in Thumb-format ldr and str instructions. */
+ BFD_RELOC_ARM_THUMB_OFFSET,
+
+/* Pc-relative or absolute relocation depending on target. Used for
+entries in .init_array sections. */
+ BFD_RELOC_ARM_TARGET1,
+
+/* Read-only segment base relative address. */
+ BFD_RELOC_ARM_ROSEGREL32,
+
+/* Data segment base relative address. */
+ BFD_RELOC_ARM_SBREL32,
+
+/* This reloc is used for references to RTTI data from exception handling
+tables. The actual definition depends on the target. It may be a
+pc-relative or some form of GOT-indirect relocation. */
+ BFD_RELOC_ARM_TARGET2,
+
+/* 31-bit PC relative address. */
+ BFD_RELOC_ARM_PREL31,
+
+/* Relocations for setting up GOTs and PLTs for shared libraries. */
+ BFD_RELOC_ARM_JUMP_SLOT,
+ BFD_RELOC_ARM_GLOB_DAT,
+ BFD_RELOC_ARM_GOT32,
+ BFD_RELOC_ARM_PLT32,
+ BFD_RELOC_ARM_RELATIVE,
+ BFD_RELOC_ARM_GOTOFF,
+ BFD_RELOC_ARM_GOTPC,
+
+/* ARM thread-local storage relocations. */
+ BFD_RELOC_ARM_TLS_GD32,
+ BFD_RELOC_ARM_TLS_LDO32,
+ BFD_RELOC_ARM_TLS_LDM32,
+ BFD_RELOC_ARM_TLS_DTPOFF32,
+ BFD_RELOC_ARM_TLS_DTPMOD32,
+ BFD_RELOC_ARM_TLS_TPOFF32,
+ BFD_RELOC_ARM_TLS_IE32,
+ BFD_RELOC_ARM_TLS_LE32,
+
+/* These relocs are only used within the ARM assembler. They are not
+(at present) written to any object files. */
+ BFD_RELOC_ARM_IMMEDIATE,
+ BFD_RELOC_ARM_ADRL_IMMEDIATE,
+ BFD_RELOC_ARM_T32_IMMEDIATE,
+ BFD_RELOC_ARM_T32_IMM12,
+ BFD_RELOC_ARM_T32_ADD_PC12,
+ BFD_RELOC_ARM_SHIFT_IMM,
+ BFD_RELOC_ARM_SMC,
+ BFD_RELOC_ARM_SWI,
+ BFD_RELOC_ARM_MULTI,
+ BFD_RELOC_ARM_CP_OFF_IMM,
+ BFD_RELOC_ARM_CP_OFF_IMM_S2,
+ BFD_RELOC_ARM_T32_CP_OFF_IMM,
+ BFD_RELOC_ARM_T32_CP_OFF_IMM_S2,
+ BFD_RELOC_ARM_ADR_IMM,
+ BFD_RELOC_ARM_LDR_IMM,
+ BFD_RELOC_ARM_LITERAL,
+ BFD_RELOC_ARM_IN_POOL,
+ BFD_RELOC_ARM_OFFSET_IMM8,
+ BFD_RELOC_ARM_T32_OFFSET_U8,
+ BFD_RELOC_ARM_T32_OFFSET_IMM,
+ BFD_RELOC_ARM_HWLITERAL,
+ BFD_RELOC_ARM_THUMB_ADD,
+ BFD_RELOC_ARM_THUMB_IMM,
+ BFD_RELOC_ARM_THUMB_SHIFT,
+
+/* Renesas / SuperH SH relocs. Not all of these appear in object files. */
+ BFD_RELOC_SH_PCDISP8BY2,
+ BFD_RELOC_SH_PCDISP12BY2,
+ BFD_RELOC_SH_IMM3,
+ BFD_RELOC_SH_IMM3U,
+ BFD_RELOC_SH_DISP12,
+ BFD_RELOC_SH_DISP12BY2,
+ BFD_RELOC_SH_DISP12BY4,
+ BFD_RELOC_SH_DISP12BY8,
+ BFD_RELOC_SH_DISP20,
+ BFD_RELOC_SH_DISP20BY8,
+ BFD_RELOC_SH_IMM4,
+ BFD_RELOC_SH_IMM4BY2,
+ BFD_RELOC_SH_IMM4BY4,
+ BFD_RELOC_SH_IMM8,
+ BFD_RELOC_SH_IMM8BY2,
+ BFD_RELOC_SH_IMM8BY4,
+ BFD_RELOC_SH_PCRELIMM8BY2,
+ BFD_RELOC_SH_PCRELIMM8BY4,
+ BFD_RELOC_SH_SWITCH16,
+ BFD_RELOC_SH_SWITCH32,
+ BFD_RELOC_SH_USES,
+ BFD_RELOC_SH_COUNT,
+ BFD_RELOC_SH_ALIGN,
+ BFD_RELOC_SH_CODE,
+ BFD_RELOC_SH_DATA,
+ BFD_RELOC_SH_LABEL,
+ BFD_RELOC_SH_LOOP_START,
+ BFD_RELOC_SH_LOOP_END,
+ BFD_RELOC_SH_COPY,
+ BFD_RELOC_SH_GLOB_DAT,
+ BFD_RELOC_SH_JMP_SLOT,
+ BFD_RELOC_SH_RELATIVE,
+ BFD_RELOC_SH_GOTPC,
+ BFD_RELOC_SH_GOT_LOW16,
+ BFD_RELOC_SH_GOT_MEDLOW16,
+ BFD_RELOC_SH_GOT_MEDHI16,
+ BFD_RELOC_SH_GOT_HI16,
+ BFD_RELOC_SH_GOTPLT_LOW16,
+ BFD_RELOC_SH_GOTPLT_MEDLOW16,
+ BFD_RELOC_SH_GOTPLT_MEDHI16,
+ BFD_RELOC_SH_GOTPLT_HI16,
+ BFD_RELOC_SH_PLT_LOW16,
+ BFD_RELOC_SH_PLT_MEDLOW16,
+ BFD_RELOC_SH_PLT_MEDHI16,
+ BFD_RELOC_SH_PLT_HI16,
+ BFD_RELOC_SH_GOTOFF_LOW16,
+ BFD_RELOC_SH_GOTOFF_MEDLOW16,
+ BFD_RELOC_SH_GOTOFF_MEDHI16,
+ BFD_RELOC_SH_GOTOFF_HI16,
+ BFD_RELOC_SH_GOTPC_LOW16,
+ BFD_RELOC_SH_GOTPC_MEDLOW16,
+ BFD_RELOC_SH_GOTPC_MEDHI16,
+ BFD_RELOC_SH_GOTPC_HI16,
+ BFD_RELOC_SH_COPY64,
+ BFD_RELOC_SH_GLOB_DAT64,
+ BFD_RELOC_SH_JMP_SLOT64,
+ BFD_RELOC_SH_RELATIVE64,
+ BFD_RELOC_SH_GOT10BY4,
+ BFD_RELOC_SH_GOT10BY8,
+ BFD_RELOC_SH_GOTPLT10BY4,
+ BFD_RELOC_SH_GOTPLT10BY8,
+ BFD_RELOC_SH_GOTPLT32,
+ BFD_RELOC_SH_SHMEDIA_CODE,
+ BFD_RELOC_SH_IMMU5,
+ BFD_RELOC_SH_IMMS6,
+ BFD_RELOC_SH_IMMS6BY32,
+ BFD_RELOC_SH_IMMU6,
+ BFD_RELOC_SH_IMMS10,
+ BFD_RELOC_SH_IMMS10BY2,
+ BFD_RELOC_SH_IMMS10BY4,
+ BFD_RELOC_SH_IMMS10BY8,
+ BFD_RELOC_SH_IMMS16,
+ BFD_RELOC_SH_IMMU16,
+ BFD_RELOC_SH_IMM_LOW16,
+ BFD_RELOC_SH_IMM_LOW16_PCREL,
+ BFD_RELOC_SH_IMM_MEDLOW16,
+ BFD_RELOC_SH_IMM_MEDLOW16_PCREL,
+ BFD_RELOC_SH_IMM_MEDHI16,
+ BFD_RELOC_SH_IMM_MEDHI16_PCREL,
+ BFD_RELOC_SH_IMM_HI16,
+ BFD_RELOC_SH_IMM_HI16_PCREL,
+ BFD_RELOC_SH_PT_16,
+ BFD_RELOC_SH_TLS_GD_32,
+ BFD_RELOC_SH_TLS_LD_32,
+ BFD_RELOC_SH_TLS_LDO_32,
+ BFD_RELOC_SH_TLS_IE_32,
+ BFD_RELOC_SH_TLS_LE_32,
+ BFD_RELOC_SH_TLS_DTPMOD32,
+ BFD_RELOC_SH_TLS_DTPOFF32,
+ BFD_RELOC_SH_TLS_TPOFF32,
+
+/* ARC Cores relocs.
+ARC 22 bit pc-relative branch. The lowest two bits must be zero and are
+not stored in the instruction. The high 20 bits are installed in bits 26
+through 7 of the instruction. */
+ BFD_RELOC_ARC_B22_PCREL,
+
+/* ARC 26 bit absolute branch. The lowest two bits must be zero and are not
+stored in the instruction. The high 24 bits are installed in bits 23
+through 0. */
+ BFD_RELOC_ARC_B26,
+
+/* ADI Blackfin 16 bit immediate absolute reloc. */
+ BFD_RELOC_BFIN_16_IMM,
+
+/* ADI Blackfin 16 bit immediate absolute reloc higher 16 bits. */
+ BFD_RELOC_BFIN_16_HIGH,
+
+/* ADI Blackfin 'a' part of LSETUP. */
+ BFD_RELOC_BFIN_4_PCREL,
+
+/* ADI Blackfin. */
+ BFD_RELOC_BFIN_5_PCREL,
+
+/* ADI Blackfin 16 bit immediate absolute reloc lower 16 bits. */
+ BFD_RELOC_BFIN_16_LOW,
+
+/* ADI Blackfin. */
+ BFD_RELOC_BFIN_10_PCREL,
+
+/* ADI Blackfin 'b' part of LSETUP. */
+ BFD_RELOC_BFIN_11_PCREL,
+
+/* ADI Blackfin. */
+ BFD_RELOC_BFIN_12_PCREL_JUMP,
+
+/* ADI Blackfin Short jump, pcrel. */
+ BFD_RELOC_BFIN_12_PCREL_JUMP_S,
+
+/* ADI Blackfin Call.x not implemented. */
+ BFD_RELOC_BFIN_24_PCREL_CALL_X,
+
+/* ADI Blackfin Long Jump pcrel. */
+ BFD_RELOC_BFIN_24_PCREL_JUMP_L,
+
+/* ADI Blackfin GOT relocation. */
+ BFD_RELOC_BFIN_GOT,
+
+/* ADI Blackfin PLTPC relocation. */
+ BFD_RELOC_BFIN_PLTPC,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_PUSH,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_CONST,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_ADD,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_SUB,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_MULT,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_DIV,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_MOD,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_LSHIFT,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_RSHIFT,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_AND,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_OR,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_XOR,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_LAND,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_LOR,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_LEN,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_NEG,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_COMP,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_PAGE,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_HWPAGE,
+
+/* ADI Blackfin arithmetic relocation. */
+ BFD_ARELOC_BFIN_ADDR,
+
+/* Mitsubishi D10V relocs.
+This is a 10-bit reloc with the right 2 bits
+assumed to be 0. */
+ BFD_RELOC_D10V_10_PCREL_R,
+
+/* Mitsubishi D10V relocs.
+This is a 10-bit reloc with the right 2 bits
+assumed to be 0. This is the same as the previous reloc
+except it is in the left container, i.e.,
+shifted left 15 bits. */
+ BFD_RELOC_D10V_10_PCREL_L,
+
+/* This is an 18-bit reloc with the right 2 bits
+assumed to be 0. */
+ BFD_RELOC_D10V_18,
+
+/* This is an 18-bit reloc with the right 2 bits
+assumed to be 0. */
+ BFD_RELOC_D10V_18_PCREL,
+
+/* Mitsubishi D30V relocs.
+This is a 6-bit absolute reloc. */
+ BFD_RELOC_D30V_6,
+
+/* This is a 6-bit pc-relative reloc with
+the right 3 bits assumed to be 0. */
+ BFD_RELOC_D30V_9_PCREL,
+
+/* This is a 6-bit pc-relative reloc with
+the right 3 bits assumed to be 0. Same
+as the previous reloc but on the right side
+of the container. */
+ BFD_RELOC_D30V_9_PCREL_R,
+
+/* This is a 12-bit absolute reloc with the
+right 3 bitsassumed to be 0. */
+ BFD_RELOC_D30V_15,
+
+/* This is a 12-bit pc-relative reloc with
+the right 3 bits assumed to be 0. */
+ BFD_RELOC_D30V_15_PCREL,
+
+/* This is a 12-bit pc-relative reloc with
+the right 3 bits assumed to be 0. Same
+as the previous reloc but on the right side
+of the container. */
+ BFD_RELOC_D30V_15_PCREL_R,
+
+/* This is an 18-bit absolute reloc with
+the right 3 bits assumed to be 0. */
+ BFD_RELOC_D30V_21,
+
+/* This is an 18-bit pc-relative reloc with
+the right 3 bits assumed to be 0. */
+ BFD_RELOC_D30V_21_PCREL,
+
+/* This is an 18-bit pc-relative reloc with
+the right 3 bits assumed to be 0. Same
+as the previous reloc but on the right side
+of the container. */
+ BFD_RELOC_D30V_21_PCREL_R,
+
+/* This is a 32-bit absolute reloc. */
+ BFD_RELOC_D30V_32,
+
+/* This is a 32-bit pc-relative reloc. */
+ BFD_RELOC_D30V_32_PCREL,
+
+/* DLX relocs */
+ BFD_RELOC_DLX_HI16_S,
+
+/* DLX relocs */
+ BFD_RELOC_DLX_LO16,
+
+/* DLX relocs */
+ BFD_RELOC_DLX_JMP26,
+
+/* Renesas M16C/M32C Relocations. */
+ BFD_RELOC_M32C_HI8,
+
+/* Renesas M32R (formerly Mitsubishi M32R) relocs.
+This is a 24 bit absolute address. */
+ BFD_RELOC_M32R_24,
+
+/* This is a 10-bit pc-relative reloc with the right 2 bits assumed to be 0. */
+ BFD_RELOC_M32R_10_PCREL,
+
+/* This is an 18-bit reloc with the right 2 bits assumed to be 0. */
+ BFD_RELOC_M32R_18_PCREL,
+
+/* This is a 26-bit reloc with the right 2 bits assumed to be 0. */
+ BFD_RELOC_M32R_26_PCREL,
+
+/* This is a 16-bit reloc containing the high 16 bits of an address
+used when the lower 16 bits are treated as unsigned. */
+ BFD_RELOC_M32R_HI16_ULO,
+
+/* This is a 16-bit reloc containing the high 16 bits of an address
+used when the lower 16 bits are treated as signed. */
+ BFD_RELOC_M32R_HI16_SLO,
+
+/* This is a 16-bit reloc containing the lower 16 bits of an address. */
+ BFD_RELOC_M32R_LO16,
+
+/* This is a 16-bit reloc containing the small data area offset for use in
+add3, load, and store instructions. */
+ BFD_RELOC_M32R_SDA16,
+
+/* For PIC. */
+ BFD_RELOC_M32R_GOT24,
+ BFD_RELOC_M32R_26_PLTREL,
+ BFD_RELOC_M32R_COPY,
+ BFD_RELOC_M32R_GLOB_DAT,
+ BFD_RELOC_M32R_JMP_SLOT,
+ BFD_RELOC_M32R_RELATIVE,
+ BFD_RELOC_M32R_GOTOFF,
+ BFD_RELOC_M32R_GOTOFF_HI_ULO,
+ BFD_RELOC_M32R_GOTOFF_HI_SLO,
+ BFD_RELOC_M32R_GOTOFF_LO,
+ BFD_RELOC_M32R_GOTPC24,
+ BFD_RELOC_M32R_GOT16_HI_ULO,
+ BFD_RELOC_M32R_GOT16_HI_SLO,
+ BFD_RELOC_M32R_GOT16_LO,
+ BFD_RELOC_M32R_GOTPC_HI_ULO,
+ BFD_RELOC_M32R_GOTPC_HI_SLO,
+ BFD_RELOC_M32R_GOTPC_LO,
+
+/* This is a 9-bit reloc */
+ BFD_RELOC_V850_9_PCREL,
+
+/* This is a 22-bit reloc */
+ BFD_RELOC_V850_22_PCREL,
+
+/* This is a 16 bit offset from the short data area pointer. */
+ BFD_RELOC_V850_SDA_16_16_OFFSET,
+
+/* This is a 16 bit offset (of which only 15 bits are used) from the
+short data area pointer. */
+ BFD_RELOC_V850_SDA_15_16_OFFSET,
+
+/* This is a 16 bit offset from the zero data area pointer. */
+ BFD_RELOC_V850_ZDA_16_16_OFFSET,
+
+/* This is a 16 bit offset (of which only 15 bits are used) from the
+zero data area pointer. */
+ BFD_RELOC_V850_ZDA_15_16_OFFSET,
+
+/* This is an 8 bit offset (of which only 6 bits are used) from the
+tiny data area pointer. */
+ BFD_RELOC_V850_TDA_6_8_OFFSET,
+
+/* This is an 8bit offset (of which only 7 bits are used) from the tiny
+data area pointer. */
+ BFD_RELOC_V850_TDA_7_8_OFFSET,
+
+/* This is a 7 bit offset from the tiny data area pointer. */
+ BFD_RELOC_V850_TDA_7_7_OFFSET,
+
+/* This is a 16 bit offset from the tiny data area pointer. */
+ BFD_RELOC_V850_TDA_16_16_OFFSET,
+
+/* This is a 5 bit offset (of which only 4 bits are used) from the tiny
+data area pointer. */
+ BFD_RELOC_V850_TDA_4_5_OFFSET,
+
+/* This is a 4 bit offset from the tiny data area pointer. */
+ BFD_RELOC_V850_TDA_4_4_OFFSET,
+
+/* This is a 16 bit offset from the short data area pointer, with the
+bits placed non-contiguously in the instruction. */
+ BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET,
+
+/* This is a 16 bit offset from the zero data area pointer, with the
+bits placed non-contiguously in the instruction. */
+ BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET,
+
+/* This is a 6 bit offset from the call table base pointer. */
+ BFD_RELOC_V850_CALLT_6_7_OFFSET,
+
+/* This is a 16 bit offset from the call table base pointer. */
+ BFD_RELOC_V850_CALLT_16_16_OFFSET,
+
+/* Used for relaxing indirect function calls. */
+ BFD_RELOC_V850_LONGCALL,
+
+/* Used for relaxing indirect jumps. */
+ BFD_RELOC_V850_LONGJUMP,
+
+/* Used to maintain alignment whilst relaxing. */
+ BFD_RELOC_V850_ALIGN,
+
+/* This is a variation of BFD_RELOC_LO16 that can be used in v850e ld.bu
+instructions. */
+ BFD_RELOC_V850_LO16_SPLIT_OFFSET,
+
+/* This is a 32bit pcrel reloc for the mn10300, offset by two bytes in the
+instruction. */
+ BFD_RELOC_MN10300_32_PCREL,
+
+/* This is a 16bit pcrel reloc for the mn10300, offset by two bytes in the
+instruction. */
+ BFD_RELOC_MN10300_16_PCREL,
+
+/* This is a 8bit DP reloc for the tms320c30, where the most
+significant 8 bits of a 24 bit word are placed into the least
+significant 8 bits of the opcode. */
+ BFD_RELOC_TIC30_LDP,
+
+/* This is a 7bit reloc for the tms320c54x, where the least
+significant 7 bits of a 16 bit word are placed into the least
+significant 7 bits of the opcode. */
+ BFD_RELOC_TIC54X_PARTLS7,
+
+/* This is a 9bit DP reloc for the tms320c54x, where the most
+significant 9 bits of a 16 bit word are placed into the least
+significant 9 bits of the opcode. */
+ BFD_RELOC_TIC54X_PARTMS9,
+
+/* This is an extended address 23-bit reloc for the tms320c54x. */
+ BFD_RELOC_TIC54X_23,
+
+/* This is a 16-bit reloc for the tms320c54x, where the least
+significant 16 bits of a 23-bit extended address are placed into
+the opcode. */
+ BFD_RELOC_TIC54X_16_OF_23,
+
+/* This is a reloc for the tms320c54x, where the most
+significant 7 bits of a 23-bit extended address are placed into
+the opcode. */
+ BFD_RELOC_TIC54X_MS7_OF_23,
+
+/* This is a 48 bit reloc for the FR30 that stores 32 bits. */
+ BFD_RELOC_FR30_48,
+
+/* This is a 32 bit reloc for the FR30 that stores 20 bits split up into
+two sections. */
+ BFD_RELOC_FR30_20,
+
+/* This is a 16 bit reloc for the FR30 that stores a 6 bit word offset in
+4 bits. */
+ BFD_RELOC_FR30_6_IN_4,
+
+/* This is a 16 bit reloc for the FR30 that stores an 8 bit byte offset
+into 8 bits. */
+ BFD_RELOC_FR30_8_IN_8,
+
+/* This is a 16 bit reloc for the FR30 that stores a 9 bit short offset
+into 8 bits. */
+ BFD_RELOC_FR30_9_IN_8,
+
+/* This is a 16 bit reloc for the FR30 that stores a 10 bit word offset
+into 8 bits. */
+ BFD_RELOC_FR30_10_IN_8,
+
+/* This is a 16 bit reloc for the FR30 that stores a 9 bit pc relative
+short offset into 8 bits. */
+ BFD_RELOC_FR30_9_PCREL,
+
+/* This is a 16 bit reloc for the FR30 that stores a 12 bit pc relative
+short offset into 11 bits. */
+ BFD_RELOC_FR30_12_PCREL,
+
+/* Motorola Mcore relocations. */
+ BFD_RELOC_MCORE_PCREL_IMM8BY4,
+ BFD_RELOC_MCORE_PCREL_IMM11BY2,
+ BFD_RELOC_MCORE_PCREL_IMM4BY2,
+ BFD_RELOC_MCORE_PCREL_32,
+ BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2,
+ BFD_RELOC_MCORE_RVA,
+
+/* These are relocations for the GETA instruction. */
+ BFD_RELOC_MMIX_GETA,
+ BFD_RELOC_MMIX_GETA_1,
+ BFD_RELOC_MMIX_GETA_2,
+ BFD_RELOC_MMIX_GETA_3,
+
+/* These are relocations for a conditional branch instruction. */
+ BFD_RELOC_MMIX_CBRANCH,
+ BFD_RELOC_MMIX_CBRANCH_J,
+ BFD_RELOC_MMIX_CBRANCH_1,
+ BFD_RELOC_MMIX_CBRANCH_2,
+ BFD_RELOC_MMIX_CBRANCH_3,
+
+/* These are relocations for the PUSHJ instruction. */
+ BFD_RELOC_MMIX_PUSHJ,
+ BFD_RELOC_MMIX_PUSHJ_1,
+ BFD_RELOC_MMIX_PUSHJ_2,
+ BFD_RELOC_MMIX_PUSHJ_3,
+ BFD_RELOC_MMIX_PUSHJ_STUBBABLE,
+
+/* These are relocations for the JMP instruction. */
+ BFD_RELOC_MMIX_JMP,
+ BFD_RELOC_MMIX_JMP_1,
+ BFD_RELOC_MMIX_JMP_2,
+ BFD_RELOC_MMIX_JMP_3,
+
+/* This is a relocation for a relative address as in a GETA instruction or
+a branch. */
+ BFD_RELOC_MMIX_ADDR19,
+
+/* This is a relocation for a relative address as in a JMP instruction. */
+ BFD_RELOC_MMIX_ADDR27,
+
+/* This is a relocation for an instruction field that may be a general
+register or a value 0..255. */
+ BFD_RELOC_MMIX_REG_OR_BYTE,
+
+/* This is a relocation for an instruction field that may be a general
+register. */
+ BFD_RELOC_MMIX_REG,
+
+/* This is a relocation for two instruction fields holding a register and
+an offset, the equivalent of the relocation. */
+ BFD_RELOC_MMIX_BASE_PLUS_OFFSET,
+
+/* This relocation is an assertion that the expression is not allocated as
+a global register. It does not modify contents. */
+ BFD_RELOC_MMIX_LOCAL,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit pc relative
+short offset into 7 bits. */
+ BFD_RELOC_AVR_7_PCREL,
+
+/* This is a 16 bit reloc for the AVR that stores 13 bit pc relative
+short offset into 12 bits. */
+ BFD_RELOC_AVR_13_PCREL,
+
+/* This is a 16 bit reloc for the AVR that stores 17 bit value (usually
+program memory address) into 16 bits. */
+ BFD_RELOC_AVR_16_PM,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (usually
+data memory address) into 8 bit immediate value of LDI insn. */
+ BFD_RELOC_AVR_LO8_LDI,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
+of data memory address) into 8 bit immediate value of LDI insn. */
+ BFD_RELOC_AVR_HI8_LDI,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
+of program memory address) into 8 bit immediate value of LDI insn. */
+ BFD_RELOC_AVR_HH8_LDI,
+
+/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(usually data memory address) into 8 bit immediate value of SUBI insn. */
+ BFD_RELOC_AVR_LO8_LDI_NEG,
+
+/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(high 8 bit of data memory address) into 8 bit immediate value of
+SUBI insn. */
+ BFD_RELOC_AVR_HI8_LDI_NEG,
+
+/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(most high 8 bit of program memory address) into 8 bit immediate value
+of LDI or SUBI insn. */
+ BFD_RELOC_AVR_HH8_LDI_NEG,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (usually
+command address) into 8 bit immediate value of LDI insn. */
+ BFD_RELOC_AVR_LO8_LDI_PM,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
+of command address) into 8 bit immediate value of LDI insn. */
+ BFD_RELOC_AVR_HI8_LDI_PM,
+
+/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
+of command address) into 8 bit immediate value of LDI insn. */
+ BFD_RELOC_AVR_HH8_LDI_PM,
+
+/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(usually command address) into 8 bit immediate value of SUBI insn. */
+ BFD_RELOC_AVR_LO8_LDI_PM_NEG,
+
+/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(high 8 bit of 16 bit command address) into 8 bit immediate value
+of SUBI insn. */
+ BFD_RELOC_AVR_HI8_LDI_PM_NEG,
+
+/* This is a 16 bit reloc for the AVR that stores negated 8 bit value
+(high 6 bit of 22 bit command address) into 8 bit immediate
+value of SUBI insn. */
+ BFD_RELOC_AVR_HH8_LDI_PM_NEG,
+
+/* This is a 32 bit reloc for the AVR that stores 23 bit value
+into 22 bits. */
+ BFD_RELOC_AVR_CALL,
+
+/* This is a 16 bit reloc for the AVR that stores all needed bits
+for absolute addressing with ldi with overflow check to linktime */
+ BFD_RELOC_AVR_LDI,
+
+/* This is a 6 bit reloc for the AVR that stores offset for ldd/std
+instructions */
+ BFD_RELOC_AVR_6,
+
+/* This is a 6 bit reloc for the AVR that stores offset for adiw/sbiw
+instructions */
+ BFD_RELOC_AVR_6_ADIW,
+
+/* Direct 12 bit. */
+ BFD_RELOC_390_12,
+
+/* 12 bit GOT offset. */
+ BFD_RELOC_390_GOT12,
+
+/* 32 bit PC relative PLT address. */
+ BFD_RELOC_390_PLT32,
+
+/* Copy symbol at runtime. */
+ BFD_RELOC_390_COPY,
+
+/* Create GOT entry. */
+ BFD_RELOC_390_GLOB_DAT,
+
+/* Create PLT entry. */
+ BFD_RELOC_390_JMP_SLOT,
+
+/* Adjust by program base. */
+ BFD_RELOC_390_RELATIVE,
+
+/* 32 bit PC relative offset to GOT. */
+ BFD_RELOC_390_GOTPC,
+
+/* 16 bit GOT offset. */
+ BFD_RELOC_390_GOT16,
+
+/* PC relative 16 bit shifted by 1. */
+ BFD_RELOC_390_PC16DBL,
+
+/* 16 bit PC rel. PLT shifted by 1. */
+ BFD_RELOC_390_PLT16DBL,
+
+/* PC relative 32 bit shifted by 1. */
+ BFD_RELOC_390_PC32DBL,
+
+/* 32 bit PC rel. PLT shifted by 1. */
+ BFD_RELOC_390_PLT32DBL,
+
+/* 32 bit PC rel. GOT shifted by 1. */
+ BFD_RELOC_390_GOTPCDBL,
+
+/* 64 bit GOT offset. */
+ BFD_RELOC_390_GOT64,
+
+/* 64 bit PC relative PLT address. */
+ BFD_RELOC_390_PLT64,
+
+/* 32 bit rel. offset to GOT entry. */
+ BFD_RELOC_390_GOTENT,
+
+/* 64 bit offset to GOT. */
+ BFD_RELOC_390_GOTOFF64,
+
+/* 12-bit offset to symbol-entry within GOT, with PLT handling. */
+ BFD_RELOC_390_GOTPLT12,
+
+/* 16-bit offset to symbol-entry within GOT, with PLT handling. */
+ BFD_RELOC_390_GOTPLT16,
+
+/* 32-bit offset to symbol-entry within GOT, with PLT handling. */
+ BFD_RELOC_390_GOTPLT32,
+
+/* 64-bit offset to symbol-entry within GOT, with PLT handling. */
+ BFD_RELOC_390_GOTPLT64,
+
+/* 32-bit rel. offset to symbol-entry within GOT, with PLT handling. */
+ BFD_RELOC_390_GOTPLTENT,
+
+/* 16-bit rel. offset from the GOT to a PLT entry. */
+ BFD_RELOC_390_PLTOFF16,
+
+/* 32-bit rel. offset from the GOT to a PLT entry. */
+ BFD_RELOC_390_PLTOFF32,
+
+/* 64-bit rel. offset from the GOT to a PLT entry. */
+ BFD_RELOC_390_PLTOFF64,
+
+/* s390 tls relocations. */
+ BFD_RELOC_390_TLS_LOAD,
+ BFD_RELOC_390_TLS_GDCALL,
+ BFD_RELOC_390_TLS_LDCALL,
+ BFD_RELOC_390_TLS_GD32,
+ BFD_RELOC_390_TLS_GD64,
+ BFD_RELOC_390_TLS_GOTIE12,
+ BFD_RELOC_390_TLS_GOTIE32,
+ BFD_RELOC_390_TLS_GOTIE64,
+ BFD_RELOC_390_TLS_LDM32,
+ BFD_RELOC_390_TLS_LDM64,
+ BFD_RELOC_390_TLS_IE32,
+ BFD_RELOC_390_TLS_IE64,
+ BFD_RELOC_390_TLS_IEENT,
+ BFD_RELOC_390_TLS_LE32,
+ BFD_RELOC_390_TLS_LE64,
+ BFD_RELOC_390_TLS_LDO32,
+ BFD_RELOC_390_TLS_LDO64,
+ BFD_RELOC_390_TLS_DTPMOD,
+ BFD_RELOC_390_TLS_DTPOFF,
+ BFD_RELOC_390_TLS_TPOFF,
+
+/* Long displacement extension. */
+ BFD_RELOC_390_20,
+ BFD_RELOC_390_GOT20,
+ BFD_RELOC_390_GOTPLT20,
+ BFD_RELOC_390_TLS_GOTIE20,
+
+/* Scenix IP2K - 9-bit register number / data address */
+ BFD_RELOC_IP2K_FR9,
+
+/* Scenix IP2K - 4-bit register/data bank number */
+ BFD_RELOC_IP2K_BANK,
+
+/* Scenix IP2K - low 13 bits of instruction word address */
+ BFD_RELOC_IP2K_ADDR16CJP,
+
+/* Scenix IP2K - high 3 bits of instruction word address */
+ BFD_RELOC_IP2K_PAGE3,
+
+/* Scenix IP2K - ext/low/high 8 bits of data address */
+ BFD_RELOC_IP2K_LO8DATA,
+ BFD_RELOC_IP2K_HI8DATA,
+ BFD_RELOC_IP2K_EX8DATA,
+
+/* Scenix IP2K - low/high 8 bits of instruction word address */
+ BFD_RELOC_IP2K_LO8INSN,
+ BFD_RELOC_IP2K_HI8INSN,
+
+/* Scenix IP2K - even/odd PC modifier to modify snb pcl.0 */
+ BFD_RELOC_IP2K_PC_SKIP,
+
+/* Scenix IP2K - 16 bit word address in text section. */
+ BFD_RELOC_IP2K_TEXT,
+
+/* Scenix IP2K - 7-bit sp or dp offset */
+ BFD_RELOC_IP2K_FR_OFFSET,
+
+/* Scenix VPE4K coprocessor - data/insn-space addressing */
+ BFD_RELOC_VPE4KMATH_DATA,
+ BFD_RELOC_VPE4KMATH_INSN,
+
+/* These two relocations are used by the linker to determine which of
+the entries in a C++ virtual function table are actually used. When
+the --gc-sections option is given, the linker will zero out the entries
+that are not used, so that the code for those functions need not be
+included in the output.
+
+VTABLE_INHERIT is a zero-space relocation used to describe to the
+linker the inheritance tree of a C++ virtual function table. The
+relocation's symbol should be the parent class' vtable, and the
+relocation should be located at the child vtable.
+
+VTABLE_ENTRY is a zero-space relocation that describes the use of a
+virtual function table entry. The reloc's symbol should refer to the
+table of the class mentioned in the code. Off of that base, an offset
+describes the entry that is being used. For Rela hosts, this offset
+is stored in the reloc's addend. For Rel hosts, we are forced to put
+this offset in the reloc's section offset. */
+ BFD_RELOC_VTABLE_INHERIT,
+ BFD_RELOC_VTABLE_ENTRY,
+
+/* Intel IA64 Relocations. */
+ BFD_RELOC_IA64_IMM14,
+ BFD_RELOC_IA64_IMM22,
+ BFD_RELOC_IA64_IMM64,
+ BFD_RELOC_IA64_DIR32MSB,
+ BFD_RELOC_IA64_DIR32LSB,
+ BFD_RELOC_IA64_DIR64MSB,
+ BFD_RELOC_IA64_DIR64LSB,
+ BFD_RELOC_IA64_GPREL22,
+ BFD_RELOC_IA64_GPREL64I,
+ BFD_RELOC_IA64_GPREL32MSB,
+ BFD_RELOC_IA64_GPREL32LSB,
+ BFD_RELOC_IA64_GPREL64MSB,
+ BFD_RELOC_IA64_GPREL64LSB,
+ BFD_RELOC_IA64_LTOFF22,
+ BFD_RELOC_IA64_LTOFF64I,
+ BFD_RELOC_IA64_PLTOFF22,
+ BFD_RELOC_IA64_PLTOFF64I,
+ BFD_RELOC_IA64_PLTOFF64MSB,
+ BFD_RELOC_IA64_PLTOFF64LSB,
+ BFD_RELOC_IA64_FPTR64I,
+ BFD_RELOC_IA64_FPTR32MSB,
+ BFD_RELOC_IA64_FPTR32LSB,
+ BFD_RELOC_IA64_FPTR64MSB,
+ BFD_RELOC_IA64_FPTR64LSB,
+ BFD_RELOC_IA64_PCREL21B,
+ BFD_RELOC_IA64_PCREL21BI,
+ BFD_RELOC_IA64_PCREL21M,
+ BFD_RELOC_IA64_PCREL21F,
+ BFD_RELOC_IA64_PCREL22,
+ BFD_RELOC_IA64_PCREL60B,
+ BFD_RELOC_IA64_PCREL64I,
+ BFD_RELOC_IA64_PCREL32MSB,
+ BFD_RELOC_IA64_PCREL32LSB,
+ BFD_RELOC_IA64_PCREL64MSB,
+ BFD_RELOC_IA64_PCREL64LSB,
+ BFD_RELOC_IA64_LTOFF_FPTR22,
+ BFD_RELOC_IA64_LTOFF_FPTR64I,
+ BFD_RELOC_IA64_LTOFF_FPTR32MSB,
+ BFD_RELOC_IA64_LTOFF_FPTR32LSB,
+ BFD_RELOC_IA64_LTOFF_FPTR64MSB,
+ BFD_RELOC_IA64_LTOFF_FPTR64LSB,
+ BFD_RELOC_IA64_SEGREL32MSB,
+ BFD_RELOC_IA64_SEGREL32LSB,
+ BFD_RELOC_IA64_SEGREL64MSB,
+ BFD_RELOC_IA64_SEGREL64LSB,
+ BFD_RELOC_IA64_SECREL32MSB,
+ BFD_RELOC_IA64_SECREL32LSB,
+ BFD_RELOC_IA64_SECREL64MSB,
+ BFD_RELOC_IA64_SECREL64LSB,
+ BFD_RELOC_IA64_REL32MSB,
+ BFD_RELOC_IA64_REL32LSB,
+ BFD_RELOC_IA64_REL64MSB,
+ BFD_RELOC_IA64_REL64LSB,
+ BFD_RELOC_IA64_LTV32MSB,
+ BFD_RELOC_IA64_LTV32LSB,
+ BFD_RELOC_IA64_LTV64MSB,
+ BFD_RELOC_IA64_LTV64LSB,
+ BFD_RELOC_IA64_IPLTMSB,
+ BFD_RELOC_IA64_IPLTLSB,
+ BFD_RELOC_IA64_COPY,
+ BFD_RELOC_IA64_LTOFF22X,
+ BFD_RELOC_IA64_LDXMOV,
+ BFD_RELOC_IA64_TPREL14,
+ BFD_RELOC_IA64_TPREL22,
+ BFD_RELOC_IA64_TPREL64I,
+ BFD_RELOC_IA64_TPREL64MSB,
+ BFD_RELOC_IA64_TPREL64LSB,
+ BFD_RELOC_IA64_LTOFF_TPREL22,
+ BFD_RELOC_IA64_DTPMOD64MSB,
+ BFD_RELOC_IA64_DTPMOD64LSB,
+ BFD_RELOC_IA64_LTOFF_DTPMOD22,
+ BFD_RELOC_IA64_DTPREL14,
+ BFD_RELOC_IA64_DTPREL22,
+ BFD_RELOC_IA64_DTPREL64I,
+ BFD_RELOC_IA64_DTPREL32MSB,
+ BFD_RELOC_IA64_DTPREL32LSB,
+ BFD_RELOC_IA64_DTPREL64MSB,
+ BFD_RELOC_IA64_DTPREL64LSB,
+ BFD_RELOC_IA64_LTOFF_DTPREL22,
+
+/* Motorola 68HC11 reloc.
+This is the 8 bit high part of an absolute address. */
+ BFD_RELOC_M68HC11_HI8,
+
+/* Motorola 68HC11 reloc.
+This is the 8 bit low part of an absolute address. */
+ BFD_RELOC_M68HC11_LO8,
+
+/* Motorola 68HC11 reloc.
+This is the 3 bit of a value. */
+ BFD_RELOC_M68HC11_3B,
+
+/* Motorola 68HC11 reloc.
+This reloc marks the beginning of a jump/call instruction.
+It is used for linker relaxation to correctly identify beginning
+of instruction and change some branches to use PC-relative
+addressing mode. */
+ BFD_RELOC_M68HC11_RL_JUMP,
+
+/* Motorola 68HC11 reloc.
+This reloc marks a group of several instructions that gcc generates
+and for which the linker relaxation pass can modify and/or remove
+some of them. */
+ BFD_RELOC_M68HC11_RL_GROUP,
+
+/* Motorola 68HC11 reloc.
+This is the 16-bit lower part of an address. It is used for 'call'
+instruction to specify the symbol address without any special
+transformation (due to memory bank window). */
+ BFD_RELOC_M68HC11_LO16,
+
+/* Motorola 68HC11 reloc.
+This is a 8-bit reloc that specifies the page number of an address.
+It is used by 'call' instruction to specify the page number of
+the symbol. */
+ BFD_RELOC_M68HC11_PAGE,
+
+/* Motorola 68HC11 reloc.
+This is a 24-bit reloc that represents the address with a 16-bit
+value and a 8-bit page number. The symbol address is transformed
+to follow the 16K memory bank of 68HC12 (seen as mapped in the window). */
+ BFD_RELOC_M68HC11_24,
+
+/* Motorola 68HC12 reloc.
+This is the 5 bits of a value. */
+ BFD_RELOC_M68HC12_5B,
+
+/* NS CR16C Relocations. */
+ BFD_RELOC_16C_NUM08,
+ BFD_RELOC_16C_NUM08_C,
+ BFD_RELOC_16C_NUM16,
+ BFD_RELOC_16C_NUM16_C,
+ BFD_RELOC_16C_NUM32,
+ BFD_RELOC_16C_NUM32_C,
+ BFD_RELOC_16C_DISP04,
+ BFD_RELOC_16C_DISP04_C,
+ BFD_RELOC_16C_DISP08,
+ BFD_RELOC_16C_DISP08_C,
+ BFD_RELOC_16C_DISP16,
+ BFD_RELOC_16C_DISP16_C,
+ BFD_RELOC_16C_DISP24,
+ BFD_RELOC_16C_DISP24_C,
+ BFD_RELOC_16C_DISP24a,
+ BFD_RELOC_16C_DISP24a_C,
+ BFD_RELOC_16C_REG04,
+ BFD_RELOC_16C_REG04_C,
+ BFD_RELOC_16C_REG04a,
+ BFD_RELOC_16C_REG04a_C,
+ BFD_RELOC_16C_REG14,
+ BFD_RELOC_16C_REG14_C,
+ BFD_RELOC_16C_REG16,
+ BFD_RELOC_16C_REG16_C,
+ BFD_RELOC_16C_REG20,
+ BFD_RELOC_16C_REG20_C,
+ BFD_RELOC_16C_ABS20,
+ BFD_RELOC_16C_ABS20_C,
+ BFD_RELOC_16C_ABS24,
+ BFD_RELOC_16C_ABS24_C,
+ BFD_RELOC_16C_IMM04,
+ BFD_RELOC_16C_IMM04_C,
+ BFD_RELOC_16C_IMM16,
+ BFD_RELOC_16C_IMM16_C,
+ BFD_RELOC_16C_IMM20,
+ BFD_RELOC_16C_IMM20_C,
+ BFD_RELOC_16C_IMM24,
+ BFD_RELOC_16C_IMM24_C,
+ BFD_RELOC_16C_IMM32,
+ BFD_RELOC_16C_IMM32_C,
+
+/* NS CRX Relocations. */
+ BFD_RELOC_CRX_REL4,
+ BFD_RELOC_CRX_REL8,
+ BFD_RELOC_CRX_REL8_CMP,
+ BFD_RELOC_CRX_REL16,
+ BFD_RELOC_CRX_REL24,
+ BFD_RELOC_CRX_REL32,
+ BFD_RELOC_CRX_REGREL12,
+ BFD_RELOC_CRX_REGREL22,
+ BFD_RELOC_CRX_REGREL28,
+ BFD_RELOC_CRX_REGREL32,
+ BFD_RELOC_CRX_ABS16,
+ BFD_RELOC_CRX_ABS32,
+ BFD_RELOC_CRX_NUM8,
+ BFD_RELOC_CRX_NUM16,
+ BFD_RELOC_CRX_NUM32,
+ BFD_RELOC_CRX_IMM16,
+ BFD_RELOC_CRX_IMM32,
+ BFD_RELOC_CRX_SWITCH8,
+ BFD_RELOC_CRX_SWITCH16,
+ BFD_RELOC_CRX_SWITCH32,
+
+/* These relocs are only used within the CRIS assembler. They are not
+(at present) written to any object files. */
+ BFD_RELOC_CRIS_BDISP8,
+ BFD_RELOC_CRIS_UNSIGNED_5,
+ BFD_RELOC_CRIS_SIGNED_6,
+ BFD_RELOC_CRIS_UNSIGNED_6,
+ BFD_RELOC_CRIS_SIGNED_8,
+ BFD_RELOC_CRIS_UNSIGNED_8,
+ BFD_RELOC_CRIS_SIGNED_16,
+ BFD_RELOC_CRIS_UNSIGNED_16,
+ BFD_RELOC_CRIS_LAPCQ_OFFSET,
+ BFD_RELOC_CRIS_UNSIGNED_4,
+
+/* Relocs used in ELF shared libraries for CRIS. */
+ BFD_RELOC_CRIS_COPY,
+ BFD_RELOC_CRIS_GLOB_DAT,
+ BFD_RELOC_CRIS_JUMP_SLOT,
+ BFD_RELOC_CRIS_RELATIVE,
+
+/* 32-bit offset to symbol-entry within GOT. */
+ BFD_RELOC_CRIS_32_GOT,
+
+/* 16-bit offset to symbol-entry within GOT. */
+ BFD_RELOC_CRIS_16_GOT,
+
+/* 32-bit offset to symbol-entry within GOT, with PLT handling. */
+ BFD_RELOC_CRIS_32_GOTPLT,
+
+/* 16-bit offset to symbol-entry within GOT, with PLT handling. */
+ BFD_RELOC_CRIS_16_GOTPLT,
+
+/* 32-bit offset to symbol, relative to GOT. */
+ BFD_RELOC_CRIS_32_GOTREL,
+
+/* 32-bit offset to symbol with PLT entry, relative to GOT. */
+ BFD_RELOC_CRIS_32_PLT_GOTREL,
+
+/* 32-bit offset to symbol with PLT entry, relative to this relocation. */
+ BFD_RELOC_CRIS_32_PLT_PCREL,
+
+/* Intel i860 Relocations. */
+ BFD_RELOC_860_COPY,
+ BFD_RELOC_860_GLOB_DAT,
+ BFD_RELOC_860_JUMP_SLOT,
+ BFD_RELOC_860_RELATIVE,
+ BFD_RELOC_860_PC26,
+ BFD_RELOC_860_PLT26,
+ BFD_RELOC_860_PC16,
+ BFD_RELOC_860_LOW0,
+ BFD_RELOC_860_SPLIT0,
+ BFD_RELOC_860_LOW1,
+ BFD_RELOC_860_SPLIT1,
+ BFD_RELOC_860_LOW2,
+ BFD_RELOC_860_SPLIT2,
+ BFD_RELOC_860_LOW3,
+ BFD_RELOC_860_LOGOT0,
+ BFD_RELOC_860_SPGOT0,
+ BFD_RELOC_860_LOGOT1,
+ BFD_RELOC_860_SPGOT1,
+ BFD_RELOC_860_LOGOTOFF0,
+ BFD_RELOC_860_SPGOTOFF0,
+ BFD_RELOC_860_LOGOTOFF1,
+ BFD_RELOC_860_SPGOTOFF1,
+ BFD_RELOC_860_LOGOTOFF2,
+ BFD_RELOC_860_LOGOTOFF3,
+ BFD_RELOC_860_LOPC,
+ BFD_RELOC_860_HIGHADJ,
+ BFD_RELOC_860_HAGOT,
+ BFD_RELOC_860_HAGOTOFF,
+ BFD_RELOC_860_HAPC,
+ BFD_RELOC_860_HIGH,
+ BFD_RELOC_860_HIGOT,
+ BFD_RELOC_860_HIGOTOFF,
+
+/* OpenRISC Relocations. */
+ BFD_RELOC_OPENRISC_ABS_26,
+ BFD_RELOC_OPENRISC_REL_26,
+
+/* H8 elf Relocations. */
+ BFD_RELOC_H8_DIR16A8,
+ BFD_RELOC_H8_DIR16R8,
+ BFD_RELOC_H8_DIR24A8,
+ BFD_RELOC_H8_DIR24R8,
+ BFD_RELOC_H8_DIR32A16,
+
+/* Sony Xstormy16 Relocations. */
+ BFD_RELOC_XSTORMY16_REL_12,
+ BFD_RELOC_XSTORMY16_12,
+ BFD_RELOC_XSTORMY16_24,
+ BFD_RELOC_XSTORMY16_FPTR16,
+
+/* Relocations used by VAX ELF. */
+ BFD_RELOC_VAX_GLOB_DAT,
+ BFD_RELOC_VAX_JMP_SLOT,
+ BFD_RELOC_VAX_RELATIVE,
+
+/* Morpho MT - 16 bit immediate relocation. */
+ BFD_RELOC_MT_PC16,
+
+/* Morpho MT - Hi 16 bits of an address. */
+ BFD_RELOC_MT_HI16,
+
+/* Morpho MT - Low 16 bits of an address. */
+ BFD_RELOC_MT_LO16,
+
+/* Morpho MT - Used to tell the linker which vtable entries are used. */
+ BFD_RELOC_MT_GNU_VTINHERIT,
+
+/* Morpho MT - Used to tell the linker which vtable entries are used. */
+ BFD_RELOC_MT_GNU_VTENTRY,
+
+/* Morpho MT - 8 bit immediate relocation. */
+ BFD_RELOC_MT_PCINSN8,
+
+/* msp430 specific relocation codes */
+ BFD_RELOC_MSP430_10_PCREL,
+ BFD_RELOC_MSP430_16_PCREL,
+ BFD_RELOC_MSP430_16,
+ BFD_RELOC_MSP430_16_PCREL_BYTE,
+ BFD_RELOC_MSP430_16_BYTE,
+ BFD_RELOC_MSP430_2X_PCREL,
+ BFD_RELOC_MSP430_RL_PCREL,
+
+/* IQ2000 Relocations. */
+ BFD_RELOC_IQ2000_OFFSET_16,
+ BFD_RELOC_IQ2000_OFFSET_21,
+ BFD_RELOC_IQ2000_UHI16,
+
+/* Special Xtensa relocation used only by PLT entries in ELF shared
+objects to indicate that the runtime linker should set the value
+to one of its own internal functions or data structures. */
+ BFD_RELOC_XTENSA_RTLD,
+
+/* Xtensa relocations for ELF shared objects. */
+ BFD_RELOC_XTENSA_GLOB_DAT,
+ BFD_RELOC_XTENSA_JMP_SLOT,
+ BFD_RELOC_XTENSA_RELATIVE,
+
+/* Xtensa relocation used in ELF object files for symbols that may require
+PLT entries. Otherwise, this is just a generic 32-bit relocation. */
+ BFD_RELOC_XTENSA_PLT,
+
+/* Xtensa relocations to mark the difference of two local symbols.
+These are only needed to support linker relaxation and can be ignored
+when not relaxing. The field is set to the value of the difference
+assuming no relaxation. The relocation encodes the position of the
+first symbol so the linker can determine whether to adjust the field
+value. */
+ BFD_RELOC_XTENSA_DIFF8,
+ BFD_RELOC_XTENSA_DIFF16,
+ BFD_RELOC_XTENSA_DIFF32,
+
+/* Generic Xtensa relocations for instruction operands. Only the slot
+number is encoded in the relocation. The relocation applies to the
+last PC-relative immediate operand, or if there are no PC-relative
+immediates, to the last immediate operand. */
+ BFD_RELOC_XTENSA_SLOT0_OP,
+ BFD_RELOC_XTENSA_SLOT1_OP,
+ BFD_RELOC_XTENSA_SLOT2_OP,
+ BFD_RELOC_XTENSA_SLOT3_OP,
+ BFD_RELOC_XTENSA_SLOT4_OP,
+ BFD_RELOC_XTENSA_SLOT5_OP,
+ BFD_RELOC_XTENSA_SLOT6_OP,
+ BFD_RELOC_XTENSA_SLOT7_OP,
+ BFD_RELOC_XTENSA_SLOT8_OP,
+ BFD_RELOC_XTENSA_SLOT9_OP,
+ BFD_RELOC_XTENSA_SLOT10_OP,
+ BFD_RELOC_XTENSA_SLOT11_OP,
+ BFD_RELOC_XTENSA_SLOT12_OP,
+ BFD_RELOC_XTENSA_SLOT13_OP,
+ BFD_RELOC_XTENSA_SLOT14_OP,
+
+/* Alternate Xtensa relocations. Only the slot is encoded in the
+relocation. The meaning of these relocations is opcode-specific. */
+ BFD_RELOC_XTENSA_SLOT0_ALT,
+ BFD_RELOC_XTENSA_SLOT1_ALT,
+ BFD_RELOC_XTENSA_SLOT2_ALT,
+ BFD_RELOC_XTENSA_SLOT3_ALT,
+ BFD_RELOC_XTENSA_SLOT4_ALT,
+ BFD_RELOC_XTENSA_SLOT5_ALT,
+ BFD_RELOC_XTENSA_SLOT6_ALT,
+ BFD_RELOC_XTENSA_SLOT7_ALT,
+ BFD_RELOC_XTENSA_SLOT8_ALT,
+ BFD_RELOC_XTENSA_SLOT9_ALT,
+ BFD_RELOC_XTENSA_SLOT10_ALT,
+ BFD_RELOC_XTENSA_SLOT11_ALT,
+ BFD_RELOC_XTENSA_SLOT12_ALT,
+ BFD_RELOC_XTENSA_SLOT13_ALT,
+ BFD_RELOC_XTENSA_SLOT14_ALT,
+
+/* Xtensa relocations for backward compatibility. These have all been
+replaced by BFD_RELOC_XTENSA_SLOT0_OP. */
+ BFD_RELOC_XTENSA_OP0,
+ BFD_RELOC_XTENSA_OP1,
+ BFD_RELOC_XTENSA_OP2,
+
+/* Xtensa relocation to mark that the assembler expanded the
+instructions from an original target. The expansion size is
+encoded in the reloc size. */
+ BFD_RELOC_XTENSA_ASM_EXPAND,
+
+/* Xtensa relocation to mark that the linker should simplify
+assembler-expanded instructions. This is commonly used
+internally by the linker after analysis of a
+BFD_RELOC_XTENSA_ASM_EXPAND. */
+ BFD_RELOC_XTENSA_ASM_SIMPLIFY,
+
+/* 8 bit signed offset in (ix+d) or (iy+d). */
+ BFD_RELOC_Z80_DISP8,
+
+/* DJNZ offset. */
+ BFD_RELOC_Z8K_DISP7,
+
+/* CALR offset. */
+ BFD_RELOC_Z8K_CALLR,
+
+/* 4 bit value. */
+ BFD_RELOC_Z8K_IMM4L,
+ BFD_RELOC_UNUSED };
+typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
+reloc_howto_type *bfd_reloc_type_lookup
+ (bfd *abfd, bfd_reloc_code_real_type code);
+
+const char *bfd_get_reloc_code_name (bfd_reloc_code_real_type code);
+
+/* Extracted from syms.c. */
+
+typedef struct bfd_symbol
+{
+ /* A pointer to the BFD which owns the symbol. This information
+ is necessary so that a back end can work out what additional
+ information (invisible to the application writer) is carried
+ with the symbol.
+
+ This field is *almost* redundant, since you can use section->owner
+ instead, except that some symbols point to the global sections
+ bfd_{abs,com,und}_section. This could be fixed by making
+ these globals be per-bfd (or per-target-flavor). FIXME. */
+ struct bfd *the_bfd; /* Use bfd_asymbol_bfd(sym) to access this field. */
+
+ /* The text of the symbol. The name is left alone, and not copied; the
+ application may not alter it. */
+ const char *name;
+
+ /* The value of the symbol. This really should be a union of a
+ numeric value with a pointer, since some flags indicate that
+ a pointer to another symbol is stored here. */
+ symvalue value;
+
+ /* Attributes of a symbol. */
+#define BSF_NO_FLAGS 0x00
+
+ /* The symbol has local scope; <<static>> in <<C>>. The value
+ is the offset into the section of the data. */
+#define BSF_LOCAL 0x01
+
+ /* The symbol has global scope; initialized data in <<C>>. The
+ value is the offset into the section of the data. */
+#define BSF_GLOBAL 0x02
+
+ /* The symbol has global scope and is exported. The value is
+ the offset into the section of the data. */
+#define BSF_EXPORT BSF_GLOBAL /* No real difference. */
+
+ /* A normal C symbol would be one of:
+ <<BSF_LOCAL>>, <<BSF_FORT_COMM>>, <<BSF_UNDEFINED>> or
+ <<BSF_GLOBAL>>. */
+
+ /* The symbol is a debugging record. The value has an arbitrary
+ meaning, unless BSF_DEBUGGING_RELOC is also set. */
+#define BSF_DEBUGGING 0x08
+
+ /* The symbol denotes a function entry point. Used in ELF,
+ perhaps others someday. */
+#define BSF_FUNCTION 0x10
+
+ /* Used by the linker. */
+#define BSF_KEEP 0x20
+#define BSF_KEEP_G 0x40
+
+ /* A weak global symbol, overridable without warnings by
+ a regular global symbol of the same name. */
+#define BSF_WEAK 0x80
+
+ /* This symbol was created to point to a section, e.g. ELF's
+ STT_SECTION symbols. */
+#define BSF_SECTION_SYM 0x100
+
+ /* The symbol used to be a common symbol, but now it is
+ allocated. */
+#define BSF_OLD_COMMON 0x200
+
+ /* The default value for common data. */
+#define BFD_FORT_COMM_DEFAULT_VALUE 0
+
+ /* In some files the type of a symbol sometimes alters its
+ location in an output file - ie in coff a <<ISFCN>> symbol
+ which is also <<C_EXT>> symbol appears where it was
+ declared and not at the end of a section. This bit is set
+ by the target BFD part to convey this information. */
+#define BSF_NOT_AT_END 0x400
+
+ /* Signal that the symbol is the label of constructor section. */
+#define BSF_CONSTRUCTOR 0x800
+
+ /* Signal that the symbol is a warning symbol. The name is a
+ warning. The name of the next symbol is the one to warn about;
+ if a reference is made to a symbol with the same name as the next
+ symbol, a warning is issued by the linker. */
+#define BSF_WARNING 0x1000
+
+ /* Signal that the symbol is indirect. This symbol is an indirect
+ pointer to the symbol with the same name as the next symbol. */
+#define BSF_INDIRECT 0x2000
+
+ /* BSF_FILE marks symbols that contain a file name. This is used
+ for ELF STT_FILE symbols. */
+#define BSF_FILE 0x4000
+
+ /* Symbol is from dynamic linking information. */
+#define BSF_DYNAMIC 0x8000
+
+ /* The symbol denotes a data object. Used in ELF, and perhaps
+ others someday. */
+#define BSF_OBJECT 0x10000
+
+ /* This symbol is a debugging symbol. The value is the offset
+ into the section of the data. BSF_DEBUGGING should be set
+ as well. */
+#define BSF_DEBUGGING_RELOC 0x20000
+
+ /* This symbol is thread local. Used in ELF. */
+#define BSF_THREAD_LOCAL 0x40000
+
+ flagword flags;
+
+ /* A pointer to the section to which this symbol is
+ relative. This will always be non NULL, there are special
+ sections for undefined and absolute symbols. */
+ struct bfd_section *section;
+
+ /* Back end special data. */
+ union
+ {
+ void *p;
+ bfd_vma i;
+ }
+ udata;
+}
+asymbol;
+
+#define bfd_get_symtab_upper_bound(abfd) \
+ BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd))
+
+bfd_boolean bfd_is_local_label (bfd *abfd, asymbol *sym);
+
+bfd_boolean bfd_is_local_label_name (bfd *abfd, const char *name);
+
+#define bfd_is_local_label_name(abfd, name) \
+ BFD_SEND (abfd, _bfd_is_local_label_name, (abfd, name))
+
+bfd_boolean bfd_is_target_special_symbol (bfd *abfd, asymbol *sym);
+
+#define bfd_is_target_special_symbol(abfd, sym) \
+ BFD_SEND (abfd, _bfd_is_target_special_symbol, (abfd, sym))
+
+#define bfd_canonicalize_symtab(abfd, location) \
+ BFD_SEND (abfd, _bfd_canonicalize_symtab, (abfd, location))
+
+bfd_boolean bfd_set_symtab
+ (bfd *abfd, asymbol **location, unsigned int count);
+
+void bfd_print_symbol_vandf (bfd *abfd, void *file, asymbol *symbol);
+
+#define bfd_make_empty_symbol(abfd) \
+ BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd))
+
+asymbol *_bfd_generic_make_empty_symbol (bfd *);
+
+#define bfd_make_debug_symbol(abfd,ptr,size) \
+ BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size))
+
+int bfd_decode_symclass (asymbol *symbol);
+
+bfd_boolean bfd_is_undefined_symclass (int symclass);
+
+void bfd_symbol_info (asymbol *symbol, symbol_info *ret);
+
+bfd_boolean bfd_copy_private_symbol_data
+ (bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym);
+
+#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \
+ BFD_SEND (obfd, _bfd_copy_private_symbol_data, \
+ (ibfd, isymbol, obfd, osymbol))
+
+/* Extracted from bfd.c. */
+struct bfd
+{
+ /* A unique identifier of the BFD */
+ unsigned int id;
+
+ /* The filename the application opened the BFD with. */
+ const char *filename;
+
+ /* A pointer to the target jump table. */
+ const struct bfd_target *xvec;
+
+ /* The IOSTREAM, and corresponding IO vector that provide access
+ to the file backing the BFD. */
+ void *iostream;
+ const struct bfd_iovec *iovec;
+
+ /* Is the file descriptor being cached? That is, can it be closed as
+ needed, and re-opened when accessed later? */
+ bfd_boolean cacheable;
+
+ /* Marks whether there was a default target specified when the
+ BFD was opened. This is used to select which matching algorithm
+ to use to choose the back end. */
+ bfd_boolean target_defaulted;
+
+ /* The caching routines use these to maintain a
+ least-recently-used list of BFDs. */
+ struct bfd *lru_prev, *lru_next;
+
+ /* When a file is closed by the caching routines, BFD retains
+ state information on the file here... */
+ ufile_ptr where;
+
+ /* ... and here: (``once'' means at least once). */
+ bfd_boolean opened_once;
+
+ /* Set if we have a locally maintained mtime value, rather than
+ getting it from the file each time. */
+ bfd_boolean mtime_set;
+
+ /* File modified time, if mtime_set is TRUE. */
+ long mtime;
+
+ /* Reserved for an unimplemented file locking extension. */
+ int ifd;
+
+ /* The format which belongs to the BFD. (object, core, etc.) */
+ bfd_format format;
+
+ /* The direction with which the BFD was opened. */
+ enum bfd_direction
+ {
+ no_direction = 0,
+ read_direction = 1,
+ write_direction = 2,
+ both_direction = 3
+ }
+ direction;
+
+ /* Format_specific flags. */
+ flagword flags;
+
+ /* Currently my_archive is tested before adding origin to
+ anything. I believe that this can become always an add of
+ origin, with origin set to 0 for non archive files. */
+ ufile_ptr origin;
+
+ /* Remember when output has begun, to stop strange things
+ from happening. */
+ bfd_boolean output_has_begun;
+
+ /* A hash table for section names. */
+ struct bfd_hash_table section_htab;
+
+ /* Pointer to linked list of sections. */
+ struct bfd_section *sections;
+
+ /* The last section on the section list. */
+ struct bfd_section *section_last;
+
+ /* The number of sections. */
+ unsigned int section_count;
+
+ /* Stuff only useful for object files:
+ The start address. */
+ bfd_vma start_address;
+
+ /* Used for input and output. */
+ unsigned int symcount;
+
+ /* Symbol table for output BFD (with symcount entries). */
+ struct bfd_symbol **outsymbols;
+
+ /* Used for slurped dynamic symbol tables. */
+ unsigned int dynsymcount;
+
+ /* Pointer to structure which contains architecture information. */
+ const struct bfd_arch_info *arch_info;
+
+ /* Flag set if symbols from this BFD should not be exported. */
+ bfd_boolean no_export;
+
+ /* Stuff only useful for archives. */
+ void *arelt_data;
+ struct bfd *my_archive; /* The containing archive BFD. */
+ struct bfd *next; /* The next BFD in the archive. */
+ struct bfd *archive_head; /* The first BFD in the archive. */
+ bfd_boolean has_armap;
+
+ /* A chain of BFD structures involved in a link. */
+ struct bfd *link_next;
+
+ /* A field used by _bfd_generic_link_add_archive_symbols. This will
+ be used only for archive elements. */
+ int archive_pass;
+
+ /* Used by the back end to hold private data. */
+ union
+ {
+ struct aout_data_struct *aout_data;
+ struct artdata *aout_ar_data;
+ struct _oasys_data *oasys_obj_data;
+ struct _oasys_ar_data *oasys_ar_data;
+ struct coff_tdata *coff_obj_data;
+ struct pe_tdata *pe_obj_data;
+ struct xcoff_tdata *xcoff_obj_data;
+ struct ecoff_tdata *ecoff_obj_data;
+ struct ieee_data_struct *ieee_data;
+ struct ieee_ar_data_struct *ieee_ar_data;
+ struct srec_data_struct *srec_data;
+ struct ihex_data_struct *ihex_data;
+ struct tekhex_data_struct *tekhex_data;
+ struct elf_obj_tdata *elf_obj_data;
+ struct nlm_obj_tdata *nlm_obj_data;
+ struct bout_data_struct *bout_data;
+ struct mmo_data_struct *mmo_data;
+ struct sun_core_struct *sun_core_data;
+ struct sco5_core_struct *sco5_core_data;
+ struct trad_core_struct *trad_core_data;
+ struct som_data_struct *som_data;
+ struct hpux_core_struct *hpux_core_data;
+ struct hppabsd_core_struct *hppabsd_core_data;
+ struct sgi_core_struct *sgi_core_data;
+ struct lynx_core_struct *lynx_core_data;
+ struct osf_core_struct *osf_core_data;
+ struct cisco_core_struct *cisco_core_data;
+ struct versados_data_struct *versados_data;
+ struct netbsd_core_struct *netbsd_core_data;
+ struct mach_o_data_struct *mach_o_data;
+ struct mach_o_fat_data_struct *mach_o_fat_data;
+ struct bfd_pef_data_struct *pef_data;
+ struct bfd_pef_xlib_data_struct *pef_xlib_data;
+ struct bfd_sym_data_struct *sym_data;
+ void *any;
+ }
+ tdata;
+
+ /* Used by the application to hold private data. */
+ void *usrdata;
+
+ /* Where all the allocated stuff under this BFD goes. This is a
+ struct objalloc *, but we use void * to avoid requiring the inclusion
+ of objalloc.h. */
+ void *memory;
+};
+
+typedef enum bfd_error
+{
+ bfd_error_no_error = 0,
+ bfd_error_system_call,
+ bfd_error_invalid_target,
+ bfd_error_wrong_format,
+ bfd_error_wrong_object_format,
+ bfd_error_invalid_operation,
+ bfd_error_no_memory,
+ bfd_error_no_symbols,
+ bfd_error_no_armap,
+ bfd_error_no_more_archived_files,
+ bfd_error_malformed_archive,
+ bfd_error_file_not_recognized,
+ bfd_error_file_ambiguously_recognized,
+ bfd_error_no_contents,
+ bfd_error_nonrepresentable_section,
+ bfd_error_no_debug_section,
+ bfd_error_bad_value,
+ bfd_error_file_truncated,
+ bfd_error_file_too_big,
+ bfd_error_invalid_error_code
+}
+bfd_error_type;
+
+bfd_error_type bfd_get_error (void);
+
+void bfd_set_error (bfd_error_type error_tag);
+
+const char *bfd_errmsg (bfd_error_type error_tag);
+
+void bfd_perror (const char *message);
+
+typedef void (*bfd_error_handler_type) (const char *, ...);
+
+bfd_error_handler_type bfd_set_error_handler (bfd_error_handler_type);
+
+void bfd_set_error_program_name (const char *);
+
+bfd_error_handler_type bfd_get_error_handler (void);
+
+long bfd_get_reloc_upper_bound (bfd *abfd, asection *sect);
+
+long bfd_canonicalize_reloc
+ (bfd *abfd, asection *sec, arelent **loc, asymbol **syms);
+
+void bfd_set_reloc
+ (bfd *abfd, asection *sec, arelent **rel, unsigned int count);
+
+bfd_boolean bfd_set_file_flags (bfd *abfd, flagword flags);
+
+int bfd_get_arch_size (bfd *abfd);
+
+int bfd_get_sign_extend_vma (bfd *abfd);
+
+bfd_boolean bfd_set_start_address (bfd *abfd, bfd_vma vma);
+
+unsigned int bfd_get_gp_size (bfd *abfd);
+
+void bfd_set_gp_size (bfd *abfd, unsigned int i);
+
+bfd_vma bfd_scan_vma (const char *string, const char **end, int base);
+
+bfd_boolean bfd_copy_private_header_data (bfd *ibfd, bfd *obfd);
+
+#define bfd_copy_private_header_data(ibfd, obfd) \
+ BFD_SEND (obfd, _bfd_copy_private_header_data, \
+ (ibfd, obfd))
+bfd_boolean bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd);
+
+#define bfd_copy_private_bfd_data(ibfd, obfd) \
+ BFD_SEND (obfd, _bfd_copy_private_bfd_data, \
+ (ibfd, obfd))
+bfd_boolean bfd_merge_private_bfd_data (bfd *ibfd, bfd *obfd);
+
+#define bfd_merge_private_bfd_data(ibfd, obfd) \
+ BFD_SEND (obfd, _bfd_merge_private_bfd_data, \
+ (ibfd, obfd))
+bfd_boolean bfd_set_private_flags (bfd *abfd, flagword flags);
+
+#define bfd_set_private_flags(abfd, flags) \
+ BFD_SEND (abfd, _bfd_set_private_flags, (abfd, flags))
+#define bfd_sizeof_headers(abfd, reloc) \
+ BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc))
+
+#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \
+ BFD_SEND (abfd, _bfd_find_nearest_line, \
+ (abfd, sec, syms, off, file, func, line))
+
+#define bfd_find_line(abfd, syms, sym, file, line) \
+ BFD_SEND (abfd, _bfd_find_line, \
+ (abfd, syms, sym, file, line))
+
+#define bfd_find_inliner_info(abfd, file, func, line) \
+ BFD_SEND (abfd, _bfd_find_inliner_info, \
+ (abfd, file, func, line))
+
+#define bfd_debug_info_start(abfd) \
+ BFD_SEND (abfd, _bfd_debug_info_start, (abfd))
+
+#define bfd_debug_info_end(abfd) \
+ BFD_SEND (abfd, _bfd_debug_info_end, (abfd))
+
+#define bfd_debug_info_accumulate(abfd, section) \
+ BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section))
+
+#define bfd_stat_arch_elt(abfd, stat) \
+ BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat))
+
+#define bfd_update_armap_timestamp(abfd) \
+ BFD_SEND (abfd, _bfd_update_armap_timestamp, (abfd))
+
+#define bfd_set_arch_mach(abfd, arch, mach)\
+ BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach))
+
+#define bfd_relax_section(abfd, section, link_info, again) \
+ BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again))
+
+#define bfd_gc_sections(abfd, link_info) \
+ BFD_SEND (abfd, _bfd_gc_sections, (abfd, link_info))
+
+#define bfd_merge_sections(abfd, link_info) \
+ BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info))
+
+#define bfd_is_group_section(abfd, sec) \
+ BFD_SEND (abfd, _bfd_is_group_section, (abfd, sec))
+
+#define bfd_discard_group(abfd, sec) \
+ BFD_SEND (abfd, _bfd_discard_group, (abfd, sec))
+
+#define bfd_link_hash_table_create(abfd) \
+ BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd))
+
+#define bfd_link_hash_table_free(abfd, hash) \
+ BFD_SEND (abfd, _bfd_link_hash_table_free, (hash))
+
+#define bfd_link_add_symbols(abfd, info) \
+ BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info))
+
+#define bfd_link_just_syms(abfd, sec, info) \
+ BFD_SEND (abfd, _bfd_link_just_syms, (sec, info))
+
+#define bfd_final_link(abfd, info) \
+ BFD_SEND (abfd, _bfd_final_link, (abfd, info))
+
+#define bfd_free_cached_info(abfd) \
+ BFD_SEND (abfd, _bfd_free_cached_info, (abfd))
+
+#define bfd_get_dynamic_symtab_upper_bound(abfd) \
+ BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd))
+
+#define bfd_print_private_bfd_data(abfd, file)\
+ BFD_SEND (abfd, _bfd_print_private_bfd_data, (abfd, file))
+
+#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \
+ BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols))
+
+#define bfd_get_synthetic_symtab(abfd, count, syms, dyncount, dynsyms, ret) \
+ BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, count, syms, \
+ dyncount, dynsyms, ret))
+
+#define bfd_get_dynamic_reloc_upper_bound(abfd) \
+ BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd))
+
+#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \
+ BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms))
+
+extern bfd_byte *bfd_get_relocated_section_contents
+ (bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *,
+ bfd_boolean, asymbol **);
+
+bfd_boolean bfd_alt_mach_code (bfd *abfd, int alternative);
+
+struct bfd_preserve
+{
+ void *marker;
+ void *tdata;
+ flagword flags;
+ const struct bfd_arch_info *arch_info;
+ struct bfd_section *sections;
+ struct bfd_section *section_last;
+ unsigned int section_count;
+ struct bfd_hash_table section_htab;
+};
+
+bfd_boolean bfd_preserve_save (bfd *, struct bfd_preserve *);
+
+void bfd_preserve_restore (bfd *, struct bfd_preserve *);
+
+void bfd_preserve_finish (bfd *, struct bfd_preserve *);
+
+/* Extracted from archive.c. */
+symindex bfd_get_next_mapent
+ (bfd *abfd, symindex previous, carsym **sym);
+
+bfd_boolean bfd_set_archive_head (bfd *output, bfd *new_head);
+
+bfd *bfd_openr_next_archived_file (bfd *archive, bfd *previous);
+
+/* Extracted from corefile.c. */
+const char *bfd_core_file_failing_command (bfd *abfd);
+
+int bfd_core_file_failing_signal (bfd *abfd);
+
+bfd_boolean core_file_matches_executable_p
+ (bfd *core_bfd, bfd *exec_bfd);
+
+/* Extracted from targets.c. */
+#define BFD_SEND(bfd, message, arglist) \
+ ((*((bfd)->xvec->message)) arglist)
+
+#ifdef DEBUG_BFD_SEND
+#undef BFD_SEND
+#define BFD_SEND(bfd, message, arglist) \
+ (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \
+ ((*((bfd)->xvec->message)) arglist) : \
+ (bfd_assert (__FILE__,__LINE__), NULL))
+#endif
+#define BFD_SEND_FMT(bfd, message, arglist) \
+ (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist)
+
+#ifdef DEBUG_BFD_SEND
+#undef BFD_SEND_FMT
+#define BFD_SEND_FMT(bfd, message, arglist) \
+ (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \
+ (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist) : \
+ (bfd_assert (__FILE__,__LINE__), NULL))
+#endif
+
+enum bfd_flavour
+{
+ bfd_target_unknown_flavour,
+ bfd_target_aout_flavour,
+ bfd_target_coff_flavour,
+ bfd_target_ecoff_flavour,
+ bfd_target_xcoff_flavour,
+ bfd_target_elf_flavour,
+ bfd_target_ieee_flavour,
+ bfd_target_nlm_flavour,
+ bfd_target_oasys_flavour,
+ bfd_target_tekhex_flavour,
+ bfd_target_srec_flavour,
+ bfd_target_ihex_flavour,
+ bfd_target_som_flavour,
+ bfd_target_os9k_flavour,
+ bfd_target_versados_flavour,
+ bfd_target_msdos_flavour,
+ bfd_target_ovax_flavour,
+ bfd_target_evax_flavour,
+ bfd_target_mmo_flavour,
+ bfd_target_mach_o_flavour,
+ bfd_target_pef_flavour,
+ bfd_target_pef_xlib_flavour,
+ bfd_target_sym_flavour
+};
+
+enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
+
+/* Forward declaration. */
+typedef struct bfd_link_info _bfd_link_info;
+
+typedef struct bfd_target
+{
+ /* Identifies the kind of target, e.g., SunOS4, Ultrix, etc. */
+ char *name;
+
+ /* The "flavour" of a back end is a general indication about
+ the contents of a file. */
+ enum bfd_flavour flavour;
+
+ /* The order of bytes within the data area of a file. */
+ enum bfd_endian byteorder;
+
+ /* The order of bytes within the header parts of a file. */
+ enum bfd_endian header_byteorder;
+
+ /* A mask of all the flags which an executable may have set -
+ from the set <<BFD_NO_FLAGS>>, <<HAS_RELOC>>, ...<<D_PAGED>>. */
+ flagword object_flags;
+
+ /* A mask of all the flags which a section may have set - from
+ the set <<SEC_NO_FLAGS>>, <<SEC_ALLOC>>, ...<<SET_NEVER_LOAD>>. */
+ flagword section_flags;
+
+ /* The character normally found at the front of a symbol.
+ (if any), perhaps `_'. */
+ char symbol_leading_char;
+
+ /* The pad character for file names within an archive header. */
+ char ar_pad_char;
+
+ /* The maximum number of characters in an archive header. */
+ unsigned short ar_max_namelen;
+
+ /* Entries for byte swapping for data. These are different from the
+ other entry points, since they don't take a BFD as the first argument.
+ Certain other handlers could do the same. */
+ bfd_uint64_t (*bfd_getx64) (const void *);
+ bfd_int64_t (*bfd_getx_signed_64) (const void *);
+ void (*bfd_putx64) (bfd_uint64_t, void *);
+ bfd_vma (*bfd_getx32) (const void *);
+ bfd_signed_vma (*bfd_getx_signed_32) (const void *);
+ void (*bfd_putx32) (bfd_vma, void *);
+ bfd_vma (*bfd_getx16) (const void *);
+ bfd_signed_vma (*bfd_getx_signed_16) (const void *);
+ void (*bfd_putx16) (bfd_vma, void *);
+
+ /* Byte swapping for the headers. */
+ bfd_uint64_t (*bfd_h_getx64) (const void *);
+ bfd_int64_t (*bfd_h_getx_signed_64) (const void *);
+ void (*bfd_h_putx64) (bfd_uint64_t, void *);
+ bfd_vma (*bfd_h_getx32) (const void *);
+ bfd_signed_vma (*bfd_h_getx_signed_32) (const void *);
+ void (*bfd_h_putx32) (bfd_vma, void *);
+ bfd_vma (*bfd_h_getx16) (const void *);
+ bfd_signed_vma (*bfd_h_getx_signed_16) (const void *);
+ void (*bfd_h_putx16) (bfd_vma, void *);
+
+ /* Format dependent routines: these are vectors of entry points
+ within the target vector structure, one for each format to check. */
+
+ /* Check the format of a file being read. Return a <<bfd_target *>> or zero. */
+ const struct bfd_target *(*_bfd_check_format[bfd_type_end]) (bfd *);
+
+ /* Set the format of a file being written. */
+ bfd_boolean (*_bfd_set_format[bfd_type_end]) (bfd *);
+
+ /* Write cached information into a file being written, at <<bfd_close>>. */
+ bfd_boolean (*_bfd_write_contents[bfd_type_end]) (bfd *);
+
+
+ /* Generic entry points. */
+#define BFD_JUMP_TABLE_GENERIC(NAME) \
+ NAME##_close_and_cleanup, \
+ NAME##_bfd_free_cached_info, \
+ NAME##_new_section_hook, \
+ NAME##_get_section_contents, \
+ NAME##_get_section_contents_in_window
+
+ /* Called when the BFD is being closed to do any necessary cleanup. */
+ bfd_boolean (*_close_and_cleanup) (bfd *);
+ /* Ask the BFD to free all cached information. */
+ bfd_boolean (*_bfd_free_cached_info) (bfd *);
+ /* Called when a new section is created. */
+ bfd_boolean (*_new_section_hook) (bfd *, sec_ptr);
+ /* Read the contents of a section. */
+ bfd_boolean (*_bfd_get_section_contents)
+ (bfd *, sec_ptr, void *, file_ptr, bfd_size_type);
+ bfd_boolean (*_bfd_get_section_contents_in_window)
+ (bfd *, sec_ptr, bfd_window *, file_ptr, bfd_size_type);
+
+ /* Entry points to copy private data. */
+#define BFD_JUMP_TABLE_COPY(NAME) \
+ NAME##_bfd_copy_private_bfd_data, \
+ NAME##_bfd_merge_private_bfd_data, \
+ _bfd_generic_init_private_section_data, \
+ NAME##_bfd_copy_private_section_data, \
+ NAME##_bfd_copy_private_symbol_data, \
+ NAME##_bfd_copy_private_header_data, \
+ NAME##_bfd_set_private_flags, \
+ NAME##_bfd_print_private_bfd_data
+
+ /* Called to copy BFD general private data from one object file
+ to another. */
+ bfd_boolean (*_bfd_copy_private_bfd_data) (bfd *, bfd *);
+ /* Called to merge BFD general private data from one object file
+ to a common output file when linking. */
+ bfd_boolean (*_bfd_merge_private_bfd_data) (bfd *, bfd *);
+ /* Called to initialize BFD private section data from one object file
+ to another. */
+#define bfd_init_private_section_data(ibfd, isec, obfd, osec, link_info) \
+ BFD_SEND (obfd, _bfd_init_private_section_data, (ibfd, isec, obfd, osec, link_info))
+ bfd_boolean (*_bfd_init_private_section_data)
+ (bfd *, sec_ptr, bfd *, sec_ptr, struct bfd_link_info *);
+ /* Called to copy BFD private section data from one object file
+ to another. */
+ bfd_boolean (*_bfd_copy_private_section_data)
+ (bfd *, sec_ptr, bfd *, sec_ptr);
+ /* Called to copy BFD private symbol data from one symbol
+ to another. */
+ bfd_boolean (*_bfd_copy_private_symbol_data)
+ (bfd *, asymbol *, bfd *, asymbol *);
+ /* Called to copy BFD private header data from one object file
+ to another. */
+ bfd_boolean (*_bfd_copy_private_header_data)
+ (bfd *, bfd *);
+ /* Called to set private backend flags. */
+ bfd_boolean (*_bfd_set_private_flags) (bfd *, flagword);
+
+ /* Called to print private BFD data. */
+ bfd_boolean (*_bfd_print_private_bfd_data) (bfd *, void *);
+
+ /* Core file entry points. */
+#define BFD_JUMP_TABLE_CORE(NAME) \
+ NAME##_core_file_failing_command, \
+ NAME##_core_file_failing_signal, \
+ NAME##_core_file_matches_executable_p
+
+ char * (*_core_file_failing_command) (bfd *);
+ int (*_core_file_failing_signal) (bfd *);
+ bfd_boolean (*_core_file_matches_executable_p) (bfd *, bfd *);
+
+ /* Archive entry points. */
+#define BFD_JUMP_TABLE_ARCHIVE(NAME) \
+ NAME##_slurp_armap, \
+ NAME##_slurp_extended_name_table, \
+ NAME##_construct_extended_name_table, \
+ NAME##_truncate_arname, \
+ NAME##_write_armap, \
+ NAME##_read_ar_hdr, \
+ NAME##_openr_next_archived_file, \
+ NAME##_get_elt_at_index, \
+ NAME##_generic_stat_arch_elt, \
+ NAME##_update_armap_timestamp
+
+ bfd_boolean (*_bfd_slurp_armap) (bfd *);
+ bfd_boolean (*_bfd_slurp_extended_name_table) (bfd *);
+ bfd_boolean (*_bfd_construct_extended_name_table)
+ (bfd *, char **, bfd_size_type *, const char **);
+ void (*_bfd_truncate_arname) (bfd *, const char *, char *);
+ bfd_boolean (*write_armap)
+ (bfd *, unsigned int, struct orl *, unsigned int, int);
+ void * (*_bfd_read_ar_hdr_fn) (bfd *);
+ bfd * (*openr_next_archived_file) (bfd *, bfd *);
+#define bfd_get_elt_at_index(b,i) BFD_SEND (b, _bfd_get_elt_at_index, (b,i))
+ bfd * (*_bfd_get_elt_at_index) (bfd *, symindex);
+ int (*_bfd_stat_arch_elt) (bfd *, struct stat *);
+ bfd_boolean (*_bfd_update_armap_timestamp) (bfd *);
+
+ /* Entry points used for symbols. */
+#define BFD_JUMP_TABLE_SYMBOLS(NAME) \
+ NAME##_get_symtab_upper_bound, \
+ NAME##_canonicalize_symtab, \
+ NAME##_make_empty_symbol, \
+ NAME##_print_symbol, \
+ NAME##_get_symbol_info, \
+ NAME##_bfd_is_local_label_name, \
+ NAME##_bfd_is_target_special_symbol, \
+ NAME##_get_lineno, \
+ NAME##_find_nearest_line, \
+ _bfd_generic_find_line, \
+ NAME##_find_inliner_info, \
+ NAME##_bfd_make_debug_symbol, \
+ NAME##_read_minisymbols, \
+ NAME##_minisymbol_to_symbol
+
+ long (*_bfd_get_symtab_upper_bound) (bfd *);
+ long (*_bfd_canonicalize_symtab)
+ (bfd *, struct bfd_symbol **);
+ struct bfd_symbol *
+ (*_bfd_make_empty_symbol) (bfd *);
+ void (*_bfd_print_symbol)
+ (bfd *, void *, struct bfd_symbol *, bfd_print_symbol_type);
+#define bfd_print_symbol(b,p,s,e) BFD_SEND (b, _bfd_print_symbol, (b,p,s,e))
+ void (*_bfd_get_symbol_info)
+ (bfd *, struct bfd_symbol *, symbol_info *);
+#define bfd_get_symbol_info(b,p,e) BFD_SEND (b, _bfd_get_symbol_info, (b,p,e))
+ bfd_boolean (*_bfd_is_local_label_name) (bfd *, const char *);
+ bfd_boolean (*_bfd_is_target_special_symbol) (bfd *, asymbol *);
+ alent * (*_get_lineno) (bfd *, struct bfd_symbol *);
+ bfd_boolean (*_bfd_find_nearest_line)
+ (bfd *, struct bfd_section *, struct bfd_symbol **, bfd_vma,
+ const char **, const char **, unsigned int *);
+ bfd_boolean (*_bfd_find_line)
+ (bfd *, struct bfd_symbol **, struct bfd_symbol *,
+ const char **, unsigned int *);
+ bfd_boolean (*_bfd_find_inliner_info)
+ (bfd *, const char **, const char **, unsigned int *);
+ /* Back-door to allow format-aware applications to create debug symbols
+ while using BFD for everything else. Currently used by the assembler
+ when creating COFF files. */
+ asymbol * (*_bfd_make_debug_symbol)
+ (bfd *, void *, unsigned long size);
+#define bfd_read_minisymbols(b, d, m, s) \
+ BFD_SEND (b, _read_minisymbols, (b, d, m, s))
+ long (*_read_minisymbols)
+ (bfd *, bfd_boolean, void **, unsigned int *);
+#define bfd_minisymbol_to_symbol(b, d, m, f) \
+ BFD_SEND (b, _minisymbol_to_symbol, (b, d, m, f))
+ asymbol * (*_minisymbol_to_symbol)
+ (bfd *, bfd_boolean, const void *, asymbol *);
+
+ /* Routines for relocs. */
+#define BFD_JUMP_TABLE_RELOCS(NAME) \
+ NAME##_get_reloc_upper_bound, \
+ NAME##_canonicalize_reloc, \
+ NAME##_bfd_reloc_type_lookup
+
+ long (*_get_reloc_upper_bound) (bfd *, sec_ptr);
+ long (*_bfd_canonicalize_reloc)
+ (bfd *, sec_ptr, arelent **, struct bfd_symbol **);
+ /* See documentation on reloc types. */
+ reloc_howto_type *
+ (*reloc_type_lookup) (bfd *, bfd_reloc_code_real_type);
+
+ /* Routines used when writing an object file. */
+#define BFD_JUMP_TABLE_WRITE(NAME) \
+ NAME##_set_arch_mach, \
+ NAME##_set_section_contents
+
+ bfd_boolean (*_bfd_set_arch_mach)
+ (bfd *, enum bfd_architecture, unsigned long);
+ bfd_boolean (*_bfd_set_section_contents)
+ (bfd *, sec_ptr, const void *, file_ptr, bfd_size_type);
+
+ /* Routines used by the linker. */
+#define BFD_JUMP_TABLE_LINK(NAME) \
+ NAME##_sizeof_headers, \
+ NAME##_bfd_get_relocated_section_contents, \
+ NAME##_bfd_relax_section, \
+ NAME##_bfd_link_hash_table_create, \
+ NAME##_bfd_link_hash_table_free, \
+ NAME##_bfd_link_add_symbols, \
+ NAME##_bfd_link_just_syms, \
+ NAME##_bfd_final_link, \
+ NAME##_bfd_link_split_section, \
+ NAME##_bfd_gc_sections, \
+ NAME##_bfd_merge_sections, \
+ NAME##_bfd_is_group_section, \
+ NAME##_bfd_discard_group, \
+ NAME##_section_already_linked \
+
+ int (*_bfd_sizeof_headers) (bfd *, bfd_boolean);
+ bfd_byte * (*_bfd_get_relocated_section_contents)
+ (bfd *, struct bfd_link_info *, struct bfd_link_order *,
+ bfd_byte *, bfd_boolean, struct bfd_symbol **);
+
+ bfd_boolean (*_bfd_relax_section)
+ (bfd *, struct bfd_section *, struct bfd_link_info *, bfd_boolean *);
+
+ /* Create a hash table for the linker. Different backends store
+ different information in this table. */
+ struct bfd_link_hash_table *
+ (*_bfd_link_hash_table_create) (bfd *);
+
+ /* Release the memory associated with the linker hash table. */
+ void (*_bfd_link_hash_table_free) (struct bfd_link_hash_table *);
+
+ /* Add symbols from this object file into the hash table. */
+ bfd_boolean (*_bfd_link_add_symbols) (bfd *, struct bfd_link_info *);
+
+ /* Indicate that we are only retrieving symbol values from this section. */
+ void (*_bfd_link_just_syms) (asection *, struct bfd_link_info *);
+
+ /* Do a link based on the link_order structures attached to each
+ section of the BFD. */
+ bfd_boolean (*_bfd_final_link) (bfd *, struct bfd_link_info *);
+
+ /* Should this section be split up into smaller pieces during linking. */
+ bfd_boolean (*_bfd_link_split_section) (bfd *, struct bfd_section *);
+
+ /* Remove sections that are not referenced from the output. */
+ bfd_boolean (*_bfd_gc_sections) (bfd *, struct bfd_link_info *);
+
+ /* Attempt to merge SEC_MERGE sections. */
+ bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *);
+
+ /* Is this section a member of a group? */
+ bfd_boolean (*_bfd_is_group_section) (bfd *, const struct bfd_section *);
+
+ /* Discard members of a group. */
+ bfd_boolean (*_bfd_discard_group) (bfd *, struct bfd_section *);
+
+ /* Check if SEC has been already linked during a reloceatable or
+ final link. */
+ void (*_section_already_linked) (bfd *, struct bfd_section *);
+
+ /* Routines to handle dynamic symbols and relocs. */
+#define BFD_JUMP_TABLE_DYNAMIC(NAME) \
+ NAME##_get_dynamic_symtab_upper_bound, \
+ NAME##_canonicalize_dynamic_symtab, \
+ NAME##_get_synthetic_symtab, \
+ NAME##_get_dynamic_reloc_upper_bound, \
+ NAME##_canonicalize_dynamic_reloc
+
+ /* Get the amount of memory required to hold the dynamic symbols. */
+ long (*_bfd_get_dynamic_symtab_upper_bound) (bfd *);
+ /* Read in the dynamic symbols. */
+ long (*_bfd_canonicalize_dynamic_symtab)
+ (bfd *, struct bfd_symbol **);
+ /* Create synthetized symbols. */
+ long (*_bfd_get_synthetic_symtab)
+ (bfd *, long, struct bfd_symbol **, long, struct bfd_symbol **,
+ struct bfd_symbol **);
+ /* Get the amount of memory required to hold the dynamic relocs. */
+ long (*_bfd_get_dynamic_reloc_upper_bound) (bfd *);
+ /* Read in the dynamic relocs. */
+ long (*_bfd_canonicalize_dynamic_reloc)
+ (bfd *, arelent **, struct bfd_symbol **);
+
+ /* Opposite endian version of this target. */
+ const struct bfd_target * alternative_target;
+
+ /* Data for use by back-end routines, which isn't
+ generic enough to belong in this structure. */
+ const void *backend_data;
+
+} bfd_target;
+
+bfd_boolean bfd_set_default_target (const char *name);
+
+const bfd_target *bfd_find_target (const char *target_name, bfd *abfd);
+
+const char ** bfd_target_list (void);
+
+const bfd_target *bfd_search_for_target
+ (int (*search_func) (const bfd_target *, void *),
+ void *);
+
+/* Extracted from format.c. */
+bfd_boolean bfd_check_format (bfd *abfd, bfd_format format);
+
+bfd_boolean bfd_check_format_matches
+ (bfd *abfd, bfd_format format, char ***matching);
+
+bfd_boolean bfd_set_format (bfd *abfd, bfd_format format);
+
+const char *bfd_format_string (bfd_format format);
+
+/* Extracted from linker.c. */
+bfd_boolean bfd_link_split_section (bfd *abfd, asection *sec);
+
+#define bfd_link_split_section(abfd, sec) \
+ BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec))
+
+void bfd_section_already_linked (bfd *abfd, asection *sec);
+
+#define bfd_section_already_linked(abfd, sec) \
+ BFD_SEND (abfd, _section_already_linked, (abfd, sec))
+
+/* Extracted from simple.c. */
+bfd_byte *bfd_simple_get_relocated_section_contents
+ (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
--- /dev/null
+#ifndef _ASM_KDB_H
+#define _ASM_KDB_H
+
+/*
+ * Kernel Debugger Architecture Dependent Global Headers
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * KDB_ENTER() is a macro which causes entry into the kernel
+ * debugger from any point in the kernel code stream. If it
+ * is intended to be used from interrupt level, it must use
+ * a non-maskable entry method.
+ */
+#include <asm/kdb_break.h> /* break numbers are separated for CONFIG_KDB_LOCK */
+#define __KDB_ENTER2(b) asm("\tbreak.m "#b"\n")
+#define __KDB_ENTER1(b) __KDB_ENTER2(b)
+#define KDB_ENTER() do {if (kdb_on && !KDB_IS_RUNNING()) { __KDB_ENTER1(KDB_BREAK_ENTER); }} while(0)
+#define KDB_ENTER_SLAVE() do {if (kdb_on) { __KDB_ENTER1(KDB_BREAK_ENTER_SLAVE); }} while(0)
+
+ /*
+ * Needed for exported symbols.
+ */
+typedef unsigned long kdb_machreg_t;
+
+#define kdb_machreg_fmt "0x%lx"
+#define kdb_machreg_fmt0 "0x%016lx"
+#define kdb_bfd_vma_fmt "0x%lx"
+#define kdb_bfd_vma_fmt0 "0x%016lx"
+#define kdb_elfw_addr_fmt "0x%lx"
+#define kdb_elfw_addr_fmt0 "0x%016lx"
+
+static inline unsigned long
+kdba_funcptr_value(void *fp)
+{
+ /* ia64 function descriptor, first word is address of code */
+ return *(unsigned long *)fp;
+}
+
+#endif /* !_ASM_KDB_H */
--- /dev/null
+#ifndef _ASM_KDB_BREAK_H
+#define _ASM_KDB_BREAK_H
+
+/*
+ * Kernel Debugger Architecture Dependent Global Headers
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * Break numbers are used by CONFIG_KDB_LOCK code. They need to be seperated
+ * from asm/kdb.h to let spinlock code build without pulling in all of the kdb
+ * headers.
+ */
+
+#define KDB_BREAK_BREAK 0x80100 /* kdb breakpoint in kernel */
+#define KDB_BREAK_ENTER 0x80101 /* KDB_ENTER(), single event or monarch */
+#define KDB_BREAK_ENTER_SLAVE 0x80102 /* KDB_ENTER_SLAVE(), concurrent slave events */
+
+#endif /* !_ASM_KDB_BREAK_H */
--- /dev/null
+#ifndef _ASM_KDBPRIVATE_H
+#define _ASM_KDBPRIVATE_H
+
+/*
+ * Kernel Debugger Architecture Dependent Private Headers
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/* Definition of an machine instruction.
+ * Takes care of VLIW processors like Itanium
+ */
+
+typedef struct {
+ unsigned long inst[2];
+} kdb_machinst_t;
+
+/*
+ * KDB_MAXBPT describes the total number of breakpoints
+ * supported by this architecure.
+ */
+#define KDB_MAXBPT 16
+
+/*
+ * KDB_MAXHARDBPT describes the total number of hardware
+ * breakpoint registers that exist.
+ */
+#define KDB_MAXHARDBPT 4
+
+/*
+ * Platform specific environment entries
+ */
+#define KDB_PLATFORM_ENV "IDMODE=ia64", "BYTESPERWORD=4", "IDCOUNT=8"
+
+/*
+ * Support for IA64 debug registers
+ */
+typedef struct _kdbhard_bp {
+ kdb_machreg_t bph_reg; /* Register this breakpoint uses */
+
+ unsigned int bph_free:1; /* Register available for use */
+ unsigned int bph_data:1; /* Data Access breakpoint */
+
+ unsigned int bph_write:1; /* Write Data breakpoint */
+ unsigned int bph_mode:2; /* 0=inst, 1=write, 2=io, 3=read */
+ unsigned int bph_length:2; /* 0=1, 1=2, 2=BAD, 3=4 (bytes) */
+} kdbhard_bp_t;
+
+#define getprsregs(regs) ((struct switch_stack *)regs -1)
+
+/* bkpt support using break inst instead of IBP reg */
+
+/*
+ * Define certain specific instructions
+ */
+#define BREAK_INSTR (long)(KDB_BREAK_BREAK << (5+6))
+#define INST_SLOT0_MASK (0x1ffffffffffL << 5)
+
+#define BKPTMODE_DATAR 3
+#define BKPTMODE_IO 2
+#define BKPTMODE_DATAW 1
+#define BKPTMODE_INST 0
+
+/* Some of the fault registers needed by kdb but not passed with
+ * regs or switch stack.
+ */
+typedef struct fault_regs {
+ unsigned long isr ;
+ unsigned long ifa ;
+ unsigned long iim ;
+ unsigned long itir ;
+} fault_regs_t ;
+
+/*
+ * Support for setjmp/longjmp
+ */
+
+/* __jmp_buf definition copied from libc/sysdeps/unix/sysv/linux/ia64/bits/setjmp.h */
+
+#define _JBLEN 70
+
+typedef struct __kdb_jmp_buf {
+ unsigned long __jmp_buf[_JBLEN];
+} kdb_jmp_buf __attribute__ ((aligned (16)));
+
+extern int kdba_setjmp(kdb_jmp_buf *);
+extern void kdba_longjmp(kdb_jmp_buf *, int);
+#define kdba_setjmp kdba_setjmp
+
+extern kdb_jmp_buf *kdbjmpbuf;
+
+/* Arch specific data saved for running processes */
+
+struct kdba_running_process {
+ struct switch_stack *sw;
+};
+
+extern void kdba_save_running(struct kdba_running_process *, struct pt_regs *);
+extern void kdba_unsave_running(struct kdba_running_process *, struct pt_regs *);
+
+/* kdba wrappers which want to save switch stack will call unw_init_running().
+ * That routine only takes a void* so pack the interrupt data into a structure.
+ */
+
+#include <linux/interrupt.h> /* for irqreturn_t */
+
+/* The kdba handlers that sit between wrapper -> unw_init_running -> real
+ * function are almost identical. They differ in the function name, the
+ * type of data passed as void* to unw_init_running, the value to print
+ * in the debug statement and the invocation of the real function.
+ *
+ * data_type must be a structure that contains 'struct pt_regs *regs;'.
+ */
+
+#define KDBA_UNWIND_HANDLER(name, data_type, debug_value, invoke...) \
+void name(struct unw_frame_info *info, void *vdata) \
+{ \
+ data_type *data = vdata; \
+ struct switch_stack *sw, *prev_sw; \
+ struct pt_regs *prev_regs; \
+ struct kdb_running_process *krp = \
+ kdb_running_process + smp_processor_id(); \
+ KDB_DEBUG_STATE(__FUNCTION__, debug_value); \
+ prev_sw = krp->arch.sw; \
+ sw = (struct switch_stack *)(info+1); \
+ /* padding from unw_init_running */ \
+ sw = (struct switch_stack *)(((unsigned long)sw + 15) & ~15); \
+ krp->arch.sw = sw; \
+ prev_regs = krp->regs; \
+ kdb_save_running(data->regs); \
+ invoke; \
+ kdb_unsave_running(data->regs); \
+ krp->regs = prev_regs; \
+ krp->arch.sw = prev_sw; \
+}
+
+enum kdba_serial_console {
+ KDBA_SC_NONE = 0,
+ KDBA_SC_STANDARD,
+ KDBA_SC_SGI_L1,
+};
+
+extern enum kdba_serial_console kdba_serial_console;
+
+#define KDB_RUNNING_PROCESS_ORIGINAL kdb_running_process_save
+extern struct kdb_running_process *kdb_running_process_save; /* [NR_CPUS] */
+
+extern void kdba_wait_for_cpus(void);
+
+#endif /* !_ASM_KDBPRIVATE_H */
extern void xpc_activate_kthreads(struct xpc_channel *, int);
extern void xpc_create_kthreads(struct xpc_channel *, int, int);
extern void xpc_disconnect_wait(int);
+extern int xpc_kdebug_force_disengage(void);
/* found in xpc_partition.c */
--- /dev/null
+/* Cut down version, enough for KDB */
+/* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically
+ generated from "bfd-in.h", "init.c", "opncls.c", "libbfd.c",
+ "bfdio.c", "bfdwin.c", "section.c", "archures.c", "reloc.c",
+ "syms.c", "bfd.c", "archive.c", "corefile.c", "targets.c", "format.c",
+ "linker.c" and "simple.c".
+ Run "make headers" in your build bfd/ to regenerate. */
+
+/* Main header file for the bfd library -- portable access to object files.
+
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Support.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use.
+ * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as
+ * required.
+ * Keith Owens <kaos@sgi.com> 15 May 2006
+ */
+
+#ifndef __BFD_H_SEEN__
+#define __BFD_H_SEEN__
+
+#ifdef __KERNEL__
+#include <linux/ansidecl.h>
+#else /* __KERNEL__ */
+#include "ansidecl.h"
+#include "symcat.h"
+#endif /* __KERNEL__ */
+
+/* The word size used by BFD on the host. This may be 64 with a 32
+ bit target if the host is 64 bit, or if other 64 bit targets have
+ been selected with --enable-targets, or if --enable-64-bit-bfd. */
+#define BFD_ARCH_SIZE 64
+
+/* The word size of the default bfd target. */
+#define BFD_DEFAULT_TARGET_SIZE 64
+
+#define BFD_HOST_64BIT_LONG 1
+#define BFD_HOST_LONG_LONG 1
+#if 1
+#define BFD_HOST_64_BIT long
+#define BFD_HOST_U_64_BIT unsigned long
+typedef BFD_HOST_64_BIT bfd_int64_t;
+typedef BFD_HOST_U_64_BIT bfd_uint64_t;
+#endif
+
+#if BFD_ARCH_SIZE >= 64
+#define BFD64
+#endif
+
+#ifndef INLINE
+#if __GNUC__ >= 2
+#define INLINE __inline__
+#else
+#define INLINE
+#endif
+#endif
+
+/* Forward declaration. */
+typedef struct bfd bfd;
+
+/* Boolean type used in bfd. Too many systems define their own
+ versions of "boolean" for us to safely typedef a "boolean" of
+ our own. Using an enum for "bfd_boolean" has its own set of
+ problems, with strange looking casts required to avoid warnings
+ on some older compilers. Thus we just use an int.
+
+ General rule: Functions which are bfd_boolean return TRUE on
+ success and FALSE on failure (unless they're a predicate). */
+
+typedef int bfd_boolean;
+#undef FALSE
+#undef TRUE
+#define FALSE 0
+#define TRUE 1
+
+#ifdef BFD64
+
+#ifndef BFD_HOST_64_BIT
+ #error No 64 bit integer type available
+#endif /* ! defined (BFD_HOST_64_BIT) */
+
+typedef BFD_HOST_U_64_BIT bfd_vma;
+typedef BFD_HOST_64_BIT bfd_signed_vma;
+typedef BFD_HOST_U_64_BIT bfd_size_type;
+typedef BFD_HOST_U_64_BIT symvalue;
+
+#ifndef fprintf_vma
+#if BFD_HOST_64BIT_LONG
+#define sprintf_vma(s,x) sprintf (s, "%016lx", x)
+#define fprintf_vma(f,x) fprintf (f, "%016lx", x)
+#else
+#define _bfd_int64_low(x) ((unsigned long) (((x) & 0xffffffff)))
+#define _bfd_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff))
+#define fprintf_vma(s,x) \
+ fprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x))
+#define sprintf_vma(s,x) \
+ sprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x))
+#endif
+#endif
+
+#else /* not BFD64 */
+
+/* Represent a target address. Also used as a generic unsigned type
+ which is guaranteed to be big enough to hold any arithmetic types
+ we need to deal with. */
+typedef unsigned long bfd_vma;
+
+/* A generic signed type which is guaranteed to be big enough to hold any
+ arithmetic types we need to deal with. Can be assumed to be compatible
+ with bfd_vma in the same way that signed and unsigned ints are compatible
+ (as parameters, in assignment, etc). */
+typedef long bfd_signed_vma;
+
+typedef unsigned long symvalue;
+typedef unsigned long bfd_size_type;
+
+/* Print a bfd_vma x on stream s. */
+#define fprintf_vma(s,x) fprintf (s, "%08lx", x)
+#define sprintf_vma(s,x) sprintf (s, "%08lx", x)
+
+#endif /* not BFD64 */
+
+#define HALF_BFD_SIZE_TYPE \
+ (((bfd_size_type) 1) << (8 * sizeof (bfd_size_type) / 2))
+
+#ifndef BFD_HOST_64_BIT
+/* Fall back on a 32 bit type. The idea is to make these types always
+ available for function return types, but in the case that
+ BFD_HOST_64_BIT is undefined such a function should abort or
+ otherwise signal an error. */
+typedef bfd_signed_vma bfd_int64_t;
+typedef bfd_vma bfd_uint64_t;
+#endif
+
+/* An offset into a file. BFD always uses the largest possible offset
+ based on the build time availability of fseek, fseeko, or fseeko64. */
+typedef BFD_HOST_64_BIT file_ptr;
+typedef unsigned BFD_HOST_64_BIT ufile_ptr;
+
+extern void bfd_sprintf_vma (bfd *, char *, bfd_vma);
+extern void bfd_fprintf_vma (bfd *, void *, bfd_vma);
+
+#define printf_vma(x) fprintf_vma(stdout,x)
+#define bfd_printf_vma(abfd,x) bfd_fprintf_vma (abfd,stdout,x)
+
+typedef unsigned int flagword; /* 32 bits of flags */
+typedef unsigned char bfd_byte;
+
+/* Extracted from archures.c. */
+enum bfd_architecture
+{
+ bfd_arch_unknown, /* File arch not known. */
+ bfd_arch_obscure, /* Arch known, not one of these. */
+ bfd_arch_m68k, /* Motorola 68xxx */
+#define bfd_mach_m68000 1
+#define bfd_mach_m68008 2
+#define bfd_mach_m68010 3
+#define bfd_mach_m68020 4
+#define bfd_mach_m68030 5
+#define bfd_mach_m68040 6
+#define bfd_mach_m68060 7
+#define bfd_mach_cpu32 8
+#define bfd_mach_mcf5200 9
+#define bfd_mach_mcf5206e 10
+#define bfd_mach_mcf5307 11
+#define bfd_mach_mcf5407 12
+#define bfd_mach_mcf528x 13
+#define bfd_mach_mcfv4e 14
+#define bfd_mach_mcf521x 15
+#define bfd_mach_mcf5249 16
+#define bfd_mach_mcf547x 17
+#define bfd_mach_mcf548x 18
+ bfd_arch_vax, /* DEC Vax */
+ bfd_arch_i960, /* Intel 960 */
+ /* The order of the following is important.
+ lower number indicates a machine type that
+ only accepts a subset of the instructions
+ available to machines with higher numbers.
+ The exception is the "ca", which is
+ incompatible with all other machines except
+ "core". */
+
+#define bfd_mach_i960_core 1
+#define bfd_mach_i960_ka_sa 2
+#define bfd_mach_i960_kb_sb 3
+#define bfd_mach_i960_mc 4
+#define bfd_mach_i960_xa 5
+#define bfd_mach_i960_ca 6
+#define bfd_mach_i960_jx 7
+#define bfd_mach_i960_hx 8
+
+ bfd_arch_or32, /* OpenRISC 32 */
+
+ bfd_arch_a29k, /* AMD 29000 */
+ bfd_arch_sparc, /* SPARC */
+#define bfd_mach_sparc 1
+/* The difference between v8plus and v9 is that v9 is a true 64 bit env. */
+#define bfd_mach_sparc_sparclet 2
+#define bfd_mach_sparc_sparclite 3
+#define bfd_mach_sparc_v8plus 4
+#define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns. */
+#define bfd_mach_sparc_sparclite_le 6
+#define bfd_mach_sparc_v9 7
+#define bfd_mach_sparc_v9a 8 /* with ultrasparc add'ns. */
+#define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */
+#define bfd_mach_sparc_v9b 10 /* with cheetah add'ns. */
+/* Nonzero if MACH has the v9 instruction set. */
+#define bfd_mach_sparc_v9_p(mach) \
+ ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9b \
+ && (mach) != bfd_mach_sparc_sparclite_le)
+/* Nonzero if MACH is a 64 bit sparc architecture. */
+#define bfd_mach_sparc_64bit_p(mach) \
+ ((mach) >= bfd_mach_sparc_v9 && (mach) != bfd_mach_sparc_v8plusb)
+ bfd_arch_mips, /* MIPS Rxxxx */
+#define bfd_mach_mips3000 3000
+#define bfd_mach_mips3900 3900
+#define bfd_mach_mips4000 4000
+#define bfd_mach_mips4010 4010
+#define bfd_mach_mips4100 4100
+#define bfd_mach_mips4111 4111
+#define bfd_mach_mips4120 4120
+#define bfd_mach_mips4300 4300
+#define bfd_mach_mips4400 4400
+#define bfd_mach_mips4600 4600
+#define bfd_mach_mips4650 4650
+#define bfd_mach_mips5000 5000
+#define bfd_mach_mips5400 5400
+#define bfd_mach_mips5500 5500
+#define bfd_mach_mips6000 6000
+#define bfd_mach_mips7000 7000
+#define bfd_mach_mips8000 8000
+#define bfd_mach_mips9000 9000
+#define bfd_mach_mips10000 10000
+#define bfd_mach_mips12000 12000
+#define bfd_mach_mips16 16
+#define bfd_mach_mips5 5
+#define bfd_mach_mips_sb1 12310201 /* octal 'SB', 01 */
+#define bfd_mach_mipsisa32 32
+#define bfd_mach_mipsisa32r2 33
+#define bfd_mach_mipsisa64 64
+#define bfd_mach_mipsisa64r2 65
+ bfd_arch_i386, /* Intel 386 */
+#define bfd_mach_i386_i386 1
+#define bfd_mach_i386_i8086 2
+#define bfd_mach_i386_i386_intel_syntax 3
+#define bfd_mach_x86_64 64
+#define bfd_mach_x86_64_intel_syntax 65
+ bfd_arch_we32k, /* AT&T WE32xxx */
+ bfd_arch_tahoe, /* CCI/Harris Tahoe */
+ bfd_arch_i860, /* Intel 860 */
+ bfd_arch_i370, /* IBM 360/370 Mainframes */
+ bfd_arch_romp, /* IBM ROMP PC/RT */
+ bfd_arch_alliant, /* Alliant */
+ bfd_arch_convex, /* Convex */
+ bfd_arch_m88k, /* Motorola 88xxx */
+ bfd_arch_m98k, /* Motorola 98xxx */
+ bfd_arch_pyramid, /* Pyramid Technology */
+ bfd_arch_h8300, /* Renesas H8/300 (formerly Hitachi H8/300) */
+#define bfd_mach_h8300 1
+#define bfd_mach_h8300h 2
+#define bfd_mach_h8300s 3
+#define bfd_mach_h8300hn 4
+#define bfd_mach_h8300sn 5
+#define bfd_mach_h8300sx 6
+#define bfd_mach_h8300sxn 7
+ bfd_arch_pdp11, /* DEC PDP-11 */
+ bfd_arch_powerpc, /* PowerPC */
+#define bfd_mach_ppc 32
+#define bfd_mach_ppc64 64
+#define bfd_mach_ppc_403 403
+#define bfd_mach_ppc_403gc 4030
+#define bfd_mach_ppc_505 505
+#define bfd_mach_ppc_601 601
+#define bfd_mach_ppc_602 602
+#define bfd_mach_ppc_603 603
+#define bfd_mach_ppc_ec603e 6031
+#define bfd_mach_ppc_604 604
+#define bfd_mach_ppc_620 620
+#define bfd_mach_ppc_630 630
+#define bfd_mach_ppc_750 750
+#define bfd_mach_ppc_860 860
+#define bfd_mach_ppc_a35 35
+#define bfd_mach_ppc_rs64ii 642
+#define bfd_mach_ppc_rs64iii 643
+#define bfd_mach_ppc_7400 7400
+#define bfd_mach_ppc_e500 500
+ bfd_arch_rs6000, /* IBM RS/6000 */
+#define bfd_mach_rs6k 6000
+#define bfd_mach_rs6k_rs1 6001
+#define bfd_mach_rs6k_rsc 6003
+#define bfd_mach_rs6k_rs2 6002
+ bfd_arch_hppa, /* HP PA RISC */
+#define bfd_mach_hppa10 10
+#define bfd_mach_hppa11 11
+#define bfd_mach_hppa20 20
+#define bfd_mach_hppa20w 25
+ bfd_arch_d10v, /* Mitsubishi D10V */
+#define bfd_mach_d10v 1
+#define bfd_mach_d10v_ts2 2
+#define bfd_mach_d10v_ts3 3
+ bfd_arch_d30v, /* Mitsubishi D30V */
+ bfd_arch_dlx, /* DLX */
+ bfd_arch_m68hc11, /* Motorola 68HC11 */
+ bfd_arch_m68hc12, /* Motorola 68HC12 */
+#define bfd_mach_m6812_default 0
+#define bfd_mach_m6812 1
+#define bfd_mach_m6812s 2
+ bfd_arch_z8k, /* Zilog Z8000 */
+#define bfd_mach_z8001 1
+#define bfd_mach_z8002 2
+ bfd_arch_h8500, /* Renesas H8/500 (formerly Hitachi H8/500) */
+ bfd_arch_sh, /* Renesas / SuperH SH (formerly Hitachi SH) */
+#define bfd_mach_sh 1
+#define bfd_mach_sh2 0x20
+#define bfd_mach_sh_dsp 0x2d
+#define bfd_mach_sh2a 0x2a
+#define bfd_mach_sh2a_nofpu 0x2b
+#define bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu 0x2a1
+#define bfd_mach_sh2a_nofpu_or_sh3_nommu 0x2a2
+#define bfd_mach_sh2a_or_sh4 0x2a3
+#define bfd_mach_sh2a_or_sh3e 0x2a4
+#define bfd_mach_sh2e 0x2e
+#define bfd_mach_sh3 0x30
+#define bfd_mach_sh3_nommu 0x31
+#define bfd_mach_sh3_dsp 0x3d
+#define bfd_mach_sh3e 0x3e
+#define bfd_mach_sh4 0x40
+#define bfd_mach_sh4_nofpu 0x41
+#define bfd_mach_sh4_nommu_nofpu 0x42
+#define bfd_mach_sh4a 0x4a
+#define bfd_mach_sh4a_nofpu 0x4b
+#define bfd_mach_sh4al_dsp 0x4d
+#define bfd_mach_sh5 0x50
+ bfd_arch_alpha, /* Dec Alpha */
+#define bfd_mach_alpha_ev4 0x10
+#define bfd_mach_alpha_ev5 0x20
+#define bfd_mach_alpha_ev6 0x30
+ bfd_arch_arm, /* Advanced Risc Machines ARM. */
+#define bfd_mach_arm_unknown 0
+#define bfd_mach_arm_2 1
+#define bfd_mach_arm_2a 2
+#define bfd_mach_arm_3 3
+#define bfd_mach_arm_3M 4
+#define bfd_mach_arm_4 5
+#define bfd_mach_arm_4T 6
+#define bfd_mach_arm_5 7
+#define bfd_mach_arm_5T 8
+#define bfd_mach_arm_5TE 9
+#define bfd_mach_arm_XScale 10
+#define bfd_mach_arm_ep9312 11
+#define bfd_mach_arm_iWMMXt 12
+ bfd_arch_ns32k, /* National Semiconductors ns32000 */
+ bfd_arch_w65, /* WDC 65816 */
+ bfd_arch_tic30, /* Texas Instruments TMS320C30 */
+ bfd_arch_tic4x, /* Texas Instruments TMS320C3X/4X */
+#define bfd_mach_tic3x 30
+#define bfd_mach_tic4x 40
+ bfd_arch_tic54x, /* Texas Instruments TMS320C54X */
+ bfd_arch_tic80, /* TI TMS320c80 (MVP) */
+ bfd_arch_v850, /* NEC V850 */
+#define bfd_mach_v850 1
+#define bfd_mach_v850e 'E'
+#define bfd_mach_v850e1 '1'
+ bfd_arch_arc, /* ARC Cores */
+#define bfd_mach_arc_5 5
+#define bfd_mach_arc_6 6
+#define bfd_mach_arc_7 7
+#define bfd_mach_arc_8 8
+ bfd_arch_m32c, /* Renesas M16C/M32C. */
+#define bfd_mach_m16c 0x75
+#define bfd_mach_m32c 0x78
+ bfd_arch_m32r, /* Renesas M32R (formerly Mitsubishi M32R/D) */
+#define bfd_mach_m32r 1 /* For backwards compatibility. */
+#define bfd_mach_m32rx 'x'
+#define bfd_mach_m32r2 '2'
+ bfd_arch_mn10200, /* Matsushita MN10200 */
+ bfd_arch_mn10300, /* Matsushita MN10300 */
+#define bfd_mach_mn10300 300
+#define bfd_mach_am33 330
+#define bfd_mach_am33_2 332
+ bfd_arch_fr30,
+#define bfd_mach_fr30 0x46523330
+ bfd_arch_frv,
+#define bfd_mach_frv 1
+#define bfd_mach_frvsimple 2
+#define bfd_mach_fr300 300
+#define bfd_mach_fr400 400
+#define bfd_mach_fr450 450
+#define bfd_mach_frvtomcat 499 /* fr500 prototype */
+#define bfd_mach_fr500 500
+#define bfd_mach_fr550 550
+ bfd_arch_mcore,
+ bfd_arch_ia64, /* HP/Intel ia64 */
+#define bfd_mach_ia64_elf64 64
+#define bfd_mach_ia64_elf32 32
+ bfd_arch_ip2k, /* Ubicom IP2K microcontrollers. */
+#define bfd_mach_ip2022 1
+#define bfd_mach_ip2022ext 2
+ bfd_arch_iq2000, /* Vitesse IQ2000. */
+#define bfd_mach_iq2000 1
+#define bfd_mach_iq10 2
+ bfd_arch_ms1,
+#define bfd_mach_ms1 1
+#define bfd_mach_mrisc2 2
+ bfd_arch_pj,
+ bfd_arch_avr, /* Atmel AVR microcontrollers. */
+#define bfd_mach_avr1 1
+#define bfd_mach_avr2 2
+#define bfd_mach_avr3 3
+#define bfd_mach_avr4 4
+#define bfd_mach_avr5 5
+ bfd_arch_cr16c, /* National Semiconductor CompactRISC. */
+#define bfd_mach_cr16c 1
+ bfd_arch_crx, /* National Semiconductor CRX. */
+#define bfd_mach_crx 1
+ bfd_arch_cris, /* Axis CRIS */
+#define bfd_mach_cris_v0_v10 255
+#define bfd_mach_cris_v32 32
+#define bfd_mach_cris_v10_v32 1032
+ bfd_arch_s390, /* IBM s390 */
+#define bfd_mach_s390_31 31
+#define bfd_mach_s390_64 64
+ bfd_arch_openrisc, /* OpenRISC */
+ bfd_arch_mmix, /* Donald Knuth's educational processor. */
+ bfd_arch_xstormy16,
+#define bfd_mach_xstormy16 1
+ bfd_arch_msp430, /* Texas Instruments MSP430 architecture. */
+#define bfd_mach_msp11 11
+#define bfd_mach_msp110 110
+#define bfd_mach_msp12 12
+#define bfd_mach_msp13 13
+#define bfd_mach_msp14 14
+#define bfd_mach_msp15 15
+#define bfd_mach_msp16 16
+#define bfd_mach_msp31 31
+#define bfd_mach_msp32 32
+#define bfd_mach_msp33 33
+#define bfd_mach_msp41 41
+#define bfd_mach_msp42 42
+#define bfd_mach_msp43 43
+#define bfd_mach_msp44 44
+ bfd_arch_xtensa, /* Tensilica's Xtensa cores. */
+#define bfd_mach_xtensa 1
+ bfd_arch_maxq, /* Dallas MAXQ 10/20 */
+#define bfd_mach_maxq10 10
+#define bfd_mach_maxq20 20
+ bfd_arch_last
+ };
+
+enum bfd_flavour
+{
+ bfd_target_unknown_flavour,
+ bfd_target_aout_flavour,
+ bfd_target_coff_flavour,
+ bfd_target_ecoff_flavour,
+ bfd_target_xcoff_flavour,
+ bfd_target_elf_flavour,
+ bfd_target_ieee_flavour,
+ bfd_target_nlm_flavour,
+ bfd_target_oasys_flavour,
+ bfd_target_tekhex_flavour,
+ bfd_target_srec_flavour,
+ bfd_target_ihex_flavour,
+ bfd_target_som_flavour,
+ bfd_target_os9k_flavour,
+ bfd_target_versados_flavour,
+ bfd_target_msdos_flavour,
+ bfd_target_ovax_flavour,
+ bfd_target_evax_flavour,
+ bfd_target_mmo_flavour,
+ bfd_target_mach_o_flavour,
+ bfd_target_pef_flavour,
+ bfd_target_pef_xlib_flavour,
+ bfd_target_sym_flavour
+};
+
+enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
+
+#endif
--- /dev/null
+#ifndef _ASM_KDB_H
+#define _ASM_KDB_H
+
+/*
+ * Kernel Debugger Architecture Dependent Global Headers
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * KDB_ENTER() is a macro which causes entry into the kernel
+ * debugger from any point in the kernel code stream. If it
+ * is intended to be used from interrupt level, it must use
+ * a non-maskable entry method.
+ */
+extern void kdb_become_debugger(void);
+#define KDB_ENTER() do { kdb_become_debugger(); \
+ kdb(KDB_REASON_ENTER,0,NULL); } while (0)
+
+/*
+ * Define the exception frame for this architecture
+ */
+struct pt_regs;
+typedef struct pt_regs *kdb_eframe_t;
+
+/*
+ * Needed for exported symbols.
+ */
+typedef unsigned long kdb_machreg_t;
+
+#define kdb_machreg_fmt "0x%016lx"
+#define kdb_machreg_fmt0 "0x%016lx"
+#define kdb_bfd_vma_fmt "0x%016lx"
+#define kdb_bfd_vma_fmt0 "0x%016lx"
+#define kdb_elfw_addr_fmt "0x%016lx"
+#define kdb_elfw_addr_fmt0 "0x%016lx"
+
+/*
+ * Per cpu arch specific kdb state. Must be in range 0xff000000.
+ */
+#define KDB_STATE_A_IF 0x01000000 /* Saved IF flag */
+
+/*
+ * Interface from kernel trap handling code to kernel debugger.
+ */
+extern int kdba_callback_die(struct pt_regs *, int, long, void*);
+extern int kdba_callback_bp(struct pt_regs *, int, long, void*);
+extern int kdba_callback_debug(struct pt_regs *, int, long, void *);
+
+static inline unsigned long
+kdba_funcptr_value(void *fp)
+{
+ // XXX is this right? or is this fpdesc, of which we should
+ // return the first of the three pointers? (i.e. *fp) ???
+ return (unsigned long)fp;
+}
+
+#endif /* !_ASM_KDB_H */
--- /dev/null
+#ifndef _ASM_KDBPRIVATE_H
+#define _ASM_KDBPRIVATE_H
+
+/*
+ * Kernel Debugger Architecture Dependent Private Headers
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+typedef unsigned long kdb_machinst_t;
+
+ /*
+ * KDB_MAXBPT describes the total number of breakpoints
+ * supported by this architecure.
+ */
+#define KDB_MAXBPT 4
+ /*
+ * KDB_MAXHARDBPT describes the total number of hardware
+ * breakpoint registers that exist.
+ */
+#define KDB_MAXHARDBPT 1
+ /*
+ * Maximum number of arguments to a function.
+ */
+#define KDBA_MAXARGS 16
+ /*
+ * Provide space for KDB_MAX_COMMANDS commands.
+ */
+#define KDB_MAX_COMMANDS 125
+
+ /*
+ * Platform specific environment entries
+ */
+#define KDB_PLATFORM_ENV "IDMODE=PPC64", "BYTESPERWORD=8", "IDCOUNT=16", "RECURSE=2"
+
+ /*
+ * Support for ia32 debug registers
+ */
+typedef struct _kdbhard_bp {
+ kdb_machreg_t bph_reg; /* Register this breakpoint uses */
+
+ unsigned int bph_free:1; /* Register available for use */
+ unsigned int bph_data:1; /* Data Access breakpoint */
+
+ unsigned int bph_write:1; /* Write Data breakpoint */
+ unsigned int bph_mode:2; /* 0=inst, 1=write, 2=io, 3=read */
+ unsigned int bph_length:2; /* 0=1, 1=2, 2=BAD, 3=4 (bytes) */
+} kdbhard_bp_t;
+
+extern kdbhard_bp_t kdb_hardbreaks[/* KDB_MAXHARDBPT */];
+
+#define PPC64_BREAKPOINT_INSTRUCTION 0x7fe00008
+#define PPC64_ADJUST_OFFSET 0x00
+
+typedef struct __kdb_jmp_buf {
+ unsigned int regs[100];
+} kdb_jmp_buf;
+extern int kdba_setjmp(kdb_jmp_buf *);
+extern void kdba_longjmp(kdb_jmp_buf *, int);
+extern kdb_jmp_buf *kdbjmpbuf;
+#define kdba_setjmp kdba_setjmp
+
+/*
+ A traceback table typically follows each function.
+ The find_tb_table() func will fill in this struct. Note that the struct
+ is not an exact match with the encoded table defined by the ABI. It is
+ defined here more for programming convenience.
+ */
+#if 0 /* comment this as of now */
+typedef struct {
+ unsigned long flags; /* flags: */
+#define KDBTBTAB_FLAGSGLOBALLINK (1L<<47)
+#define KDBTBTAB_FLAGSISEPROL (1L<<46)
+#define KDBTBTAB_FLAGSHASTBOFF (1L<<45)
+#define KDBTBTAB_FLAGSINTPROC (1L<<44)
+#define KDBTBTAB_FLAGSHASCTL (1L<<43)
+#define KDBTBTAB_FLAGSTOCLESS (1L<<42)
+#define KDBTBTAB_FLAGSFPPRESENT (1L<<41)
+#define KDBTBTAB_FLAGSNAMEPRESENT (1L<<38)
+#define KDBTBTAB_FLAGSUSESALLOCA (1L<<37)
+#define KDBTBTAB_FLAGSSAVESCR (1L<<33)
+#define KDBTBTAB_FLAGSSAVESLR (1L<<32)
+#define KDBTBTAB_FLAGSSTORESBC (1L<<31)
+#define KDBTBTAB_FLAGSFIXUP (1L<<30)
+#define KDBTBTAB_FLAGSPARMSONSTK (1L<<0)
+ unsigned char fp_saved; /* num fp regs saved f(32-n)..f31 */
+ unsigned char gpr_saved; /* num gpr's saved */
+ unsigned char fixedparms; /* num fixed point parms */
+ unsigned char floatparms; /* num float parms */
+ unsigned char parminfo[32]; /* types of args. null terminated */
+#define KDBTBTAB_PARMFIXED 1
+#define KDBTBTAB_PARMSFLOAT 2
+#define KDBTBTAB_PARMDFLOAT 3
+ unsigned int tb_offset; /* offset from start of func */
+ unsigned long funcstart; /* addr of start of function */
+ char name[64]; /* name of function (null terminated)*/
+ kdb_symtab_t symtab; /* fake symtab entry */
+} kdbtbtable_t;
+extern int kdba_find_tb_table(kdb_machreg_t eip, kdbtbtable_t *tab);
+#endif /* if 0 */
+
+/* Arch specific data saved for running processes */
+
+struct kdba_running_process {
+ int dummy[0]; /* Everything is in pt_regs for i386 */
+};
+
+static inline
+void kdba_save_running(struct kdba_running_process *k, struct pt_regs *regs)
+{
+}
+
+static inline
+void kdba_unsave_running(struct kdba_running_process *k, struct pt_regs *regs)
+{
+}
+
+extern void kdba_wait_for_cpus(void);
+
+#endif /* !_ASM_KDBPRIVATE_H */
DIE_BPT,
DIE_SSTEP,
DIE_PAGE_FAULT,
+ DIE_KDEBUG_ENTER,
+ DIE_KDEBUG_LEAVE,
};
static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig)
extern int (*__debugger_iabr_match)(struct pt_regs *regs);
extern int (*__debugger_dabr_match)(struct pt_regs *regs);
extern int (*__debugger_fault_handler)(struct pt_regs *regs);
+extern int *__debugger_on;
#define DEBUGGER_BOILERPLATE(__NAME) \
static inline int __NAME(struct pt_regs *regs) \
return 0; \
}
-DEBUGGER_BOILERPLATE(debugger)
+extern int debugger(struct pt_regs *regs);
DEBUGGER_BOILERPLATE(debugger_ipi)
DEBUGGER_BOILERPLATE(debugger_bpt)
DEBUGGER_BOILERPLATE(debugger_sstep)
DEBUGGER_BOILERPLATE(debugger_dabr_match)
DEBUGGER_BOILERPLATE(debugger_fault_handler)
-#ifdef CONFIG_XMON
extern void xmon_init(int enable);
-#endif
+extern int xmon_on;
#else
static inline int debugger(struct pt_regs *regs) { return 0; }
--- /dev/null
+/* Cut down version, enough for KDB */
+/* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically
+ generated from "bfd-in.h", "init.c", "opncls.c", "libbfd.c",
+ "bfdio.c", "bfdwin.c", "section.c", "archures.c", "reloc.c",
+ "syms.c", "bfd.c", "archive.c", "corefile.c", "targets.c", "format.c",
+ "linker.c" and "simple.c".
+ Run "make headers" in your build bfd/ to regenerate. */
+
+/* Main header file for the bfd library -- portable access to object files.
+
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+ Contributed by Cygnus Support.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use.
+ * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as
+ * required.
+ * Keith Owens <kaos@sgi.com> 15 May 2006
+ */
+
+#ifndef __BFD_H_SEEN__
+#define __BFD_H_SEEN__
+
+#ifdef __KERNEL__
+#include <linux/ansidecl.h>
+#else /* __KERNEL__ */
+#include "ansidecl.h"
+#include "symcat.h"
+#endif /* __KERNEL__ */
+
+/* The word size used by BFD on the host. This may be 64 with a 32
+ bit target if the host is 64 bit, or if other 64 bit targets have
+ been selected with --enable-targets, or if --enable-64-bit-bfd. */
+#define BFD_ARCH_SIZE 64
+
+/* The word size of the default bfd target. */
+#define BFD_DEFAULT_TARGET_SIZE 64
+
+#define BFD_HOST_64BIT_LONG 1
+#define BFD_HOST_LONG_LONG 1
+#if 1
+#define BFD_HOST_64_BIT long
+#define BFD_HOST_U_64_BIT unsigned long
+typedef BFD_HOST_64_BIT bfd_int64_t;
+typedef BFD_HOST_U_64_BIT bfd_uint64_t;
+#endif
+
+#if BFD_ARCH_SIZE >= 64
+#define BFD64
+#endif
+
+#ifndef INLINE
+#if __GNUC__ >= 2
+#define INLINE __inline__
+#else
+#define INLINE
+#endif
+#endif
+
+/* Forward declaration. */
+typedef struct bfd bfd;
+
+/* Boolean type used in bfd. Too many systems define their own
+ versions of "boolean" for us to safely typedef a "boolean" of
+ our own. Using an enum for "bfd_boolean" has its own set of
+ problems, with strange looking casts required to avoid warnings
+ on some older compilers. Thus we just use an int.
+
+ General rule: Functions which are bfd_boolean return TRUE on
+ success and FALSE on failure (unless they're a predicate). */
+
+typedef int bfd_boolean;
+#undef FALSE
+#undef TRUE
+#define FALSE 0
+#define TRUE 1
+
+#ifdef BFD64
+
+#ifndef BFD_HOST_64_BIT
+ #error No 64 bit integer type available
+#endif /* ! defined (BFD_HOST_64_BIT) */
+
+typedef BFD_HOST_U_64_BIT bfd_vma;
+typedef BFD_HOST_64_BIT bfd_signed_vma;
+typedef BFD_HOST_U_64_BIT bfd_size_type;
+typedef BFD_HOST_U_64_BIT symvalue;
+
+#ifndef fprintf_vma
+#if BFD_HOST_64BIT_LONG
+#define sprintf_vma(s,x) sprintf (s, "%016lx", x)
+#define fprintf_vma(f,x) fprintf (f, "%016lx", x)
+#else
+#define _bfd_int64_low(x) ((unsigned long) (((x) & 0xffffffff)))
+#define _bfd_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff))
+#define fprintf_vma(s,x) \
+ fprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x))
+#define sprintf_vma(s,x) \
+ sprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x))
+#endif
+#endif
+
+#else /* not BFD64 */
+
+/* Represent a target address. Also used as a generic unsigned type
+ which is guaranteed to be big enough to hold any arithmetic types
+ we need to deal with. */
+typedef unsigned long bfd_vma;
+
+/* A generic signed type which is guaranteed to be big enough to hold any
+ arithmetic types we need to deal with. Can be assumed to be compatible
+ with bfd_vma in the same way that signed and unsigned ints are compatible
+ (as parameters, in assignment, etc). */
+typedef long bfd_signed_vma;
+
+typedef unsigned long symvalue;
+typedef unsigned long bfd_size_type;
+
+/* Print a bfd_vma x on stream s. */
+#define fprintf_vma(s,x) fprintf (s, "%08lx", x)
+#define sprintf_vma(s,x) sprintf (s, "%08lx", x)
+
+#endif /* not BFD64 */
+
+#define HALF_BFD_SIZE_TYPE \
+ (((bfd_size_type) 1) << (8 * sizeof (bfd_size_type) / 2))
+
+#ifndef BFD_HOST_64_BIT
+/* Fall back on a 32 bit type. The idea is to make these types always
+ available for function return types, but in the case that
+ BFD_HOST_64_BIT is undefined such a function should abort or
+ otherwise signal an error. */
+typedef bfd_signed_vma bfd_int64_t;
+typedef bfd_vma bfd_uint64_t;
+#endif
+
+/* An offset into a file. BFD always uses the largest possible offset
+ based on the build time availability of fseek, fseeko, or fseeko64. */
+typedef BFD_HOST_64_BIT file_ptr;
+typedef unsigned BFD_HOST_64_BIT ufile_ptr;
+
+extern void bfd_sprintf_vma (bfd *, char *, bfd_vma);
+extern void bfd_fprintf_vma (bfd *, void *, bfd_vma);
+
+#define printf_vma(x) fprintf_vma(stdout,x)
+#define bfd_printf_vma(abfd,x) bfd_fprintf_vma (abfd,stdout,x)
+
+typedef unsigned int flagword; /* 32 bits of flags */
+typedef unsigned char bfd_byte;
+
+/* Extracted from archures.c. */
+enum bfd_architecture
+{
+ bfd_arch_unknown, /* File arch not known. */
+ bfd_arch_obscure, /* Arch known, not one of these. */
+ bfd_arch_m68k, /* Motorola 68xxx */
+#define bfd_mach_m68000 1
+#define bfd_mach_m68008 2
+#define bfd_mach_m68010 3
+#define bfd_mach_m68020 4
+#define bfd_mach_m68030 5
+#define bfd_mach_m68040 6
+#define bfd_mach_m68060 7
+#define bfd_mach_cpu32 8
+#define bfd_mach_mcf5200 9
+#define bfd_mach_mcf5206e 10
+#define bfd_mach_mcf5307 11
+#define bfd_mach_mcf5407 12
+#define bfd_mach_mcf528x 13
+#define bfd_mach_mcfv4e 14
+#define bfd_mach_mcf521x 15
+#define bfd_mach_mcf5249 16
+#define bfd_mach_mcf547x 17
+#define bfd_mach_mcf548x 18
+ bfd_arch_vax, /* DEC Vax */
+ bfd_arch_i960, /* Intel 960 */
+ /* The order of the following is important.
+ lower number indicates a machine type that
+ only accepts a subset of the instructions
+ available to machines with higher numbers.
+ The exception is the "ca", which is
+ incompatible with all other machines except
+ "core". */
+
+#define bfd_mach_i960_core 1
+#define bfd_mach_i960_ka_sa 2
+#define bfd_mach_i960_kb_sb 3
+#define bfd_mach_i960_mc 4
+#define bfd_mach_i960_xa 5
+#define bfd_mach_i960_ca 6
+#define bfd_mach_i960_jx 7
+#define bfd_mach_i960_hx 8
+
+ bfd_arch_or32, /* OpenRISC 32 */
+
+ bfd_arch_a29k, /* AMD 29000 */
+ bfd_arch_sparc, /* SPARC */
+#define bfd_mach_sparc 1
+/* The difference between v8plus and v9 is that v9 is a true 64 bit env. */
+#define bfd_mach_sparc_sparclet 2
+#define bfd_mach_sparc_sparclite 3
+#define bfd_mach_sparc_v8plus 4
+#define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns. */
+#define bfd_mach_sparc_sparclite_le 6
+#define bfd_mach_sparc_v9 7
+#define bfd_mach_sparc_v9a 8 /* with ultrasparc add'ns. */
+#define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */
+#define bfd_mach_sparc_v9b 10 /* with cheetah add'ns. */
+/* Nonzero if MACH has the v9 instruction set. */
+#define bfd_mach_sparc_v9_p(mach) \
+ ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9b \
+ && (mach) != bfd_mach_sparc_sparclite_le)
+/* Nonzero if MACH is a 64 bit sparc architecture. */
+#define bfd_mach_sparc_64bit_p(mach) \
+ ((mach) >= bfd_mach_sparc_v9 && (mach) != bfd_mach_sparc_v8plusb)
+ bfd_arch_mips, /* MIPS Rxxxx */
+#define bfd_mach_mips3000 3000
+#define bfd_mach_mips3900 3900
+#define bfd_mach_mips4000 4000
+#define bfd_mach_mips4010 4010
+#define bfd_mach_mips4100 4100
+#define bfd_mach_mips4111 4111
+#define bfd_mach_mips4120 4120
+#define bfd_mach_mips4300 4300
+#define bfd_mach_mips4400 4400
+#define bfd_mach_mips4600 4600
+#define bfd_mach_mips4650 4650
+#define bfd_mach_mips5000 5000
+#define bfd_mach_mips5400 5400
+#define bfd_mach_mips5500 5500
+#define bfd_mach_mips6000 6000
+#define bfd_mach_mips7000 7000
+#define bfd_mach_mips8000 8000
+#define bfd_mach_mips9000 9000
+#define bfd_mach_mips10000 10000
+#define bfd_mach_mips12000 12000
+#define bfd_mach_mips16 16
+#define bfd_mach_mips5 5
+#define bfd_mach_mips_sb1 12310201 /* octal 'SB', 01 */
+#define bfd_mach_mipsisa32 32
+#define bfd_mach_mipsisa32r2 33
+#define bfd_mach_mipsisa64 64
+#define bfd_mach_mipsisa64r2 65
+ bfd_arch_i386, /* Intel 386 */
+#define bfd_mach_i386_i386 1
+#define bfd_mach_i386_i8086 2
+#define bfd_mach_i386_i386_intel_syntax 3
+#define bfd_mach_x86_64 64
+#define bfd_mach_x86_64_intel_syntax 65
+ bfd_arch_we32k, /* AT&T WE32xxx */
+ bfd_arch_tahoe, /* CCI/Harris Tahoe */
+ bfd_arch_i860, /* Intel 860 */
+ bfd_arch_i370, /* IBM 360/370 Mainframes */
+ bfd_arch_romp, /* IBM ROMP PC/RT */
+ bfd_arch_alliant, /* Alliant */
+ bfd_arch_convex, /* Convex */
+ bfd_arch_m88k, /* Motorola 88xxx */
+ bfd_arch_m98k, /* Motorola 98xxx */
+ bfd_arch_pyramid, /* Pyramid Technology */
+ bfd_arch_h8300, /* Renesas H8/300 (formerly Hitachi H8/300) */
+#define bfd_mach_h8300 1
+#define bfd_mach_h8300h 2
+#define bfd_mach_h8300s 3
+#define bfd_mach_h8300hn 4
+#define bfd_mach_h8300sn 5
+#define bfd_mach_h8300sx 6
+#define bfd_mach_h8300sxn 7
+ bfd_arch_pdp11, /* DEC PDP-11 */
+ bfd_arch_powerpc, /* PowerPC */
+#define bfd_mach_ppc 32
+#define bfd_mach_ppc64 64
+#define bfd_mach_ppc_403 403
+#define bfd_mach_ppc_403gc 4030
+#define bfd_mach_ppc_505 505
+#define bfd_mach_ppc_601 601
+#define bfd_mach_ppc_602 602
+#define bfd_mach_ppc_603 603
+#define bfd_mach_ppc_ec603e 6031
+#define bfd_mach_ppc_604 604
+#define bfd_mach_ppc_620 620
+#define bfd_mach_ppc_630 630
+#define bfd_mach_ppc_750 750
+#define bfd_mach_ppc_860 860
+#define bfd_mach_ppc_a35 35
+#define bfd_mach_ppc_rs64ii 642
+#define bfd_mach_ppc_rs64iii 643
+#define bfd_mach_ppc_7400 7400
+#define bfd_mach_ppc_e500 500
+ bfd_arch_rs6000, /* IBM RS/6000 */
+#define bfd_mach_rs6k 6000
+#define bfd_mach_rs6k_rs1 6001
+#define bfd_mach_rs6k_rsc 6003
+#define bfd_mach_rs6k_rs2 6002
+ bfd_arch_hppa, /* HP PA RISC */
+#define bfd_mach_hppa10 10
+#define bfd_mach_hppa11 11
+#define bfd_mach_hppa20 20
+#define bfd_mach_hppa20w 25
+ bfd_arch_d10v, /* Mitsubishi D10V */
+#define bfd_mach_d10v 1
+#define bfd_mach_d10v_ts2 2
+#define bfd_mach_d10v_ts3 3
+ bfd_arch_d30v, /* Mitsubishi D30V */
+ bfd_arch_dlx, /* DLX */
+ bfd_arch_m68hc11, /* Motorola 68HC11 */
+ bfd_arch_m68hc12, /* Motorola 68HC12 */
+#define bfd_mach_m6812_default 0
+#define bfd_mach_m6812 1
+#define bfd_mach_m6812s 2
+ bfd_arch_z8k, /* Zilog Z8000 */
+#define bfd_mach_z8001 1
+#define bfd_mach_z8002 2
+ bfd_arch_h8500, /* Renesas H8/500 (formerly Hitachi H8/500) */
+ bfd_arch_sh, /* Renesas / SuperH SH (formerly Hitachi SH) */
+#define bfd_mach_sh 1
+#define bfd_mach_sh2 0x20
+#define bfd_mach_sh_dsp 0x2d
+#define bfd_mach_sh2a 0x2a
+#define bfd_mach_sh2a_nofpu 0x2b
+#define bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu 0x2a1
+#define bfd_mach_sh2a_nofpu_or_sh3_nommu 0x2a2
+#define bfd_mach_sh2a_or_sh4 0x2a3
+#define bfd_mach_sh2a_or_sh3e 0x2a4
+#define bfd_mach_sh2e 0x2e
+#define bfd_mach_sh3 0x30
+#define bfd_mach_sh3_nommu 0x31
+#define bfd_mach_sh3_dsp 0x3d
+#define bfd_mach_sh3e 0x3e
+#define bfd_mach_sh4 0x40
+#define bfd_mach_sh4_nofpu 0x41
+#define bfd_mach_sh4_nommu_nofpu 0x42
+#define bfd_mach_sh4a 0x4a
+#define bfd_mach_sh4a_nofpu 0x4b
+#define bfd_mach_sh4al_dsp 0x4d
+#define bfd_mach_sh5 0x50
+ bfd_arch_alpha, /* Dec Alpha */
+#define bfd_mach_alpha_ev4 0x10
+#define bfd_mach_alpha_ev5 0x20
+#define bfd_mach_alpha_ev6 0x30
+ bfd_arch_arm, /* Advanced Risc Machines ARM. */
+#define bfd_mach_arm_unknown 0
+#define bfd_mach_arm_2 1
+#define bfd_mach_arm_2a 2
+#define bfd_mach_arm_3 3
+#define bfd_mach_arm_3M 4
+#define bfd_mach_arm_4 5
+#define bfd_mach_arm_4T 6
+#define bfd_mach_arm_5 7
+#define bfd_mach_arm_5T 8
+#define bfd_mach_arm_5TE 9
+#define bfd_mach_arm_XScale 10
+#define bfd_mach_arm_ep9312 11
+#define bfd_mach_arm_iWMMXt 12
+ bfd_arch_ns32k, /* National Semiconductors ns32000 */
+ bfd_arch_w65, /* WDC 65816 */
+ bfd_arch_tic30, /* Texas Instruments TMS320C30 */
+ bfd_arch_tic4x, /* Texas Instruments TMS320C3X/4X */
+#define bfd_mach_tic3x 30
+#define bfd_mach_tic4x 40
+ bfd_arch_tic54x, /* Texas Instruments TMS320C54X */
+ bfd_arch_tic80, /* TI TMS320c80 (MVP) */
+ bfd_arch_v850, /* NEC V850 */
+#define bfd_mach_v850 1
+#define bfd_mach_v850e 'E'
+#define bfd_mach_v850e1 '1'
+ bfd_arch_arc, /* ARC Cores */
+#define bfd_mach_arc_5 5
+#define bfd_mach_arc_6 6
+#define bfd_mach_arc_7 7
+#define bfd_mach_arc_8 8
+ bfd_arch_m32c, /* Renesas M16C/M32C. */
+#define bfd_mach_m16c 0x75
+#define bfd_mach_m32c 0x78
+ bfd_arch_m32r, /* Renesas M32R (formerly Mitsubishi M32R/D) */
+#define bfd_mach_m32r 1 /* For backwards compatibility. */
+#define bfd_mach_m32rx 'x'
+#define bfd_mach_m32r2 '2'
+ bfd_arch_mn10200, /* Matsushita MN10200 */
+ bfd_arch_mn10300, /* Matsushita MN10300 */
+#define bfd_mach_mn10300 300
+#define bfd_mach_am33 330
+#define bfd_mach_am33_2 332
+ bfd_arch_fr30,
+#define bfd_mach_fr30 0x46523330
+ bfd_arch_frv,
+#define bfd_mach_frv 1
+#define bfd_mach_frvsimple 2
+#define bfd_mach_fr300 300
+#define bfd_mach_fr400 400
+#define bfd_mach_fr450 450
+#define bfd_mach_frvtomcat 499 /* fr500 prototype */
+#define bfd_mach_fr500 500
+#define bfd_mach_fr550 550
+ bfd_arch_mcore,
+ bfd_arch_ia64, /* HP/Intel ia64 */
+#define bfd_mach_ia64_elf64 64
+#define bfd_mach_ia64_elf32 32
+ bfd_arch_ip2k, /* Ubicom IP2K microcontrollers. */
+#define bfd_mach_ip2022 1
+#define bfd_mach_ip2022ext 2
+ bfd_arch_iq2000, /* Vitesse IQ2000. */
+#define bfd_mach_iq2000 1
+#define bfd_mach_iq10 2
+ bfd_arch_ms1,
+#define bfd_mach_ms1 1
+#define bfd_mach_mrisc2 2
+ bfd_arch_pj,
+ bfd_arch_avr, /* Atmel AVR microcontrollers. */
+#define bfd_mach_avr1 1
+#define bfd_mach_avr2 2
+#define bfd_mach_avr3 3
+#define bfd_mach_avr4 4
+#define bfd_mach_avr5 5
+ bfd_arch_cr16c, /* National Semiconductor CompactRISC. */
+#define bfd_mach_cr16c 1
+ bfd_arch_crx, /* National Semiconductor CRX. */
+#define bfd_mach_crx 1
+ bfd_arch_cris, /* Axis CRIS */
+#define bfd_mach_cris_v0_v10 255
+#define bfd_mach_cris_v32 32
+#define bfd_mach_cris_v10_v32 1032
+ bfd_arch_s390, /* IBM s390 */
+#define bfd_mach_s390_31 31
+#define bfd_mach_s390_64 64
+ bfd_arch_openrisc, /* OpenRISC */
+ bfd_arch_mmix, /* Donald Knuth's educational processor. */
+ bfd_arch_xstormy16,
+#define bfd_mach_xstormy16 1
+ bfd_arch_msp430, /* Texas Instruments MSP430 architecture. */
+#define bfd_mach_msp11 11
+#define bfd_mach_msp110 110
+#define bfd_mach_msp12 12
+#define bfd_mach_msp13 13
+#define bfd_mach_msp14 14
+#define bfd_mach_msp15 15
+#define bfd_mach_msp16 16
+#define bfd_mach_msp31 31
+#define bfd_mach_msp32 32
+#define bfd_mach_msp33 33
+#define bfd_mach_msp41 41
+#define bfd_mach_msp42 42
+#define bfd_mach_msp43 43
+#define bfd_mach_msp44 44
+ bfd_arch_xtensa, /* Tensilica's Xtensa cores. */
+#define bfd_mach_xtensa 1
+ bfd_arch_maxq, /* Dallas MAXQ 10/20 */
+#define bfd_mach_maxq10 10
+#define bfd_mach_maxq20 20
+ bfd_arch_last
+ };
+
+enum bfd_flavour
+{
+ bfd_target_unknown_flavour,
+ bfd_target_aout_flavour,
+ bfd_target_coff_flavour,
+ bfd_target_ecoff_flavour,
+ bfd_target_xcoff_flavour,
+ bfd_target_elf_flavour,
+ bfd_target_ieee_flavour,
+ bfd_target_nlm_flavour,
+ bfd_target_oasys_flavour,
+ bfd_target_tekhex_flavour,
+ bfd_target_srec_flavour,
+ bfd_target_ihex_flavour,
+ bfd_target_som_flavour,
+ bfd_target_os9k_flavour,
+ bfd_target_versados_flavour,
+ bfd_target_msdos_flavour,
+ bfd_target_ovax_flavour,
+ bfd_target_evax_flavour,
+ bfd_target_mmo_flavour,
+ bfd_target_mach_o_flavour,
+ bfd_target_pef_flavour,
+ bfd_target_pef_xlib_flavour,
+ bfd_target_sym_flavour
+};
+
+enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
+
+#endif
#define ERROR_APIC_VECTOR 0xfe
#define RESCHEDULE_VECTOR 0xfd
#define CALL_FUNCTION_VECTOR 0xfc
-/* fb free - please don't readd KDB here because it's useless
- (hint - think what a NMI bit does to a vector) */
+#define KDB_VECTOR 0xfb
#define THERMAL_APIC_VECTOR 0xfa
#define THRESHOLD_APIC_VECTOR 0xf9
-/* f8 free */
+#define KDBENTER_VECTOR 0xf8
#define INVALIDATE_TLB_VECTOR_END 0xf7
#define INVALIDATE_TLB_VECTOR_START 0xf0 /* f0-f7 used for TLB flush */
--- /dev/null
+#ifndef _ASM_KDB_H
+#define _ASM_KDB_H
+
+/*
+ * Kernel Debugger Architecture Dependent Global Headers
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * KDB_ENTER() is a macro which causes entry into the kernel
+ * debugger from any point in the kernel code stream. If it
+ * is intended to be used from interrupt level, it must use
+ * a non-maskable entry method. The vector is KDBENTER_VECTOR.
+ */
+#define KDB_ENTER() do {if (kdb_on && !KDB_IS_RUNNING()) { asm("\tint $248\n"); }} while(0)
+
+/*
+ * Needed for exported symbols.
+ */
+typedef unsigned long kdb_machreg_t;
+
+#define kdb_machreg_fmt "0x%lx"
+#define kdb_machreg_fmt0 "%016lx"
+#define kdb_bfd_vma_fmt "0x%lx"
+#define kdb_bfd_vma_fmt0 "0x%016lx"
+#define kdb_elfw_addr_fmt "0x%x"
+#define kdb_elfw_addr_fmt0 "0x%016x"
+
+/*
+ * Per cpu arch specific kdb state. Must be in range 0xff000000.
+ */
+#define KDB_STATE_A_IF 0x01000000 /* Saved IF flag */
+
+static inline unsigned long
+kdba_funcptr_value(void *fp)
+{
+ return (unsigned long)fp;
+}
+
+#endif /* !_ASM_KDB_H */
--- /dev/null
+#ifndef _ASM_KDBPRIVATE_H
+#define _ASM_KDBPRIVATE_H
+
+/*
+ * Kernel Debugger Architecture Dependent Private Headers
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2006 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+typedef unsigned char kdb_machinst_t;
+
+ /*
+ * KDB_MAXBPT describes the total number of breakpoints
+ * supported by this architecure.
+ */
+#define KDB_MAXBPT 16
+
+ /*
+ * KDB_MAXHARDBPT describes the total number of hardware
+ * breakpoint registers that exist.
+ */
+#define KDB_MAXHARDBPT 4
+
+/* Maximum number of arguments to a function */
+#define KDBA_MAXARGS 16
+
+ /*
+ * Platform specific environment entries
+ */
+#define KDB_PLATFORM_ENV "IDMODE=x86_64", "BYTESPERWORD=8", "IDCOUNT=16"
+
+ /*
+ * Support for ia32 debug registers
+ */
+typedef struct _kdbhard_bp {
+ kdb_machreg_t bph_reg; /* Register this breakpoint uses */
+
+ unsigned int bph_free:1; /* Register available for use */
+ unsigned int bph_data:1; /* Data Access breakpoint */
+
+ unsigned int bph_write:1; /* Write Data breakpoint */
+ unsigned int bph_mode:2; /* 0=inst, 1=write, 2=io, 3=read */
+ unsigned int bph_length:2; /* 0=1, 1=2, 2=BAD, 3=4 (bytes) */
+} kdbhard_bp_t;
+
+extern kdbhard_bp_t kdb_hardbreaks[/* KDB_MAXHARDBPT */];
+
+#define IA32_BREAKPOINT_INSTRUCTION 0xcc
+
+#define DR6_BT 0x00008000
+#define DR6_BS 0x00004000
+#define DR6_BD 0x00002000
+
+#define DR6_B3 0x00000008
+#define DR6_B2 0x00000004
+#define DR6_B1 0x00000002
+#define DR6_B0 0x00000001
+
+#define DR7_RW_VAL(dr, drnum) \
+ (((dr) >> (16 + (4 * (drnum)))) & 0x3)
+
+#define DR7_RW_SET(dr, drnum, rw) \
+ do { \
+ (dr) &= ~(0x3 << (16 + (4 * (drnum)))); \
+ (dr) |= (((rw) & 0x3) << (16 + (4 * (drnum)))); \
+ } while (0)
+
+#define DR7_RW0(dr) DR7_RW_VAL(dr, 0)
+#define DR7_RW0SET(dr,rw) DR7_RW_SET(dr, 0, rw)
+#define DR7_RW1(dr) DR7_RW_VAL(dr, 1)
+#define DR7_RW1SET(dr,rw) DR7_RW_SET(dr, 1, rw)
+#define DR7_RW2(dr) DR7_RW_VAL(dr, 2)
+#define DR7_RW2SET(dr,rw) DR7_RW_SET(dr, 2, rw)
+#define DR7_RW3(dr) DR7_RW_VAL(dr, 3)
+#define DR7_RW3SET(dr,rw) DR7_RW_SET(dr, 3, rw)
+
+
+#define DR7_LEN_VAL(dr, drnum) \
+ (((dr) >> (18 + (4 * (drnum)))) & 0x3)
+
+#define DR7_LEN_SET(dr, drnum, rw) \
+ do { \
+ (dr) &= ~(0x3 << (18 + (4 * (drnum)))); \
+ (dr) |= (((rw) & 0x3) << (18 + (4 * (drnum)))); \
+ } while (0)
+#define DR7_LEN0(dr) DR7_LEN_VAL(dr, 0)
+#define DR7_LEN0SET(dr,len) DR7_LEN_SET(dr, 0, len)
+#define DR7_LEN1(dr) DR7_LEN_VAL(dr, 1)
+#define DR7_LEN1SET(dr,len) DR7_LEN_SET(dr, 1, len)
+#define DR7_LEN2(dr) DR7_LEN_VAL(dr, 2)
+#define DR7_LEN2SET(dr,len) DR7_LEN_SET(dr, 2, len)
+#define DR7_LEN3(dr) DR7_LEN_VAL(dr, 3)
+#define DR7_LEN3SET(dr,len) DR7_LEN_SET(dr, 3, len)
+
+#define DR7_G0(dr) (((dr)>>1)&0x1)
+#define DR7_G0SET(dr) ((dr) |= 0x2)
+#define DR7_G0CLR(dr) ((dr) &= ~0x2)
+#define DR7_G1(dr) (((dr)>>3)&0x1)
+#define DR7_G1SET(dr) ((dr) |= 0x8)
+#define DR7_G1CLR(dr) ((dr) &= ~0x8)
+#define DR7_G2(dr) (((dr)>>5)&0x1)
+#define DR7_G2SET(dr) ((dr) |= 0x20)
+#define DR7_G2CLR(dr) ((dr) &= ~0x20)
+#define DR7_G3(dr) (((dr)>>7)&0x1)
+#define DR7_G3SET(dr) ((dr) |= 0x80)
+#define DR7_G3CLR(dr) ((dr) &= ~0x80)
+
+#define DR7_L0(dr) (((dr))&0x1)
+#define DR7_L0SET(dr) ((dr) |= 0x1)
+#define DR7_L0CLR(dr) ((dr) &= ~0x1)
+#define DR7_L1(dr) (((dr)>>2)&0x1)
+#define DR7_L1SET(dr) ((dr) |= 0x4)
+#define DR7_L1CLR(dr) ((dr) &= ~0x4)
+#define DR7_L2(dr) (((dr)>>4)&0x1)
+#define DR7_L2SET(dr) ((dr) |= 0x10)
+#define DR7_L2CLR(dr) ((dr) &= ~0x10)
+#define DR7_L3(dr) (((dr)>>6)&0x1)
+#define DR7_L3SET(dr) ((dr) |= 0x40)
+#define DR7_L3CLR(dr) ((dr) &= ~0x40)
+
+#define DR7_GD 0x00002000 /* General Detect Enable */
+#define DR7_GE 0x00000200 /* Global exact */
+#define DR7_LE 0x00000100 /* Local exact */
+
+extern kdb_machreg_t kdba_getdr6(void);
+extern void kdba_putdr6(kdb_machreg_t);
+
+extern kdb_machreg_t kdba_getdr7(void);
+
+extern kdb_machreg_t kdba_getdr(int);
+extern void kdba_putdr(int, kdb_machreg_t);
+
+extern kdb_machreg_t kdb_getcr(int);
+
+/*
+ * reg indicies for x86_64 setjmp/longjmp
+ */
+#define JB_RBX 0
+#define JB_RBP 1
+#define JB_R12 2
+#define JB_R13 3
+#define JB_R14 4
+#define JB_R15 5
+#define JB_RSP 6
+#define JB_PC 7
+
+typedef struct __kdb_jmp_buf {
+ unsigned long regs[8]; /* kdba_setjmp assumes fixed offsets here */
+} kdb_jmp_buf;
+
+extern int asmlinkage kdba_setjmp(kdb_jmp_buf *);
+extern void asmlinkage kdba_longjmp(kdb_jmp_buf *, int);
+#define kdba_setjmp kdba_setjmp
+
+extern kdb_jmp_buf *kdbjmpbuf;
+
+/* Arch specific data saved for running processes */
+
+struct kdba_running_process {
+ long rsp; /* KDB may be on a different stack */
+};
+
+register unsigned long current_stack_pointer asm("rsp") __attribute_used__;
+
+static inline
+void kdba_save_running(struct kdba_running_process *k, struct pt_regs *regs)
+{
+ k->rsp = current_stack_pointer;
+}
+
+static inline
+void kdba_unsave_running(struct kdba_running_process *k, struct pt_regs *regs)
+{
+}
+
+struct kdb_activation_record;
+extern void kdba_get_stack_info_alternate(kdb_machreg_t addr, int cpu,
+ struct kdb_activation_record *ar);
+
+extern void kdba_wait_for_cpus(void);
+
+extern asmlinkage void kdb_interrupt(void);
+
+#endif /* !_ASM_KDBPRIVATE_H */
DIE_CALL,
DIE_NMI_IPI,
DIE_PAGE_FAULT,
+ DIE_KDEBUG_ENTER,
+ DIE_KDEBUG_LEAVE,
};
static inline int notify_die(enum die_val val, const char *str,
--- /dev/null
+/*
+ * include/linux/pc_keyb.h
+ *
+ * PC Keyboard And Keyboard Controller
+ *
+ * (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ */
+
+/*
+ * Configuration Switches
+ */
+
+#undef KBD_REPORT_ERR /* Report keyboard errors */
+#define KBD_REPORT_UNKN /* Report unknown scan codes */
+#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */
+#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */
+#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */
+
+
+
+#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */
+#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */
+#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */
+
+/*
+ * Internal variables of the driver
+ */
+
+extern unsigned char pckbd_read_mask;
+extern unsigned char aux_device_present;
+
+/*
+ * Keyboard Controller Registers on normal PCs.
+ */
+
+#define KBD_STATUS_REG 0x64 /* Status register (R) */
+#define KBD_CNTL_REG 0x64 /* Controller command register (W) */
+#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */
+
+/*
+ * Keyboard Controller Commands
+ */
+
+#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
+#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
+#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
+#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
+#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
+#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
+#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
+#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
+#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
+#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
+#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if
+ initiated by the auxiliary device */
+#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
+
+/*
+ * Keyboard Commands
+ */
+
+#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
+#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
+#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
+#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */
+#define KBD_CMD_RESET 0xFF /* Reset */
+
+/*
+ * Keyboard Replies
+ */
+
+#define KBD_REPLY_POR 0xAA /* Power on reset */
+#define KBD_REPLY_ACK 0xFA /* Command ACK */
+#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
+
+/*
+ * Status Register Bits
+ */
+
+#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
+#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
+#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
+#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
+#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
+#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
+#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
+#define KBD_STAT_PERR 0x80 /* Parity error */
+
+#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
+
+/*
+ * Controller Mode Register Bits
+ */
+
+#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */
+#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
+#define KBD_MODE_SYS 0x04 /* The system flag (?) */
+#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
+#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
+#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
+#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
+#define KBD_MODE_RFU 0x80
+
+/*
+ * Mouse Commands
+ */
+
+#define AUX_SET_RES 0xE8 /* Set resolution */
+#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
+#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
+#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
+#define AUX_SET_STREAM 0xEA /* Set stream mode */
+#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
+#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
+#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
+#define AUX_RESET 0xFF /* Reset aux device */
+#define AUX_ACK 0xFA /* Command byte ACK. */
+
+#define AUX_BUF_SIZE 2048 /* This might be better divisible by
+ three to make overruns stay in sync
+ but then the read function would need
+ a lock etc - ick */
+
+struct aux_queue {
+ unsigned long head;
+ unsigned long tail;
+ wait_queue_head_t proc_list;
+ struct fasync_struct *fasync;
+ unsigned char buf[AUX_BUF_SIZE];
+};
+
+
+/* How to access the keyboard macros on this platform. */
+#define kbd_read_input() inb(KBD_DATA_REG)
+#define kbd_read_status() inb(KBD_STATUS_REG)
+#define kbd_write_output(val) outb(val, KBD_DATA_REG)
+#define kbd_write_command(val) outb(val, KBD_CNTL_REG)
--- /dev/null
+/* ANSI and traditional C compatability macros
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use.
+ * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as
+ * required.
+ * Keith Owens <kaos@sgi.com> 15 May 2006
+ */
+
+/* ANSI and traditional C compatibility macros
+
+ ANSI C is assumed if __STDC__ is #defined.
+
+ Macro ANSI C definition Traditional C definition
+ ----- ---- - ---------- ----------- - ----------
+ ANSI_PROTOTYPES 1 not defined
+ PTR `void *' `char *'
+ PTRCONST `void *const' `char *'
+ LONG_DOUBLE `long double' `double'
+ const not defined `'
+ volatile not defined `'
+ signed not defined `'
+ VA_START(ap, var) va_start(ap, var) va_start(ap)
+
+ Note that it is safe to write "void foo();" indicating a function
+ with no return value, in all K+R compilers we have been able to test.
+
+ For declaring functions with prototypes, we also provide these:
+
+ PARAMS ((prototype))
+ -- for functions which take a fixed number of arguments. Use this
+ when declaring the function. When defining the function, write a
+ K+R style argument list. For example:
+
+ char *strcpy PARAMS ((char *dest, char *source));
+ ...
+ char *
+ strcpy (dest, source)
+ char *dest;
+ char *source;
+ { ... }
+
+
+ VPARAMS ((prototype, ...))
+ -- for functions which take a variable number of arguments. Use
+ PARAMS to declare the function, VPARAMS to define it. For example:
+
+ int printf PARAMS ((const char *format, ...));
+ ...
+ int
+ printf VPARAMS ((const char *format, ...))
+ {
+ ...
+ }
+
+ For writing functions which take variable numbers of arguments, we
+ also provide the VA_OPEN, VA_CLOSE, and VA_FIXEDARG macros. These
+ hide the differences between K+R <varargs.h> and C89 <stdarg.h> more
+ thoroughly than the simple VA_START() macro mentioned above.
+
+ VA_OPEN and VA_CLOSE are used *instead of* va_start and va_end.
+ Immediately after VA_OPEN, put a sequence of VA_FIXEDARG calls
+ corresponding to the list of fixed arguments. Then use va_arg
+ normally to get the variable arguments, or pass your va_list object
+ around. You do not declare the va_list yourself; VA_OPEN does it
+ for you.
+
+ Here is a complete example:
+
+ int
+ printf VPARAMS ((const char *format, ...))
+ {
+ int result;
+
+ VA_OPEN (ap, format);
+ VA_FIXEDARG (ap, const char *, format);
+
+ result = vfprintf (stdout, format, ap);
+ VA_CLOSE (ap);
+
+ return result;
+ }
+
+
+ You can declare variables either before or after the VA_OPEN,
+ VA_FIXEDARG sequence. Also, VA_OPEN and VA_CLOSE are the beginning
+ and end of a block. They must appear at the same nesting level,
+ and any variables declared after VA_OPEN go out of scope at
+ VA_CLOSE. Unfortunately, with a K+R compiler, that includes the
+ argument list. You can have multiple instances of VA_OPEN/VA_CLOSE
+ pairs in a single function in case you need to traverse the
+ argument list more than once.
+
+ For ease of writing code which uses GCC extensions but needs to be
+ portable to other compilers, we provide the GCC_VERSION macro that
+ simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various
+ wrappers around __attribute__. Also, __extension__ will be #defined
+ to nothing if it doesn't work. See below.
+
+ This header also defines a lot of obsolete macros:
+ CONST, VOLATILE, SIGNED, PROTO, EXFUN, DEFUN, DEFUN_VOID,
+ AND, DOTS, NOARGS. Don't use them. */
+
+#ifndef _ANSIDECL_H
+#define _ANSIDECL_H 1
+
+/* Every source file includes this file,
+ so they will all get the switch for lint. */
+/* LINTLIBRARY */
+
+/* Using MACRO(x,y) in cpp #if conditionals does not work with some
+ older preprocessors. Thus we can't define something like this:
+
+#define HAVE_GCC_VERSION(MAJOR, MINOR) \
+ (__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR)))
+
+and then test "#if HAVE_GCC_VERSION(2,7)".
+
+So instead we use the macro below and test it against specific values. */
+
+/* This macro simplifies testing whether we are using gcc, and if it
+ is of a particular minimum version. (Both major & minor numbers are
+ significant.) This macro will evaluate to 0 if we are not using
+ gcc at all. */
+#ifndef GCC_VERSION
+#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
+#endif /* GCC_VERSION */
+
+#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32) || (defined(__alpha) && defined(__cplusplus))
+/* All known AIX compilers implement these things (but don't always
+ define __STDC__). The RISC/OS MIPS compiler defines these things
+ in SVR4 mode, but does not define __STDC__. */
+/* eraxxon@alumni.rice.edu: The Compaq C++ compiler, unlike many other
+ C++ compilers, does not define __STDC__, though it acts as if this
+ was so. (Verified versions: 5.7, 6.2, 6.3, 6.5) */
+
+#define ANSI_PROTOTYPES 1
+#define PTR void *
+#define PTRCONST void *const
+#define LONG_DOUBLE long double
+
+/* PARAMS is often defined elsewhere (e.g. by libintl.h), so wrap it in
+ a #ifndef. */
+#ifndef PARAMS
+#define PARAMS(ARGS) ARGS
+#endif
+
+#define VPARAMS(ARGS) ARGS
+#define VA_START(VA_LIST, VAR) va_start(VA_LIST, VAR)
+
+/* variadic function helper macros */
+/* "struct Qdmy" swallows the semicolon after VA_OPEN/VA_FIXEDARG's
+ use without inhibiting further decls and without declaring an
+ actual variable. */
+#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP, VAR); { struct Qdmy
+#define VA_CLOSE(AP) } va_end(AP); }
+#define VA_FIXEDARG(AP, T, N) struct Qdmy
+
+#undef const
+#undef volatile
+#undef signed
+
+#ifdef __KERNEL__
+#ifndef __STDC_VERSION__
+#define __STDC_VERSION__ 0
+#endif
+#endif /* __KERNEL__ */
+
+/* inline requires special treatment; it's in C99, and GCC >=2.7 supports
+ it too, but it's not in C89. */
+#undef inline
+#if __STDC_VERSION__ > 199901L
+/* it's a keyword */
+#else
+# if GCC_VERSION >= 2007
+# define inline __inline__ /* __inline__ prevents -pedantic warnings */
+# else
+# define inline /* nothing */
+# endif
+#endif
+
+/* These are obsolete. Do not use. */
+#ifndef IN_GCC
+#define CONST const
+#define VOLATILE volatile
+#define SIGNED signed
+
+#define PROTO(type, name, arglist) type name arglist
+#define EXFUN(name, proto) name proto
+#define DEFUN(name, arglist, args) name(args)
+#define DEFUN_VOID(name) name(void)
+#define AND ,
+#define DOTS , ...
+#define NOARGS void
+#endif /* ! IN_GCC */
+
+#else /* Not ANSI C. */
+
+#undef ANSI_PROTOTYPES
+#define PTR char *
+#define PTRCONST PTR
+#define LONG_DOUBLE double
+
+#define PARAMS(args) ()
+#define VPARAMS(args) (va_alist) va_dcl
+#define VA_START(va_list, var) va_start(va_list)
+
+#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP); { struct Qdmy
+#define VA_CLOSE(AP) } va_end(AP); }
+#define VA_FIXEDARG(AP, TYPE, NAME) TYPE NAME = va_arg(AP, TYPE)
+
+/* some systems define these in header files for non-ansi mode */
+#undef const
+#undef volatile
+#undef signed
+#undef inline
+#define const
+#define volatile
+#define signed
+#define inline
+
+#ifndef IN_GCC
+#define CONST
+#define VOLATILE
+#define SIGNED
+
+#define PROTO(type, name, arglist) type name ()
+#define EXFUN(name, proto) name()
+#define DEFUN(name, arglist, args) name arglist args;
+#define DEFUN_VOID(name) name()
+#define AND ;
+#define DOTS
+#define NOARGS
+#endif /* ! IN_GCC */
+
+#endif /* ANSI C. */
+
+/* Define macros for some gcc attributes. This permits us to use the
+ macros freely, and know that they will come into play for the
+ version of gcc in which they are supported. */
+
+#if (GCC_VERSION < 2007)
+# define __attribute__(x)
+#endif
+
+/* Attribute __malloc__ on functions was valid as of gcc 2.96. */
+#ifndef ATTRIBUTE_MALLOC
+# if (GCC_VERSION >= 2096)
+# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
+# else
+# define ATTRIBUTE_MALLOC
+# endif /* GNUC >= 2.96 */
+#endif /* ATTRIBUTE_MALLOC */
+
+/* Attributes on labels were valid as of gcc 2.93. */
+#ifndef ATTRIBUTE_UNUSED_LABEL
+# if (!defined (__cplusplus) && GCC_VERSION >= 2093)
+# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED
+# else
+# define ATTRIBUTE_UNUSED_LABEL
+# endif /* !__cplusplus && GNUC >= 2.93 */
+#endif /* ATTRIBUTE_UNUSED_LABEL */
+
+#ifndef ATTRIBUTE_UNUSED
+#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+#endif /* ATTRIBUTE_UNUSED */
+
+/* Before GCC 3.4, the C++ frontend couldn't parse attributes placed after the
+ identifier name. */
+#if ! defined(__cplusplus) || (GCC_VERSION >= 3004)
+# define ARG_UNUSED(NAME) NAME ATTRIBUTE_UNUSED
+#else /* !__cplusplus || GNUC >= 3.4 */
+# define ARG_UNUSED(NAME) NAME
+#endif /* !__cplusplus || GNUC >= 3.4 */
+
+#ifndef ATTRIBUTE_NORETURN
+#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
+#endif /* ATTRIBUTE_NORETURN */
+
+/* Attribute `nonnull' was valid as of gcc 3.3. */
+#ifndef ATTRIBUTE_NONNULL
+# if (GCC_VERSION >= 3003)
+# define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m)))
+# else
+# define ATTRIBUTE_NONNULL(m)
+# endif /* GNUC >= 3.3 */
+#endif /* ATTRIBUTE_NONNULL */
+
+/* Attribute `pure' was valid as of gcc 3.0. */
+#ifndef ATTRIBUTE_PURE
+# if (GCC_VERSION >= 3000)
+# define ATTRIBUTE_PURE __attribute__ ((__pure__))
+# else
+# define ATTRIBUTE_PURE
+# endif /* GNUC >= 3.0 */
+#endif /* ATTRIBUTE_PURE */
+
+/* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL.
+ This was the case for the `printf' format attribute by itself
+ before GCC 3.3, but as of 3.3 we need to add the `nonnull'
+ attribute to retain this behavior. */
+#ifndef ATTRIBUTE_PRINTF
+#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m)
+#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2)
+#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3)
+#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4)
+#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5)
+#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6)
+#endif /* ATTRIBUTE_PRINTF */
+
+/* Use ATTRIBUTE_FPTR_PRINTF when the format attribute is to be set on
+ a function pointer. Format attributes were allowed on function
+ pointers as of gcc 3.1. */
+#ifndef ATTRIBUTE_FPTR_PRINTF
+# if (GCC_VERSION >= 3001)
+# define ATTRIBUTE_FPTR_PRINTF(m, n) ATTRIBUTE_PRINTF(m, n)
+# else
+# define ATTRIBUTE_FPTR_PRINTF(m, n)
+# endif /* GNUC >= 3.1 */
+# define ATTRIBUTE_FPTR_PRINTF_1 ATTRIBUTE_FPTR_PRINTF(1, 2)
+# define ATTRIBUTE_FPTR_PRINTF_2 ATTRIBUTE_FPTR_PRINTF(2, 3)
+# define ATTRIBUTE_FPTR_PRINTF_3 ATTRIBUTE_FPTR_PRINTF(3, 4)
+# define ATTRIBUTE_FPTR_PRINTF_4 ATTRIBUTE_FPTR_PRINTF(4, 5)
+# define ATTRIBUTE_FPTR_PRINTF_5 ATTRIBUTE_FPTR_PRINTF(5, 6)
+#endif /* ATTRIBUTE_FPTR_PRINTF */
+
+/* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL. A
+ NULL format specifier was allowed as of gcc 3.3. */
+#ifndef ATTRIBUTE_NULL_PRINTF
+# if (GCC_VERSION >= 3003)
+# define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
+# else
+# define ATTRIBUTE_NULL_PRINTF(m, n)
+# endif /* GNUC >= 3.3 */
+# define ATTRIBUTE_NULL_PRINTF_1 ATTRIBUTE_NULL_PRINTF(1, 2)
+# define ATTRIBUTE_NULL_PRINTF_2 ATTRIBUTE_NULL_PRINTF(2, 3)
+# define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4)
+# define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5)
+# define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6)
+#endif /* ATTRIBUTE_NULL_PRINTF */
+
+/* Attribute `sentinel' was valid as of gcc 3.5. */
+#ifndef ATTRIBUTE_SENTINEL
+# if (GCC_VERSION >= 3005)
+# define ATTRIBUTE_SENTINEL __attribute__ ((__sentinel__))
+# else
+# define ATTRIBUTE_SENTINEL
+# endif /* GNUC >= 3.5 */
+#endif /* ATTRIBUTE_SENTINEL */
+
+
+#ifndef ATTRIBUTE_ALIGNED_ALIGNOF
+# if (GCC_VERSION >= 3000)
+# define ATTRIBUTE_ALIGNED_ALIGNOF(m) __attribute__ ((__aligned__ (__alignof__ (m))))
+# else
+# define ATTRIBUTE_ALIGNED_ALIGNOF(m)
+# endif /* GNUC >= 3.0 */
+#endif /* ATTRIBUTE_ALIGNED_ALIGNOF */
+
+/* We use __extension__ in some places to suppress -pedantic warnings
+ about GCC extensions. This feature didn't work properly before
+ gcc 2.8. */
+#if GCC_VERSION < 2008
+#define __extension__
+#endif
+
+#endif /* ansidecl.h */
--- /dev/null
+/* Interface between the opcode library and its callers.
+
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ Written by Cygnus Support, 1993.
+
+ The opcode library (libopcodes.a) provides instruction decoders for
+ a large variety of instruction sets, callable with an identical
+ interface, for making instruction-processing programs more independent
+ of the instruction set being processed. */
+
+/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use.
+ * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as
+ * required.
+ * Keith Owens <kaos@sgi.com> 15 May 2006
+ */
+
+#ifndef DIS_ASM_H
+#define DIS_ASM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __KERNEL__
+#include <linux/ansidecl.h>
+#include <asm/bfd.h>
+typedef void FILE;
+#else /* __KERNEL__ */
+#include <stdio.h>
+#include "bfd.h"
+#endif /* __KERNEL__ */
+
+typedef int (*fprintf_ftype) (void *, const char*, ...) ATTRIBUTE_FPTR_PRINTF_2;
+
+enum dis_insn_type {
+ dis_noninsn, /* Not a valid instruction */
+ dis_nonbranch, /* Not a branch instruction */
+ dis_branch, /* Unconditional branch */
+ dis_condbranch, /* Conditional branch */
+ dis_jsr, /* Jump to subroutine */
+ dis_condjsr, /* Conditional jump to subroutine */
+ dis_dref, /* Data reference instruction */
+ dis_dref2 /* Two data references in instruction */
+};
+
+/* This struct is passed into the instruction decoding routine,
+ and is passed back out into each callback. The various fields are used
+ for conveying information from your main routine into your callbacks,
+ for passing information into the instruction decoders (such as the
+ addresses of the callback functions), or for passing information
+ back from the instruction decoders to their callers.
+
+ It must be initialized before it is first passed; this can be done
+ by hand, or using one of the initialization macros below. */
+
+typedef struct disassemble_info {
+ fprintf_ftype fprintf_func;
+ void *stream;
+ void *application_data;
+
+ /* Target description. We could replace this with a pointer to the bfd,
+ but that would require one. There currently isn't any such requirement
+ so to avoid introducing one we record these explicitly. */
+ /* The bfd_flavour. This can be bfd_target_unknown_flavour. */
+ enum bfd_flavour flavour;
+ /* The bfd_arch value. */
+ enum bfd_architecture arch;
+ /* The bfd_mach value. */
+ unsigned long mach;
+ /* Endianness (for bi-endian cpus). Mono-endian cpus can ignore this. */
+ enum bfd_endian endian;
+ /* An arch/mach-specific bitmask of selected instruction subsets, mainly
+ for processors with run-time-switchable instruction sets. The default,
+ zero, means that there is no constraint. CGEN-based opcodes ports
+ may use ISA_foo masks. */
+ unsigned long insn_sets;
+
+ /* Some targets need information about the current section to accurately
+ display insns. If this is NULL, the target disassembler function
+ will have to make its best guess. */
+ struct bfd_section *section;
+
+ /* An array of pointers to symbols either at the location being disassembled
+ or at the start of the function being disassembled. The array is sorted
+ so that the first symbol is intended to be the one used. The others are
+ present for any misc. purposes. This is not set reliably, but if it is
+ not NULL, it is correct. */
+ struct bfd_symbol **symbols;
+ /* Number of symbols in array. */
+ int num_symbols;
+
+ /* For use by the disassembler.
+ The top 16 bits are reserved for public use (and are documented here).
+ The bottom 16 bits are for the internal use of the disassembler. */
+ unsigned long flags;
+#define INSN_HAS_RELOC 0x80000000
+ void *private_data;
+
+ /* Function used to get bytes to disassemble. MEMADDR is the
+ address of the stuff to be disassembled, MYADDR is the address to
+ put the bytes in, and LENGTH is the number of bytes to read.
+ INFO is a pointer to this struct.
+ Returns an errno value or 0 for success. */
+ int (*read_memory_func)
+ (bfd_vma memaddr, bfd_byte *myaddr, unsigned int length,
+ struct disassemble_info *info);
+
+ /* Function which should be called if we get an error that we can't
+ recover from. STATUS is the errno value from read_memory_func and
+ MEMADDR is the address that we were trying to read. INFO is a
+ pointer to this struct. */
+ void (*memory_error_func)
+ (int status, bfd_vma memaddr, struct disassemble_info *info);
+
+ /* Function called to print ADDR. */
+ void (*print_address_func)
+ (bfd_vma addr, struct disassemble_info *info);
+
+ /* Function called to determine if there is a symbol at the given ADDR.
+ If there is, the function returns 1, otherwise it returns 0.
+ This is used by ports which support an overlay manager where
+ the overlay number is held in the top part of an address. In
+ some circumstances we want to include the overlay number in the
+ address, (normally because there is a symbol associated with
+ that address), but sometimes we want to mask out the overlay bits. */
+ int (* symbol_at_address_func)
+ (bfd_vma addr, struct disassemble_info * info);
+
+ /* Function called to check if a SYMBOL is can be displayed to the user.
+ This is used by some ports that want to hide special symbols when
+ displaying debugging outout. */
+ bfd_boolean (* symbol_is_valid)
+ (struct bfd_symbol *, struct disassemble_info * info);
+
+ /* These are for buffer_read_memory. */
+ bfd_byte *buffer;
+ bfd_vma buffer_vma;
+ unsigned int buffer_length;
+
+ /* This variable may be set by the instruction decoder. It suggests
+ the number of bytes objdump should display on a single line. If
+ the instruction decoder sets this, it should always set it to
+ the same value in order to get reasonable looking output. */
+ int bytes_per_line;
+
+ /* The next two variables control the way objdump displays the raw data. */
+ /* For example, if bytes_per_line is 8 and bytes_per_chunk is 4, the */
+ /* output will look like this:
+ 00: 00000000 00000000
+ with the chunks displayed according to "display_endian". */
+ int bytes_per_chunk;
+ enum bfd_endian display_endian;
+
+ /* Number of octets per incremented target address
+ Normally one, but some DSPs have byte sizes of 16 or 32 bits. */
+ unsigned int octets_per_byte;
+
+ /* The number of zeroes we want to see at the end of a section before we
+ start skipping them. */
+ unsigned int skip_zeroes;
+
+ /* The number of zeroes to skip at the end of a section. If the number
+ of zeroes at the end is between SKIP_ZEROES_AT_END and SKIP_ZEROES,
+ they will be disassembled. If there are fewer than
+ SKIP_ZEROES_AT_END, they will be skipped. This is a heuristic
+ attempt to avoid disassembling zeroes inserted by section
+ alignment. */
+ unsigned int skip_zeroes_at_end;
+
+ /* Results from instruction decoders. Not all decoders yet support
+ this information. This info is set each time an instruction is
+ decoded, and is only valid for the last such instruction.
+
+ To determine whether this decoder supports this information, set
+ insn_info_valid to 0, decode an instruction, then check it. */
+
+ char insn_info_valid; /* Branch info has been set. */
+ char branch_delay_insns; /* How many sequential insn's will run before
+ a branch takes effect. (0 = normal) */
+ char data_size; /* Size of data reference in insn, in bytes */
+ enum dis_insn_type insn_type; /* Type of instruction */
+ bfd_vma target; /* Target address of branch or dref, if known;
+ zero if unknown. */
+ bfd_vma target2; /* Second target address for dref2 */
+
+ /* Command line options specific to the target disassembler. */
+ char * disassembler_options;
+
+} disassemble_info;
+
+\f
+/* Standard disassemblers. Disassemble one instruction at the given
+ target address. Return number of octets processed. */
+typedef int (*disassembler_ftype) (bfd_vma, disassemble_info *);
+
+extern int print_insn_big_mips (bfd_vma, disassemble_info *);
+extern int print_insn_little_mips (bfd_vma, disassemble_info *);
+extern int print_insn_i386 (bfd_vma, disassemble_info *);
+extern int print_insn_i386_att (bfd_vma, disassemble_info *);
+extern int print_insn_i386_intel (bfd_vma, disassemble_info *);
+extern int print_insn_ia64 (bfd_vma, disassemble_info *);
+extern int print_insn_i370 (bfd_vma, disassemble_info *);
+extern int print_insn_m68hc11 (bfd_vma, disassemble_info *);
+extern int print_insn_m68hc12 (bfd_vma, disassemble_info *);
+extern int print_insn_m68k (bfd_vma, disassemble_info *);
+extern int print_insn_z8001 (bfd_vma, disassemble_info *);
+extern int print_insn_z8002 (bfd_vma, disassemble_info *);
+extern int print_insn_h8300 (bfd_vma, disassemble_info *);
+extern int print_insn_h8300h (bfd_vma, disassemble_info *);
+extern int print_insn_h8300s (bfd_vma, disassemble_info *);
+extern int print_insn_h8500 (bfd_vma, disassemble_info *);
+extern int print_insn_alpha (bfd_vma, disassemble_info *);
+extern int print_insn_big_arm (bfd_vma, disassemble_info *);
+extern int print_insn_little_arm (bfd_vma, disassemble_info *);
+extern int print_insn_sparc (bfd_vma, disassemble_info *);
+extern int print_insn_big_a29k (bfd_vma, disassemble_info *);
+extern int print_insn_little_a29k (bfd_vma, disassemble_info *);
+extern int print_insn_avr (bfd_vma, disassemble_info *);
+extern int print_insn_d10v (bfd_vma, disassemble_info *);
+extern int print_insn_d30v (bfd_vma, disassemble_info *);
+extern int print_insn_dlx (bfd_vma, disassemble_info *);
+extern int print_insn_fr30 (bfd_vma, disassemble_info *);
+extern int print_insn_hppa (bfd_vma, disassemble_info *);
+extern int print_insn_i860 (bfd_vma, disassemble_info *);
+extern int print_insn_i960 (bfd_vma, disassemble_info *);
+extern int print_insn_ip2k (bfd_vma, disassemble_info *);
+extern int print_insn_m32r (bfd_vma, disassemble_info *);
+extern int print_insn_m88k (bfd_vma, disassemble_info *);
+extern int print_insn_maxq_little (bfd_vma, disassemble_info *);
+extern int print_insn_maxq_big (bfd_vma, disassemble_info *);
+extern int print_insn_mcore (bfd_vma, disassemble_info *);
+extern int print_insn_mmix (bfd_vma, disassemble_info *);
+extern int print_insn_mn10200 (bfd_vma, disassemble_info *);
+extern int print_insn_mn10300 (bfd_vma, disassemble_info *);
+extern int print_insn_ms1 (bfd_vma, disassemble_info *);
+extern int print_insn_msp430 (bfd_vma, disassemble_info *);
+extern int print_insn_ns32k (bfd_vma, disassemble_info *);
+extern int print_insn_crx (bfd_vma, disassemble_info *);
+extern int print_insn_openrisc (bfd_vma, disassemble_info *);
+extern int print_insn_big_or32 (bfd_vma, disassemble_info *);
+extern int print_insn_little_or32 (bfd_vma, disassemble_info *);
+extern int print_insn_pdp11 (bfd_vma, disassemble_info *);
+extern int print_insn_pj (bfd_vma, disassemble_info *);
+extern int print_insn_big_powerpc (bfd_vma, disassemble_info *);
+extern int print_insn_little_powerpc (bfd_vma, disassemble_info *);
+extern int print_insn_rs6000 (bfd_vma, disassemble_info *);
+extern int print_insn_s390 (bfd_vma, disassemble_info *);
+extern int print_insn_sh (bfd_vma, disassemble_info *);
+extern int print_insn_tic30 (bfd_vma, disassemble_info *);
+extern int print_insn_tic4x (bfd_vma, disassemble_info *);
+extern int print_insn_tic54x (bfd_vma, disassemble_info *);
+extern int print_insn_tic80 (bfd_vma, disassemble_info *);
+extern int print_insn_v850 (bfd_vma, disassemble_info *);
+extern int print_insn_vax (bfd_vma, disassemble_info *);
+extern int print_insn_w65 (bfd_vma, disassemble_info *);
+extern int print_insn_xstormy16 (bfd_vma, disassemble_info *);
+extern int print_insn_xtensa (bfd_vma, disassemble_info *);
+extern int print_insn_sh64 (bfd_vma, disassemble_info *);
+extern int print_insn_sh64x_media (bfd_vma, disassemble_info *);
+extern int print_insn_frv (bfd_vma, disassemble_info *);
+extern int print_insn_iq2000 (bfd_vma, disassemble_info *);
+extern int print_insn_m32c (bfd_vma, disassemble_info *);
+
+extern disassembler_ftype arc_get_disassembler (void *);
+extern disassembler_ftype cris_get_disassembler (bfd *);
+
+extern void print_mips_disassembler_options (FILE *);
+extern void print_ppc_disassembler_options (FILE *);
+extern void print_arm_disassembler_options (FILE *);
+extern void parse_arm_disassembler_option (char *);
+extern int get_arm_regname_num_options (void);
+extern int set_arm_regname_option (int);
+extern int get_arm_regnames (int, const char **, const char **, const char *const **);
+extern bfd_boolean arm_symbol_is_valid (struct bfd_symbol *, struct disassemble_info *);
+
+/* Fetch the disassembler for a given BFD, if that support is available. */
+extern disassembler_ftype disassembler (bfd *);
+
+/* Amend the disassemble_info structure as necessary for the target architecture.
+ Should only be called after initialising the info->arch field. */
+extern void disassemble_init_for_target (struct disassemble_info * info);
+
+/* Document any target specific options available from the disassembler. */
+extern void disassembler_usage (FILE *);
+
+\f
+/* This block of definitions is for particular callers who read instructions
+ into a buffer before calling the instruction decoder. */
+
+/* Here is a function which callers may wish to use for read_memory_func.
+ It gets bytes from a buffer. */
+extern int buffer_read_memory
+ (bfd_vma, bfd_byte *, unsigned int, struct disassemble_info *);
+
+/* This function goes with buffer_read_memory.
+ It prints a message using info->fprintf_func and info->stream. */
+extern void perror_memory (int, bfd_vma, struct disassemble_info *);
+
+
+/* Just print the address in hex. This is included for completeness even
+ though both GDB and objdump provide their own (to print symbolic
+ addresses). */
+extern void generic_print_address
+ (bfd_vma, struct disassemble_info *);
+
+/* Always true. */
+extern int generic_symbol_at_address
+ (bfd_vma, struct disassemble_info *);
+
+/* Also always true. */
+extern bfd_boolean generic_symbol_is_valid
+ (struct bfd_symbol *, struct disassemble_info *);
+
+/* Method to initialize a disassemble_info struct. This should be
+ called by all applications creating such a struct. */
+extern void init_disassemble_info (struct disassemble_info *info, void *stream,
+ fprintf_ftype fprintf_func);
+
+/* For compatibility with existing code. */
+#define INIT_DISASSEMBLE_INFO(INFO, STREAM, FPRINTF_FUNC) \
+ init_disassemble_info (&(INFO), (STREAM), (fprintf_ftype) (FPRINTF_FUNC))
+#define INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC) \
+ init_disassemble_info (&(INFO), (STREAM), (fprintf_ftype) (FPRINTF_FUNC))
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! defined (DIS_ASM_H) */
--- /dev/null
+#ifndef _KDB_H
+#define _KDB_H
+
+/*
+ * Kernel Debugger Architecture Independent Global Headers
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (C) 2000 Stephane Eranian <eranian@hpl.hp.com>
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <asm/atomic.h>
+
+/* These are really private, but they must be defined before including
+ * asm-$(ARCH)/kdb.h, so make them public and put them here.
+ */
+extern int kdb_getuserarea_size(void *, unsigned long, size_t);
+extern int kdb_putuserarea_size(unsigned long, void *, size_t);
+
+#include <asm/kdb.h>
+
+#define KDB_MAJOR_VERSION 4
+#define KDB_MINOR_VERSION 4
+#define KDB_TEST_VERSION ""
+
+/*
+ * kdb_initial_cpu is initialized to -1, and is set to the cpu
+ * number whenever the kernel debugger is entered.
+ */
+extern volatile int kdb_initial_cpu;
+extern atomic_t kdb_8250;
+#ifdef CONFIG_KDB
+#define KDB_IS_RUNNING() (kdb_initial_cpu != -1)
+#define KDB_8250() (atomic_read(&kdb_8250) != 0)
+#else
+#define KDB_IS_RUNNING() (0)
+#define KDB_8250() (0)
+#endif /* CONFIG_KDB */
+
+/*
+ * kdb_on
+ *
+ * Defines whether kdb is on or not. Default value
+ * is set by CONFIG_KDB_OFF. Boot with kdb=on/off/on-nokey
+ * or echo "[012]" > /proc/sys/kernel/kdb to change it.
+ */
+extern int kdb_on;
+
+/*
+ * kdb_serial.iobase is initialized to zero, and is set to the I/O
+ * address of the serial port when the console is setup in
+ * serial_console_setup.
+ */
+extern struct kdb_serial {
+ int io_type;
+ unsigned long iobase;
+ unsigned long ioreg_shift;
+} kdb_serial;
+
+/*
+ * kdb_diemsg
+ *
+ * Contains a pointer to the last string supplied to the
+ * kernel 'die' panic function.
+ */
+extern const char *kdb_diemsg;
+
+#define KDB_FLAG_EARLYKDB (1 << 0) /* set from boot parameter kdb=early */
+#define KDB_FLAG_CATASTROPHIC (1 << 1) /* A catastrophic event has occurred */
+#define KDB_FLAG_CMD_INTERRUPT (1 << 2) /* Previous command was interrupted */
+#define KDB_FLAG_NOIPI (1 << 3) /* Do not send IPIs */
+#define KDB_FLAG_ONLY_DO_DUMP (1 << 4) /* Only do a dump, used when kdb is off */
+#define KDB_FLAG_NO_CONSOLE (1 << 5) /* No console is available, kdb is disabled */
+#define KDB_FLAG_RECOVERY (1 << 6) /* kdb is being entered for an error which has been recovered */
+
+extern volatile int kdb_flags; /* Global flags, see kdb_state for per cpu state */
+
+extern void kdb_save_flags(void);
+extern void kdb_restore_flags(void);
+
+#define KDB_FLAG(flag) (kdb_flags & KDB_FLAG_##flag)
+#define KDB_FLAG_SET(flag) ((void)(kdb_flags |= KDB_FLAG_##flag))
+#define KDB_FLAG_CLEAR(flag) ((void)(kdb_flags &= ~KDB_FLAG_##flag))
+
+/*
+ * External entry point for the kernel debugger. The pt_regs
+ * at the time of entry are supplied along with the reason for
+ * entry to the kernel debugger.
+ */
+
+typedef enum {
+ KDB_REASON_ENTER=1, /* KDB_ENTER() trap/fault - regs valid */
+ KDB_REASON_ENTER_SLAVE, /* KDB_ENTER_SLAVE() trap/fault - regs valid */
+ KDB_REASON_BREAK, /* Breakpoint inst. - regs valid */
+ KDB_REASON_DEBUG, /* Debug Fault - regs valid */
+ KDB_REASON_OOPS, /* Kernel Oops - regs valid */
+ KDB_REASON_SWITCH, /* CPU switch - regs valid*/
+ KDB_REASON_KEYBOARD, /* Keyboard entry - regs valid */
+ KDB_REASON_NMI, /* Non-maskable interrupt; regs valid */
+ KDB_REASON_RECURSE, /* Recursive entry to kdb; regs probably valid */
+ KDB_REASON_CPU_UP, /* Add one cpu to kdb; regs invalid */
+ KDB_REASON_SILENT, /* Silent entry/exit to kdb; regs invalid - internal only */
+} kdb_reason_t;
+
+#ifdef CONFIG_KDB
+extern asmlinkage int kdb(kdb_reason_t, int, struct pt_regs *);
+#else
+#define kdb(reason,error_code,frame) (0)
+#endif
+
+/* Mainly used by kdb code, but this function is sometimes used
+ * by hacked debug code so make it generally available, not private.
+ */
+extern void kdb_printf(const char *,...)
+ __attribute__ ((format (printf, 1, 2)));
+typedef void (*kdb_printf_t)(const char *, ...);
+extern void kdb_init(void);
+
+#if defined(CONFIG_SMP)
+/*
+ * Kernel debugger non-maskable IPI handler.
+ */
+extern int kdb_ipi(struct pt_regs *, void (*ack_interrupt)(void));
+extern void smp_kdb_stop(void);
+#else /* CONFIG_SMP */
+#define smp_kdb_stop()
+#endif /* CONFIG_SMP */
+
+#ifdef CONFIG_KDB_USB
+#include <linux/usb.h>
+
+struct kdb_usb_exchange {
+ void *uhci; /* pointer to the UHCI structure */
+ struct urb *urb; /* pointer to the URB */
+ unsigned char *buffer; /* pointer to buffer */
+ void (*poll_func)(void *, struct urb *); /* pointer to the polling function */
+ void (*reset_timer)(void); /* pointer to the reset timer function */
+};
+extern struct kdb_usb_exchange kdb_usb_infos; /* KDB common structure */
+#endif /* CONFIG_KDB_USB */
+
+static inline
+int kdb_process_cpu(const struct task_struct *p)
+{
+ unsigned int cpu = p->thread_info->cpu;
+ if (cpu > NR_CPUS)
+ cpu = 0;
+ return cpu;
+}
+
+extern const char kdb_serial_str[];
+
+#endif /* !_KDB_H */
--- /dev/null
+#ifndef _KDBPRIVATE_H
+#define _KDBPRIVATE_H
+
+/*
+ * Kernel Debugger Architecture Independent Private Headers
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+
+#include <linux/dis-asm.h>
+#include <asm/kdbprivate.h>
+#include <asm/bfd.h>
+
+ /*
+ * Kernel Debugger Error codes. Must not overlap with command codes.
+ */
+
+#define KDB_NOTFOUND (-1)
+#define KDB_ARGCOUNT (-2)
+#define KDB_BADWIDTH (-3)
+#define KDB_BADRADIX (-4)
+#define KDB_NOTENV (-5)
+#define KDB_NOENVVALUE (-6)
+#define KDB_NOTIMP (-7)
+#define KDB_ENVFULL (-8)
+#define KDB_ENVBUFFULL (-9 )
+#define KDB_TOOMANYBPT (-10)
+#define KDB_TOOMANYDBREGS (-11)
+#define KDB_DUPBPT (-12)
+#define KDB_BPTNOTFOUND (-13)
+#define KDB_BADMODE (-14)
+#define KDB_BADINT (-15)
+#define KDB_INVADDRFMT (-16)
+#define KDB_BADREG (-17)
+#define KDB_BADCPUNUM (-18)
+#define KDB_BADLENGTH (-19)
+#define KDB_NOBP (-20)
+#define KDB_BADADDR (-21)
+
+ /*
+ * Kernel Debugger Command codes. Must not overlap with error codes.
+ */
+#define KDB_CMD_GO (-1001)
+#define KDB_CMD_CPU (-1002)
+#define KDB_CMD_SS (-1003)
+#define KDB_CMD_SSB (-1004)
+
+ /*
+ * Internal debug flags
+ */
+#define KDB_DEBUG_FLAG_BT 0x0001 /* Stack traceback debug */
+#define KDB_DEBUG_FLAG_BP 0x0002 /* Breakpoint subsystem debug */
+/* KDB_DEBUG_FLAG_LBR 0x0004 WAS Print last branch register */
+#define KDB_DEBUG_FLAG_AR 0x0008 /* Activation record, generic */
+#define KDB_DEBUG_FLAG_ARA 0x0010 /* Activation record, arch specific */
+/* KDB_DEBUG_FLAG_CALLBACK 0x0020 WAS Event callbacks to kdb */
+#define KDB_DEBUG_FLAG_STATE 0x0040 /* State flags */
+#define KDB_DEBUG_FLAG_MASK 0xffff /* All debug flags */
+#define KDB_DEBUG_FLAG_SHIFT 16 /* Shift factor for dbflags */
+
+#define KDB_DEBUG(flag) (kdb_flags & (KDB_DEBUG_FLAG_##flag << KDB_DEBUG_FLAG_SHIFT))
+#define KDB_DEBUG_STATE(text,value) if (KDB_DEBUG(STATE)) kdb_print_state(text, value)
+
+typedef enum {
+ KDB_REPEAT_NONE = 0, /* Do not repeat this command */
+ KDB_REPEAT_NO_ARGS, /* Repeat the command without arguments */
+ KDB_REPEAT_WITH_ARGS, /* Repeat the command including its arguments */
+} kdb_repeat_t;
+
+typedef int (*kdb_func_t)(int, const char **, const char **, struct pt_regs *);
+
+ /*
+ * Symbol table format returned by kallsyms.
+ */
+
+typedef struct __ksymtab {
+ unsigned long value; /* Address of symbol */
+ const char *mod_name; /* Module containing symbol or "kernel" */
+ const char *sym_name; /* Full symbol name, including any version */
+ unsigned long sym_start;
+ unsigned long sym_end;
+ } kdb_symtab_t;
+extern int kallsyms_symbol_next(char *prefix_name, int flag);
+extern int kallsyms_symbol_complete(char *prefix_name, int max_len);
+
+ /*
+ * Exported Symbols for kernel loadable modules to use.
+ */
+extern int kdb_register(char *, kdb_func_t, char *, char *, short);
+extern int kdb_register_repeat(char *, kdb_func_t, char *, char *, short, kdb_repeat_t);
+extern int kdb_unregister(char *);
+
+extern int kdb_getarea_size(void *, unsigned long, size_t);
+extern int kdb_putarea_size(unsigned long, void *, size_t);
+
+/* Like get_user and put_user, kdb_getarea and kdb_putarea take variable
+ * names, not pointers. The underlying *_size functions take pointers.
+ */
+#define kdb_getarea(x,addr) kdb_getarea_size(&(x), addr, sizeof((x)))
+#define kdb_putarea(addr,x) kdb_putarea_size(addr, &(x), sizeof((x)))
+
+extern int kdb_getphysword(unsigned long *word,
+ unsigned long addr, size_t size);
+extern int kdb_getword(unsigned long *, unsigned long, size_t);
+extern int kdb_putword(unsigned long, unsigned long, size_t);
+
+extern int kdbgetularg(const char *, unsigned long *);
+extern char *kdbgetenv(const char *);
+extern int kdbgetintenv(const char *, int *);
+extern int kdbgetaddrarg(int, const char**, int*, unsigned long *,
+ long *, char **, struct pt_regs *);
+extern int kdbgetsymval(const char *, kdb_symtab_t *);
+extern int kdbnearsym(unsigned long, kdb_symtab_t *);
+extern char *kdb_read(char *buffer, size_t bufsize);
+extern void kdb_symbol_print(kdb_machreg_t, const kdb_symtab_t *, unsigned int);
+
+ /*
+ * Do we have a set of registers?
+ */
+
+#define KDB_NULL_REGS(regs) (regs < (struct pt_regs *)PAGE_OFFSET ? \
+ kdb_printf("%s: null regs - should never happen\n", __FUNCTION__), 1 : 0)
+
+ /*
+ * Routine for debugging the debugger state.
+ */
+
+extern void kdb_print_state(const char *, int);
+
+ /*
+ * Per cpu kdb state. A cpu can be under kdb control but outside kdb,
+ * for example when doing single step.
+ */
+volatile extern int kdb_state[ /*NR_CPUS*/ ];
+#define KDB_STATE_KDB 0x00000001 /* Cpu is inside kdb */
+#define KDB_STATE_LEAVING 0x00000002 /* Cpu is leaving kdb */
+#define KDB_STATE_CMD 0x00000004 /* Running a kdb command */
+#define KDB_STATE_KDB_CONTROL 0x00000008 /* This cpu is under kdb control */
+#define KDB_STATE_HOLD_CPU 0x00000010 /* Hold this cpu inside kdb */
+#define KDB_STATE_DOING_SS 0x00000020 /* Doing ss command */
+#define KDB_STATE_DOING_SSB 0x00000040 /* Doing ssb command, DOING_SS is also set */
+#define KDB_STATE_SSBPT 0x00000080 /* Install breakpoint after one ss, independent of DOING_SS */
+#define KDB_STATE_REENTRY 0x00000100 /* Valid re-entry into kdb */
+#define KDB_STATE_SUPPRESS 0x00000200 /* Suppress error messages */
+#define KDB_STATE_LONGJMP 0x00000400 /* longjmp() data is available */
+#define KDB_STATE_GO_SWITCH 0x00000800 /* go is switching back to initial cpu */
+#define KDB_STATE_PRINTF_LOCK 0x00001000 /* Holds kdb_printf lock */
+#define KDB_STATE_WAIT_IPI 0x00002000 /* Waiting for kdb_ipi() NMI */
+#define KDB_STATE_RECURSE 0x00004000 /* Recursive entry to kdb */
+#define KDB_STATE_IP_ADJUSTED 0x00008000 /* Restart IP has been adjusted */
+#define KDB_STATE_GO1 0x00010000 /* go only releases one cpu */
+#define KDB_STATE_KEYBOARD 0x00020000 /* kdb entered via keyboard on this cpu */
+#define KDB_STATE_ARCH 0xff000000 /* Reserved for arch specific use */
+
+#define KDB_STATE_CPU(flag,cpu) (kdb_state[cpu] & KDB_STATE_##flag)
+#define KDB_STATE_SET_CPU(flag,cpu) ((void)(kdb_state[cpu] |= KDB_STATE_##flag))
+#define KDB_STATE_CLEAR_CPU(flag,cpu) ((void)(kdb_state[cpu] &= ~KDB_STATE_##flag))
+
+#define KDB_STATE(flag) KDB_STATE_CPU(flag,smp_processor_id())
+#define KDB_STATE_SET(flag) KDB_STATE_SET_CPU(flag,smp_processor_id())
+#define KDB_STATE_CLEAR(flag) KDB_STATE_CLEAR_CPU(flag,smp_processor_id())
+
+ /*
+ * kdb_nextline
+ *
+ * Contains the current line number on the screen. Used
+ * to handle the built-in pager (LINES env variable)
+ */
+extern volatile int kdb_nextline;
+
+ /*
+ * Breakpoint state
+ *
+ * Each active and inactive breakpoint is represented by
+ * an instance of the following data structure.
+ */
+
+typedef struct _kdb_bp {
+ bfd_vma bp_addr; /* Address breakpoint is present at */
+ kdb_machinst_t bp_inst; /* Replaced instruction */
+
+ unsigned int bp_free:1; /* This entry is available */
+
+ unsigned int bp_enabled:1; /* Breakpoint is active in register */
+ unsigned int bp_global:1; /* Global to all processors */
+
+ unsigned int bp_hardtype:1; /* Uses hardware register */
+ unsigned int bp_forcehw:1; /* Force hardware register */
+ unsigned int bp_installed:1; /* Breakpoint is installed */
+ unsigned int bp_delay:1; /* Do delayed bp handling */
+ unsigned int bp_delayed:1; /* Delayed breakpoint */
+
+ int bp_cpu; /* Cpu # (if bp_global == 0) */
+ kdbhard_bp_t bp_template; /* Hardware breakpoint template */
+ kdbhard_bp_t *bp_hard; /* Hardware breakpoint structure */
+ int bp_adjust; /* Adjustment to PC for real instruction */
+} kdb_bp_t;
+
+ /*
+ * Breakpoint handling subsystem global variables
+ */
+extern kdb_bp_t kdb_breakpoints[/* KDB_MAXBPT */];
+
+ /*
+ * Breakpoint architecture dependent functions. Must be provided
+ * in some form for all architectures.
+ */
+extern void kdba_initbp(void);
+extern void kdba_printbp(kdb_bp_t *);
+extern kdbhard_bp_t *kdba_allocbp(kdbhard_bp_t *, int *);
+extern void kdba_freebp(kdbhard_bp_t *);
+extern int kdba_parsebp(int, const char**, int *, kdb_bp_t*);
+extern char *kdba_bptype(kdbhard_bp_t *);
+extern void kdba_setsinglestep(struct pt_regs *);
+extern void kdba_clearsinglestep(struct pt_regs *);
+
+ /*
+ * Adjust instruction pointer architecture dependent function. Must be
+ * provided in some form for all architectures.
+ */
+extern void kdba_adjust_ip(kdb_reason_t, int, struct pt_regs *);
+
+ /*
+ * KDB-only global function prototypes.
+ */
+extern void kdb_id1(unsigned long);
+extern void kdb_id_init(void);
+
+ /*
+ * Initialization functions.
+ */
+extern void kdba_init(void);
+extern void kdb_io_init(void);
+
+ /*
+ * Architecture specific function to read a string.
+ */
+typedef int (*get_char_func)(void);
+extern get_char_func poll_funcs[];
+
+#ifndef CONFIG_IA64
+ /*
+ * Data for a single activation record on stack.
+ */
+
+struct kdb_stack_info {
+ kdb_machreg_t physical_start;
+ kdb_machreg_t physical_end;
+ kdb_machreg_t logical_start;
+ kdb_machreg_t logical_end;
+ kdb_machreg_t next;
+ const char * id;
+};
+
+struct kdb_activation_record {
+ struct kdb_stack_info stack; /* information about current stack */
+ kdb_machreg_t start; /* -> start of activation record */
+ kdb_machreg_t end; /* -> end+1 of activation record */
+ kdb_machreg_t ret; /* Return address to caller */
+ kdb_machreg_t oldfp; /* Frame pointer for caller's frame */
+ kdb_machreg_t fp; /* Frame pointer for callee's frame */
+ int args; /* number of arguments detected */
+ kdb_machreg_t arg[KDBA_MAXARGS]; /* -> arguments */
+};
+#endif
+
+ /*
+ * Architecture specific Stack Traceback functions.
+ */
+
+struct task_struct;
+
+extern int kdba_bt_address(kdb_machreg_t, int);
+extern int kdba_bt_process(const struct task_struct *, int);
+
+ /*
+ * KDB Command Table
+ */
+
+typedef struct _kdbtab {
+ char *cmd_name; /* Command name */
+ kdb_func_t cmd_func; /* Function to execute command */
+ char *cmd_usage; /* Usage String for this command */
+ char *cmd_help; /* Help message for this command */
+ short cmd_flags; /* Parsing flags */
+ short cmd_minlen; /* Minimum legal # command chars required */
+ kdb_repeat_t cmd_repeat; /* Does command auto repeat on enter? */
+} kdbtab_t;
+
+ /*
+ * External command function declarations
+ */
+
+extern int kdb_id(int, const char **, const char **, struct pt_regs *);
+extern int kdb_bt(int, const char **, const char **, struct pt_regs *);
+
+ /*
+ * External utility function declarations
+ */
+extern char* kdb_getstr(char *, size_t, char *);
+
+ /*
+ * Register contents manipulation
+ */
+extern int kdba_getregcontents(const char *, struct pt_regs *, kdb_machreg_t *);
+extern int kdba_setregcontents(const char *, struct pt_regs *, kdb_machreg_t);
+extern int kdba_dumpregs(struct pt_regs *, const char *, const char *);
+extern int kdba_setpc(struct pt_regs *, kdb_machreg_t);
+extern kdb_machreg_t kdba_getpc(struct pt_regs *);
+
+ /*
+ * Debug register handling.
+ */
+extern void kdba_installdbreg(kdb_bp_t*);
+extern void kdba_removedbreg(kdb_bp_t*);
+
+ /*
+ * Breakpoint handling - External interfaces
+ */
+extern void kdb_initbptab(void);
+extern void kdb_bp_install_global(struct pt_regs *);
+extern void kdb_bp_install_local(struct pt_regs *);
+extern void kdb_bp_remove_global(void);
+extern void kdb_bp_remove_local(void);
+
+ /*
+ * Breakpoint handling - Internal to kdb_bp.c/kdba_bp.c
+ */
+extern int kdba_installbp(struct pt_regs *regs, kdb_bp_t *);
+extern int kdba_removebp(kdb_bp_t *);
+
+
+typedef enum {
+ KDB_DB_BPT, /* Breakpoint */
+ KDB_DB_SS, /* Single-step trap */
+ KDB_DB_SSB, /* Single step to branch */
+ KDB_DB_SSBPT, /* Single step over breakpoint */
+ KDB_DB_NOBPT /* Spurious breakpoint */
+} kdb_dbtrap_t;
+
+extern kdb_dbtrap_t kdba_db_trap(struct pt_regs *, int); /* DEBUG trap/fault handler */
+extern kdb_dbtrap_t kdba_bp_trap(struct pt_regs *, int); /* Breakpoint trap/fault hdlr */
+
+ /*
+ * Interrupt Handling
+ */
+typedef unsigned long kdb_intstate_t;
+
+extern void kdba_disableint(kdb_intstate_t *);
+extern void kdba_restoreint(kdb_intstate_t *);
+
+ /*
+ * SMP and process stack manipulation routines.
+ */
+extern int kdba_ipi(struct pt_regs *, void (*)(void));
+extern int kdba_main_loop(kdb_reason_t, kdb_reason_t, int, kdb_dbtrap_t, struct pt_regs *);
+extern int kdb_main_loop(kdb_reason_t, kdb_reason_t, int, kdb_dbtrap_t, struct pt_regs *);
+
+ /*
+ * General Disassembler interfaces
+ */
+extern int kdb_dis_fprintf(PTR, const char *, ...) __attribute__ ((format (printf, 2, 3)));
+extern int kdb_dis_fprintf_dummy(PTR, const char *, ...) __attribute__ ((format (printf, 2, 3)));
+extern disassemble_info kdb_di;
+
+ /*
+ * Architecture Dependent Disassembler interfaces
+ */
+extern int kdba_id_printinsn(kdb_machreg_t, disassemble_info *);
+extern int kdba_id_parsemode(const char *, disassemble_info*);
+extern void kdba_id_init(disassemble_info *);
+extern void kdba_check_pc(kdb_machreg_t *);
+
+ /*
+ * Miscellaneous functions and data areas
+ */
+extern char *kdb_cmds[];
+extern void kdb_syslog_data(char *syslog_data[]);
+extern unsigned long kdb_task_state_string(const char *);
+extern char kdb_task_state_char (const struct task_struct *);
+extern unsigned long kdb_task_state(const struct task_struct *p, unsigned long mask);
+extern void kdb_ps_suppressed(void);
+extern void kdb_ps1(const struct task_struct *p);
+extern int kdb_parse(const char *cmdstr, struct pt_regs *regs);
+extern void kdb_print_nameval(const char *name, unsigned long val);
+extern void kdb_send_sig_info(struct task_struct *p, struct siginfo *info, int seqno);
+#ifdef CONFIG_PPC64
+extern int kdb_ss(int, const char **, const char **, struct pt_regs *);
+#endif
+extern const char *kdb_walk_kallsyms(loff_t *pos);
+
+ /*
+ * Architecture Dependant Local Processor setup & cleanup interfaces
+ */
+extern void kdba_local_arch_setup(void);
+extern void kdba_local_arch_cleanup(void);
+
+ /*
+ * Defines for kdb_symbol_print.
+ */
+#define KDB_SP_SPACEB 0x0001 /* Space before string */
+#define KDB_SP_SPACEA 0x0002 /* Space after string */
+#define KDB_SP_PAREN 0x0004 /* Parenthesis around string */
+#define KDB_SP_VALUE 0x0008 /* Print the value of the address */
+#define KDB_SP_SYMSIZE 0x0010 /* Print the size of the symbol */
+#define KDB_SP_NEWLINE 0x0020 /* Newline after string */
+#define KDB_SP_DEFAULT (KDB_SP_VALUE|KDB_SP_PAREN)
+
+/* Save data about running processes */
+
+struct kdb_running_process {
+ struct task_struct *p;
+ struct pt_regs *regs;
+ int seqno; /* kdb sequence number */
+ int irq_depth; /* irq count */
+ struct kdba_running_process arch; /* arch dependent save data */
+};
+
+extern struct kdb_running_process kdb_running_process[/* NR_CPUS */];
+
+extern void kdb_save_running(struct pt_regs *);
+extern void kdb_unsave_running(struct pt_regs *);
+extern struct task_struct *kdb_curr_task(int);
+
+/* Incremented each time the main kdb loop is entered on the initial cpu,
+ * it gives some indication of how old the saved data is.
+ */
+extern int kdb_seqno;
+
+extern void kdb_runqueue(unsigned long cpu, kdb_printf_t xxx_printf);
+
+extern void kdba_set_current_task(const struct task_struct *);
+extern const struct task_struct *kdb_current_task;
+extern struct pt_regs *kdb_current_regs;
+
+/* Functions to safely read and write kernel areas. The {to,from}_xxx
+ * addresses are not necessarily valid, these functions must check for
+ * validity. If the arch already supports get and put routines with suitable
+ * validation and/or recovery on invalid addresses then use those routines,
+ * otherwise check it yourself.
+ */
+
+extern int kdba_putarea_size(unsigned long to_xxx, void *from, size_t size);
+extern int kdba_getarea_size(void *to, unsigned long from_xxx, size_t size);
+extern int kdba_verify_rw(unsigned long addr, size_t size);
+
+#ifndef KDB_RUNNING_PROCESS_ORIGINAL
+#define KDB_RUNNING_PROCESS_ORIGINAL kdb_running_process
+#endif
+
+extern int kdb_wait_for_cpus_secs;
+extern void kdba_cpu_up(void);
+
+#define KM_KDB KM_BOUNCE_READ /* not quite safe, but avoids kmap_types.h */
+
+#endif /* !_KDBPRIVATE_H */
static inline void pagevec_init(struct pagevec *pvec, int cold)
{
- pvec->nr = 0;
+ memset(pvec, 0, sizeof(*pvec));
pvec->cold = cold;
}
KERN_PRINT_FATAL=1001, /* int: print fatal signals (0/1/2) */
KERN_VDSO=1002, /* int: VDSO enabled (0/1) */
KERN_REALROOTDEV=16, /* real root device to mount after initrd */
-
+ KERN_XMON=19, /* int: xmon debugger enabled */
+ KERN_KDB=20, /* int: kdb on/off */
KERN_SPARC_REBOOT=21, /* reboot command on Sparc */
KERN_CTLALTDEL=22, /* int: allow ctl-alt-del to reboot */
KERN_PRINTK=23, /* struct: control printk logging parameters */
#include <asm/smp.h>
#endif
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#endif /* CONFIG_KDB */
+
/*
* This is one of the first .c files built. Error out early if we have compiler
* trouble.
extern struct obs_kernel_param __setup_start[], __setup_end[];
+#ifdef CONFIG_KDB
+static int __init kdb_setup(char *str)
+{
+ if (strcmp(str, "on") == 0) {
+ kdb_on = 1;
+ } else if (strcmp(str, "on-nokey") == 0) {
+ kdb_on = 2;
+ } else if (strcmp(str, "off") == 0) {
+ kdb_on = 0;
+ } else if (strcmp(str, "early") == 0) {
+ kdb_on = 1;
+ kdb_flags |= KDB_FLAG_EARLYKDB;
+ } else
+ printk("kdb flag %s not recognised\n", str);
+ return 0;
+}
+
+__setup("kdb=", kdb_setup);
+#endif /* CONFIG_KDB */
+
static int __init obsolete_checksetup(char *line)
{
struct obs_kernel_param *p;
pgtable_cache_init();
prio_tree_init();
anon_vma_init();
+
+#ifdef CONFIG_KDB
+ kdb_init();
+ if (KDB_FLAG(EARLYKDB)) {
+ KDB_ENTER();
+ }
+#endif /* CONFIG_KDB */
+
#ifdef CONFIG_X86
if (efi_enabled)
efi_enter_virtual_mode();
--- /dev/null
+2006-09-20 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-common-1.
+
+2006-09-15 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc7-common-1.
+
+2006-08-29 Keith Owens <kaos@sgi.com>
+
+ * Rewrite all backtrace code.
+ * kdb v4.4-2.6.18-rc5-common-2.
+
+2006-08-28 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc5-common-1.
+
+2006-08-08 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc4-common-1.
+
+2006-08-04 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc3-common-1.
+
+2006-07-18 Keith Owens <kaos@sgi.com>
+
+ * 8250.c locking has been fixed so there is no need to break spinlocks
+ for keyboard entry.
+ * kdb v4.4-2.6.18-rc2-common-2.
+
+2006-07-18 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc2-common-1.
+
+2006-07-12 Keith Owens <kaos@sgi.com>
+
+ * Remove dead KDB_REASON codes.
+ * The main kdb() function is now always entered with interrupts
+ disabled, so there is no need to disable bottom halves.
+ * sparse cleanups.
+ * kdb v4.4-2.6.18-rc1-common-2.
+
+2006-07-07 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.18-rc1-common-1.
+
+2006-07-04 Keith Owens <kaos@sgi.com>
+
+ * Add KDB_REASON_CPU_UP and callbacks for cpus coming online.
+ * Relegate KDB_REASON_SILENT to KDB internal use only.
+ * Backout the v4.4-2.6.15-common-3 change that made KDB_REASON_SILENT
+ wait for cpus, the Dell Xeon problem has been fixed.
+ * notify_die() is not called for KDB_REASON_SILENT nor
+ KDB_REASON_CPU_UP, these events do not stay in KDB.
+ * Export kdb_current_task for kdbm_x86. SuSE patch
+ kdb-missing-export.diff
+ * Scale kdb_wait_for_cpus_secs by the number of online cpus.
+ * Delete kdb_enablehwfault, architectures now do their own setup.
+ * Delete kdba_enable_mce, architectures now do their own setup.
+ * Delete kdba_enable_lbr, kdba_disable_lbr, kdba_print_lbr,
+ page_fault_mca. Only ever implemented on x86, difficult to maintain
+ and rarely used in the field.
+ * Replace #ifdef KDB_HAVE_LONGJMP with #ifdef kdba_setjmp.
+ * kdb v4.4-2.6.17-common-2.
+
+2006-06-19 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-common-1.
+
+2006-05-31 Keith Owens <kaos@sgi.com>
+
+ * Break spinlocks for keyboard entry. Hopefully a temporary hack while
+ I track down why keyboard entry to KDB is hanging.
+ * kdb v4.4-2.6.17-rc5-common-2.
+
+2006-05-25 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-rc5-common-1.
+
+2006-05-15 Keith Owens <kaos@sgi.com>
+
+ * Refresh bfd related files from binutils 2.16.91.0.2.
+ * kdb v4.4-2.6.17-rc4-common-2.
+
+2006-05-12 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-rc4-common-1.
+
+2006-04-28 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-rc3-common-1.
+
+2006-04-22 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-rc2-common-1.
+
+2006-04-11 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.17-rc1-common-1.
+
+2006-04-05 Keith Owens <kaos@sgi.com>
+
+ * More fixes for the timing race with KDB_ENTER_SLAVE.
+ * kdb v4.4-2.6.16-common-5.
+
+2006-03-30 Keith Owens <kaos@sgi.com>
+
+ * Some code was testing KDB_IS_RUNNING() twice, which left it open to
+ races. Cache the result instead.
+ * kdb v4.4-2.6.16-common-4.
+
+2006-03-30 Keith Owens <kaos@sgi.com>
+
+ * Change CONFIG_LKCD to CONFIG_LKCD_DUMP.
+ * kdb v4.4-2.6.16-common-3.
+
+2006-03-22 Keith Owens <kaos@sgi.com>
+
+ * Add some more xpc flags. Dean Nelson, SGI.
+ * Replace open coded counter references with atomic_read().
+ * Pass early_uart_console to early_uart_setup(). Francois
+ Wellenreiter, Bull.
+ * Replace open code with for_each_online_cpu().
+ * If cpus do not come into kdb after a few seconds then let
+ architectures send a more forceful interrupt.
+ * Close a timing race with KDB_ENTER_SLAVE.
+ * kdb v4.4-2.6.16-common-2.
+
+2006-03-21 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.16-common-1.
+
+2006-03-14 Nathan Scott <nathans@sgi.com>
+
+ * kdb v4.4-2.6.16-rc6-common-1.
+
+2006-02-28 Nathan Scott <nathans@sgi.com>
+
+ * kdb v4.4-2.6.16-rc5-common-1.
+
+2006-02-20 Nathan Scott <nathans@sgi.com>
+
+ * kdb v4.4-2.6.16-rc4-common-1.
+
+2006-02-06 Keith Owens <kaos@sgi.com>
+
+ * Change CONFIG_CRASH_DUMP to CONFIG_LKCD.
+ * Remove obsolete kdb_notifier_list.
+ * kdb v4.4-2.6.16-rc2-common-2.
+
+2006-02-06 Keith Owens <kaos@sgi.com>
+
+ * Add xpcusers command. Dean Nelson, SGI.
+ * kdb v4.4-2.6.16-rc2-common-1.
+
+2006-02-02 Keith Owens <kaos@sgi.com>
+
+ * Check if we have a console before using it for KDB.
+ * kdb v4.4-2.6.16-rc1-common-3.
+
+2006-02-01 Keith Owens <kaos@sgi.com>
+
+ * Add option 'R' to the pid command to reset to the original task.
+ * Include 'pid R' in archkdb* commands to reset up the original failing
+ task. Users may have switched to other cpus and/or tasks before
+ issuing archkdb.
+ * Compile fix for kdbm_pg.c on i386.
+ * kdb v4.4-2.6.16-rc1-common-2.
+
+2006-01-18 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.16-rc1-common-1.
+
+2006-01-11 Keith Owens <kaos@sgi.com>
+
+ * Plug a timing race between KDB_ENTER_SLAVE and KDB_ENTER, and allow
+ the cpu command to switch to a slave cpu.
+ * KDB_REASON_SILENT now waits for other cpus, to avoid spurious NMI
+ events that were seen on some Xeon systems.
+ * kdb v4.4-2.6.15-common-3.
+
+2006-01-08 Keith Owens <kaos@sgi.com>
+
+ * kdb mainline invokes DIE_KDEBUG_ENTER and DIE_KDEBUG_LEAVE via
+ notify_die.
+ * Move xpc debug support from xpc to mainline kdb.
+ * kdbm_cm.c: check if file_lock_operations or lock_manager_operations
+ are set before dereferencing them. Felix Blyakher, SGI.
+ * kdb v4.4-2.6.15-common-2.
+
+2006-01-04 Keith Owens <kaos@sgi.com>
+
+ * Print all buffers on a page in inode pages and update formatting to be
+ legible, too. David Chinner, SGI.
+ * Update page flags in kdbm_pg.
+ * Remove inline from *.c files.
+ * kdb v4.4-2.6.15-common-1.
+
+2005-12-25 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.15-rc7-common-1.
+
+2005-12-20 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.15-rc6-common-1.
+
+2005-12-10 Keith Owens <kaos@sgi.com>
+
+ * Update mapping of flags to strings in kdbm_pg.c and kdbm_vm.c.
+ * kdb v4.4-2.6.15-rc5-common-3.
+
+2005-12-06 Keith Owens <kaos@sgi.com>
+
+ * Add RECOVERY flag to global KDB flags.
+ * Add kdb_{save,restore}_flags.
+ * kdb v4.4-2.6.15-rc5-common-2.
+
+2005-12-05 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.15-rc5-common-1.
+
+2005-12-02 Keith Owens <kaos@sgi.com>
+
+ * kdbm_vm.c: offsets of page macros should be unsigned long. Reported
+ by Dean Nelson, SGI.
+ * kdb v4.4-2.6.15-rc4-common-1.
+
+2005-11-30 Keith Owens <kaos@sgi.com>
+
+ * New follow_page() API.
+ * kdb v4.4-2.6.15-rc3-common-1.
+
+2005-11-21 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.15-rc2-common-1.
+
+2005-11-15 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.15-rc1-common-1.
+
+2005-11-15 Keith Owens <kaos@sgi.com>
+
+ * Allow kdb_printf() to be used outside kdb, in preemptible context.
+ * Build with CONFIG_SWAP=n. Reported by Leo Yuriev.
+ * kdb v4.4-2.6.14-common-2.
+
+2005-10-28 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.14-common-1.
+
+2005-10-21 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.14-rc5-common-1.
+
+2005-10-11 Keith Owens <kaos@sgi.com>
+
+ * Handle removal of USB keyboard. Aaron Young, SGI.
+ * kdb v4.4-2.6.14-rc4-common-1.
+
+2005-10-05 Keith Owens <kaos@sgi.com>
+
+ * Extend kdb_notifier_list() codes to include dumping.
+ * Use emergency_restart() for reboot, it can be called from interrupt
+ context, unlike machine_restart().
+ * kdb v4.4-2.6.14-rc3-common-1.
+
+2005-09-21 Keith Owens <kaos@sgi.com>
+
+ * Support kdb_current_task in register display and modify commands.
+ * Document what changes kdb's notion of the current task.
+ * Update rd documentation for IA64.
+ * Move some definictions to kdbprivate.h and remove some unused symbol
+ exports.
+ * kdb v4.4-2.6.14-rc2-common-1.
+
+2005-09-20 Keith Owens <kaos@sgi.com>
+
+ * Document IA64 handlers command.
+ * Add more fields to the task command.
+ * Cope with MCA/INIT handlers in the ps command.
+ * Namespace cleanup, delete unused exports, make some functions static.
+ * Add a kdb_notifier_list callback when kdb is about to reboot the
+ system.
+ * kdb v4.4-2.6.14-rc1-common-1.
+
+2005-08-29 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.13-common-1.
+
+2005-08-24 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.13-rc7-common-1.
+
+2005-08-08 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.13-rc6-common-1.
+
+2005-08-02 Keith Owens <kaos@sgi.com>
+
+ * Print more fields from filp, dentry.
+ * Add kdb=on-nokey to suppress kdb entry from the keyboard.
+ * kdb v4.4-2.6.13-rc5-common-1.
+
+2005-07-30 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.13-rc4-common-1.
+
+2005-07-26 Keith Owens <kaos@sgi.com>
+
+ * Fix compile problem with CONFIG_USB_KBD.
+ * kdb v4.4-2.6.13-rc3-common-3.
+
+2005-07-22 Keith Owens <kaos@sgi.com>
+
+ * The asmlinkage kdb() patch was lost during packaging. Reinstate it.
+ * kdb v4.4-2.6.13-rc3-common-2.
+
+2005-07-19 Keith Owens <kaos@sgi.com>
+
+ * Add support for USB keyboard (OHCI only). Aaron Young, SGI.
+ * kdb v4.4-2.6.13-rc3-common-1.
+
+2005-07-08 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.13-rc2-common-1.
+
+2005-07-01 Keith Owens <kaos@sgi.com>
+
+ * Make kdb() asmlinkage to avoid problems with CONFIG_REGPARM.
+ * Change some uses of smp_processor_id() to be preempt safe.
+ * Use DEFINE_SPINLOCK().
+ * kdb v4.4-2.6.13-rc1-common-1.
+
+2005-06-18 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.12-common-1.
+
+2005-06-08 Keith Owens <kaos@sgi.com>
+
+ * Correct early exit from bd *.
+ * kdb v4.4-2.6.12-rc6-common-1.
+
+2005-05-25 Keith Owens <kaos@sgi.com>
+
+ * Delete Documentation/kdb/dump.txt. lkcd now has reasonable
+ integration with kdb.
+ * kdb v4.4-2.6.12-rc5-common-1.
+
+2005-05-08 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.12-rc4-common-1.
+
+2005-04-21 Keith Owens <kaos@sgi.com>
+
+ * Add rpte command (find the pte for a physical page).
+ * kdb v4.4-2.6.12-rc3-common-1.
+
+2005-04-06 Keith Owens <kaos@sgi.com>
+
+ * Add rq and rqa commands. John Hawkes, SGI.
+ * kdb v4.4-2.6.12-rc2-common-1.
+
+2005-03-29 Keith Owens <kaos@sgi.com>
+
+ * Use register_sysctl_table() instead of patching kernel/sysctl.c.
+ * Non-ASCII characters are not printable.
+ * kdb v4.4-2.6.12-rc1-common-1.
+
+2005-03-15 Keith Owens <kaos@sgi.com>
+
+ * More coexistence patches for lkcd. Jason Uhlenkott, SGI.
+ * kdb v4.4-2.6.11-common-3.
+
+2005-03-08 Keith Owens <kaos@sgi.com>
+
+ * Coexistence patches for lkcd. Jason Uhlenkott, SGI.
+ * kdb v4.4-2.6.11-common-2.
+
+2005-03-03 Keith Owens <kaos@sgi.com>
+
+ * Add kdb to drivers/serial/8250_early.c. Francois Wellenreiter, Bull.
+ * kdb v4.4-2.6.11-common-1.
+
+2005-02-14 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.11-rc4-common-1.
+
+2005-02-08 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.11-rc3-bk4-common-1.
+
+2005-02-03 Keith Owens <kaos@sgi.com>
+
+ * Print more superblock fields. Nathan Scott, SGI.
+ * Remove kallsyms correction for modules, Linus took it.
+ * kdb v4.4-2.6.11-rc3-common-1.
+
+2005-01-27 Keith Owens <kaos@sgi.com>
+
+ * Add bio command. Nathan Scott, SGI.
+ * kdb v4.4-2.6.11-rc2-common-1.
+
+2005-01-20 Keith Owens <kaos@sgi.com>
+
+ * Include kallsyms correction for modules until Linus takes it.
+ * kdb v4.4-2.6.11-rc1-bk7-common-1.
+
+2005-01-12 Keith Owens <kaos@sgi.com>
+
+ * kallsyms now supports all symbols properly, remove kdb patch.
+ * Add last ditch allocator for debugging.
+ * Update kdb_meminfo_read_proc() for vmalloc changes.
+ * Update kdbm_vm.c for 4 level page tables.
+ * kdb v4.4-2.6.11-rc1-common-1.
+
+2004-12-25 Keith Owens <kaos@sgi.com>
+
+ * Add kobject command.
+ * Ignore low addresses and large offsets in kdbnearsym().
+ * Console updates for sn2 simulator.
+ * kdb v4.4-2.6.10-common-1.
+
+2004-12-07 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.10-rc3-common-1.
+
+2004-11-23 Keith Owens <kaos@sgi.com>
+
+ * Remove warning message from kdb_get_one_user_page(), it was too noisy.
+ * kdb v4.4-2.6.10-rc2-common-1.
+
+2004-11-02 Keith Owens <kaos@sgi.com>
+
+ * Build with kdb patch applied but CONFIG_KDB=n.
+ * kdb v4.4-2.6.10-rc1-common-2.
+
+2004-10-29 Keith Owens <kaos@sgi.com>
+
+ * Handle new compression scheme for kallsyms.
+ * Handle move of DEAD and ZOMBIE for task->state to task->exit_state.
+ * Tweak the concept of a valid kernel address to get all symbols,
+ including the symbols in the ia64 gate page.
+ * kdb v4.4-2.6.10-rc1-common-1.
+
+2004-10-21 Keith Owens <kaos@sgi.com>
+
+ * Handle variable size for the kernel log buffer.
+ * kdb v4.4-2.6.9-common-2.
+
+2004-10-19 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.9-common-1.
+
+2004-10-12 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.9-rc4-common-1.
+
+2004-10-01 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.9-rc3-common-1.
+
+2004-09-30 Keith Owens <kaos@sgi.com>
+
+ * Add stackdepth command to Documentation/kdb/kdb.mm. stackdepth is
+ only supported on i386 and ia64 at the moment.
+ * Skip kdbm_pg memmap build on x86_64. Scott Lurndal, 3leafnetworks.
+ * Export kdb_serial_str for modular I/O. Bryan Cardillo, UPenn.
+ * Reinstate tab completion for symbols.
+ * kdb v4.4-2.6.9-rc2-common-2.
+
+2004-09-14 Keith Owens <kaos@sgi.com>
+
+ * Add task states C (traCed) and E (dEad).
+ * kdb v4.4-2.6.9-rc2-common-1.
+
+2004-08-27 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.9-rc1-common-1.
+
+2004-08-14 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.8-common-1.
+
+2004-08-12 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.8-rc4-common-1.
+
+2004-08-05 Keith Owens <kaos@sgi.com>
+
+ * Mark kdb_initcall as __attribute_used__ for newer gcc.
+ * kdb v4.4-2.6.8-rc3-common-2.
+
+2004-08-04 Keith Owens <kaos@sgi.com>
+
+ * Add mdp (memory display physical) comnmand.
+ Ananth N Mavinakayanahalli, IBM.
+ * kdb v4.4-2.6.8-rc3-common-1.
+
+2004-07-18 Keith Owens <kaos@sgi.com>
+
+ * Patch for new sn_console. Erik Jacobson. SGI.
+ * kdb v4.4-2.6.8-rc2-common-1.
+
+2004-07-12 Keith Owens <kaos@sgi.com>
+
+ * Convert kdbm_task to standard cpumask_t.
+ * Document '*' (all breakpoints) option on bd/be/bc commands.
+ * kdb v4.4-2.6.8-rc1-common-1.
+
+2004-06-30 Keith Owens <kaos@sgi.com>
+
+ * Common changes to help the x86-64 port.
+ * kdb v4.4-2.6.7-common-3.
+
+2004-06-20 Keith Owens <kaos@sgi.com>
+
+ * Move kdb includes in mm/swapfile.c to reduce conflicts with other
+ SGI patches.
+ * kdb v4.4-2.6.7-common-2.
+
+2004-06-16 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.7-common-1.
+
+2004-06-09 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.7-rc3-common-1.
+
+2004-06-09 Keith Owens <kaos@sgi.com>
+
+ * Namespace clean up. Mark code/variables as static when it is only
+ used in one file, delete dead code/variables.
+ * Saved interrupt state requires long, not int.
+ * kdb v4.4-2.6.7-rc2-common-3.
+
+2004-06-08 Keith Owens <kaos@sgi.com>
+
+ * Whitespace clean up, no code changes.
+ * kdb v4.4-2.6.7-rc2-common-2.
+
+2004-06-07 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.4-2.6.7-rc2-common-1.
+
+2004-06-06 Keith Owens <kaos@sgi.com>
+
+ * Avoid recursion problems in kdb_init().
+ * Add standard archkdb commands.
+ * Add per_cpu command.
+ * Move kdb_{get,put}userarea_size definitions to linux/kdb.h.
+ * kdb v4.4-2.6.6-common-2.
+
+2004-05-23 Keith Owens <kaos@sgi.com>
+
+ * Shrink the output from the cpu command.
+ * Add cpu state 'I', the cpu is idle.
+ * Add cpu state '+', some kdb data is available but the cpu is not
+ responding.
+ * Do not print tasks in state I or M by default in ps and bta commands.
+ * Add states I (idle task) and M (sleeping system daemon) to ps and
+ bta commands.
+ * Delete unused variables.
+ * Move private kdb fields from kdb.h to kdbprivate.h.
+ * Print 'for keyboard entry' for the special cases when KDB_ENTER() is
+ used to get registers.
+ * Move bfd.h and ansidecl.h from arch/$(ARCH)/kdb to include/asm-$(ARCH)
+ and remove -I arch/$(ARCH)/kdb.
+ * dmesg command now prints from either the start or end of dmesg, or at
+ an arbitrary point in the middle of the kernel log buffer.
+ * Sensible string dump for multi byte md commands.
+ * 'page' command handles ia64 correctly.
+ * Show some activity when waiting for cpus to enter kdb.
+ * Change the KDB entry code to <esc>KDB.
+ * Allow comment commands, starting with '#'.
+ * Commands defined using defcmd from kdb_cmds are not printed as they
+ are entered, use defcmd with no parameters to print all the defined
+ commands.
+ * Add summary command.
+ * Update copyright notices.
+ * Zero suppression on md command.
+ * Make set NOSECT=1 the default.
+ * PPC64 uses OF-stdout instead of console. Ananth N Mavinakayanahalli.
+ * kdb v4.4-2.6.6-common-1.
+
+2004-05-10 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.6.6-common-1.
+
+2004-05-06 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.6.6-rc3-common-1.
+
+2004-05-06 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.6.6-rc2-common-1.
+
+2004-04-30 Keith Owens <kaos@sgi.com>
+
+ * Rewrite inode_pages command for new radix code in struct page.
+ * kdb v4.3-2.6.6-rc1-common-1.
+
+2004-04-11 Keith Owens <kaos@sgi.com>
+
+ * Unlock sn_sal_lock before entering kdb from sn_serial.
+ * kdb v4.3-2.6.5-common-2.
+
+2004-04-05 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.6.5-common-1.
+
+2004-03-22 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.6.5-rc2-common-1.
+
+2004-03-12 Keith Owens <kaos@sgi.com>
+
+ * More work to avoid spurious messages from WARN_CONSOLE_UNLOCKED().
+ * bh command bug fixes. Nathan Scott.
+ * kdb v4.3-2.6.4-common-1.
+
+2004-03-06 Keith Owens <kaos@sgi.com>
+
+ * Set KDB_IS_RUNNING() during kdb_init to avoid spurious messages from
+ WARN_CONSOLE_UNLOCKED().
+ * Correct loss of symbol names in kdbnearsym.
+ * kdb v4.3-2.6.4-rc2-common-1.
+
+2004-02-29 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.6.4-rc1-common-1.
+
+2004-02-21 Keith Owens <kaos@sgi.com>
+
+ * Correct build of kdb_cmds when using a separate object directory and
+ make it quiet. j-nomura (NEC), Keith Owens.
+ * kdb v4.3-2.6.3-common-2.
+
+2004-02-18 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.6.3-common-1.
+
+2004-02-17 Keith Owens <kaos@sgi.com>
+
+ * Remove WAR for incorrect console registration patch.
+ * kdb v4.3-2.6.3-rc4-common-1.
+
+2004-02-17 Keith Owens <kaos@sgi.com>
+
+ * Convert longjmp buffers from static to dynamic allocation, for large
+ cpu counts.
+ * Tweak kdbm_task for SMP/UP.
+ * Reconcile with kdb-v4.3 2.4.25-rc1-common-1.
+ * Simplify coexistence with NPTL patches.
+ * Support kill command on new scheduler.
+ * Do not refetch data when printing a value as characters.
+ * Document the pid command.
+ * Work around 2.6 kallsyms 'feature'.
+ * Upgrade to 2.6.3-rc3.
+ * WAR for incorrect console registration patch.
+ * kdb v4.3-2.6.3-rc3-common-1.
+
+2003-12-03 Keith Owens <kaos@sgi.com>
+
+ * Reconcile 2.6-test versions from Xavier Bru (Bull), Greg Banks (SGI),
+ Jim Houston (Concurrent Computer Corp).
+ * Reconcile with kdb v4.3-2.4.23-common-2.
+ * Clean up CONFIG_KDB changes to {scripts,kernel}/kallsyms.c.
+ * Correct handling of kdb command line arguments.
+ * Make hooks into module code less intrusive.
+ * Delete kdb_active_task, not required with O(1) scheduler.
+ * Port kdbm_task.c from 2.4.
+ * Disable debug check in exit.c::next_thread() when kdb is running.
+ * Remove "only bh_disable when interrupts are set". BH must be disabled
+ in kdb to prevent deadlock on breakpoints in interrupt handlers.
+ * Add kdb to drivers/char/sn_serial.c.
+ * kdb v4.3-2.6.0-test11-common-1.
+
+2003-11-11 Xavier Bru <xavier.bru@bull.net>
+ * Merge to 2.6.0-test9
+2003-10-17 Xavier Bru <xavier.bru@bull.net>
+ * fix NUll ptr in kdb_ps at early prompt.
+2003-10-14 Xavier Bru <xavier.bru@bull.net>
+ * fix NUll ptr in kdb_ps when cpu not present.
+2003-10-06 Xavier Bru <xavier.bru@bull.net>
+ * Merge to 2.6.0-test5
+ * fix compile error with CONFIG_MODULES not set.
+
+2003-09-08 Xavier Bru <xavier.bru@bull.net>
+ * Merge to 2.6.0-test4
+
+2003-07-10 Xavier Bru <xavier.bru@bull.net>
+
+ * Merge kdb v4.3 to 2.5.72 ia64
+ * don't call local_bh_enable() with interrupts masked.
+
+2003-04-07 Xavier Bru <xavier.bru@bull.net>
+
+ * Merge kdb v4.1 to 2.5.64 ia64
+ * new kernel parameters support
+ * new module format
+ * new kallsyms support
+
+2003-12-02 Keith Owens <kaos@sgi.com>
+
+ * Use correct page alignment in kdb_get_one_user_page().
+ Prasanna S Panchamukhi, IBM.
+ * Split pte command into pte -m and pte -p. Dean Roe, SGI.
+ * kdb v4.3-2.4.23-common-2.
+
+2003-12-01 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.4.23-common-1.
+
+2003-11-11 Keith Owens <kaos@sgi.com>
+
+ * Make KDB for USB keyboards build. Peter T. Breuer.
+ * Do not use USB keyboard if it has not been probed.
+ * kdb v4.3-2.4.23-rc1-common-1.
+
+2003-10-10 Keith Owens <kaos@sgi.com>
+
+ * Sync with XFS 2.4.22 tree.
+ * kdb v4.3-2.4.22-common-2.
+
+2003-08-29 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.4.22-common-1.
+
+2003-07-27 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.4.22-pre8-common-8.
+
+2003-07-20 Keith Owens <kaos@sgi.com>
+
+ * Make kdb_serial_str a common constant, the same for all consoles.
+ * Support SGI L1 console.
+ * kdb v4.3-2.4.21-common-8.
+
+2003-07-14 Keith Owens <kaos@sgi.com>
+
+ * Correct ll command.
+ * kdb v4.3-2.4.21-common-7.
+
+2003-07-08 Keith Owens <kaos@sgi.com>
+
+ * Export more kdb symbols. Vamsi Krishna S., IBM.
+ * kdb v4.3-2.4.21-common-6.
+
+2003-07-07 Keith Owens <kaos@sgi.com>
+
+ * Tweak 'waiting for cpus' message.
+ * kdb v4.3-2.4.21-common-5.
+
+2003-07-07 Keith Owens <kaos@sgi.com>
+
+ * 2.4.21-ia64-030702 patches common code that affects kdb. Workaround
+ this nuisance.
+ * kdb v4.3-2.4.21-common-4.
+
+2003-06-24 Keith Owens <kaos@sgi.com>
+
+ * Add task and sigset commands. Mark Goodwin, SGI.
+ * kdb v4.3-2.4.21-common-3.
+
+2003-06-23 Keith Owens <kaos@sgi.com>
+
+ * Sync with XFS 2.4.21 tree.
+ * kdb v4.3-2.4.21-common-2.
+
+2003-06-20 Keith Owens <kaos@sgi.com>
+
+ * kdb v4.3-2.4.21-common-1.
+
+2003-06-20 Keith Owens <kaos@sgi.com>
+
+ * More details on vm command, add vmp and pte commands.
+ Dean Nelson, Dean Roe, SGI.
+ * YAO1SCF (Yet Another O(1) Scheduler Coexistence Fix).
+ * Changes to common code to build on sparc. Tom Duffy.
+ * Move Tom Duffy's changes to drivers/sbus from the sparc64
+ patch to the common patch to keep all the serial changes
+ together.
+ * Changes to common code to build on Xscale. Eddie Dong, Intel.
+ * Remove CROSS_COMPILE_INC.
+ * Remove obsolete boot parameter 'kdb', long since replaced by
+ 'kdb=on'.
+ * Remove obsolete kdb_eframe_t casts.
+ * Add CONFIG_KDB_CONTINUE_CATASTROPHIC.
+ * Wait a short interval for cpus to join kdb before proceeding.
+ * Automatically enable sysrq for sr command.
+ * Correct double free of kdb_printf lock, spotted by Richard Sanders.
+ * Add optional cpu parameter to btc command.
+ * kdb v4.3-2.4.20-common-1.
+
+2003-05-02 Keith Owens <kaos@sgi.com>
+
+ * Some architectures have problems with the initial empty kallsyms
+ section so revert to three kallsyms passes.
+ * Flush buffered input at startup and at 'more' prompt.
+ * Only print 'more' prompt when longjmp data is available.
+ * Print more data for buffers and inodes.
+ * Disable kill command when O(1) scheduler is installed, the code
+ needs to be redone for O(1).
+ * The kernel has an undocumented assumption that enable_bh() is
+ always called with interrupts enabled, make it so.
+ * Print trailing punctuation even for symbols that are not in kernel.
+ * Add read/write access to user pages. Vamsi Krishna S., IBM
+ * Rename cpu_is_online to cpu_online, as in 2.5.
+ * O(1) scheduler removes init_task so kdb maintains its own list of
+ active tasks.
+ * Delete btp 0 <cpuid> option, it needed init_tasks.
+ * Clean up USB keyboard support. Steven Dake.
+ * Sync with XFS 2.4.20 tree.
+ * kdb v4.2-2.4.20-common-1.
+
+2003-04-04 Keith Owens <kaos@sgi.com>
+
+ * Remove one kallsyms pass.
+ * Automatic detection of O(1) scheduler.
+ * Rename cpu_online to cpu_is_online.
+ * Workarounds for scheduler bugs.
+ * Tweak algorithm for detecting if cpu process data is available.
+ * Add 'kill' command. Sonic Zhang, Keith Owens.
+ * kdb v4.1-2.4.20-common-1.
+
+2003-03-16 Keith Owens <kaos@sgi.com>
+
+ * Each cpu saves its state as it enters kdb or before it enters code
+ which cannot call kdb.
+ * Allow btp on process 0 for a specified cpu.
+ * Add btt command, backtrace given a struct task address.
+ * btc command no longer switches cpus, instead it uses the saved data.
+ * bta shows the idle task on each cpu as well as real tasks, the idle
+ task could be handling an interrupt.
+ * ps command shows the idle task on each cpu.
+ * ps checks that the saved data for a cpu matches the process running on
+ that cpu and warns about stale saved data or no saved data at all.
+ * Remove special cases for i386 backtrace from common code and simplify
+ common bt code.
+ * Clean up kdb interaction with CONFIG_SERIAL_CONSOLE.
+ * Do not automatically repeat commands after the user typed 'q'.
+ * O(1) scheduler patch changes the process cpu field but does not set
+ any indicator that O(1) is being used. Adjust kdb_process_cpu() by
+ hand after applying O(1).
+ * Add kdb_print_nameval() to common code.
+ * Convert tests of cpu_online_map to cpu_online() macro.
+ * module.h needs errno.h when compiling with CONFIG_MODULES=n.
+ * Correct duplicate breakpoint handling.
+ * Do not try to send IPI during a catastrophic error, send_ipi can hang
+ and take kdb with it.
+ * kdb memmap command is i386 only, restrict it.
+ * Add large block device (LBD) support from XFS tree. Eric Sandeen.
+ * kdb v4.0-2.4.20-common-1.
+
+2003-02-03 Keith Owens <kaos@sgi.com>
+
+ * Register kdb commands early.
+ * Decode oops via kallsyms if it is available.
+ * Update copyright notices to 2003.
+ * Add defcmd/endefcmd to allow users to package their own macros.
+ * kdb commands that fail are ignored when prefixed with '-'.
+ * Add selection options to bta command.
+ * Add btc command (switch to each cpu and backtrace).
+ * Do real time detection of dead cpus.
+ * Clear ip adjusted flag when leaving kdb.
+ * Clean up ps command.
+ * Print ps output for each task when backtracing.
+ * Bump to version v3.0 to reduce confusion between kdb and kernel
+ version numbers.
+ * Add kdba_local_arch_setup/kdba_local_arch_cleanup to correct
+ keyboard freeze. Ashish Kalra.
+ * Refuse multiple breakpoints at the same address.
+ * Add fl (file_lock) command, from XFS development tree.
+ * Correct inode_pages, from XFS development tree.
+ * Add command history and editing. Sonic Zhang.
+ * Extend command history and editing to handle vt100 escape sequences.
+ * Allow tab completion at start of line.
+ * Touch nmi watchdog on long running bta and btc commands.
+ * Clean up ps output and standardize with bta codes.
+ * Correctly handle escaped characters in commands.
+ * Update man pages for btc and command history/editing.
+ * kdb v3.0-2.4.20-common-1.
+
+2002-11-29 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.20.
+ * Correct Documentation/kdb/kdb_sr.man.
+ * Remove leading zeroes from pids, they are decimal, not octal.
+ * kdb v2.5-2.4.20-common-1.
+
+2002-11-14 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.20-rc1.
+ * kdb v2.5-2.4.20-rc1-common-1.
+
+2002-11-14 Keith Owens <kaos@sgi.com>
+
+ * Fix processing with O(1) scheduler.
+ * 'go' switches back to initial cpu first.
+ * 'go <address>' only allowed on initial cpu.
+ * 'go' installs the global breakpoints from the initial cpu before
+ releasing the other cpus.
+ * If 'go' has to single step over a breakpoint then it single steps just
+ the initial cpu, installs the global breakpoints then releases the
+ other cpus.
+ * General clean up of handling for breakpoints and single stepping over
+ software breakpoints.
+ * Add kdb_notifier_block so other code can tell when kdb is in control.
+ * kdb v2.5-2.4.19-common-1.
+
+2002-11-02 Keith Owens <kaos@sgi.com>
+
+ * Correct build without CONFIG_KDB.
+ * kdb v2.4-2.4.19-common-3.
+
+2002-11-01 Keith Owens <kaos@sgi.com>
+
+ * Minimize differences from 2.5.44.
+ * kdb v2.4-2.4.19-common-2.
+
+2002-10-31 Keith Owens <kaos@sgi.com>
+
+ * Add defcmd/endefcmd feature.
+ * Remove kdb_eframe_t.
+ * Clear bp data before using.
+ * Sanity check if we have pt_regs.
+ * Force LINES > 1.
+ * Remove special case for KDB_REASON_PANIC, use KDB_ENTER() instead.
+ * Remove kdba_getcurrentframe().
+ * Coexist with O(1) scheduler.
+ * Add lines option to dmesg, speed up dmesg.
+ * kdb v2.4-2.4.19-common-1.
+
+2002-10-17 Keith Owens <kaos@sgi.com>
+
+ * Add selection critera to ps and bta commands.
+ * kdb v2.3-2.4.19-common-4.
+
+2002-10-07 Keith Owens <kaos@sgi.com>
+
+ * New man page, Documentation/kdb/kdb_sr.man.
+
+2002-10-04 Keith Owens <kaos@sgi.com>
+
+ * Minimize differences between patches for 2.4 and 2.5 kernels.
+ * Add Configure.help for CONFIG_KDB_USB.
+ * Reduce stack usage.
+ * kdb v2.3-2.4.19-common-3.
+
+2002-08-10 Keith Owens <kaos@sgi.com>
+
+ * Replace kdb_port with kdb_serial to support memory mapped I/O.
+ David Mosberger.
+ * kdb v2.3-2.4.19-common-2.
+
+2002-08-07 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.19.
+ * Remove individual SGI copyrights, the general SGI copyright applies.
+ * Handle md0. Reported by Hugh Dickins, different fix by Keith Owens.
+ * Use page_address() in kdbm_pg.c. Hugh Dickins.
+ * Remove debugging printk from kdbm_pg.c. Hugh Dickins.
+ * Move breakpoint address verification into arch dependent code.
+ * Dynamically resize kdb command table as required.
+ * Common code to support USB keyboard. Sebastien Lelarge.
+ * kdb v2.3-2.4.19-common-1.
+
+2002-07-09 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.19-rc1.
+ * Add dmesg command.
+ * Clean up copyrights, Eric Sandeen.
+ * kdb v2.2-2.4.19-rc1-common-1.
+
+2002-06-14 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.19-pre10.
+ * Sync with XFS.
+ * kdb v2.1-2.4.19-pre10-common-1.
+
+2002-04-09 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.19-pre6.
+ * kdb v2.1-2.4.19-pre6-common-1.
+
+2002-03-18 Keith Owens <kaos@sgi.com>
+
+ * Syntax check mdWcN commands.
+
+2002-03-01 Keith Owens <kaos@sgi.com>
+
+ * Sync with XFS 2.4.18.
+ * kdb v2.1-2.4.18-common-2.
+
+2002-02-26 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.18.
+ * Add Paul Dorwin (IBM) magicpoint slides on using kdb as
+ Documentation/kdb/slides.
+ * kdb v2.1-2.4.18-common-1.
+
+2002-01-23 Keith Owens <kaos@sgi.com>
+
+ * Sync with XFS pagebuf changes.
+ * kdb v2.1-2.4.17-common-2.
+
+2002-01-18 Keith Owens <kaos@sgi.com>
+
+ * Ignore single stepping during panic.
+ * Remove kdba_getword, kdba_putword. Replace with kdb_getword,
+ kdb_putword that rely on copy_xx_user. The new functions return
+ an error code, like copy_xx_user.
+ * New functions kdb_getarea, kdb_putarea for copying areas of data
+ such as structures. These functions also return an error code.
+ * Change all common code to use the new functions.
+ * bp command checks that it can read and write the word at the
+ breakpoint before accepting the address.
+ * Break points are now set FIFO and cleared LIFO so overlapping
+ entries give sensible results.
+ * Verify address before disassembling code.
+ * Common changes for sparc64. Ethan Solomita, Tom Duffy.
+ * Remove ss <count>, never supported.
+ * Remove kallsyms entries from arch vmlinux.lds files.
+ * Specify which commands auto repeat.
+ * kdb v2.1-2.4.17-common-1.
+
+2002-01-07 Keith Owens <kaos@sgi.com>
+
+ * Remove console semaphore code, not good in interrupt.
+ * Remove fragment of ia64 patch that had crept into kdb.
+ * Release as kdb v2.0-2.4.17-common-3.
+
+2002-01-04 Keith Owens <kaos@sgi.com>
+
+ * Sync xfs <-> kdb common code.
+
+2001-12-22 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.17.
+ * Clean up ifdef CONFIG_KDB.
+ * Add ifdef CONFIG_KDB around include kdb.h.
+ * Delete dummy kdb.h files for unsupported architectures.
+ * Delete arch i386 and ia64 specific files. This changelog now
+ applies to kdb common code only.
+ * Release as kdb v2.0-2.4.17-common-1.
+
+2001-12-03 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.16.
+ * Add include/asm-um/kdb.h stub to allow XFS to be tested under UML.
+ * Check if an interrupt frame on i386 came from user space.
+ * Out of scope bug fix in kdb_id.c. Ethan Solomita.
+ * Changes to common code to support sparc64. Ethan Solomita.
+ * Change GFP_KERNEL to GFP_ATOMIC in disasm. Ethan Solomita.
+
+2001-11-16 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.15-pre5.
+ * Wrap () around #define expressions with unary operators.
+
+2001-11-13 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.15-pre4.
+ * kbdm_pg.c patch from Hugh Dickins.
+
+2001-11-07 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to 2.4.14-ia64-011105.
+ * Change name of l1 serial I/O routine, add ia64 init command. SGI.
+ * Sync kdbm_pg with XFS.
+
+2001-11-06 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to kernel 2.4.14.
+
+2001-11-02 Keith Owens <kaos@sgi.com>
+
+ * Sync kdbm_pg.c with XFS.
+
+2001-10-24 Keith Owens <kaos@sgi.com>
+
+ * Upgrade to kernel 2.4.13.
+
+2001-10-14 Keith Owens <kaos@melbourne.sgi.com>
+
+ * More use of TMPPREFIX in top level Makefile to speed up NFS compiles.
+
+ * Correct repeat calculations in md/mds commands.
+
+2001-10-10 Keith Owens <kaos@melbourne.sgi.com>
+
+ * Copy bfd.h and ansidecl.h to arch/$(ARCH)/kdb, remove dependecies on
+ user space includes.
+
+ * Update kdb v1.9 to kernel 2.4.11.
+
+2001-10-01 Keith Owens <kaos@melbourne.sgi.com>
+
+ * Update kdb v1.9 to kernel 2.4.11-pre1 and 2.4.10-ac1.
+
+ * Correct loop in kdb_parse, reported by Tachino Nobuhiro.
+
+2001-09-25 Keith Owens <kaos@melbourne.sgi.com>
+
+ * Update kdb v1.8 to kernel 2.4.10.
+
+ * kdbm_pg patch from Hugh Dickens.
+
+ * DProbes patch from Bharata B Rao.
+
+ * mdWcn and mmW patch from Vamsi Krishna S.
+
+ * i386 disasm layout patch from Jean-Marc Saffroy.
+
+ * Work around for 64 bit binutils, Simon Munton.
+
+ * kdb.mm doc correction by Chris Pascoe.
+
+ * Enter repeats the last command, IA64 disasm only prints one
+ instruction. Don Dugger.
+
+ * Allow kdb/modules to be linked into vmlinux.
+
+ * Remove obsolete code from kdb/modules/kdbm_{pg,vm}.c.
+
+ * Warn when commands are entered at more prompt.
+
+ * Add MODULE_AUTHOR, DESCRIPTION, LICENSE.
+
+ * Release as kdb v1.9.
+
+2001-02-27 Keith Owens <kaos@melbourne.sgi.com>
+
+ * Update kdb v1.8 to kernel 2.4.2, sync kdb/modules with XFS.
+
+ * Hook into panic() call.
+
+2000-12-18 Keith Owens <kaos@melbourne.sgi.com>
+
+ * Update kdb v1.7 to kernel 2.4.0-test13-pre3, sync kdb/modules with
+ XFS.
+
+2000-11-18 Keith Owens <kaos@melbourne.sgi.com>
+
+ * Update to kernel 2.4.0-test11-pre7, including forward port of
+ bug fixes from WIP 2.4.0-test9 tree.
+
+ * Update to Cygnus CVS trees for disassembly code.
+
+ * Bump to kdb v1.6.
+
+2000-10-19 Keith Owens <kaos@melbourne.sgi.com>
+
+ * Update to kernel 2.4.0-test10-pre4.
+
+2000-10-15 Keith Owens <kaos@melbourne.sgi.com>
+
+ * kdb/kdbmain.c (kdb_parse): Correctly handle blank input.
+
+ * kdb/kdbmain.c (kdb_local, kdb): Reason SILENT can have NULL regs.
+
+2000-10-13 Keith Owens <kaos@melbourne.sgi.com>
+
+ * kdb/kdbmain.c: Reduce CMD_LEN to avoid overflowing kdb_printf buffer.
+
+2000-10-11 Keith Owens <kaos@melbourne.sgi.com>
+
+ * kdb/kdbmain.c (kdb): Test for userspace breakpoints before driving
+ other cpus into kdb. Speeds up gdb and avoids SMP race.
+
+ * arch/i386/kdb/kdba_io.c (get_serial_char, get_kbd_char): Ignore
+ unprintable characters.
+
+ * arch/i386/kdb/kdba_io.c (kdba_read): Better handling of buffer size.
+
+2000-10-04 Keith Owens <kaos@melbourne.sgi.com>
+
+ * arch/i386/kdb/kdba_bt.c (kdba_bt_process): Verify that esp is inside
+ task_struct. Original patch by Mike Galbraith.
+
+ * kdb/kdb_io.c (kdb_getstr): Reset output line counter, remove
+ unnecessary prompts.
+
+ * arch/i386/kdb/kdbasupport.c (kdb_getregcontents): Change " cs" to
+ "xcs", ditto ss, ds, es. gdb2kdb does not like leading spaces.
+
+ * include/asm-xxx/kdb.h: Add dummy kdb.h for all architectures except
+ ix86. This allows #include <linux/kdb.h> to appear in arch independent
+ code without causing compile errors.
+
+ * kdb/modules/kdbm_pg: Sync with XFS.
+
+2000-10-03 Keith Owens <kaos@melbourne.sgi.com>
+
+ * kdb/kdb_io.c (kdb_read): Ignore NMI while waiting for input.
+
+ * kdb/kdb_io.c, kdb/Makefile: Export kdb_read.
+
+2000-10-02 Keith Owens <kaos@melbourne.sgi.com>
+
+ * arch/i386/kernel/smpboot.c (do_boot_cpu): Set nmi_watchdog_source to 2
+ to avoid premature NMI oops during cpu bring up. We have to assume that
+ a box with more than 1 cpu has a working IO-APIC.
+
+ * Documentation/kdb/{kdb.mm,kdb_md.man}: Add mdr command.
+
+ * kdb/kdbmain.c (kdb_md): Add mdr command.
+
+ * Release as kdb v1.5 against 2.4.0-test9-pre8.
+
+ * arch/i386/kdb/kdba_io.c, arch/i386/kdb/kdbasupport.c, kdb/kdbmain.c,
+ kdb/kdb_io.c, kdb/kdb_id.c: Remove zero initializers for static
+ variables.
+
+2000-09-28 Keith Owens <kaos@melbourne.sgi.com>
+
+ * various: Add nmi_watchdog_source, 1 local APIC, 2 IO-APIC.
+ Test nmi_watchdog_source instead of nr_ioapics so UP works on SMP hardware.
+
+ * arch/i386/kernel/io_apic.c: Rename setup_nmi to setup_nmi_io for clarity.
+
+ * kdb/kdbmain.c (kdb_parse): Only set NO_WATCHDOG if it was already set.
+
+ * kdb/kdbmain.c (kdb): Clear NO_WATCHDOG on all exit paths.
+
+ * include/linux/kdb.h: Add KDB_REASON_SILENT.
+
+ * kdb/kdbmain.c (kdb_local): Treat reason SILENT as immediate 'go'.
+
+ * kdb/kdbmain.c (kdb_init): Invoke kdb with reason SILENT to instantiate
+ any breakpoints on boot cpu.
+
+ * arch/i386/kernel/smpboot.c (smp_callin): Invoke kdb with reason SILENT
+ to instantiate any global breakpoints on this cpu.
+
+ * kdb/kdb_cmds: Remove comment that said initial commands only worked on
+ boot cpu.
+
+2000-09-27 Keith Owens <kaos@melbourne.sgi.com>
+
+ * arch/i386/kernel/msr.c: Move {rd,wr}msr_eio to include/asm-i386/apic.h.
+
+ * include/asm-i386/apic.h: Define NMI interfaces.
+
+ * kernel/sysctl.c (kern_table):
+ * kernel/sysctl.c (do_proc_set_nmi_watchdog):
+ Add /proc/sys/kernel/nmi_watchdog.
+
+ * arch/i386/kernel/apic.c: New routines set_nmi_counter_local,
+ setup_apic_nmi_watchdog.
+
+ * arch/i386/kernel/traps.c: New routine set_nmi_watchdog(). Call apic
+ routines to set/clear local apic timer.
+
+2000-09-26 Keith Owens <kaos@melbourne.sgi.com>
+
+ * include/linux/sysctl.h (enum): Add NMI_WATCHDOG.
+
+ * arch/i386/kernel/traps.c (nmi_watchdog_tick): Check nmi_watchdog is
+ still on.
+
+ * arch/i386/config.in: Add CONFIG_UP_NMI_WATCHDOG.
+
+ * Documentation/Configure.help: Add CONFIG_UP_NMI_WATCHDOG.
+
+ * Documentation/nmi_watchdog.txt: Update for UP NMI watchdog.
+
+2000-09-25 Keith Owens <kaos@melbourne.sgi.com>
+
+ * arch/i386/kernel/apic.c (init_apic_mappings):
+ * arch/i386/kernel/io_apic.c (IO_APIC_init_uniprocessor):
+ Merge Keir Fraser's local APIC for uniprocessors patch.
+
+2000-09-24 Keith Owens <kaos@melbourne.sgi.com>
+
+ * Various: Declare initialization routines as __init.
+
+ * Makefile: Define and export AWK.
+
+ * kdb/Makefile: Generate gen-kdb_cmds.c from kdb/kdb_cmds.
+
+ * kdb/kdbmain.c (kdb_init): Call new routine kdb_cmds_init to execute
+ whatever the user put in kdb/kdb_cmds.
+
+ * arch/i386/kdb/kdba_bt.c (kdba_bt_stack): New parameter to
+ indicate if esp in regs is known to be valid or not.
+
+ * kdb/kdb_bp.c, arch/i386/kdb/kdba_bp.c: More trace prints for
+ breakpoint handling.
+
+ * arch/i386/kdb/kdba_bp.c (kdba_installbp): Finally found and fixed the
+ annoying breakpoint bug where breakpoints where not always installed
+ after 'go'.
+
+ * Documentation/kdb: Update man pages kdb.mm, kdb_env.man, kdb_ss.man.
+
+ * Released as kdb-v1.5-beta1-2.4.0-test8.
+
+ * Sync to 2.4.0-test9-pre6 and release as kdb-v1.5-beta1-2.4.0-test9-pre6.
+
+2000-09-23 Keith Owens <kaos@melbourne.sgi.com>
+
+ * arch/i386/kdb/kdbasupport.c (kdba_getregcontents): New pseudo
+ registers cesp and ceflags to help with debugging the debugger.
+
+ * kdb/kdbmain.c (kdb_local, kdb): Add KDB_REASON_RECURSE. Add
+ environment variable RECURSE. Add code to cope with some types of
+ recursion.
+
+ * kdb/kdbmain.c (kdb), arch/i386/kdba/kdba_bp.c: Add
+ kdba_clearsinglestep.
+
+2000-09-22 Keith Owens <kaos@melbourne.sgi.com>
+
+ * drivers/video/vgacon.c (write_vga): No cli() if kdb is running, avoid
+ console deadlock.
+
+ * arch/i386/kernel/irq.c (get_irqlock): Warn if kdb is running, may hang.
+
+ * include/linux/kdb.h: Define KDB_IS_RUNNING as (0) if no CONFIG_KDB.
+
+ * arch/i386/kdb/kdba_bt.c (kdba_bt_stack): Do not attempt a backtrace if
+ the code segment is not in the kernel.
+
+ * kdb/modules: Change modules from MX_OBJS to M_OBJS. Remove EXPORT_NOSYMBOLS.
+
+2000-09-21 Keith Owens <kaos@melbourne.sgi.com>
+
+ * arch/i386/kernel/i386_ksyms.c: Move EXPORT_SYMBOLS for kdb to kdb/kdbmain.c.
+
+ * kdb/Makefile: Change kdb/kdbmain.o from O_OBJS to OX_OBJS.
+
+ * arch/i386/kernel/smp.c: Remove some #ifdef CONFIG_KDB. Remove kdbprivate.h.
+
+ * include/linux/kdb.h: Add kdb_print_state. Add KDB_STATE_WAIT_IPI.
+
+ * kdb/kdbmain.c (kdb): Only mark cpu as leaving if it is in KDB state. Maintain
+ WAIT_IPI state so a cpu is only driven through NMI once.
+
+ * arch/i386/kernel/smp.c (smp_kdb_stop): All state fiddling moved to kdb().
+
+2000-09-20 Keith Owens <kaos@melbourne.sgi.com>
+
+ * include/linux/kdb.h: #define kdb() as (0) if kdb is not configured.
+
+ * arch/i386/kernel/traps.c: Remove some #ifdef CONFIG_KDB.
+
+ * include/linux/kdbprivate.h: Move per cpu state to kdb.h.
+
+ * include/linux/kdb.h: Add KDB_STATE_NO_WATCHDOG, KDB_STATE_PRINTF_LOCK.
+ Rename KDB_DEBUG_xxx to KDB_DEBUG_FLAG_xxx. Clean up debug flag
+ definitions.
+
+ * arch/i386/kernel/traps.c (nmi_watchdog_tick): Check no watchdog.
+
+ * kdb/kdbmain.c (kdb): Set no watchdog in normal kdb code.
+
+ * kdb/kdbmain.c (kdb_parse): Allow watchdog in commands.
+
+ * kdb/kdb_io.c (kdb_printf): No watchdog during printing. Clean up lock handling.
+
+ * kdb/kdbmain.c (kdb_set): Clean up debug flag handling.
+
+2000-09-19 Juan J. Quintela <quintela@fi.udc.es>
+
+ * kdb/arch/i386/kdb/kdba_io.c: Allow kdb to compile without CONFIG_VT and/or
+ serial console.
+
+2000-09-19 Keith Owens <kaos@melbourne.sgi.com>
+
+ * include/linux/kdb.h: Define KDB_DEBUG_STATE().
+
+ * kdb/kdbmain.c (kdb): Add kdb_print_state(), calls to KDB_DEBUG_STATE().
+
+2000-09-16 Keith Owens <kaos@melbourne.sgi.com>
+
+ * Move to finer grained control over individual processors in kdb with
+ per cpu kdb state. Needed to allow ss[b] to only release one processor,
+ previously ss[b] released all processors. Also need to recover from
+ errors inside kdb commands, e.g. oops in kdbm_pg code.
+
+ * various:
+ Move global flags KDB_FLAG_SSB, KDB_FLAG_SUPRESS, KDB_FLAG_FAULT,
+ KDB_FLAG_SS, KDB_FLAG_SSBPT, kdb_active, to per cpu state and macros
+ KDB_STATE(xxx).
+ Replace kdb_flags & KDB_FLAG_xxx with KDB_FLAG(xxx).
+ Replace kdb_flags & KDB_DEBUG_xxx with KDB_DEBUG(xxx).
+ Replace specific tests with wrapper KDB_IS_RUNNING().
+
+ * various: Remove #ifdef CONFIG_SMP from kdb code wherever
+ possible. Simplifies the code and makes it much more readable.
+
+ * arch/i386/kdb/kdbasupport.c (kdb_setjmp): Record if we have reliable
+ longjmp data instead of assuming it is always set.
+
+ * various: Replace smp_kdb_wait with per cpu state, HOLD_CPU.
+
+ * init/main.c : Replace #ifdef KDB_DEBUG with KDB_DEBUG(CALLBACK).
+
+ * include/linux/kdbprivate.h: Separate command return codes from error
+ codes. Add more detailed command codes.
+
+ * arch/i386/kernel/traps.c (die): Change spin_lock_irq to
+ spin_lock_irqsave. Why did I do this?
+
+ * kdb/kdbmain.c (kdb_parse): Set per cpu flag CMD before executing kdb
+ command. More detailed return codes for commands that affect
+ processors.
+
+ * kdb/kdbmain.c (kdb_previous_event): New, check if any processors are
+ still executing the previous kdb event. Removes a race window where a
+ second event could enter kdb before the first had completely ended.
+
+ * kdb/kdbmain.c (kdb): Document all the concurrency conditions and how
+ kdb handles them. ss[b] now releases only the current cpu. Do not set
+ breakpoints when releasing for ss[b]. Recover from errors in kdb
+ commands. Check that we have reliable longjmp data before using it.
+
+ * various: Update return code documentation.
+
+ * kdb/kdb_bp.c (kdb_ss): Separate ss and ssb return codes.
+
+ * kdb/kdbsupport.c (kdb_ipi): Finer grained algorithm for deciding
+ whether to call send a stop signal to a cpu.
+
+ * arch/i386/kdb/kdba_bp.c (kdba_db_trap): Separate ss and ssb return
+ codes. Reinstall delayed software breakpoints per cpu instead of
+ globally. Changed algorithm for handling ss[b].
+
+ * arch/i386/kdb/kdba_bp.c (kdba_bp_trap): Match software breakpoints per
+ cpu instead of globally.
+
+ * include/linux/kdb.h: Bump version to kdb v1.5.
+
+2000-09-16 Keith Owens <kaos@melbourne.sgi.com>
+
+ * kernel/sysctl.c (kern_table): add /proc/sys/kernel/kdb.
+
+ * init/main.c (parse_options): add boot flags kdb=on, kdb=off,
+ kdb=early.
+
+ * include/linux/sysctl.h (enum): add KERN_KDB.
+
+ * drivers/char/serial.c (receive_chars): check kdb_on.
+
+ * drivers/char/keyboard.c (handle_scancode): check kdb_on.
+
+ * arch/i386/kernel/traps.c (nmi_watchdog_tick): check kdb_on.
+
+ * arch/i386/config.in: add CONFIG_KDB_OFF.
+
+ * Documentation/Configure.help: add CONFIG_KDB_OFF.
+
+ * kdb/kdbmain.c: add kdb_initial_cpu, kdb_on.
+
+ * kdb/kdbmain.c (kdb): check kdb_on, set kdb_initial_cpu.
+
+ * kdb/kdbmain.c (kdb_init): add Keith Owens to kdb banner.
+
+ * kdb/kdb_io.c (kdb_printf): serialize kdb_printf output.
+
+ * kdb/kdb_bt.c (kdb_bt): check environment variable BTAPROMPT.
+
+ * kdb/kdbsupport.c (kdb_ipi): ignore NMI for kdb_initial_cpu.
+
+ * kdb/modules/kdbm_pg.c (kdbm_page): merge updates from 2.4.0-test5-xfs.
+
+ * kdb/kdb_bt.man: add btp, bta, BTAPROMPT.
+
+ * kdb/kdb.mm: add CONFIG_KDB_OFF, boot flags, btp, bta.
+
+ * include/linux/kdbprivate.h: add kdb_initial_cpu.
+
+ * include/linux/kdb.h: add kdb_on, bump version to kdb v1.4.
--- /dev/null
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+#
+
+obj-y := kdb_bt.o kdb_bp.o kdb_id.o kdbsupport.o gen-kdb_cmds.o kdbmain.o kdb_io.o
+
+subdir-$(CONFIG_KDB_MODULES) := modules
+obj-y += $(addsuffix /built-in.o, $(subdir-y))
+
+clean-files := gen-kdb_cmds.c
+
+override CFLAGS := $(CFLAGS:%-pg=% )
+
+quiet_cmd_gen-kdb = GENKDB $@
+ cmd_gen-kdb = $(AWK) 'BEGIN {print "\#include <linux/stddef.h>"; print "\#include <linux/init.h>"} \
+ /^\#/{next} \
+ /^[ \t]*$$/{next} \
+ {gsub(/"/, "\\\"", $$0); \
+ print "static __initdata char kdb_cmd" cmds++ "[] = \"" $$0 "\\n\";"} \
+ END {print "char __initdata *kdb_cmds[] = {"; for (i = 0; i < cmds; ++i) {print " kdb_cmd" i ","}; print(" NULL\n};");}' \
+ $(filter-out %/Makefile,$^) > $@
+
+$(obj)/gen-kdb_cmds.c: $(src)/kdb_cmds $(wildcard arch/$(ARCH)/kdb/kdb_cmds) $(src)/Makefile
+ $(call cmd,gen-kdb)
--- /dev/null
+/*
+ * Kernel Debugger Architecture Independent Breakpoint Handler
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <linux/smp.h>
+#include <linux/sched.h>
+#include <asm/system.h>
+
+/*
+ * Table of kdb_breakpoints
+ */
+kdb_bp_t kdb_breakpoints[KDB_MAXBPT];
+
+/*
+ * kdb_bp_install_global
+ *
+ * Install global kdb_breakpoints prior to returning from the
+ * kernel debugger. This allows the kdb_breakpoints to be set
+ * upon functions that are used internally by kdb, such as
+ * printk().
+ *
+ * Parameters:
+ * regs Execution frame.
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ * This function is only called once per kdb session.
+ */
+
+void
+kdb_bp_install_global(struct pt_regs *regs)
+{
+ int i;
+
+ for(i=0; i<KDB_MAXBPT; i++) {
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdb_bp_install_global bp %d bp_enabled %d bp_global %d\n",
+ i, kdb_breakpoints[i].bp_enabled, kdb_breakpoints[i].bp_global);
+ }
+ if (kdb_breakpoints[i].bp_enabled
+ && kdb_breakpoints[i].bp_global) {
+ kdba_installbp(regs, &kdb_breakpoints[i]);
+ }
+ }
+}
+
+/*
+ * kdb_bp_install_local
+ *
+ * Install local kdb_breakpoints prior to returning from the
+ * kernel debugger. This allows the kdb_breakpoints to be set
+ * upon functions that are used internally by kdb, such as
+ * printk().
+ *
+ * Parameters:
+ * regs Execution frame.
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ * This function is called once per processor.
+ */
+
+void
+kdb_bp_install_local(struct pt_regs *regs)
+{
+ int i;
+
+ for(i=0; i<KDB_MAXBPT; i++) {
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdb_bp_install_local bp %d bp_enabled %d bp_global %d cpu %d bp_cpu %d\n",
+ i, kdb_breakpoints[i].bp_enabled, kdb_breakpoints[i].bp_global,
+ smp_processor_id(), kdb_breakpoints[i].bp_cpu);
+ }
+ if (kdb_breakpoints[i].bp_enabled
+ && kdb_breakpoints[i].bp_cpu == smp_processor_id()
+ && !kdb_breakpoints[i].bp_global){
+ kdba_installbp(regs, &kdb_breakpoints[i]);
+ }
+ }
+}
+
+/*
+ * kdb_bp_remove_global
+ *
+ * Remove global kdb_breakpoints upon entry to the kernel debugger.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+void
+kdb_bp_remove_global(void)
+{
+ int i;
+
+ for(i=KDB_MAXBPT-1; i>=0; i--) {
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdb_bp_remove_global bp %d bp_enabled %d bp_global %d\n",
+ i, kdb_breakpoints[i].bp_enabled, kdb_breakpoints[i].bp_global);
+ }
+ if (kdb_breakpoints[i].bp_enabled
+ && kdb_breakpoints[i].bp_global) {
+ kdba_removebp(&kdb_breakpoints[i]);
+ }
+ }
+}
+
+
+/*
+ * kdb_bp_remove_local
+ *
+ * Remove local kdb_breakpoints upon entry to the kernel debugger.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+void
+kdb_bp_remove_local(void)
+{
+ int i;
+
+ for(i=KDB_MAXBPT-1; i>=0; i--) {
+ if (KDB_DEBUG(BP)) {
+ kdb_printf("kdb_bp_remove_local bp %d bp_enabled %d bp_global %d cpu %d bp_cpu %d\n",
+ i, kdb_breakpoints[i].bp_enabled, kdb_breakpoints[i].bp_global,
+ smp_processor_id(), kdb_breakpoints[i].bp_cpu);
+ }
+ if (kdb_breakpoints[i].bp_enabled
+ && kdb_breakpoints[i].bp_cpu == smp_processor_id()
+ && !kdb_breakpoints[i].bp_global){
+ kdba_removebp(&kdb_breakpoints[i]);
+ }
+ }
+}
+
+/*
+ * kdb_printbp
+ *
+ * Internal function to format and print a breakpoint entry.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+static void
+kdb_printbp(kdb_bp_t *bp, int i)
+{
+ if (bp->bp_forcehw) {
+ kdb_printf("Forced ");
+ }
+
+ if (!bp->bp_template.bph_free) {
+ kdb_printf("%s ", kdba_bptype(&bp->bp_template));
+ } else {
+ kdb_printf("Instruction(i) ");
+ }
+
+ kdb_printf("BP #%d at ", i);
+ kdb_symbol_print(bp->bp_addr, NULL, KDB_SP_DEFAULT);
+
+ if (bp->bp_enabled) {
+ kdba_printbp(bp);
+ if (bp->bp_global)
+ kdb_printf(" globally");
+ else
+ kdb_printf(" on cpu %d", bp->bp_cpu);
+ if (bp->bp_adjust)
+ kdb_printf(" adjust %d", bp->bp_adjust);
+ } else {
+ kdb_printf("\n is disabled");
+ }
+
+ kdb_printf("\n");
+}
+
+/*
+ * kdb_bp
+ *
+ * Handle the bp, and bpa commands.
+ *
+ * [bp|bpa|bph] <addr-expression> [DATAR|DATAW|IO [length]]
+ *
+ * Parameters:
+ * argc Count of arguments in argv
+ * argv Space delimited command line arguments
+ * envp Environment value
+ * regs Exception frame at entry to kernel debugger
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero for success, a kdb diagnostic if failure.
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ * bp Set breakpoint. Only use hardware assist if necessary.
+ * bpa Set breakpoint on all cpus, only use hardware regs if necessary
+ * bph Set breakpoint - force hardware register
+ * bpha Set breakpoint on all cpus, force hardware register
+ */
+
+static int
+kdb_bp(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int i, bpno;
+ kdb_bp_t *bp, *bp_check;
+ int diag;
+ int free;
+ kdb_machreg_t addr;
+ char *symname = NULL;
+ long offset = 0ul;
+ int nextarg;
+ int hardware;
+ int global;
+
+ if (argc == 0) {
+ /*
+ * Display breakpoint table
+ */
+ for(bpno=0,bp=kdb_breakpoints; bpno<KDB_MAXBPT; bpno++, bp++) {
+ if (bp->bp_free) continue;
+
+ kdb_printbp(bp, bpno);
+ }
+
+ return 0;
+ }
+
+ global = ((strcmp(argv[0], "bpa") == 0)
+ || (strcmp(argv[0], "bpha") == 0));
+ hardware = ((strcmp(argv[0], "bph") == 0)
+ || (strcmp(argv[0], "bpha") == 0));
+
+ nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, &symname, regs);
+ if (diag)
+ return diag;
+ if (!addr)
+ return KDB_BADINT;
+
+ /*
+ * Allocate a new bp structure
+ */
+ free = KDB_MAXBPT;
+ for(bpno=0,bp=kdb_breakpoints; bpno<KDB_MAXBPT; bpno++,bp++) {
+ if (bp->bp_free) {
+ break;
+ }
+ }
+
+ if (bpno == KDB_MAXBPT)
+ return KDB_TOOMANYBPT;
+
+ memset(bp, 0, sizeof(*bp));
+ bp->bp_free = 1;
+ kdba_check_pc(&addr);
+ for(i=0,bp_check=kdb_breakpoints; i<KDB_MAXBPT; i++,bp_check++) {
+ if (!bp_check->bp_free && bp_check->bp_addr == addr) {
+ kdb_printf("You already have a breakpoint at " kdb_bfd_vma_fmt0 "\n", addr);
+ return KDB_DUPBPT;
+ }
+ }
+ bp->bp_addr = addr;
+ bp->bp_free = 0;
+
+ bp->bp_forcehw = hardware;
+ if (KDB_DEBUG(BP))
+ kdb_printf("kdb_bp: forcehw is %d hardware is %d\n", bp->bp_forcehw, hardware);
+
+ /*
+ * Handle architecture dependent parsing
+ */
+ diag = kdba_parsebp(argc, argv, &nextarg, bp);
+ if (diag) {
+ return diag;
+ }
+
+ bp->bp_enabled = 1;
+ bp->bp_global = 1; /* Most breakpoints are global */
+
+ if (hardware && !global) {
+ bp->bp_global = 0;
+ bp->bp_cpu = smp_processor_id();
+ }
+
+ /*
+ * Allocate a hardware breakpoint. If one is not available,
+ * disable the breakpoint, but leave it in the breakpoint
+ * table. When the breakpoint is re-enabled (via 'be'), we'll
+ * attempt to allocate a hardware register for it.
+ */
+ if (!bp->bp_template.bph_free) {
+ bp->bp_hard = kdba_allocbp(&bp->bp_template, &diag);
+ if (diag) {
+ bp->bp_enabled = 0;
+ return diag;
+ }
+ bp->bp_hardtype = 1;
+ }
+
+ kdb_printbp(bp, bpno);
+
+ return 0;
+}
+
+/*
+ * kdb_bc
+ *
+ * Handles the 'bc', 'be', and 'bd' commands
+ *
+ * [bd|bc|be] <breakpoint-number>
+ * [bd|bc|be] *
+ *
+ * Parameters:
+ * argc Count of arguments in argv
+ * argv Space delimited command line arguments
+ * envp Environment value
+ * regs Exception frame at entry to kernel debugger
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero for success, a kdb diagnostic for failure
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+#define KDBCMD_BC 0
+#define KDBCMD_BE 1
+#define KDBCMD_BD 2
+
+static int
+kdb_bc(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ kdb_machreg_t addr;
+ kdb_bp_t *bp = NULL;
+ int lowbp = KDB_MAXBPT;
+ int highbp = 0;
+ int done = 0;
+ int i;
+ int diag;
+ int cmd; /* KDBCMD_B? */
+
+ if (strcmp(argv[0], "be") == 0) {
+ cmd = KDBCMD_BE;
+ } else if (strcmp(argv[0], "bd") == 0) {
+ cmd = KDBCMD_BD;
+ } else
+ cmd = KDBCMD_BC;
+
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+
+ if (strcmp(argv[1], "*") == 0) {
+ lowbp = 0;
+ highbp = KDB_MAXBPT;
+ } else {
+ diag = kdbgetularg(argv[1], &addr);
+ if (diag)
+ return diag;
+
+ /*
+ * For addresses less than the maximum breakpoint number,
+ * assume that the breakpoint number is desired.
+ */
+ if (addr < KDB_MAXBPT) {
+ bp = &kdb_breakpoints[addr];
+ lowbp = highbp = addr;
+ highbp++;
+ } else {
+ for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) {
+ if (bp->bp_addr == addr) {
+ lowbp = highbp = i;
+ highbp++;
+ break;
+ }
+ }
+ }
+ }
+
+ /*
+ * Now operate on the set of breakpoints matching the input
+ * criteria (either '*' for all, or an individual breakpoint).
+ */
+ for(bp=&kdb_breakpoints[lowbp], i=lowbp;
+ i < highbp;
+ i++, bp++) {
+ if (bp->bp_free)
+ continue;
+
+ done++;
+
+ switch (cmd) {
+ case KDBCMD_BC:
+ if (bp->bp_hardtype) {
+ kdba_freebp(bp->bp_hard);
+ bp->bp_hard = NULL;
+ bp->bp_hardtype = 0;
+ }
+
+ bp->bp_enabled = 0;
+ bp->bp_global = 0;
+
+ kdb_printf("Breakpoint %d at " kdb_bfd_vma_fmt " cleared\n",
+ i, bp->bp_addr);
+
+ bp->bp_addr = 0;
+ bp->bp_free = 1;
+
+ break;
+ case KDBCMD_BE:
+ /*
+ * Allocate a hardware breakpoint. If one is not
+ * available, don't enable the breakpoint.
+ */
+ if (!bp->bp_template.bph_free
+ && !bp->bp_hardtype) {
+ bp->bp_hard = kdba_allocbp(&bp->bp_template, &diag);
+ if (diag) {
+ bp->bp_enabled = 0;
+ return diag;
+ }
+ bp->bp_hardtype = 1;
+ }
+
+ bp->bp_enabled = 1;
+
+ kdb_printf("Breakpoint %d at " kdb_bfd_vma_fmt " enabled",
+ i, bp->bp_addr);
+
+ kdb_printf("\n");
+ break;
+ case KDBCMD_BD:
+ if (!bp->bp_enabled)
+ break;
+
+ /*
+ * Since this breakpoint is now disabled, we can
+ * give up the hardware register which is allocated
+ * to it.
+ */
+ if (bp->bp_hardtype) {
+ kdba_freebp(bp->bp_hard);
+ bp->bp_hard = NULL;
+ bp->bp_hardtype = 0;
+ }
+
+ bp->bp_enabled = 0;
+
+ kdb_printf("Breakpoint %d at " kdb_bfd_vma_fmt " disabled\n",
+ i, bp->bp_addr);
+
+ break;
+ }
+ if (bp->bp_delay && (cmd == KDBCMD_BC || cmd == KDBCMD_BD)) {
+ bp->bp_delay = 0;
+ KDB_STATE_CLEAR(SSBPT);
+ }
+ }
+
+ return (!done)?KDB_BPTNOTFOUND:0;
+}
+
+/*
+ * kdb_ss
+ *
+ * Process the 'ss' (Single Step) and 'ssb' (Single Step to Branch)
+ * commands.
+ *
+ * ss
+ * ssb
+ *
+ * Parameters:
+ * argc Argument count
+ * argv Argument vector
+ * envp Environment vector
+ * regs Registers at time of entry to kernel debugger
+ * Outputs:
+ * None.
+ * Returns:
+ * KDB_CMD_SS[B] for success, a kdb error if failure.
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ * Set the arch specific option to trigger a debug trap after the next
+ * instruction.
+ *
+ * For 'ssb', set the trace flag in the debug trap handler
+ * after printing the current insn and return directly without
+ * invoking the kdb command processor, until a branch instruction
+ * is encountered.
+ */
+
+int
+kdb_ss(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int ssb = 0;
+
+ ssb = (strcmp(argv[0], "ssb") == 0);
+ if (argc != 0)
+ return KDB_ARGCOUNT;
+
+ if (!regs) {
+ kdb_printf("%s: pt_regs not available\n", __FUNCTION__);
+ return KDB_BADREG;
+ }
+
+ /*
+ * Set trace flag and go.
+ */
+ KDB_STATE_SET(DOING_SS);
+ if (ssb)
+ KDB_STATE_SET(DOING_SSB);
+
+ kdba_setsinglestep(regs); /* Enable single step */
+
+ if (ssb)
+ return KDB_CMD_SSB;
+ return KDB_CMD_SS;
+}
+
+/*
+ * kdb_initbptab
+ *
+ * Initialize the breakpoint table. Register breakpoint commands.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+void __init
+kdb_initbptab(void)
+{
+ int i;
+ kdb_bp_t *bp;
+
+ /*
+ * First time initialization.
+ */
+ memset(&kdb_breakpoints, '\0', sizeof(kdb_breakpoints));
+
+ for (i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) {
+ bp->bp_free = 1;
+ /*
+ * The bph_free flag is architecturally required. It
+ * is set by architecture-dependent code to false (zero)
+ * in the event a hardware breakpoint register is required
+ * for this breakpoint.
+ *
+ * The rest of the template is reserved to the architecture
+ * dependent code and _must_ not be touched by the architecture
+ * independent code.
+ */
+ bp->bp_template.bph_free = 1;
+ }
+
+ kdb_register_repeat("bp", kdb_bp, "[<vaddr>]", "Set/Display breakpoints", 0, KDB_REPEAT_NO_ARGS);
+ kdb_register_repeat("bl", kdb_bp, "[<vaddr>]", "Display breakpoints", 0, KDB_REPEAT_NO_ARGS);
+ kdb_register_repeat("bpa", kdb_bp, "[<vaddr>]", "Set/Display global breakpoints", 0, KDB_REPEAT_NO_ARGS);
+ kdb_register_repeat("bph", kdb_bp, "[<vaddr>]", "Set hardware breakpoint", 0, KDB_REPEAT_NO_ARGS);
+ kdb_register_repeat("bpha", kdb_bp, "[<vaddr>]", "Set global hardware breakpoint", 0, KDB_REPEAT_NO_ARGS);
+ kdb_register_repeat("bc", kdb_bc, "<bpnum>", "Clear Breakpoint", 0, KDB_REPEAT_NONE);
+ kdb_register_repeat("be", kdb_bc, "<bpnum>", "Enable Breakpoint", 0, KDB_REPEAT_NONE);
+ kdb_register_repeat("bd", kdb_bc, "<bpnum>", "Disable Breakpoint", 0, KDB_REPEAT_NONE);
+
+ kdb_register_repeat("ss", kdb_ss, "", "Single Step", 1, KDB_REPEAT_NO_ARGS);
+ kdb_register_repeat("ssb", kdb_ss, "", "Single step to branch/call", 0, KDB_REPEAT_NO_ARGS);
+ /*
+ * Architecture dependent initialization.
+ */
+ kdba_initbp();
+}
--- /dev/null
+/*
+ * Kernel Debugger Architecture Independent Stack Traceback
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <linux/nmi.h>
+#include <asm/system.h>
+
+
+/*
+ * kdb_bt
+ *
+ * This function implements the 'bt' command. Print a stack
+ * traceback.
+ *
+ * bt [<address-expression>] (addr-exp is for alternate stacks)
+ * btp <pid> Kernel stack for <pid>
+ * btt <address-expression> Kernel stack for task structure at <address-expression>
+ * bta [DRSTCZEUIMA] All useful processes, optionally filtered by state
+ * btc [<cpu>] The current process on one cpu, default is all cpus
+ *
+ * address expression refers to a return address on the stack. It
+ * is expected to be preceeded by a frame pointer.
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * Backtrack works best when the code uses frame pointers. But
+ * even without frame pointers we should get a reasonable trace.
+ *
+ * mds comes in handy when examining the stack to do a manual
+ * traceback.
+ */
+
+static int
+kdb_bt1(const struct task_struct *p, unsigned long mask, int argcount, int btaprompt)
+{
+ int diag;
+ char buffer[2];
+ /* FIXME: use kdb_verify_area */
+ if (kdb_getarea(buffer[0], (unsigned long)p) ||
+ kdb_getarea(buffer[0], (unsigned long)(p+1)-1))
+ return KDB_BADADDR;
+ if (!kdb_task_state(p, mask))
+ return 0;
+ kdb_ps1(p);
+ diag = kdba_bt_process(p, argcount);
+ if (btaprompt) {
+ kdb_printf("Enter <Space> or <Return> to continue: ");
+ buffer[0] = '\0';
+ kdb_read(buffer, 2);
+ if (buffer[0] > ' ') {
+ extern char kdb_jmpchar;
+ kdb_jmpchar = buffer[0];
+ return 1;
+ }
+ }
+ touch_nmi_watchdog();
+ return 0;
+}
+
+int
+kdb_bt(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int diag;
+ int argcount = 5;
+ int btaprompt = 1;
+ int nextarg;
+ unsigned long addr;
+ long offset;
+
+ kdbgetintenv("BTARGS", &argcount); /* Arguments to print */
+ kdbgetintenv("BTAPROMPT", &btaprompt); /* Prompt after each proc in bta */
+
+ if (strcmp(argv[0], "bta") == 0) {
+ struct task_struct *g, *p;
+ unsigned long cpu;
+ unsigned long mask = kdb_task_state_string(argc ? argv[1] : NULL);
+ if (argc == 0)
+ kdb_ps_suppressed();
+ /* Run the active tasks first */
+ for (cpu = 0; cpu < NR_CPUS; ++cpu) {
+ if (!cpu_online(cpu))
+ continue;
+ p = kdb_curr_task(cpu);
+ if (kdb_bt1(p, mask, argcount, btaprompt))
+ return 0;
+ }
+ /* Now the inactive tasks */
+ do_each_thread(g, p) {
+ if (task_curr(p))
+ continue;
+ if (kdb_bt1(p, mask, argcount, btaprompt))
+ return 0;
+ } while_each_thread(g, p);
+ return 0;
+ } else if (strcmp(argv[0], "btp") == 0) {
+ struct task_struct *p;
+ unsigned long pid;
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+ if ((diag = kdbgetularg((char *)argv[1], &pid)))
+ return diag;
+ if ((p = find_task_by_pid(pid))) {
+ kdba_set_current_task(p);
+ return kdb_bt1(p, ~0UL, argcount, 0);
+ }
+ kdb_printf("No process with pid == %ld found\n", pid);
+ return 0;
+ } else if (strcmp(argv[0], "btt") == 0) {
+ unsigned long addr;
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+ if ((diag = kdbgetularg((char *)argv[1], &addr)))
+ return diag;
+ kdba_set_current_task((struct task_struct *)addr);
+ return kdb_bt1((struct task_struct *)addr, ~0UL, argcount, 0);
+ } else if (strcmp(argv[0], "btc") == 0) {
+ unsigned long cpu = ~0;
+ struct kdb_running_process *krp;
+ if (argc > 1)
+ return KDB_ARGCOUNT;
+ if (argc == 1 && (diag = kdbgetularg((char *)argv[1], &cpu)))
+ return diag;
+ if (cpu != ~0) {
+ krp = kdb_running_process + cpu;
+ if (cpu >= NR_CPUS || !krp->seqno || !cpu_online(cpu))
+ kdb_printf("no process for cpu %ld\n", cpu);
+ else
+ kdb_bt1(krp->p, ~0UL, argcount, 0);
+ return 0;
+ }
+ for (cpu = 0, krp = kdb_running_process; cpu < NR_CPUS; ++cpu, ++krp) {
+ if (!cpu_online(cpu) || !krp->seqno)
+ continue;
+ if (kdb_bt1(krp->p, ~0UL, argcount, btaprompt))
+ return 0;
+ }
+ return 0;
+ } else {
+ if (argc) {
+ nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &addr,
+ &offset, NULL, regs);
+ if (diag)
+ return diag;
+ return kdba_bt_address(addr, argcount);
+ } else {
+ return kdb_bt1(kdb_current_task, ~0UL, argcount, 0);
+ }
+ }
+
+ /* NOTREACHED */
+ return 0;
+}
--- /dev/null
+# Initial commands for kdb, alter to suit your needs.
+# These commands are executed in kdb_init() context, no SMP, no
+# processes. Commands that require process data (including stack or
+# registers) are not reliable this early. set and bp commands should
+# be safe. Global breakpoint commands affect each cpu as it is booted.
+
+# Standard debugging information for first level support, just type archkdb
+# or archkdbcpu or archkdbshort at the kdb prompt.
+
+defcmd archkdb "" "First line arch debugging"
+ set BTSYMARG 1
+ set BTARGS 5
+ pid R
+ -archkdbcommon
+ -bta
+endefcmd
+
+defcmd archkdbcpu "" "archkdb with only tasks on cpus"
+ set BTSYMARG 1
+ set BTARGS 5
+ pid R
+ -archkdbcommon
+ -btc
+endefcmd
+
+defcmd archkdbshort "" "archkdb with less detailed backtrace"
+ set BTSYMARG 0
+ set BTARGS 0
+ pid R
+ -archkdbcommon
+ -bta
+endefcmd
--- /dev/null
+/*
+ * Kernel Debugger Architecture Independent Instruction Disassembly
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <stdarg.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+
+disassemble_info kdb_di;
+
+/*
+ * kdb_id
+ *
+ * Handle the id (instruction display) command.
+ *
+ * id [<addr>]
+ *
+ * Parameters:
+ * argc Count of arguments in argv
+ * argv Space delimited command line arguments
+ * envp Environment value
+ * regs Exception frame at entry to kernel debugger
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero for success, a kdb diagnostic if failure.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+int
+kdb_id(int argc, const char **argv, const char **envp, struct pt_regs* regs)
+{
+ kdb_machreg_t pc;
+ int icount;
+ int diag;
+ int i;
+ char *mode;
+ int nextarg;
+ long offset = 0;
+ static kdb_machreg_t lastpc;
+ struct disassemble_info *dip = &kdb_di;
+ char lastbuf[20];
+ unsigned long word;
+
+ if (argc != 1) {
+ if (lastpc == 0 || argc != 0) {
+ return KDB_ARGCOUNT;
+ } else {
+ sprintf(lastbuf, "0x%lx", lastpc);
+ argv[1] = lastbuf;
+ argc = 1;
+ }
+ }
+
+
+ /*
+ * Fetch PC. First, check to see if it is a symbol, if not,
+ * try address.
+ */
+ nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &pc, &offset, NULL, regs);
+ if (diag)
+ return diag;
+ kdba_check_pc(&pc);
+ if (kdb_getarea(word, pc))
+ return(0);
+
+ /*
+ * Number of lines to display
+ */
+ diag = kdbgetintenv("IDCOUNT", &icount);
+ if (diag)
+ return diag;
+
+ mode = kdbgetenv("IDMODE");
+ diag = kdba_id_parsemode(mode, dip);
+ if (diag) {
+ return diag;
+ }
+
+ for(i=0; i<icount; i++) {
+ pc += kdba_id_printinsn(pc, &kdb_di);
+ kdb_printf("\n");
+ }
+
+ lastpc = pc;
+
+ return 0;
+}
+
+/*
+ * kdb_id1
+ *
+ * Disassemble a single instruction at 'pc'.
+ *
+ * Parameters:
+ * pc Address of instruction to disassemble
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero for success, a kdb diagnostic if failure.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+void
+kdb_id1(unsigned long pc)
+{
+ char *mode;
+ int diag;
+
+ /*
+ * Allow the user to specify that this instruction
+ * should be treated differently.
+ */
+
+ mode = kdbgetenv("IDMODE");
+ diag = kdba_id_parsemode(mode, &kdb_di);
+ if (diag) {
+ kdb_printf("kdb_id: bad value in 'IDMODE' environment variable ignored\n");
+ }
+
+ (void) kdba_id_printinsn(pc, &kdb_di);
+ kdb_printf("\n");
+}
+
+/*
+ * kdb_dis_fprintf
+ *
+ * Format and print a string.
+ *
+ * Parameters:
+ * file Unused paramter.
+ * fmt Format string
+ * ... Optional additional parameters.
+ * Returns:
+ * 0
+ * Locking:
+ * Remarks:
+ * Result of format conversion cannot exceed 255 bytes.
+ */
+
+int
+kdb_dis_fprintf(PTR file, const char *fmt, ...)
+{
+ static char buffer[256];
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsprintf(buffer, fmt, ap);
+ va_end(ap);
+
+ kdb_printf("%s", buffer);
+
+ return 0;
+}
+
+/*
+ * kdb_disinit
+ *
+ * Initialize the disassembly information structure
+ * for the GNU disassembler.
+ *
+ * Parameters:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero for success, a kdb diagnostic if failure.
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+void __init
+kdb_id_init(void)
+{
+ kdb_di.stream = NULL;
+ kdb_di.application_data = NULL;
+ kdb_di.symbols = NULL;
+ kdb_di.num_symbols = 0;
+ kdb_di.flags = 0;
+ kdb_di.private_data = NULL;
+ kdb_di.buffer = NULL;
+ kdb_di.buffer_vma = 0;
+ kdb_di.buffer_length = 0;
+ kdb_di.bytes_per_line = 0;
+ kdb_di.bytes_per_chunk = 0;
+ kdb_di.insn_info_valid = 0;
+ kdb_di.branch_delay_insns = 0;
+ kdb_di.data_size = 0;
+ kdb_di.insn_type = 0;
+ kdb_di.target = 0;
+ kdb_di.target2 = 0;
+ kdb_di.fprintf_func = kdb_dis_fprintf;
+
+ kdba_id_init(&kdb_di);
+}
--- /dev/null
+/*
+ * Kernel Debugger Architecture Independent Console I/O handler
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/kdev_t.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/nmi.h>
+#include <linux/delay.h>
+
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <linux/kallsyms.h>
+
+#ifdef CONFIG_SPARC64
+#include <asm/oplib.h>
+#else
+static struct console *kdbcons;
+#endif
+
+#ifdef CONFIG_PPC64
+#include <asm/udbg.h>
+#endif
+
+#define CMD_BUFLEN 256
+char kdb_prompt_str[CMD_BUFLEN];
+char kdb_jmpchar;
+static int kdb_editing;
+
+/*
+ * kdb_read
+ *
+ * This function reads a string of characters, terminated by
+ * a newline, or by reaching the end of the supplied buffer,
+ * from the current kernel debugger console device.
+ * Parameters:
+ * buffer - Address of character buffer to receive input characters.
+ * bufsize - size, in bytes, of the character buffer
+ * Returns:
+ * Returns a pointer to the buffer containing the received
+ * character string. This string will be terminated by a
+ * newline character.
+ * Locking:
+ * No locks are required to be held upon entry to this
+ * function. It is not reentrant - it relies on the fact
+ * that while kdb is running on any one processor all other
+ * processors will be spinning at the kdb barrier.
+ * Remarks:
+ *
+ * Davidm asks, why doesn't kdb use the console abstraction;
+ * here are some reasons:
+ * - you cannot debug the console abstraction with kdb if
+ * kdb uses it.
+ * - you rely on the correct functioning of the abstraction
+ * in the presence of general system failures.
+ * - You must acquire the console spinlock thus restricting
+ * the usability - what if the kernel fails with the spinlock
+ * held - one still wishes to debug such situations.
+ * - How about debugging before the console(s) are registered?
+ * - None of the current consoles (sercons, vt_console_driver)
+ * have read functions defined.
+ * - The standard pc keyboard and terminal drivers are interrupt
+ * driven. We cannot enable interrupts while kdb is active,
+ * so the standard input functions cannot be used by kdb.
+ *
+ * An implementation could be improved by removing the need for
+ * lock acquisition - just keep a 'struct console *kdbconsole;' global
+ * variable which refers to the preferred kdb console.
+ *
+ * The bulk of this function is architecture dependent.
+ *
+ * The buffer size must be >= 2. A buffer size of 2 means that the caller only
+ * wants a single key.
+ *
+ * An escape key could be the start of a vt100 control sequence such as \e[D
+ * (left arrow) or it could be a character in its own right. The standard
+ * method for detecting the difference is to wait for 2 seconds to see if there
+ * are any other characters. kdb is complicated by the lack of a timer service
+ * (interrupts are off), by multiple input sources and by the need to sometimes
+ * return after just one key. Escape sequence processing has to be done as
+ * states in the polling loop.
+ */
+
+char *
+kdb_read(char *buffer, size_t bufsize)
+{
+ char *cp = buffer;
+ char *bufend = buffer+bufsize-2; /* Reserve space for newline and null byte */
+
+ char *lastchar;
+ char *p_tmp;
+ char tmp;
+ static char tmpbuffer[CMD_BUFLEN];
+ int len = strlen(buffer);
+ int len_tmp;
+ int tab=0;
+ int count;
+ int i;
+ int diag, dtab_count;
+
+#define ESCAPE_UDELAY 1000
+#define ESCAPE_DELAY 2*1000000/ESCAPE_UDELAY /* 2 seconds worth of udelays */
+ char escape_data[5]; /* longest vt100 escape sequence is 4 bytes */
+ char *ped = escape_data;
+ int escape_delay = 0;
+ get_char_func *f, *f_escape = NULL;
+
+ diag = kdbgetintenv("DTABCOUNT",&dtab_count);
+ if (diag)
+ dtab_count = 30;
+
+ if (len > 0 ) {
+ cp += len;
+ if (*(buffer+len-1) == '\n')
+ cp--;
+ }
+
+ lastchar = cp;
+ *cp = '\0';
+ kdb_printf("%s", buffer);
+
+ for (;;) {
+ int key;
+ for (f = &poll_funcs[0]; ; ++f) {
+ if (*f == NULL) {
+ /* Reset NMI watchdog once per poll loop */
+ touch_nmi_watchdog();
+ f = &poll_funcs[0];
+ }
+ if (escape_delay == 2) {
+ *ped = '\0';
+ ped = escape_data;
+ --escape_delay;
+ }
+ if (escape_delay == 1) {
+ key = *ped++;
+ if (!*ped)
+ --escape_delay;
+ break;
+ }
+ key = (*f)();
+ if (key == -1) {
+ if (escape_delay) {
+ udelay(ESCAPE_UDELAY);
+ --escape_delay;
+ }
+ continue;
+ }
+ key &= 0xff;
+ if (bufsize <= 2) {
+ kdb_nextline = 1;
+ kdb_printf("\n");
+ kdb_nextline = 1;
+ buffer[0] = key;
+ buffer[1] = '\0';
+ return buffer;
+ }
+ if (escape_delay == 0 && key == '\e') {
+ escape_delay = ESCAPE_DELAY;
+ ped = escape_data;
+ f_escape = f;
+ }
+ if (escape_delay) {
+ *ped++ = key;
+ if (f_escape != f) {
+ escape_delay = 2;
+ continue;
+ }
+ if (ped - escape_data == 1) {
+ /* \e */
+ continue;
+ }
+ else if (ped - escape_data == 2) {
+ /* \e<something> */
+ if (key != '[')
+ escape_delay = 2;
+ continue;
+ } else if (ped - escape_data == 3) {
+ /* \e[<something> */
+ int mapkey = 0;
+ switch (key) {
+ case 'A': mapkey = 16; break; /* \e[A, up arrow */
+ case 'B': mapkey = 14; break; /* \e[B, down arrow */
+ case 'C': mapkey = 6; break; /* \e[C, right arrow */
+ case 'D': mapkey = 2; break; /* \e[D, left arrow */
+ case '1': /* dropthrough */
+ case '3': /* dropthrough */
+ case '4': mapkey = -1; break; /* \e[<1,3,4>], may be home, del, end */
+ }
+ if (mapkey != -1) {
+ if (mapkey > 0) {
+ escape_data[0] = mapkey;
+ escape_data[1] = '\0';
+ }
+ escape_delay = 2;
+ }
+ continue;
+ } else if (ped - escape_data == 4) {
+ /* \e[<1,3,4><something> */
+ int mapkey = 0;
+ if (key == '~') {
+ switch (escape_data[2]) {
+ case '1': mapkey = 1; break; /* \e[1~, home */
+ case '3': mapkey = 4; break; /* \e[3~, del */
+ case '4': mapkey = 5; break; /* \e[4~, end */
+ }
+ }
+ if (mapkey > 0) {
+ escape_data[0] = mapkey;
+ escape_data[1] = '\0';
+ }
+ escape_delay = 2;
+ continue;
+ }
+ }
+ break; /* A key to process */
+ }
+
+ if (key != 9)
+ tab = 0;
+ switch (key) {
+ case 8: /* backspace */
+ if (cp > buffer) {
+ if (cp < lastchar) {
+ memcpy(tmpbuffer, cp, lastchar - cp);
+ memcpy(cp-1, tmpbuffer, lastchar - cp);
+ }
+ *(--lastchar) = '\0';
+ --cp;
+ kdb_printf("\b%s \r", cp);
+ tmp = *cp;
+ *cp = '\0';
+ kdb_printf(kdb_prompt_str);
+ kdb_printf("%s", buffer);
+ *cp = tmp;
+ }
+ break;
+ case 13: /* enter */
+ *lastchar++ = '\n';
+ *lastchar++ = '\0';
+ kdb_printf("\n");
+ return buffer;
+ case 4: /* Del */
+ if(cp < lastchar) {
+ memcpy(tmpbuffer, cp+1, lastchar - cp -1);
+ memcpy(cp, tmpbuffer, lastchar - cp -1);
+ *(--lastchar) = '\0';
+ kdb_printf("%s \r", cp);
+ tmp = *cp;
+ *cp = '\0';
+ kdb_printf(kdb_prompt_str);
+ kdb_printf("%s", buffer);
+ *cp = tmp;
+ }
+ break;
+ case 1: /* Home */
+ if(cp > buffer) {
+ kdb_printf("\r");
+ kdb_printf(kdb_prompt_str);
+ cp = buffer;
+ }
+ break;
+ case 5: /* End */
+ if(cp < lastchar) {
+ kdb_printf("%s", cp);
+ cp = lastchar;
+ }
+ break;
+ case 2: /* Left */
+ if (cp > buffer) {
+ kdb_printf("\b");
+ --cp;
+ }
+ break;
+ case 14: /* Down */
+ memset(tmpbuffer, ' ', strlen(kdb_prompt_str)+(lastchar-buffer));
+ *(tmpbuffer+strlen(kdb_prompt_str)+(lastchar-buffer)) = '\0';
+ kdb_printf("\r%s\r", tmpbuffer);
+ *lastchar = (char)key;
+ *(lastchar+1) = '\0';
+ return lastchar;
+ case 6: /* Right */
+ if (cp < lastchar) {
+ kdb_printf("%c", *cp);
+ ++cp;
+ }
+ break;
+ case 16: /* Up */
+ memset(tmpbuffer, ' ', strlen(kdb_prompt_str)+(lastchar-buffer));
+ *(tmpbuffer+strlen(kdb_prompt_str)+(lastchar-buffer)) = '\0';
+ kdb_printf("\r%s\r", tmpbuffer);
+ *lastchar = (char)key;
+ *(lastchar+1) = '\0';
+ return lastchar;
+ case 9: /* Tab */
+ if (tab < 2)
+ ++tab;
+ p_tmp = buffer;
+ while(*p_tmp==' ') p_tmp++;
+ if (p_tmp<=cp) {
+ memcpy(tmpbuffer, p_tmp, cp-p_tmp);
+ *(tmpbuffer + (cp-p_tmp)) = '\0';
+ p_tmp = strrchr(tmpbuffer, ' ');
+ if (p_tmp)
+ ++p_tmp;
+ else
+ p_tmp = tmpbuffer;
+ len = strlen(p_tmp);
+ count = kallsyms_symbol_complete(p_tmp, sizeof(tmpbuffer) - (p_tmp - tmpbuffer));
+ if (tab == 2) {
+ if (count > 0) {
+ kdb_printf("\n%d symbols found:", count);
+ if(count>dtab_count) {
+ kdb_printf(" only showing %d (set DTABCOUNT=%d to see them all)", dtab_count, count);
+ count=dtab_count;
+ }
+ kdb_printf("\n");
+ for(i=0;i<count;i++) {
+ if(kallsyms_symbol_next(p_tmp, i)<0)
+ break;
+ kdb_printf("%s ",p_tmp);
+ *(p_tmp+len)='\0';
+ }
+ if(i>=dtab_count)kdb_printf("...");
+ kdb_printf("\n");
+ kdb_printf(kdb_prompt_str);
+ kdb_printf("%s", buffer);
+ }
+ }
+ else {
+ if (count > 0) {
+ len_tmp = strlen(p_tmp);
+ strncpy(p_tmp+len_tmp,cp, lastchar-cp+1);
+ len_tmp = strlen(p_tmp);
+ strncpy(cp, p_tmp+len, len_tmp-len+1);
+ len = len_tmp - len;
+ kdb_printf("%s", cp);
+ cp+=len;
+ lastchar+=len;
+ }
+ }
+ kdb_nextline = 1; /* reset output line number */
+ }
+ break;
+ default:
+ if (key >= 32 && lastchar < bufend) {
+ if (cp < lastchar) {
+ memcpy(tmpbuffer, cp, lastchar - cp);
+ memcpy(cp+1, tmpbuffer, lastchar - cp);
+ }
+ *(++lastchar) = '\0';
+ *cp = key;
+ kdb_printf("%s", cp);
+ ++cp;
+ len = lastchar - cp;
+ while (len--)
+ kdb_printf("\b");
+ }
+ break;
+ }
+ }
+}
+
+/*
+ * kdb_getstr
+ *
+ * Print the prompt string and read a command from the
+ * input device.
+ *
+ * Parameters:
+ * buffer Address of buffer to receive command
+ * bufsize Size of buffer in bytes
+ * prompt Pointer to string to use as prompt string
+ * Returns:
+ * Pointer to command buffer.
+ * Locking:
+ * None.
+ * Remarks:
+ * For SMP kernels, the processor number will be
+ * substituted for %d, %x or %o in the prompt.
+ */
+
+char *
+kdb_getstr(char *buffer, size_t bufsize, char *prompt)
+{
+ int saved_loglevel, logging;
+
+ if (prompt && kdb_prompt_str != prompt)
+ strncpy(kdb_prompt_str, prompt, CMD_BUFLEN);
+ kdb_printf(kdb_prompt_str);
+ kdb_nextline = 1; /* Prompt and input resets line number */
+ if (kdb_jmpchar) {
+ buffer[0] = kdb_jmpchar;
+ buffer[1] = '\0';
+ kdb_jmpchar = '\0';
+ }
+ kdb_editing = 1;
+ buffer = kdb_read(buffer, bufsize);
+ kdb_editing = 0;
+ if (kdbgetintenv("LOGGING", &logging) == 0 && logging) {
+ saved_loglevel = console_loglevel;
+ console_loglevel = 0;
+ printk("%s", buffer);
+ console_loglevel = saved_loglevel;
+ }
+ return buffer;
+}
+
+/*
+ * kdb_input_flush
+ *
+ * Get rid of any buffered console input.
+ *
+ * Parameters:
+ * none
+ * Returns:
+ * nothing
+ * Locking:
+ * none
+ * Remarks:
+ * Call this function whenever you want to flush input. If there is any
+ * outstanding input, it ignores all characters until there has been no
+ * data for approximately half a second.
+ */
+
+#define FLUSH_UDELAY 100
+#define FLUSH_DELAY 500000/FLUSH_UDELAY /* 0.5 seconds worth of udelays */
+
+static void
+kdb_input_flush(void)
+{
+ get_char_func *f;
+ int flush_delay = 1;
+ while (flush_delay--) {
+ touch_nmi_watchdog();
+ for (f = &poll_funcs[0]; *f; ++f) {
+ if ((*f)() != -1) {
+ flush_delay = FLUSH_DELAY;
+ break;
+ }
+ }
+ if (flush_delay)
+ udelay(FLUSH_UDELAY);
+ }
+}
+
+/*
+ * kdb_printf
+ *
+ * Print a string to the output device(s).
+ *
+ * Parameters:
+ * printf-like format and optional args.
+ * Returns:
+ * 0
+ * Locking:
+ * None.
+ * Remarks:
+ * use 'kdbcons->write()' to avoid polluting 'log_buf' with
+ * kdb output.
+ */
+
+static char kdb_buffer[256]; /* A bit too big to go on stack */
+
+void
+kdb_printf(const char *fmt, ...)
+{
+ va_list ap;
+ int diag;
+ int linecount;
+ int logging, saved_loglevel = 0;
+ int do_longjmp = 0;
+ int got_printf_lock = 0;
+ struct console *c = console_drivers;
+ static DEFINE_SPINLOCK(kdb_printf_lock);
+
+ preempt_disable();
+ /* Serialize kdb_printf if multiple cpus try to write at once.
+ * But if any cpu goes recursive in kdb, just print the output,
+ * even if it is interleaved with any other text.
+ */
+ if (!KDB_STATE(PRINTF_LOCK)) {
+ KDB_STATE_SET(PRINTF_LOCK);
+ spin_lock(&kdb_printf_lock);
+ got_printf_lock = 1;
+ }
+
+ diag = kdbgetintenv("LINES", &linecount);
+ if (diag || linecount <= 1)
+ linecount = 22;
+
+ logging = 0;
+ if (!kdb_editing)
+ kdbgetintenv("LOGGING", &logging);
+
+ va_start(ap, fmt);
+ vsnprintf(kdb_buffer, sizeof(kdb_buffer), fmt, ap);
+ va_end(ap);
+
+ /*
+ * Write to all consoles.
+ */
+#ifdef CONFIG_SPARC64
+ if (c == NULL)
+ prom_printf("%s", kdb_buffer);
+ else
+#endif
+
+#ifdef CONFIG_PPC64
+ if (c == NULL)
+ udbg_write(kdb_buffer, strlen(kdb_buffer));
+ else
+#endif
+
+ while (c) {
+ c->write(c, kdb_buffer, strlen(kdb_buffer));
+ c = c->next;
+ }
+ if (logging) {
+ saved_loglevel = console_loglevel;
+ console_loglevel = 0;
+ printk("%s", kdb_buffer);
+ }
+
+ if (KDB_STATE(LONGJMP) && strchr(kdb_buffer, '\n'))
+ kdb_nextline++;
+
+ if (kdb_nextline == linecount) {
+ char buf1[2];
+#if defined(CONFIG_SMP)
+ char buf2[32];
+#endif
+ char *moreprompt;
+
+ /* Watch out for recursion here. Any routine that calls
+ * kdb_printf will come back through here. And kdb_read
+ * uses kdb_printf to echo on serial consoles ...
+ */
+ kdb_nextline = 1; /* In case of recursion */
+
+ /*
+ * Pause until cr.
+ */
+ moreprompt = kdbgetenv("MOREPROMPT");
+ if (moreprompt == NULL) {
+ moreprompt = "more> ";
+ }
+
+#if defined(CONFIG_SMP)
+ if (strchr(moreprompt, '%')) {
+ sprintf(buf2, moreprompt, get_cpu());
+ put_cpu();
+ moreprompt = buf2;
+ }
+#endif
+
+ kdb_input_flush();
+ c = console_drivers;
+#ifdef CONFIG_SPARC64
+ if (c == NULL)
+ prom_printf("%s", moreprompt);
+ else
+#endif
+
+#ifdef CONFIG_PPC64
+ if (c == NULL)
+ udbg_write(moreprompt, strlen(moreprompt));
+ else
+#endif
+
+ while (c) {
+ c->write(c, moreprompt, strlen(moreprompt));
+ c = c->next;
+ }
+
+ if (logging)
+ printk("%s", moreprompt);
+
+ buf1[0] = '\0';
+ kdb_read(buf1, 2); /* 2 says get just one key. */
+ if (buf1[0] > ' ') {
+ kdb_jmpchar = buf1[0];
+ KDB_FLAG_SET(CMD_INTERRUPT);
+ do_longjmp = 1;
+ }
+ kdb_input_flush();
+ }
+
+ if (logging) {
+ console_loglevel = saved_loglevel;
+ }
+ if (KDB_STATE(PRINTF_LOCK) && got_printf_lock) {
+ got_printf_lock = 0;
+ spin_unlock(&kdb_printf_lock);
+ KDB_STATE_CLEAR(PRINTF_LOCK);
+ }
+ preempt_enable();
+ if (do_longjmp)
+#ifdef kdba_setjmp
+ kdba_longjmp(&kdbjmpbuf[smp_processor_id()], 1)
+#endif /* kdba_setjmp */
+ ;
+}
+
+/*
+ * kdb_io_init
+ *
+ * Initialize kernel debugger output environment.
+ *
+ * Parameters:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ * Select a console device.
+ */
+
+void __init
+kdb_io_init(void)
+{
+#ifndef CONFIG_SPARC64 /* we don't register serial consoles in time */
+ /*
+ * Select a console.
+ */
+ struct console *c = console_drivers;
+
+ while (c) {
+ if ((c->flags & CON_CONSDEV)) {
+ kdbcons = c;
+ break;
+ }
+ c = c->next;
+ }
+
+ if (kdbcons == NULL) {
+ printk(KERN_ERR "kdb: Initialization failed - no console. kdb is disabled.\n");
+ KDB_FLAG_SET(NO_CONSOLE);
+ kdb_on = 0;
+ }
+ kdb_input_flush();
+#endif
+ return;
+}
+
+EXPORT_SYMBOL(kdb_read);
--- /dev/null
+/*
+ * Kernel Debugger Architecture Independent Main Code
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (C) 2000 Stephane Eranian <eranian@hpl.hp.com>
+ * Xscale (R) modifications copyright (C) 2003 Intel Corporation.
+ */
+
+/*
+ * Updated for Xscale (R) architecture support
+ * Eddie Dong <eddie.dong@intel.com> 8 Jan 03
+ */
+
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/sched.h>
+#include <linux/sysrq.h>
+#include <linux/smp.h>
+#include <linux/utsname.h>
+#include <linux/vmalloc.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/kallsyms.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <linux/notifier.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/nmi.h>
+#include <linux/ptrace.h>
+#include <linux/sysctl.h>
+#if defined(CONFIG_LKCD_DUMP) || defined(CONFIG_LKCD_DUMP_MODULE)
+#include <linux/dump.h>
+#endif
+#include <linux/cpu.h>
+
+#include <asm/system.h>
+#include <asm/kdebug.h>
+
+/*
+ * Kernel debugger state flags
+ */
+volatile int kdb_flags;
+atomic_t kdb_8250;
+
+/*
+ * kdb_lock protects updates to kdb_initial_cpu. Used to
+ * single thread processors through the kernel debugger.
+ */
+static DEFINE_SPINLOCK(kdb_lock);
+volatile int kdb_initial_cpu = -1; /* cpu number that owns kdb */
+int kdb_seqno = 2; /* how many times kdb has been entered */
+
+volatile int kdb_nextline = 1;
+static volatile int kdb_new_cpu; /* Which cpu to switch to */
+
+volatile int kdb_state[NR_CPUS]; /* Per cpu state */
+
+const struct task_struct *kdb_current_task;
+EXPORT_SYMBOL(kdb_current_task);
+struct pt_regs *kdb_current_regs;
+
+#ifdef CONFIG_KDB_OFF
+int kdb_on = 0; /* Default is off */
+#else
+int kdb_on = 1; /* Default is on */
+#endif /* CONFIG_KDB_OFF */
+
+const char *kdb_diemsg;
+static int kdb_go_count;
+#ifdef CONFIG_KDB_CONTINUE_CATASTROPHIC
+static unsigned int kdb_continue_catastrophic = CONFIG_KDB_CONTINUE_CATASTROPHIC;
+#else
+static unsigned int kdb_continue_catastrophic = 0;
+#endif
+
+#ifdef kdba_setjmp
+ /*
+ * Must have a setjmp buffer per CPU. Switching cpus will
+ * cause the jump buffer to be setup for the new cpu, and
+ * subsequent switches (and pager aborts) will use the
+ * appropriate per-processor values.
+ */
+kdb_jmp_buf *kdbjmpbuf;
+#endif /* kdba_setjmp */
+
+ /*
+ * kdb_commands describes the available commands.
+ */
+static kdbtab_t *kdb_commands;
+static int kdb_max_commands;
+
+typedef struct _kdbmsg {
+ int km_diag; /* kdb diagnostic */
+ char *km_msg; /* Corresponding message text */
+} kdbmsg_t;
+
+#define KDBMSG(msgnum, text) \
+ { KDB_##msgnum, text }
+
+static kdbmsg_t kdbmsgs[] = {
+ KDBMSG(NOTFOUND,"Command Not Found"),
+ KDBMSG(ARGCOUNT, "Improper argument count, see usage."),
+ KDBMSG(BADWIDTH, "Illegal value for BYTESPERWORD use 1, 2, 4 or 8, 8 is only allowed on 64 bit systems"),
+ KDBMSG(BADRADIX, "Illegal value for RADIX use 8, 10 or 16"),
+ KDBMSG(NOTENV, "Cannot find environment variable"),
+ KDBMSG(NOENVVALUE, "Environment variable should have value"),
+ KDBMSG(NOTIMP, "Command not implemented"),
+ KDBMSG(ENVFULL, "Environment full"),
+ KDBMSG(ENVBUFFULL, "Environment buffer full"),
+ KDBMSG(TOOMANYBPT, "Too many breakpoints defined"),
+#ifdef CONFIG_CPU_XSCALE
+ KDBMSG(TOOMANYDBREGS, "More breakpoints than ibcr registers defined"),
+#else
+ KDBMSG(TOOMANYDBREGS, "More breakpoints than db registers defined"),
+#endif
+ KDBMSG(DUPBPT, "Duplicate breakpoint address"),
+ KDBMSG(BPTNOTFOUND, "Breakpoint not found"),
+ KDBMSG(BADMODE, "Invalid IDMODE"),
+ KDBMSG(BADINT, "Illegal numeric value"),
+ KDBMSG(INVADDRFMT, "Invalid symbolic address format"),
+ KDBMSG(BADREG, "Invalid register name"),
+ KDBMSG(BADCPUNUM, "Invalid cpu number"),
+ KDBMSG(BADLENGTH, "Invalid length field"),
+ KDBMSG(NOBP, "No Breakpoint exists"),
+ KDBMSG(BADADDR, "Invalid address"),
+};
+#undef KDBMSG
+
+static const int __nkdb_err = sizeof(kdbmsgs) / sizeof(kdbmsg_t);
+
+
+/*
+ * Initial environment. This is all kept static and local to
+ * this file. We don't want to rely on the memory allocation
+ * mechanisms in the kernel, so we use a very limited allocate-only
+ * heap for new and altered environment variables. The entire
+ * environment is limited to a fixed number of entries (add more
+ * to __env[] if required) and a fixed amount of heap (add more to
+ * KDB_ENVBUFSIZE if required).
+ */
+
+static char *__env[] = {
+#if defined(CONFIG_SMP)
+ "PROMPT=[%d]kdb> ",
+ "MOREPROMPT=[%d]more> ",
+#else
+ "PROMPT=kdb> ",
+ "MOREPROMPT=more> ",
+#endif
+ "RADIX=16",
+ "LINES=24",
+ "COLUMNS=80",
+ "MDCOUNT=8", /* lines of md output */
+ "BTARGS=5", /* 5 possible args in bt */
+ KDB_PLATFORM_ENV,
+ "DTABCOUNT=30",
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+ (char *)0,
+};
+
+static const int __nenv = (sizeof(__env) / sizeof(char *));
+
+/*
+ * kdb_serial_str is the sequence that the user must enter on a serial
+ * console to invoke kdb. It can be a single character such as "\001"
+ * (control-A) or multiple characters such as "\eKDB". NOTE: All except the
+ * last character are passed through to the application reading from the serial
+ * console.
+ *
+ * I tried to make the sequence a CONFIG_ option but most of CML1 cannot cope
+ * with '\' in strings. CML2 would have been able to do it but we lost CML2.
+ * KAO.
+ */
+const char kdb_serial_str[] = "\001";
+EXPORT_SYMBOL(kdb_serial_str);
+
+struct task_struct *
+kdb_curr_task(int cpu)
+{
+ struct task_struct *p = curr_task(cpu);
+#ifdef _TIF_MCA_INIT
+ struct kdb_running_process *krp = kdb_running_process + cpu;
+ if ((p->thread_info->flags & _TIF_MCA_INIT) && krp->p)
+ p = krp->p;
+#endif
+ return p;
+}
+
+/*
+ * kdbgetenv
+ *
+ * This function will return the character string value of
+ * an environment variable.
+ *
+ * Parameters:
+ * match A character string representing an environment variable.
+ * Outputs:
+ * None.
+ * Returns:
+ * NULL No environment variable matches 'match'
+ * char* Pointer to string value of environment variable.
+ * Locking:
+ * No locking considerations required.
+ * Remarks:
+ */
+char *
+kdbgetenv(const char *match)
+{
+ char **ep = __env;
+ int matchlen = strlen(match);
+ int i;
+
+ for(i=0; i<__nenv; i++) {
+ char *e = *ep++;
+
+ if (!e) continue;
+
+ if ((strncmp(match, e, matchlen) == 0)
+ && ((e[matchlen] == '\0')
+ ||(e[matchlen] == '='))) {
+ char *cp = strchr(e, '=');
+ return (cp ? ++cp :"");
+ }
+ }
+ return NULL;
+}
+
+/*
+ * kdballocenv
+ *
+ * This function is used to allocate bytes for environment entries.
+ *
+ * Parameters:
+ * match A character string representing a numeric value
+ * Outputs:
+ * *value the unsigned long represntation of the env variable 'match'
+ * Returns:
+ * Zero on success, a kdb diagnostic on failure.
+ * Locking:
+ * No locking considerations required. Must be called with all
+ * processors halted.
+ * Remarks:
+ * We use a static environment buffer (envbuffer) to hold the values
+ * of dynamically generated environment variables (see kdb_set). Buffer
+ * space once allocated is never free'd, so over time, the amount of space
+ * (currently 512 bytes) will be exhausted if env variables are changed
+ * frequently.
+ */
+static char *
+kdballocenv(size_t bytes)
+{
+#define KDB_ENVBUFSIZE 512
+ static char envbuffer[KDB_ENVBUFSIZE];
+ static int envbufsize;
+ char *ep = NULL;
+
+ if ((KDB_ENVBUFSIZE - envbufsize) >= bytes) {
+ ep = &envbuffer[envbufsize];
+ envbufsize += bytes;
+ }
+ return ep;
+}
+
+/*
+ * kdbgetulenv
+ *
+ * This function will return the value of an unsigned long-valued
+ * environment variable.
+ *
+ * Parameters:
+ * match A character string representing a numeric value
+ * Outputs:
+ * *value the unsigned long represntation of the env variable 'match'
+ * Returns:
+ * Zero on success, a kdb diagnostic on failure.
+ * Locking:
+ * No locking considerations required.
+ * Remarks:
+ */
+
+static int
+kdbgetulenv(const char *match, unsigned long *value)
+{
+ int kdbgetularg(const char *arg, unsigned long *value);
+ char *ep;
+
+ ep = kdbgetenv(match);
+ if (!ep) return KDB_NOTENV;
+ if (strlen(ep) == 0) return KDB_NOENVVALUE;
+ return kdbgetularg(ep, value);
+}
+
+/*
+ * kdbgetintenv
+ *
+ * This function will return the value of an integer-valued
+ * environment variable.
+ *
+ * Parameters:
+ * match A character string representing an integer-valued env variable
+ * Outputs:
+ * *value the integer representation of the environment variable 'match'
+ * Returns:
+ * Zero on success, a kdb diagnostic on failure.
+ * Locking:
+ * No locking considerations required.
+ * Remarks:
+ */
+
+int
+kdbgetintenv(const char *match, int *value) {
+ unsigned long val;
+ int diag;
+
+ diag = kdbgetulenv(match, &val);
+ if (!diag) {
+ *value = (int) val;
+ }
+ return diag;
+}
+
+/*
+ * kdbgetularg
+ *
+ * This function will convert a numeric string
+ * into an unsigned long value.
+ *
+ * Parameters:
+ * arg A character string representing a numeric value
+ * Outputs:
+ * *value the unsigned long represntation of arg.
+ * Returns:
+ * Zero on success, a kdb diagnostic on failure.
+ * Locking:
+ * No locking considerations required.
+ * Remarks:
+ */
+
+int
+kdbgetularg(const char *arg, unsigned long *value)
+{
+ char *endp, *endp16;
+ unsigned long val, val16;
+
+ /*
+ * Interpret leading '0' to mean hexadecimal, not octal.
+ * Skip 'x', which simple_strtoul disallows if base given.
+ */
+ if (*arg == '0') {
+ if (arg[1] == 'x')
+ arg += 2;
+ endp = (char *)arg;
+ val = 0;
+ } else
+ val = simple_strtoul(arg, &endp, 10);
+
+ val16 = simple_strtoul(arg, &endp16, 16);
+
+ /*
+ * If the argument contains any hexadecimal digits,
+ * or if it is 8 or more digits long, assume hexadecimal.
+ */
+ if (endp16 > endp || endp16 >= arg + 8) {
+ endp = endp16;
+ val = val16;
+ }
+
+ /*
+ * Reject empty or overflowed or unterminated argument.
+ */
+ if (endp <= arg ||
+ endp > arg + 2*sizeof(unsigned long) ||
+ (*endp && !isspace(*endp)))
+ return KDB_BADINT;
+
+ *value = val;
+ return 0;
+}
+
+/*
+ * kdb_set
+ *
+ * This function implements the 'set' command. Alter an existing
+ * environment variable or create a new one.
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ */
+
+static int
+kdb_set(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int i;
+ char *ep;
+ size_t varlen, vallen;
+
+ /*
+ * we can be invoked two ways:
+ * set var=value argv[1]="var", argv[2]="value"
+ * set var = value argv[1]="var", argv[2]="=", argv[3]="value"
+ * - if the latter, shift 'em down.
+ */
+ if (argc == 3) {
+ argv[2] = argv[3];
+ argc--;
+ }
+
+ if (argc != 2)
+ return KDB_ARGCOUNT;
+
+ /*
+ * Check for internal variables
+ */
+ if (strcmp(argv[1], "KDBDEBUG") == 0) {
+ unsigned long debugflags;
+ int diag = kdbgetularg(argv[2], &debugflags);
+ if (diag || (debugflags & ~KDB_DEBUG_FLAG_MASK)) {
+ kdb_printf("kdb: illegal debug flags '%s'\n",
+ argv[2]);
+ return 0;
+ }
+ kdb_flags = (kdb_flags & ~(KDB_DEBUG_FLAG_MASK << KDB_DEBUG_FLAG_SHIFT))
+ | (debugflags << KDB_DEBUG_FLAG_SHIFT);
+
+ return 0;
+ }
+
+ /*
+ * Tokenizer squashed the '=' sign. argv[1] is variable
+ * name, argv[2] = value.
+ */
+ varlen = strlen(argv[1]);
+ vallen = strlen(argv[2]);
+ ep = kdballocenv(varlen + vallen + 2);
+ if (ep == (char *)0)
+ return KDB_ENVBUFFULL;
+
+ sprintf(ep, "%s=%s", argv[1], argv[2]);
+
+ ep[varlen+vallen+1]='\0';
+
+ for(i=0; i<__nenv; i++) {
+ if (__env[i]
+ && ((strncmp(__env[i], argv[1], varlen)==0)
+ && ((__env[i][varlen] == '\0')
+ || (__env[i][varlen] == '=')))) {
+ __env[i] = ep;
+ return 0;
+ }
+ }
+
+ /*
+ * Wasn't existing variable. Fit into slot.
+ */
+ for(i=0; i<__nenv-1; i++) {
+ if (__env[i] == (char *)0) {
+ __env[i] = ep;
+ return 0;
+ }
+ }
+
+ return KDB_ENVFULL;
+}
+
+/*
+ * kdbgetaddrarg
+ *
+ * This function is responsible for parsing an
+ * address-expression and returning the value of
+ * the expression, symbol name, and offset to the caller.
+ *
+ * The argument may consist of a numeric value (decimal or
+ * hexidecimal), a symbol name, a register name (preceeded
+ * by the percent sign), an environment variable with a numeric
+ * value (preceeded by a dollar sign) or a simple arithmetic
+ * expression consisting of a symbol name, +/-, and a numeric
+ * constant value (offset).
+ *
+ * Parameters:
+ * argc - count of arguments in argv
+ * argv - argument vector
+ * *nextarg - index to next unparsed argument in argv[]
+ * regs - Register state at time of KDB entry
+ * Outputs:
+ * *value - receives the value of the address-expression
+ * *offset - receives the offset specified, if any
+ * *name - receives the symbol name, if any
+ * *nextarg - index to next unparsed argument in argv[]
+ *
+ * Returns:
+ * zero is returned on success, a kdb diagnostic code is
+ * returned on error.
+ *
+ * Locking:
+ * No locking requirements.
+ *
+ * Remarks:
+ *
+ */
+
+int
+kdbgetaddrarg(int argc, const char **argv, int *nextarg,
+ kdb_machreg_t *value, long *offset,
+ char **name, struct pt_regs *regs)
+{
+ kdb_machreg_t addr;
+ long off = 0;
+ int positive;
+ int diag;
+ int found = 0;
+ char *symname;
+ char symbol = '\0';
+ char *cp;
+ kdb_symtab_t symtab;
+
+ /*
+ * Process arguments which follow the following syntax:
+ *
+ * symbol | numeric-address [+/- numeric-offset]
+ * %register
+ * $environment-variable
+ */
+
+ if (*nextarg > argc) {
+ return KDB_ARGCOUNT;
+ }
+
+ symname = (char *)argv[*nextarg];
+
+ /*
+ * If there is no whitespace between the symbol
+ * or address and the '+' or '-' symbols, we
+ * remember the character and replace it with a
+ * null so the symbol/value can be properly parsed
+ */
+ if ((cp = strpbrk(symname, "+-")) != NULL) {
+ symbol = *cp;
+ *cp++ = '\0';
+ }
+
+ if (symname[0] == '$') {
+ diag = kdbgetulenv(&symname[1], &addr);
+ if (diag)
+ return diag;
+ } else if (symname[0] == '%') {
+ diag = kdba_getregcontents(&symname[1], kdb_current_regs, &addr);
+ if (diag)
+ return diag;
+ } else {
+ found = kdbgetsymval(symname, &symtab);
+ if (found) {
+ addr = symtab.sym_start;
+ } else {
+ diag = kdbgetularg(argv[*nextarg], &addr);
+ if (diag)
+ return diag;
+ }
+ }
+
+ if (!found)
+ found = kdbnearsym(addr, &symtab);
+
+ (*nextarg)++;
+
+ if (name)
+ *name = symname;
+ if (value)
+ *value = addr;
+ if (offset && name && *name)
+ *offset = addr - symtab.sym_start;
+
+ if ((*nextarg > argc)
+ && (symbol == '\0'))
+ return 0;
+
+ /*
+ * check for +/- and offset
+ */
+
+ if (symbol == '\0') {
+ if ((argv[*nextarg][0] != '+')
+ && (argv[*nextarg][0] != '-')) {
+ /*
+ * Not our argument. Return.
+ */
+ return 0;
+ } else {
+ positive = (argv[*nextarg][0] == '+');
+ (*nextarg)++;
+ }
+ } else
+ positive = (symbol == '+');
+
+ /*
+ * Now there must be an offset!
+ */
+ if ((*nextarg > argc)
+ && (symbol == '\0')) {
+ return KDB_INVADDRFMT;
+ }
+
+ if (!symbol) {
+ cp = (char *)argv[*nextarg];
+ (*nextarg)++;
+ }
+
+ diag = kdbgetularg(cp, &off);
+ if (diag)
+ return diag;
+
+ if (!positive)
+ off = -off;
+
+ if (offset)
+ *offset += off;
+
+ if (value)
+ *value += off;
+
+ return 0;
+}
+
+static void
+kdb_cmderror(int diag)
+{
+ int i;
+
+ if (diag >= 0) {
+ kdb_printf("no error detected\n");
+ return;
+ }
+
+ for(i=0; i<__nkdb_err; i++) {
+ if (kdbmsgs[i].km_diag == diag) {
+ kdb_printf("diag: %d: %s\n", diag, kdbmsgs[i].km_msg);
+ return;
+ }
+ }
+
+ kdb_printf("Unknown diag %d\n", -diag);
+}
+
+/*
+ * kdb_defcmd, kdb_defcmd2
+ *
+ * This function implements the 'defcmd' command which defines one
+ * command as a set of other commands, terminated by endefcmd.
+ * kdb_defcmd processes the initial 'defcmd' command, kdb_defcmd2
+ * is invoked from kdb_parse for the following commands until
+ * 'endefcmd'.
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ */
+
+struct defcmd_set {
+ int count;
+ int usable;
+ char *name;
+ char *usage;
+ char *help;
+ char **command;
+};
+static struct defcmd_set *defcmd_set;
+static int defcmd_set_count;
+static int defcmd_in_progress;
+
+/* Forward references */
+static int kdb_exec_defcmd(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+
+static int
+kdb_defcmd2(const char *cmdstr, const char *argv0)
+{
+ struct defcmd_set *s = defcmd_set + defcmd_set_count - 1;
+ char **save_command = s->command;
+ if (strcmp(argv0, "endefcmd") == 0) {
+ defcmd_in_progress = 0;
+ if (!s->count)
+ s->usable = 0;
+ if (s->usable)
+ kdb_register(s->name, kdb_exec_defcmd, s->usage, s->help, 0);
+ return 0;
+ }
+ if (!s->usable)
+ return KDB_NOTIMP;
+ s->command = kmalloc((s->count + 1) * sizeof(*(s->command)), GFP_ATOMIC);
+ if (!s->command) {
+ kdb_printf("Could not allocate new kdb_defcmd table for %s\n", cmdstr);
+ s->usable = 0;
+ return KDB_NOTIMP;
+ }
+ memcpy(s->command, save_command, s->count * sizeof(*(s->command)));
+ s->command[s->count++] = kstrdup(cmdstr, GFP_ATOMIC);
+ kfree(save_command);
+ return 0;
+}
+
+static int
+kdb_defcmd(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ struct defcmd_set *save_defcmd_set = defcmd_set, *s;
+ if (defcmd_in_progress) {
+ kdb_printf("kdb: nested defcmd detected, assuming missing endefcmd\n");
+ kdb_defcmd2("endefcmd", "endefcmd");
+ }
+ if (argc == 0) {
+ int i;
+ for (s = defcmd_set; s < defcmd_set + defcmd_set_count; ++s) {
+ kdb_printf("defcmd %s \"%s\" \"%s\"\n", s->name, s->usage, s->help);
+ for (i = 0; i < s->count; ++i)
+ kdb_printf("%s", s->command[i]);
+ kdb_printf("endefcmd\n");
+ }
+ return 0;
+ }
+ if (argc != 3)
+ return KDB_ARGCOUNT;
+ defcmd_set = kmalloc((defcmd_set_count + 1) * sizeof(*defcmd_set), GFP_ATOMIC);
+ if (!defcmd_set) {
+ kdb_printf("Could not allocate new defcmd_set entry for %s\n", argv[1]);
+ defcmd_set = save_defcmd_set;
+ return KDB_NOTIMP;
+ }
+ memcpy(defcmd_set, save_defcmd_set, defcmd_set_count * sizeof(*defcmd_set));
+ kfree(save_defcmd_set);
+ s = defcmd_set + defcmd_set_count;
+ memset(s, 0, sizeof(*s));
+ s->usable = 1;
+ s->name = kstrdup(argv[1], GFP_ATOMIC);
+ s->usage = kstrdup(argv[2], GFP_ATOMIC);
+ s->help = kstrdup(argv[3], GFP_ATOMIC);
+ if (s->usage[0] == '"') {
+ strcpy(s->usage, s->usage+1);
+ s->usage[strlen(s->usage)-1] = '\0';
+ }
+ if (s->help[0] == '"') {
+ strcpy(s->help, s->help+1);
+ s->help[strlen(s->help)-1] = '\0';
+ }
+ ++defcmd_set_count;
+ defcmd_in_progress = 1;
+ return 0;
+}
+
+/*
+ * kdb_exec_defcmd
+ *
+ * Execute the set of commands associated with this defcmd name.
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ */
+
+static int
+kdb_exec_defcmd(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int i, ret;
+ struct defcmd_set *s;
+ if (argc != 0)
+ return KDB_ARGCOUNT;
+ for (s = defcmd_set, i = 0; i < defcmd_set_count; ++i, ++s) {
+ if (strcmp(s->name, argv[0]) == 0)
+ break;
+ }
+ if (i == defcmd_set_count) {
+ kdb_printf("kdb_exec_defcmd: could not find commands for %s\n", argv[0]);
+ return KDB_NOTIMP;
+ }
+ for (i = 0; i < s->count; ++i) {
+ /* Recursive use of kdb_parse, do not use argv after this point */
+ argv = NULL;
+ kdb_printf("[%s]kdb> %s\n", s->name, s->command[i]);
+ if ((ret = kdb_parse(s->command[i], regs)))
+ return ret;
+ }
+ return 0;
+}
+
+/* Command history */
+#define KDB_CMD_HISTORY_COUNT 32
+#define CMD_BUFLEN 200 /* kdb_printf: max printline size == 256 */
+static unsigned int cmd_head=0, cmd_tail=0;
+static unsigned int cmdptr;
+static char cmd_hist[KDB_CMD_HISTORY_COUNT][CMD_BUFLEN];
+static char cmd_cur[CMD_BUFLEN];
+
+/*
+ * kdb_parse
+ *
+ * Parse the command line, search the command table for a
+ * matching command and invoke the command function.
+ * This function may be called recursively, if it is, the second call
+ * will overwrite argv and cbuf. It is the caller's responsibility to
+ * save their argv if they recursively call kdb_parse().
+ *
+ * Parameters:
+ * cmdstr The input command line to be parsed.
+ * regs The registers at the time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero for success, a kdb diagnostic if failure.
+ * Locking:
+ * None.
+ * Remarks:
+ * Limited to 20 tokens.
+ *
+ * Real rudimentary tokenization. Basically only whitespace
+ * is considered a token delimeter (but special consideration
+ * is taken of the '=' sign as used by the 'set' command).
+ *
+ * The algorithm used to tokenize the input string relies on
+ * there being at least one whitespace (or otherwise useless)
+ * character between tokens as the character immediately following
+ * the token is altered in-place to a null-byte to terminate the
+ * token string.
+ */
+
+#define MAXARGC 20
+
+int
+kdb_parse(const char *cmdstr, struct pt_regs *regs)
+{
+ static char *argv[MAXARGC];
+ static int argc = 0;
+ static char cbuf[CMD_BUFLEN+2];
+ const char *cp;
+ char *cpp, quoted;
+ kdbtab_t *tp;
+ int i, escaped, ignore_errors = 0;
+
+ /*
+ * First tokenize the command string.
+ */
+ cp = cmdstr;
+
+ if (KDB_FLAG(CMD_INTERRUPT)) {
+ /* Previous command was interrupted, newline must not repeat the command */
+ KDB_FLAG_CLEAR(CMD_INTERRUPT);
+ argc = 0; /* no repeat */
+ }
+
+ if (*cp != '\n' && *cp != '\0') {
+ argc = 0;
+ cpp = cbuf;
+ while (*cp) {
+ /* skip whitespace */
+ while (isspace(*cp)) cp++;
+ if ((*cp == '\0') || (*cp == '\n') || (*cp == '#' && !defcmd_in_progress))
+ break;
+ if (cpp >= cbuf + CMD_BUFLEN) {
+ kdb_printf("kdb_parse: command buffer overflow, command ignored\n%s\n", cmdstr);
+ return KDB_NOTFOUND;
+ }
+ if (argc >= MAXARGC - 1) {
+ kdb_printf("kdb_parse: too many arguments, command ignored\n%s\n", cmdstr);
+ return KDB_NOTFOUND;
+ }
+ argv[argc++] = cpp;
+ escaped = 0;
+ quoted = '\0';
+ /* Copy to next unquoted and unescaped whitespace or '=' */
+ while (*cp && *cp != '\n' && (escaped || quoted || !isspace(*cp))) {
+ if (cpp >= cbuf + CMD_BUFLEN)
+ break;
+ if (escaped) {
+ escaped = 0;
+ *cpp++ = *cp++;
+ continue;
+ }
+ if (*cp == '\\') {
+ escaped = 1;
+ ++cp;
+ continue;
+ }
+ if (*cp == quoted) {
+ quoted = '\0';
+ } else if (*cp == '\'' || *cp == '"') {
+ quoted = *cp;
+ }
+ if ((*cpp = *cp++) == '=' && !quoted)
+ break;
+ ++cpp;
+ }
+ *cpp++ = '\0'; /* Squash a ws or '=' character */
+ }
+ }
+ if (!argc)
+ return 0;
+ if (defcmd_in_progress) {
+ int result = kdb_defcmd2(cmdstr, argv[0]);
+ if (!defcmd_in_progress) {
+ argc = 0; /* avoid repeat on endefcmd */
+ *(argv[0]) = '\0';
+ }
+ return result;
+ }
+ if (argv[0][0] == '-' && argv[0][1] && (argv[0][1] < '0' || argv[0][1] > '9')) {
+ ignore_errors = 1;
+ ++argv[0];
+ }
+
+ for(tp=kdb_commands, i=0; i < kdb_max_commands; i++,tp++) {
+ if (tp->cmd_name) {
+ /*
+ * If this command is allowed to be abbreviated,
+ * check to see if this is it.
+ */
+
+ if (tp->cmd_minlen
+ && (strlen(argv[0]) <= tp->cmd_minlen)) {
+ if (strncmp(argv[0],
+ tp->cmd_name,
+ tp->cmd_minlen) == 0) {
+ break;
+ }
+ }
+
+ if (strcmp(argv[0], tp->cmd_name)==0) {
+ break;
+ }
+ }
+ }
+
+ /*
+ * If we don't find a command by this name, see if the first
+ * two characters match md e.g. md1c20 should match md.
+ */
+ if (i==kdb_max_commands && argc>1 && strncmp(argv[0],"md",2)==0) {
+ for(tp=kdb_commands, i=0; i < kdb_max_commands; i++,tp++) {
+ if (tp->cmd_name) {
+ if (strncmp(argv[0],
+ tp->cmd_name,
+ strlen(tp->cmd_name))==0) {
+ break;
+ }
+ }
+ }
+ }
+
+ if (i < kdb_max_commands) {
+ int result;
+ KDB_STATE_SET(CMD);
+ result = (*tp->cmd_func)(argc-1,
+ (const char**)argv,
+ (const char**)__env,
+ regs);
+ if (result && ignore_errors && result > KDB_CMD_GO)
+ result = 0;
+ KDB_STATE_CLEAR(CMD);
+ switch (tp->cmd_repeat) {
+ case KDB_REPEAT_NONE:
+ argc = 0;
+ if (argv[0])
+ *(argv[0]) = '\0';
+ break;
+ case KDB_REPEAT_NO_ARGS:
+ argc = 1;
+ if (argv[1])
+ *(argv[1]) = '\0';
+ break;
+ case KDB_REPEAT_WITH_ARGS:
+ break;
+ }
+ return result;
+ }
+
+ /*
+ * If the input with which we were presented does not
+ * map to an existing command, attempt to parse it as an
+ * address argument and display the result. Useful for
+ * obtaining the address of a variable, or the nearest symbol
+ * to an address contained in a register.
+ */
+ if (argc == 1) {
+ kdb_machreg_t value;
+ char *name = NULL;
+ long offset;
+ int nextarg = 0;
+
+ if (kdbgetaddrarg(0, (const char **)argv, &nextarg,
+ &value, &offset, &name, regs)) {
+ return KDB_NOTFOUND;
+ }
+
+ kdb_printf("%s = ", argv[0]);
+ kdb_symbol_print(value, NULL, KDB_SP_DEFAULT);
+ kdb_printf("\n");
+ return 0;
+ }
+
+ return KDB_NOTFOUND;
+}
+
+
+static int
+handle_ctrl_cmd(char *cmd)
+{
+#define CTRL_P 16
+#define CTRL_N 14
+
+ /* initial situation */
+ if (cmd_head == cmd_tail) return 0;
+
+ switch(*cmd) {
+ case CTRL_P:
+ if (cmdptr != cmd_tail)
+ cmdptr = (cmdptr-1) % KDB_CMD_HISTORY_COUNT;
+ strncpy(cmd_cur, cmd_hist[cmdptr], CMD_BUFLEN);
+ return 1;
+ case CTRL_N:
+ if (cmdptr != cmd_head)
+ cmdptr = (cmdptr+1) % KDB_CMD_HISTORY_COUNT;
+ strncpy(cmd_cur, cmd_hist[cmdptr], CMD_BUFLEN);
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * kdb_do_dump
+ *
+ * Call the dump() function if the kernel is configured for LKCD.
+ * Inputs:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * None. dump() may or may not return.
+ * Locking:
+ * none.
+ * Remarks:
+ */
+
+static void
+kdb_do_dump(struct pt_regs *regs)
+{
+#if defined(CONFIG_LKCD_DUMP) || defined(CONFIG_LKCD_DUMP_MODULE)
+ kdb_printf("Forcing dump (if configured)\n");
+ console_loglevel = 8; /* to see the dump messages */
+ dump("kdb_do_dump", regs);
+#endif
+}
+
+/*
+ * kdb_reboot
+ *
+ * This function implements the 'reboot' command. Reboot the system
+ * immediately.
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * Shouldn't return from this function.
+ */
+
+static int
+kdb_reboot(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ emergency_restart();
+ kdb_printf("Hmm, kdb_reboot did not reboot, spinning here\n");
+ while (1)
+ cpu_relax();
+ /* NOTREACHED */
+ return 0;
+}
+
+static int
+kdb_quiet(int reason)
+{
+ return (reason == KDB_REASON_CPU_UP || reason == KDB_REASON_SILENT);
+}
+
+/*
+ * kdb_local
+ *
+ * The main code for kdb. This routine is invoked on a specific
+ * processor, it is not global. The main kdb() routine ensures
+ * that only one processor at a time is in this routine. This
+ * code is called with the real reason code on the first entry
+ * to a kdb session, thereafter it is called with reason SWITCH,
+ * even if the user goes back to the original cpu.
+ *
+ * Inputs:
+ * reason The reason KDB was invoked
+ * error The hardware-defined error code
+ * regs The exception frame at time of fault/breakpoint. NULL
+ * for reason SILENT or CPU_UP, otherwise valid.
+ * db_result Result code from the break or debug point.
+ * Returns:
+ * 0 KDB was invoked for an event which it wasn't responsible
+ * 1 KDB handled the event for which it was invoked.
+ * KDB_CMD_GO User typed 'go'.
+ * KDB_CMD_CPU User switched to another cpu.
+ * KDB_CMD_SS Single step.
+ * KDB_CMD_SSB Single step until branch.
+ * Locking:
+ * none
+ * Remarks:
+ * none
+ */
+
+extern char kdb_prompt_str[];
+
+static int
+kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs, kdb_dbtrap_t db_result)
+{
+ char *cmdbuf;
+ int diag;
+ struct task_struct *kdb_current = kdb_curr_task(smp_processor_id());
+
+ /* If kdb has been entered for an event which has been/will be
+ * recovered then silently return. We have to get this far into kdb in
+ * order to synchronize all the cpus, typically only one cpu (monarch)
+ * knows that the event is recoverable but the other cpus (slaves) may
+ * also be driven into kdb before that decision is made by the monarch.
+ *
+ * To pause in kdb even for recoverable events, 'set RECOVERY_PAUSE 1'
+ */
+ KDB_DEBUG_STATE("kdb_local 1", reason);
+ if (reason == KDB_REASON_ENTER
+ && KDB_FLAG(RECOVERY)
+ && !KDB_FLAG(CATASTROPHIC)) {
+ int recovery_pause = 0;
+ kdbgetintenv("RECOVERY_PAUSE", &recovery_pause);
+ if (recovery_pause == 0)
+ reason = KDB_REASON_SILENT;
+ else
+ kdb_printf("%s: Recoverable error detected but"
+ " RECOVERY_PAUSE is set, staying in KDB\n",
+ __FUNCTION__);
+ }
+
+ KDB_DEBUG_STATE("kdb_local 2", reason);
+ kdb_go_count = 0;
+ if (kdb_quiet(reason)) {
+ /* no message */
+ } else if (reason == KDB_REASON_DEBUG) {
+ /* special case below */
+ } else {
+ if (reason != KDB_REASON_SWITCH)
+ kdb_printf("\n");
+ kdb_printf("Entering kdb (task 0x%p pid %d) ",
+ kdb_current, kdb_current->pid);
+#if defined(CONFIG_SMP)
+ kdb_printf("on cpu %d ", smp_processor_id());
+#endif
+ }
+
+ switch (reason) {
+ case KDB_REASON_DEBUG:
+ {
+ /*
+ * If re-entering kdb after a single step
+ * command, don't print the message.
+ */
+ switch(db_result) {
+ case KDB_DB_BPT:
+ kdb_printf("\nEntering kdb (task 0x%p pid %d) ",
+ kdb_current, kdb_current->pid);
+#if defined(CONFIG_SMP)
+ kdb_printf("on cpu %d ", smp_processor_id());
+#endif
+ kdb_printf("due to Debug @ " kdb_machreg_fmt "\n", kdba_getpc(regs));
+ break;
+ case KDB_DB_SSB:
+ /*
+ * In the midst of ssb command. Just return.
+ */
+ KDB_DEBUG_STATE("kdb_local 3", reason);
+ return KDB_CMD_SSB; /* Continue with SSB command */
+
+ break;
+ case KDB_DB_SS:
+ break;
+ case KDB_DB_SSBPT:
+ KDB_DEBUG_STATE("kdb_local 4", reason);
+ return 1; /* kdba_db_trap did the work */
+ default:
+ kdb_printf("kdb: Bad result from kdba_db_trap: %d\n",
+ db_result);
+ break;
+ }
+
+ }
+ break;
+ case KDB_REASON_ENTER:
+ if (KDB_STATE(KEYBOARD))
+ kdb_printf("due to Keyboard Entry\n");
+ else
+ kdb_printf("due to KDB_ENTER()\n");
+ break;
+ case KDB_REASON_KEYBOARD:
+ KDB_STATE_SET(KEYBOARD);
+ kdb_printf("due to Keyboard Entry\n");
+ break;
+ case KDB_REASON_ENTER_SLAVE: /* drop through, slaves only get released via cpu switch */
+ case KDB_REASON_SWITCH:
+ kdb_printf("due to cpu switch\n");
+ if (KDB_STATE(GO_SWITCH)) {
+ KDB_STATE_CLEAR(GO_SWITCH);
+ KDB_DEBUG_STATE("kdb_local 5", reason);
+ return KDB_CMD_GO;
+ }
+ break;
+ case KDB_REASON_OOPS:
+ kdb_printf("Oops: %s\n", kdb_diemsg);
+ kdb_printf("due to oops @ " kdb_machreg_fmt "\n", kdba_getpc(regs));
+ kdba_dumpregs(regs, NULL, NULL);
+ break;
+ case KDB_REASON_NMI:
+ kdb_printf("due to NonMaskable Interrupt @ " kdb_machreg_fmt "\n",
+ kdba_getpc(regs));
+ kdba_dumpregs(regs, NULL, NULL);
+ break;
+ case KDB_REASON_BREAK:
+ kdb_printf("due to Breakpoint @ " kdb_machreg_fmt "\n", kdba_getpc(regs));
+ /*
+ * Determine if this breakpoint is one that we
+ * are interested in.
+ */
+ if (db_result != KDB_DB_BPT) {
+ kdb_printf("kdb: error return from kdba_bp_trap: %d\n", db_result);
+ KDB_DEBUG_STATE("kdb_local 6", reason);
+ return 0; /* Not for us, dismiss it */
+ }
+ break;
+ case KDB_REASON_RECURSE:
+ kdb_printf("due to Recursion @ " kdb_machreg_fmt "\n", kdba_getpc(regs));
+ break;
+ case KDB_REASON_CPU_UP:
+ case KDB_REASON_SILENT:
+ KDB_DEBUG_STATE("kdb_local 7", reason);
+ if (reason == KDB_REASON_CPU_UP)
+ kdba_cpu_up();
+ return KDB_CMD_GO; /* Silent entry, silent exit */
+ break;
+ default:
+ kdb_printf("kdb: unexpected reason code: %d\n", reason);
+ KDB_DEBUG_STATE("kdb_local 8", reason);
+ return 0; /* Not for us, dismiss it */
+ }
+
+ kdba_local_arch_setup();
+
+ kdba_set_current_task(kdb_current);
+
+ while (1) {
+ /*
+ * Initialize pager context.
+ */
+ kdb_nextline = 1;
+ KDB_STATE_CLEAR(SUPPRESS);
+#ifdef kdba_setjmp
+ /*
+ * Use kdba_setjmp/kdba_longjmp to break out of
+ * the pager early and to attempt to recover from kdb errors.
+ */
+ KDB_STATE_CLEAR(LONGJMP);
+ if (kdbjmpbuf) {
+ if (kdba_setjmp(&kdbjmpbuf[smp_processor_id()])) {
+ /* Command aborted (usually in pager) */
+ continue;
+ }
+ else
+ KDB_STATE_SET(LONGJMP);
+ }
+#endif /* kdba_setjmp */
+
+ cmdbuf = cmd_cur;
+ *cmdbuf = '\0';
+ *(cmd_hist[cmd_head])='\0';
+
+ if (KDB_FLAG(ONLY_DO_DUMP)) {
+ /* kdb is off but a catastrophic error requires a dump.
+ * Take the dump and reboot.
+ * Turn on logging so the kdb output appears in the log
+ * buffer in the dump.
+ */
+ const char *setargs[] = { "set", "LOGGING", "1" };
+ kdb_set(2, setargs, NULL, regs);
+ kdb_do_dump(regs);
+ kdb_reboot(0, NULL, NULL, regs);
+ /*NOTREACHED*/
+ }
+
+do_full_getstr:
+#if defined(CONFIG_SMP)
+ snprintf(kdb_prompt_str, CMD_BUFLEN, kdbgetenv("PROMPT"), smp_processor_id());
+#else
+ snprintf(kdb_prompt_str, CMD_BUFLEN, kdbgetenv("PROMPT"));
+#endif
+ if (defcmd_in_progress)
+ strncat(kdb_prompt_str, "[defcmd]", CMD_BUFLEN);
+
+ /*
+ * Fetch command from keyboard
+ */
+ cmdbuf = kdb_getstr(cmdbuf, CMD_BUFLEN, kdb_prompt_str);
+ if (*cmdbuf != '\n') {
+ if (*cmdbuf < 32) {
+ if(cmdptr == cmd_head) {
+ strncpy(cmd_hist[cmd_head], cmd_cur, CMD_BUFLEN);
+ *(cmd_hist[cmd_head]+strlen(cmd_hist[cmd_head])-1) = '\0';
+ }
+ if(!handle_ctrl_cmd(cmdbuf))
+ *(cmd_cur+strlen(cmd_cur)-1) = '\0';
+ cmdbuf = cmd_cur;
+ goto do_full_getstr;
+ }
+ else
+ strncpy(cmd_hist[cmd_head], cmd_cur, CMD_BUFLEN);
+
+ cmd_head = (cmd_head+1) % KDB_CMD_HISTORY_COUNT;
+ if (cmd_head == cmd_tail) cmd_tail = (cmd_tail+1) % KDB_CMD_HISTORY_COUNT;
+
+ }
+
+ cmdptr = cmd_head;
+ diag = kdb_parse(cmdbuf, regs);
+ if (diag == KDB_NOTFOUND) {
+ kdb_printf("Unknown kdb command: %s", cmdbuf);
+ diag = 0;
+ }
+ if (diag == KDB_CMD_GO
+ || diag == KDB_CMD_CPU
+ || diag == KDB_CMD_SS
+ || diag == KDB_CMD_SSB)
+ break;
+
+ if (diag)
+ kdb_cmderror(diag);
+ }
+
+ kdba_local_arch_cleanup();
+
+ KDB_DEBUG_STATE("kdb_local 9", diag);
+ return diag;
+}
+
+/*
+ * kdb_print_state
+ *
+ * Print the state data for the current processor for debugging.
+ *
+ * Inputs:
+ * text Identifies the debug point
+ * value Any integer value to be printed, e.g. reason code.
+ * Returns:
+ * None.
+ * Locking:
+ * none
+ * Remarks:
+ * none
+ */
+
+void kdb_print_state(const char *text, int value)
+{
+ kdb_printf("state: %s cpu %d value %d initial %d state %x\n",
+ text, smp_processor_id(), value, kdb_initial_cpu, kdb_state[smp_processor_id()]);
+}
+
+/*
+ * kdb_previous_event
+ *
+ * Return a count of cpus that are leaving kdb, i.e. the number
+ * of processors that are still handling the previous kdb event.
+ *
+ * Inputs:
+ * None.
+ * Returns:
+ * Count of cpus in previous event.
+ * Locking:
+ * none
+ * Remarks:
+ * none
+ */
+
+static int
+kdb_previous_event(void)
+{
+ int i, leaving = 0;
+ for (i = 0; i < NR_CPUS; ++i) {
+ if (KDB_STATE_CPU(LEAVING, i))
+ ++leaving;
+ }
+ return leaving;
+}
+
+/*
+ * kdb_wait_for_cpus
+ *
+ * Invoked once at the start of a kdb event, from the controlling cpu. Wait a
+ * short period for the other cpus to enter kdb state.
+ *
+ * Inputs:
+ * none
+ * Returns:
+ * none
+ * Locking:
+ * none
+ * Remarks:
+ * none
+ */
+
+int kdb_wait_for_cpus_secs;
+
+static void
+kdb_wait_for_cpus(void)
+{
+#ifdef CONFIG_SMP
+ int online = 0, kdb_data = 0, prev_kdb_data = 0, i, c, time;
+ for (i=0;i<100;i++) udelay(1000);
+ for (time = 0; time < kdb_wait_for_cpus_secs; ++time) {
+ online = 0;
+ kdb_data = 0;
+ for_each_online_cpu(c) {
+ ++online;
+ if (kdb_running_process[c].seqno >= kdb_seqno - 1)
+ ++kdb_data;
+ }
+ if (online == kdb_data)
+ break;
+ if (prev_kdb_data != kdb_data) {
+ kdb_nextline = 0; /* no prompt yet */
+ kdb_printf(" %d out of %d cpus in kdb, waiting for the rest, timeout in %d second(s)\n",
+ kdb_data, online, kdb_wait_for_cpus_secs - time);
+ prev_kdb_data = kdb_data;
+ }
+ touch_nmi_watchdog();
+ for (i=0;i<1000;i++) udelay(1000);
+ /* Architectures may want to send a more forceful interrupt */
+ if (time == min(kdb_wait_for_cpus_secs / 2, 5))
+ kdba_wait_for_cpus();
+ if (time % 4 == 0)
+ kdb_printf(".");
+ }
+ if (time) {
+ int wait = online - kdb_data;
+ if (wait == 0)
+ kdb_printf("All cpus are now in kdb\n");
+ else
+ kdb_printf("%d cpu%s not in kdb, %s state is unknown\n",
+ wait,
+ wait == 1 ? " is" : "s are",
+ wait == 1 ? "its" : "their");
+ }
+#endif /* CONFIG_SMP */
+}
+
+/*
+ * kdb_main_loop
+ *
+ * The main kdb loop. After initial setup and assignment of the controlling
+ * cpu, all cpus are in this loop. One cpu is in control and will issue the kdb
+ * prompt, the others will spin until 'go' or cpu switch.
+ *
+ * To get a consistent view of the kernel stacks for all processes, this routine
+ * is invoked from the main kdb code via an architecture specific routine.
+ * kdba_main_loop is responsible for making the kernel stacks consistent for all
+ * processes, there should be no difference between a blocked process and a
+ * running process as far as kdb is concerned.
+ *
+ * Inputs:
+ * reason The reason KDB was invoked
+ * error The hardware-defined error code
+ * reason2 kdb's current reason code. Initially error but can change
+ * acording to kdb state.
+ * db_result Result code from break or debug point.
+ * regs The exception frame at time of fault/breakpoint. If reason
+ * is SILENT or CPU_UP then regs is NULL, otherwise it
+ * should always be valid.
+ * Returns:
+ * 0 KDB was invoked for an event which it wasn't responsible
+ * 1 KDB handled the event for which it was invoked.
+ * Locking:
+ * none
+ * Remarks:
+ * none
+ */
+
+int
+kdb_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error,
+ kdb_dbtrap_t db_result, struct pt_regs *regs)
+{
+ int result = 1;
+ /* Stay in kdb() until 'go', 'ss[b]' or an error */
+ while (1) {
+ /*
+ * All processors except the one that is in control
+ * will spin here.
+ */
+ KDB_DEBUG_STATE("kdb_main_loop 1", reason);
+ while (KDB_STATE(HOLD_CPU)) {
+ /* state KDB is turned off by kdb_cpu to see if the
+ * other cpus are still live, each cpu in this loop
+ * turns it back on.
+ */
+ if (!KDB_STATE(KDB)) {
+ KDB_STATE_SET(KDB);
+ }
+ cpu_relax();
+ }
+ KDB_STATE_CLEAR(SUPPRESS);
+ KDB_DEBUG_STATE("kdb_main_loop 2", reason);
+ if (KDB_STATE(LEAVING))
+ break; /* Another cpu said 'go' */
+
+ if (!kdb_quiet(reason))
+ kdb_wait_for_cpus();
+ /* Still using kdb, this processor is in control */
+ result = kdb_local(reason2, error, regs, db_result);
+ KDB_DEBUG_STATE("kdb_main_loop 3", result);
+
+ if (result == KDB_CMD_CPU) {
+ /* Cpu switch, hold the current cpu, release the target one. */
+ reason2 = KDB_REASON_SWITCH;
+ KDB_STATE_SET(HOLD_CPU);
+ KDB_STATE_CLEAR_CPU(HOLD_CPU, kdb_new_cpu);
+ continue;
+ }
+
+ if (result == KDB_CMD_SS) {
+ KDB_STATE_SET(DOING_SS);
+ break;
+ }
+
+ if (result == KDB_CMD_SSB) {
+ KDB_STATE_SET(DOING_SS);
+ KDB_STATE_SET(DOING_SSB);
+ break;
+ }
+
+ if (result && result != 1 && result != KDB_CMD_GO)
+ kdb_printf("\nUnexpected kdb_local return code %d\n", result);
+
+ KDB_DEBUG_STATE("kdb_main_loop 4", reason);
+ break;
+ }
+ if (KDB_STATE(DOING_SS))
+ KDB_STATE_CLEAR(SSBPT);
+ return result;
+}
+
+/*
+ * kdb
+ *
+ * This function is the entry point for the kernel debugger. It
+ * provides a command parser and associated support functions to
+ * allow examination and control of an active kernel.
+ *
+ * The breakpoint trap code should invoke this function with
+ * one of KDB_REASON_BREAK (int 03) or KDB_REASON_DEBUG (debug register)
+ *
+ * the die_if_kernel function should invoke this function with
+ * KDB_REASON_OOPS.
+ *
+ * In single step mode, one cpu is released to run without
+ * breakpoints. Interrupts and NMI are reset to their original values,
+ * the cpu is allowed to do one instruction which causes a trap
+ * into kdb with KDB_REASON_DEBUG.
+ *
+ * Inputs:
+ * reason The reason KDB was invoked
+ * error The hardware-defined error code
+ * regs The exception frame at time of fault/breakpoint. If reason
+ * is SILENT or CPU_UP then regs is NULL, otherwise it
+ * should always be valid.
+ * Returns:
+ * 0 KDB was invoked for an event which it wasn't responsible
+ * 1 KDB handled the event for which it was invoked.
+ * Locking:
+ * none
+ * Remarks:
+ * No assumptions of system state. This function may be invoked
+ * with arbitrary locks held. It will stop all other processors
+ * in an SMP environment, disable all interrupts and does not use
+ * the operating systems keyboard driver.
+ *
+ * This code is reentrant but only for cpu switch. Any other
+ * reentrancy is an error, although kdb will attempt to recover.
+ *
+ * At the start of a kdb session the initial processor is running
+ * kdb() and the other processors can be doing anything. When the
+ * initial processor calls smp_kdb_stop() the other processors are
+ * driven through kdb_ipi which calls kdb() with reason SWITCH.
+ * That brings all processors into this routine, one with a "real"
+ * reason code, the other with SWITCH.
+ *
+ * Because the other processors are driven via smp_kdb_stop(),
+ * they enter here from the NMI handler. Until the other
+ * processors exit from here and exit from kdb_ipi, they will not
+ * take any more NMI requests. The initial cpu will still take NMI.
+ *
+ * Multiple race and reentrancy conditions, each with different
+ * advoidance mechanisms.
+ *
+ * Two cpus hit debug points at the same time.
+ *
+ * kdb_lock and kdb_initial_cpu ensure that only one cpu gets
+ * control of kdb. The others spin on kdb_initial_cpu until
+ * they are driven through NMI into kdb_ipi. When the initial
+ * cpu releases the others from NMI, they resume trying to get
+ * kdb_initial_cpu to start a new event.
+ *
+ * A cpu is released from kdb and starts a new event before the
+ * original event has completely ended.
+ *
+ * kdb_previous_event() prevents any cpu from entering
+ * kdb_initial_cpu state until the previous event has completely
+ * ended on all cpus.
+ *
+ * An exception occurs inside kdb.
+ *
+ * kdb_initial_cpu detects recursive entry to kdb and attempts
+ * to recover. The recovery uses longjmp() which means that
+ * recursive calls to kdb never return. Beware of assumptions
+ * like
+ *
+ * ++depth;
+ * kdb();
+ * --depth;
+ *
+ * If the kdb call is recursive then longjmp takes over and
+ * --depth is never executed.
+ *
+ * NMI handling.
+ *
+ * NMI handling is tricky. The initial cpu is invoked by some kdb event,
+ * this event could be NMI driven but usually is not. The other cpus are
+ * driven into kdb() via kdb_ipi which uses NMI so at the start the other
+ * cpus will not accept NMI. Some operations such as SS release one cpu
+ * but hold all the others. Releasing a cpu means it drops back to
+ * whatever it was doing before the kdb event, this means it drops out of
+ * kdb_ipi and hence out of NMI status. But the software watchdog uses
+ * NMI and we do not want spurious watchdog calls into kdb. kdba_read()
+ * resets the watchdog counters in its input polling loop, when a kdb
+ * command is running it is subject to NMI watchdog events.
+ *
+ * Another problem with NMI handling is the NMI used to drive the other
+ * cpus into kdb cannot be distinguished from the watchdog NMI. State
+ * flag WAIT_IPI indicates that a cpu is waiting for NMI via kdb_ipi,
+ * if not set then software NMI is ignored by kdb_ipi.
+ *
+ * Cpu switching.
+ *
+ * All cpus are in kdb (or they should be), all but one are
+ * spinning on KDB_STATE(HOLD_CPU). Only one cpu is not in
+ * HOLD_CPU state, only that cpu can handle commands.
+ *
+ * Go command entered.
+ *
+ * If necessary, go will switch to the initial cpu first. If the event
+ * was caused by a software breakpoint (assumed to be global) that
+ * requires single-step to get over the breakpoint then only release the
+ * initial cpu, after the initial cpu has single-stepped the breakpoint
+ * then release the rest of the cpus. If SSBPT is not required then
+ * release all the cpus at once.
+ */
+
+asmlinkage int
+kdb(kdb_reason_t reason, int error, struct pt_regs *regs)
+{
+ kdb_intstate_t int_state; /* Interrupt state */
+ kdb_reason_t reason2 = reason;
+ int result = 0; /* Default is kdb did not handle it */
+ int ss_event;
+ kdb_dbtrap_t db_result=KDB_DB_NOBPT;
+#ifdef CONFIG_HW_CONSOLE
+ extern int kmsg_redirect;
+ int saved_redirect;
+#endif
+
+ preempt_disable();
+#ifdef CONFIG_HW_CONSOLE
+ saved_redirect = kmsg_redirect;
+ kmsg_redirect = 0;
+#endif
+
+ switch(reason) {
+ case KDB_REASON_OOPS:
+ case KDB_REASON_NMI:
+ KDB_FLAG_SET(CATASTROPHIC); /* kernel state is dubious now */
+ break;
+ default:
+ break;
+ }
+ if (kdb_continue_catastrophic > 2) {
+ kdb_printf("kdb_continue_catastrophic is out of range, setting to 2\n");
+ kdb_continue_catastrophic = 2;
+ }
+ if (!kdb_on && KDB_FLAG(CATASTROPHIC) && kdb_continue_catastrophic == 2) {
+ KDB_FLAG_SET(ONLY_DO_DUMP);
+ }
+ if (!kdb_on && !KDB_FLAG(ONLY_DO_DUMP))
+ goto out;
+
+ KDB_DEBUG_STATE("kdb 1", reason);
+ KDB_STATE_CLEAR(SUPPRESS);
+
+ /* Filter out userspace breakpoints first, no point in doing all
+ * the kdb smp fiddling when it is really a gdb trap.
+ * Save the single step status first, kdba_db_trap clears ss status.
+ * kdba_b[dp]_trap sets SSBPT if required.
+ */
+ ss_event = KDB_STATE(DOING_SS) || KDB_STATE(SSBPT);
+#ifdef CONFIG_CPU_XSCALE
+ if ( KDB_STATE(A_XSC_ICH) ) {
+ /* restore changed I_BIT */
+ KDB_STATE_CLEAR(A_XSC_ICH);
+ kdba_restore_retirq(regs, KDB_STATE(A_XSC_IRQ));
+ if ( !ss_event ) {
+ kdb_printf("Stranger!!! Why IRQ bit is changed====\n");
+ }
+ }
+#endif
+ if (reason == KDB_REASON_BREAK) {
+ db_result = kdba_bp_trap(regs, error); /* Only call this once */
+ }
+ if (reason == KDB_REASON_DEBUG) {
+ db_result = kdba_db_trap(regs, error); /* Only call this once */
+ }
+
+ if ((reason == KDB_REASON_BREAK || reason == KDB_REASON_DEBUG)
+ && db_result == KDB_DB_NOBPT) {
+ KDB_DEBUG_STATE("kdb 2", reason);
+ goto out; /* Not one of mine */
+ }
+
+ /* Turn off single step if it was being used */
+ if (ss_event) {
+ kdba_clearsinglestep(regs);
+ /* Single step after a breakpoint removes the need for a delayed reinstall */
+ if (reason == KDB_REASON_BREAK || reason == KDB_REASON_DEBUG)
+ KDB_STATE_CLEAR(SSBPT);
+ }
+
+ /* kdb can validly reenter but only for certain well defined conditions */
+ if (reason == KDB_REASON_DEBUG
+ && !KDB_STATE(HOLD_CPU)
+ && ss_event)
+ KDB_STATE_SET(REENTRY);
+ else
+ KDB_STATE_CLEAR(REENTRY);
+
+ /* Wait for previous kdb event to completely exit before starting
+ * a new event.
+ */
+ while (kdb_previous_event())
+ cpu_relax();
+ KDB_DEBUG_STATE("kdb 3", reason);
+
+ /*
+ * If kdb is already active, print a message and try to recover.
+ * If recovery is not possible and recursion is allowed or
+ * forced recursion without recovery is set then try to recurse
+ * in kdb. Not guaranteed to work but it makes an attempt at
+ * debugging the debugger.
+ */
+ if (reason != KDB_REASON_SWITCH &&
+ reason != KDB_REASON_ENTER_SLAVE) {
+ if (KDB_IS_RUNNING() && !KDB_STATE(REENTRY)) {
+ int recover = 1;
+ unsigned long recurse = 0;
+ kdb_printf("kdb: Debugger re-entered on cpu %d, new reason = %d\n",
+ smp_processor_id(), reason);
+ /* Should only re-enter from released cpu */
+
+ if (KDB_STATE(HOLD_CPU)) {
+ kdb_printf(" Strange, cpu %d should not be running\n", smp_processor_id());
+ recover = 0;
+ }
+ if (!KDB_STATE(CMD)) {
+ kdb_printf(" Not executing a kdb command\n");
+ recover = 0;
+ }
+ if (!KDB_STATE(LONGJMP)) {
+ kdb_printf(" No longjmp available for recovery\n");
+ recover = 0;
+ }
+ kdbgetulenv("RECURSE", &recurse);
+ if (recurse > 1) {
+ kdb_printf(" Forced recursion is set\n");
+ recover = 0;
+ }
+ if (recover) {
+ kdb_printf(" Attempting to abort command and recover\n");
+#ifdef kdba_setjmp
+ kdba_longjmp(&kdbjmpbuf[smp_processor_id()], 0);
+#endif /* kdba_setjmp */
+ }
+ if (recurse) {
+ if (KDB_STATE(RECURSE)) {
+ kdb_printf(" Already in recursive mode\n");
+ } else {
+ kdb_printf(" Attempting recursive mode\n");
+ KDB_STATE_SET(RECURSE);
+ KDB_STATE_SET(REENTRY);
+ reason2 = KDB_REASON_RECURSE;
+ recover = 1;
+ }
+ }
+ if (!recover) {
+ kdb_printf(" Cannot recover, allowing event to proceed\n");
+ /*temp*/
+ while (KDB_IS_RUNNING())
+ cpu_relax();
+ goto out;
+ }
+ }
+ } else if (reason == KDB_REASON_SWITCH && !KDB_IS_RUNNING()) {
+ kdb_printf("kdb: CPU switch without kdb running, I'm confused\n");
+ goto out;
+ }
+
+ /*
+ * Disable interrupts, breakpoints etc. on this processor
+ * during kdb command processing
+ */
+ KDB_STATE_SET(KDB);
+ kdba_disableint(&int_state);
+ if (!KDB_STATE(KDB_CONTROL)) {
+ kdb_bp_remove_local();
+ KDB_STATE_SET(KDB_CONTROL);
+ }
+
+ /*
+ * If not entering the debugger due to CPU switch or single step
+ * reentry, serialize access here.
+ * The processors may race getting to this point - if,
+ * for example, more than one processor hits a breakpoint
+ * at the same time. We'll serialize access to kdb here -
+ * other processors will loop here, and the NMI from the stop
+ * IPI will take them into kdb as switch candidates. Once
+ * the initial processor releases the debugger, the rest of
+ * the processors will race for it.
+ *
+ * The above describes the normal state of affairs, where two or more
+ * cpus that are entering kdb at the "same" time are assumed to be for
+ * separate events. However some processes such as ia64 MCA/INIT will
+ * drive all the cpus into error processing at the same time. For that
+ * case, all of the cpus entering kdb at the "same" time are really a
+ * single event.
+ *
+ * That case is handled by the use of KDB_ENTER by one cpu (the
+ * monarch) and KDB_ENTER_SLAVE on the other cpus (the slaves).
+ * KDB_ENTER_SLAVE maps to KDB_REASON_ENTER_SLAVE. The slave events
+ * will be treated as if they had just responded to the kdb IPI, i.e.
+ * as if they were KDB_REASON_SWITCH.
+ *
+ * Because of races across multiple cpus, ENTER_SLAVE can occur before
+ * the main ENTER. Hold up ENTER_SLAVE here until the main ENTER
+ * arrives.
+ */
+
+ if (reason == KDB_REASON_ENTER_SLAVE) {
+ spin_lock(&kdb_lock);
+ while (!KDB_IS_RUNNING()) {
+ spin_unlock(&kdb_lock);
+ while (!KDB_IS_RUNNING())
+ cpu_relax();
+ spin_lock(&kdb_lock);
+ }
+ reason = KDB_REASON_SWITCH;
+ KDB_STATE_SET(HOLD_CPU);
+ spin_unlock(&kdb_lock);
+ }
+
+ if (reason == KDB_REASON_SWITCH || KDB_STATE(REENTRY))
+ ; /* drop through */
+ else {
+ KDB_DEBUG_STATE("kdb 4", reason);
+ spin_lock(&kdb_lock);
+ while (KDB_IS_RUNNING() || kdb_previous_event()) {
+ spin_unlock(&kdb_lock);
+ while (KDB_IS_RUNNING() || kdb_previous_event())
+ cpu_relax();
+ spin_lock(&kdb_lock);
+ }
+ KDB_DEBUG_STATE("kdb 5", reason);
+
+ kdb_initial_cpu = smp_processor_id();
+ ++kdb_seqno;
+ spin_unlock(&kdb_lock);
+ if (!kdb_quiet(reason))
+ notify_die(DIE_KDEBUG_ENTER, "KDEBUG ENTER", regs, error, 0, 0);
+ }
+
+ if (smp_processor_id() == kdb_initial_cpu
+ && !KDB_STATE(REENTRY)) {
+ KDB_STATE_CLEAR(HOLD_CPU);
+ KDB_STATE_CLEAR(WAIT_IPI);
+ /*
+ * Remove the global breakpoints. This is only done
+ * once from the initial processor on initial entry.
+ */
+ kdb_bp_remove_global();
+
+ /*
+ * If SMP, stop other processors. The other processors
+ * will enter kdb() with KDB_REASON_SWITCH and spin in
+ * kdb_main_loop().
+ */
+ KDB_DEBUG_STATE("kdb 6", reason);
+ if (NR_CPUS > 1 && !kdb_quiet(reason)) {
+ int i;
+ for (i = 0; i < NR_CPUS; ++i) {
+ if (!cpu_online(i))
+ continue;
+ if (i != kdb_initial_cpu) {
+ KDB_STATE_SET_CPU(HOLD_CPU, i);
+ KDB_STATE_SET_CPU(WAIT_IPI, i);
+ }
+ }
+ KDB_DEBUG_STATE("kdb 7", reason);
+ smp_kdb_stop();
+ KDB_DEBUG_STATE("kdb 8", reason);
+ }
+ }
+
+ if (KDB_STATE(GO1)) {
+ kdb_bp_remove_global(); /* They were set for single-step purposes */
+ KDB_STATE_CLEAR(GO1);
+ reason = KDB_REASON_SILENT; /* Now silently go */
+ }
+
+ /* Set up a consistent set of process stacks before talking to the user */
+ KDB_DEBUG_STATE("kdb 9", result);
+ result = kdba_main_loop(reason, reason2, error, db_result, regs);
+
+ KDB_DEBUG_STATE("kdb 10", result);
+ kdba_adjust_ip(reason2, error, regs);
+ KDB_STATE_CLEAR(LONGJMP);
+ KDB_DEBUG_STATE("kdb 11", result);
+ /* go which requires single-step over a breakpoint must only release
+ * one cpu.
+ */
+ if (result == KDB_CMD_GO && KDB_STATE(SSBPT))
+ KDB_STATE_SET(GO1);
+
+ if (smp_processor_id() == kdb_initial_cpu &&
+ !KDB_STATE(DOING_SS) &&
+ !KDB_STATE(RECURSE)) {
+ /*
+ * (Re)install the global breakpoints. This is only done
+ * once from the initial processor on go.
+ */
+ KDB_DEBUG_STATE("kdb 12", reason);
+ kdb_bp_install_global(regs);
+ if (!KDB_STATE(GO1)) {
+ /*
+ * Release all other cpus which will see KDB_STATE(LEAVING) is set.
+ */
+ int i;
+ for (i = 0; i < NR_CPUS; ++i) {
+ if (KDB_STATE_CPU(KDB, i))
+ KDB_STATE_SET_CPU(LEAVING, i);
+ KDB_STATE_CLEAR_CPU(WAIT_IPI, i);
+ KDB_STATE_CLEAR_CPU(HOLD_CPU, i);
+ }
+ /* Wait until all the other processors leave kdb */
+ while (kdb_previous_event() != 1)
+ cpu_relax();
+ if (!kdb_quiet(reason))
+ notify_die(DIE_KDEBUG_LEAVE, "KDEBUG LEAVE", regs, error, 0, 0);
+ kdb_initial_cpu = -1; /* release kdb control */
+ KDB_DEBUG_STATE("kdb 13", reason);
+ }
+ }
+
+ KDB_DEBUG_STATE("kdb 14", result);
+ kdba_restoreint(&int_state);
+#ifdef CONFIG_CPU_XSCALE
+ if ( smp_processor_id() == kdb_initial_cpu &&
+ ( KDB_STATE(SSBPT) | KDB_STATE(DOING_SS) )
+ ) {
+ kdba_setsinglestep(regs);
+ // disable IRQ in stack frame
+ KDB_STATE_SET(A_XSC_ICH);
+ if ( kdba_disable_retirq(regs) ) {
+ KDB_STATE_SET(A_XSC_IRQ);
+ }
+ else {
+ KDB_STATE_CLEAR(A_XSC_IRQ);
+ }
+ }
+#endif
+
+ /* Only do this work if we are really leaving kdb */
+ if (!(KDB_STATE(DOING_SS) || KDB_STATE(SSBPT) || KDB_STATE(RECURSE))) {
+ KDB_DEBUG_STATE("kdb 15", result);
+ kdb_bp_install_local(regs);
+ KDB_STATE_CLEAR(KDB_CONTROL);
+ }
+
+ KDB_DEBUG_STATE("kdb 16", result);
+ KDB_FLAG_CLEAR(CATASTROPHIC);
+ KDB_STATE_CLEAR(IP_ADJUSTED); /* Re-adjust ip next time in */
+ KDB_STATE_CLEAR(KEYBOARD);
+ KDB_STATE_CLEAR(KDB); /* Main kdb state has been cleared */
+ KDB_STATE_CLEAR(RECURSE);
+ KDB_STATE_CLEAR(LEAVING); /* No more kdb work after this */
+ KDB_DEBUG_STATE("kdb 17", reason);
+out:
+#ifdef CONFIG_HW_CONSOLE
+ if (saved_redirect)
+ kmsg_redirect = saved_redirect;
+#endif
+ preempt_enable();
+ return result != 0;
+}
+
+/*
+ * kdb_mdr
+ *
+ * This function implements the guts of the 'mdr' command.
+ *
+ * mdr <addr arg>,<byte count>
+ *
+ * Inputs:
+ * addr Start address
+ * count Number of bytes
+ * Outputs:
+ * None.
+ * Returns:
+ * Always 0. Any errors are detected and printed by kdb_getarea.
+ * Locking:
+ * none.
+ * Remarks:
+ */
+
+static int
+kdb_mdr(kdb_machreg_t addr, unsigned int count)
+{
+ unsigned char c;
+ while (count--) {
+ if (kdb_getarea(c, addr))
+ return 0;
+ kdb_printf("%02x", c);
+ addr++;
+ }
+ kdb_printf("\n");
+ return 0;
+}
+
+/*
+ * kdb_md
+ *
+ * This function implements the 'md', 'md1', 'md2', 'md4', 'md8'
+ * 'mdr' and 'mds' commands.
+ *
+ * md|mds [<addr arg> [<line count> [<radix>]]]
+ * mdWcN [<addr arg> [<line count> [<radix>]]]
+ * where W = is the width (1, 2, 4 or 8) and N is the count.
+ * for eg., md1c20 reads 20 bytes, 1 at a time.
+ * mdr <addr arg>,<byte count>
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ */
+
+static int
+kdb_md_line(const char *fmtstr, kdb_machreg_t addr, int symbolic,
+ int bytesperword, int num, int repeat, int phys)
+{
+ /* print just one line of data */
+ kdb_symtab_t symtab;
+ char cbuf[32];
+ char *c = cbuf;
+ int i, diag;
+ unsigned long word;
+
+ memset(cbuf, '\0', sizeof(cbuf));
+ if (phys)
+ kdb_printf("phys " kdb_machreg_fmt0 " ", addr);
+ else
+ kdb_printf(kdb_machreg_fmt0 " ", addr);
+
+ for (i = 0; i < num && repeat--; i++) {
+ diag = phys? kdb_getphysword(&word, addr, bytesperword):
+ kdb_getword(&word, addr, bytesperword);
+ if (diag)
+ return diag;
+ kdb_printf(fmtstr, word);
+ if (symbolic)
+ kdbnearsym(word, &symtab);
+ else
+ memset(&symtab, 0, sizeof(symtab));
+ if (symtab.sym_name) {
+ kdb_symbol_print(word, &symtab, 0);
+ addr += bytesperword;
+ } else {
+ union {
+ u64 word;
+ unsigned char c[8];
+ } wc;
+ unsigned char *cp;
+#ifdef __BIG_ENDIAN
+ cp = wc.c + 8 - bytesperword;
+#else
+ cp = wc.c;
+#endif
+ wc.word = word;
+#define printable_char(c) ({unsigned char __c = c; isascii(__c) && isprint(__c) ? __c : '.';})
+ switch (bytesperword) {
+ case 8:
+ *c++ = printable_char(*cp++);
+ *c++ = printable_char(*cp++);
+ *c++ = printable_char(*cp++);
+ *c++ = printable_char(*cp++);
+ addr += 4;
+ case 4:
+ *c++ = printable_char(*cp++);
+ *c++ = printable_char(*cp++);
+ addr += 2;
+ case 2:
+ *c++ = printable_char(*cp++);
+ addr++;
+ case 1:
+ *c++ = printable_char(*cp++);
+ addr++;
+ break;
+ }
+#undef printable_char
+ }
+ }
+ kdb_printf("%*s %s\n", (int)((num-i)*(2*bytesperword + 1)+1), " ", cbuf);
+ return 0;
+}
+
+static int
+kdb_md(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ static kdb_machreg_t last_addr;
+ static int last_radix, last_bytesperword, last_repeat;
+ int radix = 16, mdcount = 8, bytesperword = sizeof(kdb_machreg_t), repeat;
+ char fmtchar, fmtstr[64];
+ kdb_machreg_t addr;
+ unsigned long word;
+ long offset = 0;
+ int symbolic = 0;
+ int valid = 0;
+ int phys = 0;
+
+ kdbgetintenv("MDCOUNT", &mdcount);
+ kdbgetintenv("RADIX", &radix);
+ kdbgetintenv("BYTESPERWORD", &bytesperword);
+
+ /* Assume 'md <addr>' and start with environment values */
+ repeat = mdcount * 16 / bytesperword;
+
+ if (strcmp(argv[0], "mdr") == 0) {
+ if (argc != 2)
+ return KDB_ARGCOUNT;
+ valid = 1;
+ } else if (isdigit(argv[0][2])) {
+ bytesperword = (int)(argv[0][2] - '0');
+ if (bytesperword == 0) {
+ bytesperword = last_bytesperword;
+ if (bytesperword == 0) {
+ bytesperword = 4;
+ }
+ }
+ last_bytesperword = bytesperword;
+ repeat = mdcount * 16 / bytesperword;
+ if (!argv[0][3])
+ valid = 1;
+ else if (argv[0][3] == 'c' && argv[0][4]) {
+ char *p;
+ repeat = simple_strtoul(argv[0]+4, &p, 10);
+ mdcount = ((repeat * bytesperword) + 15) / 16;
+ valid = !*p;
+ }
+ last_repeat = repeat;
+ } else if (strcmp(argv[0], "md") == 0)
+ valid = 1;
+ else if (strcmp(argv[0], "mds") == 0)
+ valid = 1;
+ else if (strcmp(argv[0], "mdp") == 0) {
+ phys = valid = 1;
+ }
+ if (!valid)
+ return KDB_NOTFOUND;
+
+ if (argc == 0) {
+ if (last_addr == 0)
+ return KDB_ARGCOUNT;
+ addr = last_addr;
+ radix = last_radix;
+ bytesperword = last_bytesperword;
+ repeat = last_repeat;
+ mdcount = ((repeat * bytesperword) + 15) / 16;
+ }
+
+ if (argc) {
+ kdb_machreg_t val;
+ int diag, nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
+ if (diag)
+ return diag;
+ if (argc > nextarg+2)
+ return KDB_ARGCOUNT;
+
+ if (argc >= nextarg) {
+ diag = kdbgetularg(argv[nextarg], &val);
+ if (!diag) {
+ mdcount = (int) val;
+ repeat = mdcount * 16 / bytesperword;
+ }
+ }
+ if (argc >= nextarg+1) {
+ diag = kdbgetularg(argv[nextarg+1], &val);
+ if (!diag)
+ radix = (int) val;
+ }
+ }
+
+ if (strcmp(argv[0], "mdr") == 0) {
+ return kdb_mdr(addr, mdcount);
+ }
+
+ switch (radix) {
+ case 10:
+ fmtchar = 'd';
+ break;
+ case 16:
+ fmtchar = 'x';
+ break;
+ case 8:
+ fmtchar = 'o';
+ break;
+ default:
+ return KDB_BADRADIX;
+ }
+
+ last_radix = radix;
+
+ if (bytesperword > sizeof(kdb_machreg_t))
+ return KDB_BADWIDTH;
+
+ switch (bytesperword) {
+ case 8:
+ sprintf(fmtstr, "%%16.16l%c ", fmtchar);
+ break;
+ case 4:
+ sprintf(fmtstr, "%%8.8l%c ", fmtchar);
+ break;
+ case 2:
+ sprintf(fmtstr, "%%4.4l%c ", fmtchar);
+ break;
+ case 1:
+ sprintf(fmtstr, "%%2.2l%c ", fmtchar);
+ break;
+ default:
+ return KDB_BADWIDTH;
+ }
+
+ last_repeat = repeat;
+ last_bytesperword = bytesperword;
+
+ if (strcmp(argv[0], "mds") == 0) {
+ symbolic = 1;
+ /* Do not save these changes as last_*, they are temporary mds
+ * overrides.
+ */
+ bytesperword = sizeof(kdb_machreg_t);
+ repeat = mdcount;
+ }
+
+ /* Round address down modulo BYTESPERWORD */
+
+ addr &= ~(bytesperword-1);
+
+ while (repeat > 0) {
+ unsigned long a;
+ int n, z, num = (symbolic ? 1 : (16 / bytesperword));
+
+ KDB_STATE_SET(SUPPRESS);
+ for (a = addr, z = 0; z < repeat; a += bytesperword, ++z) {
+ if (phys) {
+ if (kdb_getphysword(&word, a, bytesperword)
+ || word)
+ break;
+ } else if (kdb_getword(&word, a, bytesperword) || word)
+ break;
+ }
+ KDB_STATE_CLEAR(SUPPRESS);
+ n = min(num, repeat);
+ if (kdb_md_line(fmtstr, addr, symbolic, bytesperword, num, repeat, phys))
+ break;
+ addr += bytesperword * n;
+ repeat -= n;
+ z = (z + num - 1) / num;
+ if (z > 2) {
+ int s = num * (z-2);
+ kdb_printf(kdb_machreg_fmt0 "-" kdb_machreg_fmt0 " zero suppressed\n",
+ addr, addr + bytesperword * s - 1);
+ addr += bytesperword * s;
+ repeat -= s;
+ }
+ }
+ last_addr = addr;
+
+ return 0;
+}
+
+/*
+ * kdb_mm
+ *
+ * This function implements the 'mm' command.
+ *
+ * mm address-expression new-value
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * mm works on machine words, mmW works on bytes.
+ */
+
+static int
+kdb_mm(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int diag;
+ kdb_machreg_t addr;
+ long offset = 0;
+ unsigned long contents;
+ int nextarg;
+ int width;
+
+ if (argv[0][2] && !isdigit(argv[0][2]))
+ return KDB_NOTFOUND;
+
+ if (argc < 2) {
+ return KDB_ARGCOUNT;
+ }
+
+ nextarg = 1;
+ if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs)))
+ return diag;
+
+ if (nextarg > argc)
+ return KDB_ARGCOUNT;
+
+ if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &contents, NULL, NULL, regs)))
+ return diag;
+
+ if (nextarg != argc + 1)
+ return KDB_ARGCOUNT;
+
+ width = argv[0][2] ? (argv[0][2] - '0') : (sizeof(kdb_machreg_t));
+ if ((diag = kdb_putword(addr, contents, width)))
+ return diag;
+
+ kdb_printf(kdb_machreg_fmt " = " kdb_machreg_fmt "\n", addr, contents);
+
+ return 0;
+}
+
+/*
+ * kdb_go
+ *
+ * This function implements the 'go' command.
+ *
+ * go [address-expression]
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * KDB_CMD_GO for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ */
+
+static int
+kdb_go(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ kdb_machreg_t addr;
+ int diag;
+ int nextarg;
+ long offset;
+
+ if (argc == 1) {
+ if (smp_processor_id() != kdb_initial_cpu) {
+ kdb_printf("go <address> must be issued from the initial cpu, do cpu %d first\n", kdb_initial_cpu);
+ return KDB_ARGCOUNT;
+ }
+ nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg,
+ &addr, &offset, NULL, regs);
+ if (diag)
+ return diag;
+
+ kdba_setpc(regs, addr);
+ } else if (argc)
+ return KDB_ARGCOUNT;
+
+ diag = KDB_CMD_GO;
+ if (KDB_FLAG(CATASTROPHIC)) {
+ if (kdb_continue_catastrophic == 0 && kdb_go_count++ == 0) {
+ kdb_printf("Catastrophic error detected\n");
+ kdb_printf("type go a second time if you really want to continue\n");
+ return 0;
+ }
+ if (kdb_continue_catastrophic == 2) {
+ kdb_printf("Catastrophic error detected\n");
+ kdb_do_dump(regs);
+ kdb_printf("forcing reboot\n");
+ kdb_reboot(0, NULL, NULL, regs);
+ }
+ }
+ if (smp_processor_id() != kdb_initial_cpu) {
+ char buf[80];
+ kdb_printf("go was not issued from initial cpu, switching back to cpu %d\n", kdb_initial_cpu);
+ sprintf(buf, "cpu %d\n", kdb_initial_cpu);
+ /* Recursive use of kdb_parse, do not use argv after this point */
+ argv = NULL;
+ diag = kdb_parse(buf, regs);
+ if (diag == KDB_CMD_CPU)
+ KDB_STATE_SET_CPU(GO_SWITCH, kdb_initial_cpu);
+ }
+ return diag;
+}
+
+/*
+ * kdb_rd
+ *
+ * This function implements the 'rd' command.
+ *
+ * rd display all general registers.
+ * rd c display all control registers.
+ * rd d display all debug registers.
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ */
+
+static int
+kdb_rd(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ if (argc == 0) {
+ return kdba_dumpregs(kdb_current_regs, NULL, NULL);
+ }
+
+ if (argc > 2) {
+ return KDB_ARGCOUNT;
+ }
+
+ return kdba_dumpregs(kdb_current_regs, argv[1], argc==2 ? argv[2]: NULL);
+}
+
+/*
+ * kdb_rm
+ *
+ * This function implements the 'rm' (register modify) command.
+ *
+ * rm register-name new-contents
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * Currently doesn't allow modification of control or
+ * debug registers, nor does it allow modification
+ * of model-specific registers (MSR).
+ */
+
+static int
+kdb_rm(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int diag;
+ int ind = 0;
+ kdb_machreg_t contents;
+
+ if (argc != 2) {
+ return KDB_ARGCOUNT;
+ }
+
+ /*
+ * Allow presence or absence of leading '%' symbol.
+ */
+
+ if (argv[1][0] == '%')
+ ind = 1;
+
+ diag = kdbgetularg(argv[2], &contents);
+ if (diag)
+ return diag;
+
+ diag = kdba_setregcontents(&argv[1][ind], kdb_current_regs, contents);
+ if (diag)
+ return diag;
+
+ return 0;
+}
+
+#if defined(CONFIG_MAGIC_SYSRQ)
+/*
+ * kdb_sr
+ *
+ * This function implements the 'sr' (SYSRQ key) command which
+ * interfaces to the soi-disant MAGIC SYSRQ functionality.
+ *
+ * sr <magic-sysrq-code>
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * None.
+ */
+static int
+kdb_sr(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ extern int sysrq_enabled;
+ if (argc != 1) {
+ return KDB_ARGCOUNT;
+ }
+ if (!sysrq_enabled) {
+ kdb_printf("Auto activating sysrq\n");
+ sysrq_enabled = 1;
+ }
+
+ handle_sysrq(*argv[1], regs, NULL);
+
+ return 0;
+}
+#endif /* CONFIG_MAGIC_SYSRQ */
+
+/*
+ * kdb_ef
+ *
+ * This function implements the 'regs' (display exception frame)
+ * command. This command takes an address and expects to find
+ * an exception frame at that address, formats and prints it.
+ *
+ * regs address-expression
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * Not done yet.
+ */
+
+static int
+kdb_ef(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int diag;
+ kdb_machreg_t addr;
+ long offset;
+ int nextarg;
+
+ if (argc == 1) {
+ nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
+ if (diag)
+ return diag;
+
+ return kdba_dumpregs((struct pt_regs *)addr, NULL, NULL);
+ }
+
+ return KDB_ARGCOUNT;
+}
+
+#if defined(CONFIG_MODULES)
+extern struct list_head *kdb_modules;
+extern void free_module(struct module *);
+
+/* modules using other modules */
+struct module_use
+{
+ struct list_head list;
+ struct module *module_which_uses;
+};
+
+/*
+ * kdb_lsmod
+ *
+ * This function implements the 'lsmod' command. Lists currently
+ * loaded kernel modules.
+ *
+ * Mostly taken from userland lsmod.
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ *
+ */
+
+static int
+kdb_lsmod(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ struct module *mod;
+
+ if (argc != 0)
+ return KDB_ARGCOUNT;
+
+ kdb_printf("Module Size modstruct Used by\n");
+ list_for_each_entry(mod, kdb_modules, list) {
+
+ kdb_printf("%-20s%8lu 0x%p ", mod->name,
+ mod->core_size, (void *)mod);
+#ifdef CONFIG_MODULE_UNLOAD
+ kdb_printf("%4d ", module_refcount(mod));
+#endif
+ if (mod->state == MODULE_STATE_GOING)
+ kdb_printf(" (Unloading)");
+ else if (mod->state == MODULE_STATE_COMING)
+ kdb_printf(" (Loading)");
+ else
+ kdb_printf(" (Live)");
+
+#ifdef CONFIG_MODULE_UNLOAD
+ {
+ struct module_use *use;
+ kdb_printf(" [ ");
+ list_for_each_entry(use, &mod->modules_which_use_me, list)
+ kdb_printf("%s ", use->module_which_uses->name);
+ kdb_printf("]\n");
+ }
+#endif
+ }
+
+ return 0;
+}
+
+#endif /* CONFIG_MODULES */
+
+/*
+ * kdb_env
+ *
+ * This function implements the 'env' command. Display the current
+ * environment variables.
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ */
+
+static int
+kdb_env(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int i;
+
+ for(i=0; i<__nenv; i++) {
+ if (__env[i]) {
+ kdb_printf("%s\n", __env[i]);
+ }
+ }
+
+ if (KDB_DEBUG(MASK))
+ kdb_printf("KDBFLAGS=0x%x\n", kdb_flags);
+
+ return 0;
+}
+
+/*
+ * kdb_dmesg
+ *
+ * This function implements the 'dmesg' command to display the contents
+ * of the syslog buffer.
+ *
+ * dmesg [lines] [adjust]
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * None.
+ */
+
+static int
+kdb_dmesg(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ char *syslog_data[4], *start, *end, c = '\0', *p;
+ int diag, logging, logsize, lines = 0, adjust = 0, n;
+
+ if (argc > 2)
+ return KDB_ARGCOUNT;
+ if (argc) {
+ char *cp;
+ lines = simple_strtol(argv[1], &cp, 0);
+ if (*cp)
+ lines = 0;
+ if (argc > 1) {
+ adjust = simple_strtoul(argv[2], &cp, 0);
+ if (*cp || adjust < 0)
+ adjust = 0;
+ }
+ }
+
+ /* disable LOGGING if set */
+ diag = kdbgetintenv("LOGGING", &logging);
+ if (!diag && logging) {
+ const char *setargs[] = { "set", "LOGGING", "0" };
+ kdb_set(2, setargs, envp, regs);
+ }
+
+ /* syslog_data[0,1] physical start, end+1. syslog_data[2,3] logical start, end+1. */
+ kdb_syslog_data(syslog_data);
+ if (syslog_data[2] == syslog_data[3])
+ return 0;
+ logsize = syslog_data[1] - syslog_data[0];
+ start = syslog_data[2];
+ end = syslog_data[3];
+#define KDB_WRAP(p) (((p - syslog_data[0]) % logsize) + syslog_data[0])
+ for (n = 0, p = start; p < end; ++p) {
+ if ((c = *KDB_WRAP(p)) == '\n')
+ ++n;
+ }
+ if (c != '\n')
+ ++n;
+ if (lines < 0) {
+ if (adjust >= n)
+ kdb_printf("buffer only contains %d lines, nothing printed\n", n);
+ else if (adjust - lines >= n)
+ kdb_printf("buffer only contains %d lines, last %d lines printed\n",
+ n, n - adjust);
+ if (adjust) {
+ for (; start < end && adjust; ++start) {
+ if (*KDB_WRAP(start) == '\n')
+ --adjust;
+ }
+ if (start < end)
+ ++start;
+ }
+ for (p = start; p < end && lines; ++p) {
+ if (*KDB_WRAP(p) == '\n')
+ ++lines;
+ }
+ end = p;
+ } else if (lines > 0) {
+ int skip = n - (adjust + lines);
+ if (adjust >= n) {
+ kdb_printf("buffer only contains %d lines, nothing printed\n", n);
+ skip = n;
+ } else if (skip < 0) {
+ lines += skip;
+ skip = 0;
+ kdb_printf("buffer only contains %d lines, first %d lines printed\n",
+ n, lines);
+ }
+ for (; start < end && skip; ++start) {
+ if (*KDB_WRAP(start) == '\n')
+ --skip;
+ }
+ for (p = start; p < end && lines; ++p) {
+ if (*KDB_WRAP(p) == '\n')
+ --lines;
+ }
+ end = p;
+ }
+ /* Do a line at a time (max 200 chars) to reduce protocol overhead */
+ c = '\n';
+ while (start != end) {
+ static char buf[201];
+ char *p = buf;
+ while (start < end && (c = *KDB_WRAP(start)) && (p - buf) < sizeof(buf)-1) {
+ ++start;
+ *p++ = c;
+ if (c == '\n')
+ break;
+ }
+ *p = '\0';
+ kdb_printf("%s", buf);
+ }
+ if (c != '\n')
+ kdb_printf("\n");
+
+ return 0;
+}
+
+/*
+ * kdb_cpu
+ *
+ * This function implements the 'cpu' command.
+ *
+ * cpu [<cpunum>]
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * KDB_CMD_CPU for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * All cpu's should be spinning in kdb(). However just in case
+ * a cpu did not take the smp_kdb_stop NMI, check that a cpu
+ * entered kdb() before passing control to it.
+ */
+
+static void
+kdb_cpu_status(void)
+{
+ int i, start_cpu, first_print = 1;
+ char state, prev_state = '?';
+
+ kdb_printf("Currently on cpu %d\n", smp_processor_id());
+ kdb_printf("Available cpus: ");
+ for (start_cpu = -1, i = 0; i < NR_CPUS; i++) {
+ if (!cpu_online(i))
+ state = 'F'; /* cpu is offline */
+ else {
+ struct kdb_running_process *krp = kdb_running_process+i;
+ if (KDB_STATE_CPU(KDB, i)) {
+ state = ' '; /* cpu is responding to kdb */
+ if (kdb_task_state_char(krp->p) == 'I')
+ state = 'I'; /* running the idle task */
+ } else if (krp->seqno && krp->p && krp->seqno >= kdb_seqno - 1)
+ state = '+'; /* some kdb data, but not responding */
+ else
+ state = '*'; /* no kdb data */
+ }
+ if (state != prev_state) {
+ if (prev_state != '?') {
+ if (!first_print)
+ kdb_printf(", ");
+ first_print = 0;
+ kdb_printf("%d", start_cpu);
+ if (start_cpu < i-1)
+ kdb_printf("-%d", i-1);
+ if (prev_state != ' ')
+ kdb_printf("(%c)", prev_state);
+ }
+ prev_state = state;
+ start_cpu = i;
+ }
+ }
+ /* print the trailing cpus, ignoring them if they are all offline */
+ if (prev_state != 'F') {
+ if (!first_print)
+ kdb_printf(", ");
+ kdb_printf("%d", start_cpu);
+ if (start_cpu < i-1)
+ kdb_printf("-%d", i-1);
+ if (prev_state != ' ')
+ kdb_printf("(%c)", prev_state);
+ }
+ kdb_printf("\n");
+}
+
+static int
+kdb_cpu(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ unsigned long cpunum;
+ int diag, i;
+
+ /* ask the other cpus if they are still active */
+ for (i=0; i<NR_CPUS; i++) {
+ if (cpu_online(i))
+ KDB_STATE_CLEAR_CPU(KDB, i);
+ }
+ KDB_STATE_SET(KDB);
+ barrier();
+ /* wait for the other cpus to notice and set state KDB again,
+ * see kdb_main_loop
+ */
+ udelay(1000);
+
+ if (argc == 0) {
+ kdb_cpu_status();
+ return 0;
+ }
+
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+
+ diag = kdbgetularg(argv[1], &cpunum);
+ if (diag)
+ return diag;
+
+ /*
+ * Validate cpunum
+ */
+ if ((cpunum > NR_CPUS)
+ || !cpu_online(cpunum)
+ || !KDB_STATE_CPU(KDB, cpunum))
+ return KDB_BADCPUNUM;
+
+ kdb_new_cpu = cpunum;
+
+ /*
+ * Switch to other cpu
+ */
+ return KDB_CMD_CPU;
+}
+
+/* The user may not realize that ps/bta with no parameters does not print idle
+ * or sleeping system daemon processes, so tell them how many were suppressed.
+ */
+void
+kdb_ps_suppressed(void)
+{
+ int idle = 0, daemon = 0;
+ unsigned long mask_I = kdb_task_state_string("I"),
+ mask_M = kdb_task_state_string("M");
+ unsigned long cpu;
+ const struct task_struct *p, *g;
+ for (cpu = 0; cpu < NR_CPUS; ++cpu) {
+ if (!cpu_online(cpu))
+ continue;
+ p = kdb_curr_task(cpu);
+ if (kdb_task_state(p, mask_I))
+ ++idle;
+ }
+ do_each_thread(g, p) {
+ if (kdb_task_state(p, mask_M))
+ ++daemon;
+ } while_each_thread(g, p);
+ if (idle || daemon) {
+ if (idle)
+ kdb_printf("%d Idle task%s%s",
+ idle, idle == 1 ? "" : "s",
+ daemon ? " and " : "");
+ if (daemon)
+ kdb_printf("%d sleeping system daeMon%s",
+ daemon, daemon == 1 ? "" : "s");
+ kdb_printf(" not shown\n");
+ }
+}
+
+/*
+ * kdb_ps
+ *
+ * This function implements the 'ps' command which shows
+ * a list of the active processes.
+ *
+ * ps [DRSTCZEUIMA] All processes, optionally filtered by state
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ */
+
+void
+kdb_ps1(const struct task_struct *p)
+{
+ struct kdb_running_process *krp = kdb_running_process + kdb_process_cpu(p);
+ kdb_printf("%p %8d %8d %3d%c %c %p %c%s\n",
+ (void *)p, p->pid, p->parent->pid,
+ kdb_process_cpu(p), task_curr(p) ? '*': ' ',
+ kdb_task_state_char(p),
+ (void *)(&p->thread),
+ p == kdb_curr_task(smp_processor_id()) ? '*': ' ',
+ p->comm);
+ if (task_curr(p)) {
+ if (!krp->seqno || !krp->p)
+ kdb_printf(" Error: no saved data for this cpu\n");
+ else {
+ if (krp->seqno < kdb_seqno - 1)
+ kdb_printf(" Warning: process state is stale\n");
+ if (krp->p != p)
+ kdb_printf(" Error: does not match running process table (0x%p)\n", krp->p);
+ }
+ }
+}
+
+static int
+kdb_ps(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ struct task_struct *g, *p;
+ unsigned long mask, cpu;
+
+ if (argc == 0)
+ kdb_ps_suppressed();
+ kdb_printf("%-*s Pid Parent Cpu State%*s Command\n",
+ (int)(2*sizeof(void *)), "TaskAddr",
+ (int)(2*sizeof(void *)), "Thread");
+ mask = kdb_task_state_string(argc ? argv[1] : NULL);
+ /* Run the active tasks first */
+ for (cpu = 0; cpu < NR_CPUS; ++cpu) {
+ if (!cpu_online(cpu))
+ continue;
+ p = kdb_curr_task(cpu);
+ if (kdb_task_state(p, mask))
+ kdb_ps1(p);
+ }
+ /* Now the real tasks */
+ do_each_thread(g, p) {
+ if (kdb_task_state(p, mask))
+ kdb_ps1(p);
+ } while_each_thread(g, p);
+
+ return 0;
+}
+
+/*
+ * kdb_pid
+ *
+ * This function implements the 'pid' command which switches
+ * the currently active process.
+ *
+ * pid [<pid> | R]
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ */
+
+
+static int
+kdb_pid(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ struct task_struct *p;
+ unsigned long val;
+ int diag;
+
+ if (argc > 1)
+ return KDB_ARGCOUNT;
+
+ if (argc) {
+ if (strcmp(argv[1], "R") == 0) {
+ p = KDB_RUNNING_PROCESS_ORIGINAL[kdb_initial_cpu].p;
+ } else {
+ diag = kdbgetularg(argv[1], &val);
+ if (diag)
+ return KDB_BADINT;
+
+ p = find_task_by_pid((pid_t)val);
+ if (!p) {
+ kdb_printf("No task with pid=%d\n", (pid_t)val);
+ return 0;
+ }
+ }
+
+ kdba_set_current_task(p);
+ }
+
+ kdb_printf("KDB current process is %s (pid=%d)\n", kdb_current_task->comm,
+ kdb_current_task->pid);
+
+ return 0;
+}
+
+/*
+ * kdb_ll
+ *
+ * This function implements the 'll' command which follows a linked
+ * list and executes an arbitrary command for each element.
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ */
+
+static int
+kdb_ll(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int diag;
+ kdb_machreg_t addr;
+ long offset = 0;
+ kdb_machreg_t va;
+ unsigned long linkoffset;
+ int nextarg;
+ const char *command;
+
+ if (argc != 3) {
+ return KDB_ARGCOUNT;
+ }
+
+ nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
+ if (diag)
+ return diag;
+
+ diag = kdbgetularg(argv[2], &linkoffset);
+ if (diag)
+ return diag;
+
+ /*
+ * Using the starting address as
+ * the first element in the list, and assuming that
+ * the list ends with a null pointer.
+ */
+
+ va = addr;
+ if (!(command = kstrdup(argv[3], GFP_ATOMIC))) {
+ kdb_printf("%s: cannot duplicate command\n", __FUNCTION__);
+ return 0;
+ }
+ /* Recursive use of kdb_parse, do not use argv after this point */
+ argv = NULL;
+
+ while (va) {
+ char buf[80];
+
+ sprintf(buf, "%s " kdb_machreg_fmt "\n", command, va);
+ diag = kdb_parse(buf, regs);
+ if (diag)
+ return diag;
+
+ addr = va + linkoffset;
+ if (kdb_getword(&va, addr, sizeof(va)))
+ return 0;
+ }
+ kfree(command);
+
+ return 0;
+}
+
+/*
+ * kdb_help
+ *
+ * This function implements the 'help' and '?' commands.
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ */
+
+static int
+kdb_help(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ kdbtab_t *kt, *kte = kdb_commands + kdb_max_commands;
+
+ kdb_printf("%-15.15s %-20.20s %s\n", "Command", "Usage", "Description");
+ kdb_printf("----------------------------------------------------------\n");
+ for(kt=kdb_commands; kt < kte && kt->cmd_name; kt++) {
+ kdb_printf("%-15.15s %-20.20s %s\n", kt->cmd_name,
+ kt->cmd_usage, kt->cmd_help);
+ }
+ return 0;
+}
+
+/*
+ * kdb_kill
+ *
+ * This function implements the 'kill' commands.
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ */
+
+static int
+kdb_kill(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ long sig, pid;
+ char *endp;
+ struct task_struct *p;
+ struct siginfo info;
+
+ if (argc!=2)
+ return KDB_ARGCOUNT;
+
+ sig = simple_strtol(argv[1], &endp, 0);
+ if (*endp)
+ return KDB_BADINT;
+ if (sig >= 0 ) {
+ kdb_printf("Invalid signal parameter.<-signal>\n");
+ return 0;
+ }
+ sig=-sig;
+
+ pid = simple_strtol(argv[2], &endp, 0);
+ if (*endp)
+ return KDB_BADINT;
+ if (pid <=0 ) {
+ kdb_printf("Process ID must be larger than 0.\n");
+ return 0;
+ }
+
+ /* Find the process. */
+ if (!(p = find_task_by_pid(pid))) {
+ kdb_printf("The specified process isn't found.\n");
+ return 0;
+ }
+ p = p->group_leader;
+ info.si_signo = sig;
+ info.si_errno = 0;
+ info.si_code = SI_USER;
+ info.si_pid = pid; /* use same capabilities as process being signalled */
+ info.si_uid = 0; /* kdb has root authority */
+ kdb_send_sig_info(p, &info, kdb_seqno);
+ return 0;
+}
+
+struct kdb_tm {
+ int tm_sec; /* seconds */
+ int tm_min; /* minutes */
+ int tm_hour; /* hours */
+ int tm_mday; /* day of the month */
+ int tm_mon; /* month */
+ int tm_year; /* year */
+};
+
+static void
+kdb_gmtime(struct timespec *tv, struct kdb_tm *tm)
+{
+ /* This will work from 1970-2099, 2100 is not a leap year */
+ static int mon_day[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ memset(tm, 0, sizeof(*tm));
+ tm->tm_sec = tv->tv_sec % (24 * 60 * 60);
+ tm->tm_mday = tv->tv_sec / (24 * 60 * 60) + (2 * 365 + 1); /* shift base from 1970 to 1968 */
+ tm->tm_min = tm->tm_sec / 60 % 60;
+ tm->tm_hour = tm->tm_sec / 60 / 60;
+ tm->tm_sec = tm->tm_sec % 60;
+ tm->tm_year = 68 + 4*(tm->tm_mday / (4*365+1));
+ tm->tm_mday %= (4*365+1);
+ mon_day[1] = 29;
+ while (tm->tm_mday >= mon_day[tm->tm_mon]) {
+ tm->tm_mday -= mon_day[tm->tm_mon];
+ if (++tm->tm_mon == 12) {
+ tm->tm_mon = 0;
+ ++tm->tm_year;
+ mon_day[1] = 28;
+ }
+ }
+ ++tm->tm_mday;
+}
+
+/*
+ * Most of this code has been lifted from kernel/timer.c::sys_sysinfo().
+ * I cannot call that code directly from kdb, it has an unconditional
+ * cli()/sti() and calls routines that take locks which can stop the debugger.
+ */
+
+static void
+kdb_sysinfo(struct sysinfo *val)
+{
+ struct timespec uptime;
+ do_posix_clock_monotonic_gettime(&uptime);
+ memset(val, 0, sizeof(*val));
+ val->uptime = uptime.tv_sec;
+ val->loads[0] = avenrun[0];
+ val->loads[1] = avenrun[1];
+ val->loads[2] = avenrun[2];
+ val->procs = nr_threads-1;
+}
+
+/*
+ * kdb_summary
+ *
+ * This function implements the 'summary' command.
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ */
+
+static int
+kdb_summary(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ extern struct timespec xtime;
+ extern struct timezone sys_tz;
+ struct kdb_tm tm;
+ struct sysinfo val;
+
+ if (argc)
+ return KDB_ARGCOUNT;
+
+ kdb_printf("sysname %s\n", system_utsname.sysname);
+ kdb_printf("release %s\n", system_utsname.release);
+ kdb_printf("version %s\n", system_utsname.version);
+ kdb_printf("machine %s\n", system_utsname.machine);
+ kdb_printf("nodename %s\n", system_utsname.nodename);
+ kdb_printf("domainname %s\n", system_utsname.domainname);
+
+ kdb_gmtime(&xtime, &tm);
+ kdb_printf("date %04d-%02d-%02d %02d:%02d:%02d tz_minuteswest %d\n",
+ 1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec,
+ sys_tz.tz_minuteswest);
+
+ kdb_sysinfo(&val);
+ kdb_printf("uptime ");
+ if (val.uptime > (24*60*60)) {
+ int days = val.uptime / (24*60*60);
+ val.uptime %= (24*60*60);
+ kdb_printf("%d day%s ", days, days == 1 ? "" : "s");
+ }
+ kdb_printf("%02ld:%02ld\n", val.uptime/(60*60), (val.uptime/60)%60);
+
+ /* lifted from fs/proc/proc_misc.c::loadavg_read_proc() */
+
+#define LOAD_INT(x) ((x) >> FSHIFT)
+#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
+ kdb_printf("load avg %ld.%02ld %ld.%02ld %ld.%02ld\n",
+ LOAD_INT(val.loads[0]), LOAD_FRAC(val.loads[0]),
+ LOAD_INT(val.loads[1]), LOAD_FRAC(val.loads[1]),
+ LOAD_INT(val.loads[2]), LOAD_FRAC(val.loads[2]));
+ kdb_printf("\n");
+#undef LOAD_INT
+#undef LOAD_FRAC
+
+ return 0;
+}
+
+/*
+ * kdb_per_cpu
+ *
+ * This function implements the 'per_cpu' command.
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ */
+
+static int
+kdb_per_cpu(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ char buf[256], fmtstr[64];
+ kdb_symtab_t symtab;
+ cpumask_t suppress = CPU_MASK_NONE;
+ int cpu, diag;
+ unsigned long addr, val, bytesperword = 0, whichcpu = ~0UL;
+ char *cp;
+ unsigned long off = 0;
+
+ if (argc < 1 || argc > 3)
+ return KDB_ARGCOUNT;
+
+ snprintf(buf, sizeof(buf), "per_cpu__%s", argv[1]);
+ if ((cp = strchr(buf, '+')) != NULL) {
+ *cp++ = '\0';
+ diag = kdbgetularg(cp, &off);
+ if (diag)
+ return diag;
+ }
+ if (!kdbgetsymval(buf, &symtab)) {
+ kdb_printf("%s is not a per_cpu variable\n", argv[1]);
+ return KDB_BADADDR;
+ }
+ if (argc >=2 && (diag = kdbgetularg(argv[2], &bytesperword)))
+ return diag;
+ if (!bytesperword)
+ bytesperword = sizeof(kdb_machreg_t);
+ else if (bytesperword > sizeof(kdb_machreg_t))
+ return KDB_BADWIDTH;
+ sprintf(fmtstr, "%%0%dlx ", (int)(2*bytesperword));
+ if (argc >= 3) {
+ if ((diag = kdbgetularg(argv[3], &whichcpu)))
+ return diag;
+ if (!cpu_online(whichcpu)) {
+ kdb_printf("cpu %ld is not online\n", whichcpu);
+ return KDB_BADCPUNUM;
+ }
+ }
+
+ /* Most architectures use __per_cpu_offset[cpu], some use
+ * __per_cpu_offset(cpu), smp has no __per_cpu_offset.
+ */
+#ifdef __per_cpu_offset
+#define KDB_PCU(cpu) __per_cpu_offset(cpu)
+#else
+#ifdef CONFIG_SMP
+#define KDB_PCU(cpu) __per_cpu_offset[cpu]
+#else
+#define KDB_PCU(cpu) 0
+#endif
+#endif
+
+ for_each_online_cpu(cpu) {
+ if (whichcpu != ~0UL && whichcpu != cpu)
+ continue;
+ addr = symtab.sym_start + off + KDB_PCU(cpu);
+ if ((diag = kdb_getword(&val, addr, bytesperword))) {
+ kdb_printf("%5d " kdb_bfd_vma_fmt0 " - unable to read, diag=%d\n",
+ cpu, addr, diag);
+ continue;
+ }
+#ifdef CONFIG_SMP
+ if (!val) {
+ cpu_set(cpu, suppress);
+ continue;
+ }
+#endif /* CONFIG_SMP */
+ kdb_printf("%5d ", cpu);
+ kdb_md_line(fmtstr, addr,
+ bytesperword == sizeof(kdb_machreg_t),
+ bytesperword, 1, 1, 0);
+ }
+ if (cpus_weight(suppress) == 0)
+ return 0;
+ kdb_printf("Zero suppressed cpu(s):");
+ for (cpu = first_cpu(suppress); cpu < NR_CPUS; cpu = next_cpu(cpu, suppress)) {
+ kdb_printf(" %d", cpu);
+ if (cpu == NR_CPUS-1 || next_cpu(cpu, suppress) != cpu + 1)
+ continue;
+ while (cpu < NR_CPUS && next_cpu(cpu, suppress) == cpu + 1)
+ ++cpu;
+ kdb_printf("-%d", cpu);
+ }
+ kdb_printf("\n");
+
+#undef KDB_PCU
+
+ return 0;
+}
+
+/*
+ * kdb_register_repeat
+ *
+ * This function is used to register a kernel debugger command.
+ *
+ * Inputs:
+ * cmd Command name
+ * func Function to execute the command
+ * usage A simple usage string showing arguments
+ * help A simple help string describing command
+ * repeat Does the command auto repeat on enter?
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, one if a duplicate command.
+ * Locking:
+ * none.
+ * Remarks:
+ *
+ */
+
+#define kdb_command_extend 50 /* arbitrary */
+int
+kdb_register_repeat(char *cmd,
+ kdb_func_t func,
+ char *usage,
+ char *help,
+ short minlen,
+ kdb_repeat_t repeat)
+{
+ int i;
+ kdbtab_t *kp;
+
+ /*
+ * Brute force method to determine duplicates
+ */
+ for (i=0, kp=kdb_commands; i<kdb_max_commands; i++, kp++) {
+ if (kp->cmd_name && (strcmp(kp->cmd_name, cmd)==0)) {
+ kdb_printf("Duplicate kdb command registered: '%s'\n",
+ cmd);
+ return 1;
+ }
+ }
+
+ /*
+ * Insert command into first available location in table
+ */
+ for (i=0, kp=kdb_commands; i<kdb_max_commands; i++, kp++) {
+ if (kp->cmd_name == NULL) {
+ break;
+ }
+ }
+
+ if (i >= kdb_max_commands) {
+ kdbtab_t *new = kmalloc((kdb_max_commands + kdb_command_extend) * sizeof(*new), GFP_ATOMIC);
+ if (!new) {
+ kdb_printf("Could not allocate new kdb_command table\n");
+ return 1;
+ }
+ if (kdb_commands) {
+ memcpy(new, kdb_commands, kdb_max_commands * sizeof(*new));
+ kfree(kdb_commands);
+ }
+ memset(new + kdb_max_commands, 0, kdb_command_extend * sizeof(*new));
+ kdb_commands = new;
+ kp = kdb_commands + kdb_max_commands;
+ kdb_max_commands += kdb_command_extend;
+ }
+
+ kp->cmd_name = cmd;
+ kp->cmd_func = func;
+ kp->cmd_usage = usage;
+ kp->cmd_help = help;
+ kp->cmd_flags = 0;
+ kp->cmd_minlen = minlen;
+ kp->cmd_repeat = repeat;
+
+ return 0;
+}
+
+/*
+ * kdb_register
+ *
+ * Compatibility register function for commands that do not need to
+ * specify a repeat state. Equivalent to kdb_register_repeat with
+ * KDB_REPEAT_NONE.
+ *
+ * Inputs:
+ * cmd Command name
+ * func Function to execute the command
+ * usage A simple usage string showing arguments
+ * help A simple help string describing command
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, one if a duplicate command.
+ * Locking:
+ * none.
+ * Remarks:
+ *
+ */
+
+int
+kdb_register(char *cmd,
+ kdb_func_t func,
+ char *usage,
+ char *help,
+ short minlen)
+{
+ return kdb_register_repeat(cmd, func, usage, help, minlen, KDB_REPEAT_NONE);
+}
+
+/*
+ * kdb_unregister
+ *
+ * This function is used to unregister a kernel debugger command.
+ * It is generally called when a module which implements kdb
+ * commands is unloaded.
+ *
+ * Inputs:
+ * cmd Command name
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, one command not registered.
+ * Locking:
+ * none.
+ * Remarks:
+ *
+ */
+
+int
+kdb_unregister(char *cmd)
+{
+ int i;
+ kdbtab_t *kp;
+
+ /*
+ * find the command.
+ */
+ for (i=0, kp=kdb_commands; i<kdb_max_commands; i++, kp++) {
+ if (kp->cmd_name && (strcmp(kp->cmd_name, cmd)==0)) {
+ kp->cmd_name = NULL;
+ return 0;
+ }
+ }
+
+ /*
+ * Couldn't find it.
+ */
+ return 1;
+}
+
+/*
+ * kdb_inittab
+ *
+ * This function is called by the kdb_init function to initialize
+ * the kdb command table. It must be called prior to any other
+ * call to kdb_register_repeat.
+ *
+ * Inputs:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ */
+
+static void __init
+kdb_inittab(void)
+{
+ int i;
+ kdbtab_t *kp;
+
+ for(i=0, kp=kdb_commands; i < kdb_max_commands; i++,kp++) {
+ kp->cmd_name = NULL;
+ }
+
+ kdb_register_repeat("md", kdb_md, "<vaddr>", "Display Memory, also mdWcN, e.g. md8c1", 1, KDB_REPEAT_NO_ARGS);
+ kdb_register_repeat("mdr", kdb_md, "<vaddr> <bytes>", "Display Raw Memory", 0, KDB_REPEAT_NO_ARGS);
+ kdb_register_repeat("mdp", kdb_md, "<paddr> <bytes>", "Display Physical Memory", 0, KDB_REPEAT_NO_ARGS);
+ kdb_register_repeat("mds", kdb_md, "<vaddr>", "Display Memory Symbolically", 0, KDB_REPEAT_NO_ARGS);
+ kdb_register_repeat("mm", kdb_mm, "<vaddr> <contents>", "Modify Memory Contents", 0, KDB_REPEAT_NO_ARGS);
+ kdb_register_repeat("id", kdb_id, "<vaddr>", "Display Instructions", 1, KDB_REPEAT_NO_ARGS);
+ kdb_register_repeat("go", kdb_go, "[<vaddr>]", "Continue Execution", 1, KDB_REPEAT_NONE);
+ kdb_register_repeat("rd", kdb_rd, "", "Display Registers", 1, KDB_REPEAT_NONE);
+ kdb_register_repeat("rm", kdb_rm, "<reg> <contents>", "Modify Registers", 0, KDB_REPEAT_NONE);
+ kdb_register_repeat("ef", kdb_ef, "<vaddr>", "Display exception frame", 0, KDB_REPEAT_NONE);
+ kdb_register_repeat("bt", kdb_bt, "[<vaddr>]", "Stack traceback", 1, KDB_REPEAT_NONE);
+ kdb_register_repeat("btp", kdb_bt, "<pid>", "Display stack for process <pid>", 0, KDB_REPEAT_NONE);
+ kdb_register_repeat("bta", kdb_bt, "[DRSTCZEUIMA]", "Display stack all processes", 0, KDB_REPEAT_NONE);
+ kdb_register_repeat("btc", kdb_bt, "", "Backtrace current process on each cpu", 0, KDB_REPEAT_NONE);
+ kdb_register_repeat("btt", kdb_bt, "<vaddr>", "Backtrace process given struct task address", 0, KDB_REPEAT_NONE);
+ kdb_register_repeat("ll", kdb_ll, "<first-element> <linkoffset> <cmd>", "Execute cmd for each element in linked list", 0, KDB_REPEAT_NONE);
+ kdb_register_repeat("env", kdb_env, "", "Show environment variables", 0, KDB_REPEAT_NONE);
+ kdb_register_repeat("set", kdb_set, "", "Set environment variables", 0, KDB_REPEAT_NONE);
+ kdb_register_repeat("help", kdb_help, "", "Display Help Message", 1, KDB_REPEAT_NONE);
+ kdb_register_repeat("?", kdb_help, "", "Display Help Message", 0, KDB_REPEAT_NONE);
+ kdb_register_repeat("cpu", kdb_cpu, "<cpunum>","Switch to new cpu", 0, KDB_REPEAT_NONE);
+ kdb_register_repeat("ps", kdb_ps, "", "Display active task list", 0, KDB_REPEAT_NONE);
+ kdb_register_repeat("pid", kdb_pid, "<pidnum>", "Switch to another task", 0, KDB_REPEAT_NONE);
+ kdb_register_repeat("reboot", kdb_reboot, "", "Reboot the machine immediately", 0, KDB_REPEAT_NONE);
+#if defined(CONFIG_MODULES)
+ kdb_register_repeat("lsmod", kdb_lsmod, "", "List loaded kernel modules", 0, KDB_REPEAT_NONE);
+#endif
+#if defined(CONFIG_MAGIC_SYSRQ)
+ kdb_register_repeat("sr", kdb_sr, "<key>", "Magic SysRq key", 0, KDB_REPEAT_NONE);
+#endif
+ kdb_register_repeat("dmesg", kdb_dmesg, "[lines]", "Display syslog buffer", 0, KDB_REPEAT_NONE);
+ kdb_register_repeat("defcmd", kdb_defcmd, "name \"usage\" \"help\"", "Define a set of commands, down to endefcmd", 0, KDB_REPEAT_NONE);
+ kdb_register_repeat("kill", kdb_kill, "<-signal> <pid>", "Send a signal to a process", 0, KDB_REPEAT_NONE);
+ kdb_register_repeat("summary", kdb_summary, "", "Summarize the system", 4, KDB_REPEAT_NONE);
+ kdb_register_repeat("per_cpu", kdb_per_cpu, "", "Display per_cpu variables", 3, KDB_REPEAT_NONE);
+}
+
+/*
+ * kdb_cmd_init
+ *
+ * This function is called by the kdb_init function to execute any
+ * commands defined in kdb_cmds.
+ *
+ * Inputs:
+ * Commands in *kdb_cmds[];
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ *
+ */
+
+static void __init
+kdb_cmd_init(void)
+{
+ int i, diag;
+ for (i = 0; kdb_cmds[i]; ++i) {
+ if (!defcmd_in_progress)
+ kdb_printf("kdb_cmd[%d]: %s", i, kdb_cmds[i]);
+ diag = kdb_parse(kdb_cmds[i], NULL);
+ if (diag)
+ kdb_printf("command failed, kdb diag %d\n", diag);
+ }
+ if (defcmd_in_progress) {
+ kdb_printf("Incomplete 'defcmd' set, forcing endefcmd\n");
+ kdb_parse("endefcmd", NULL);
+ }
+}
+
+/*
+ * kdb_panic
+ *
+ * Invoked via the panic_notifier_list.
+ *
+ * Inputs:
+ * None.
+ * Outputs:
+ * None.
+ * Returns:
+ * Zero.
+ * Locking:
+ * None.
+ * Remarks:
+ * When this function is called from panic(), the other cpus have already
+ * been stopped.
+ *
+ */
+
+static int
+kdb_panic(struct notifier_block *self, unsigned long command, void *ptr)
+{
+ KDB_FLAG_SET(CATASTROPHIC); /* kernel state is dubious now */
+ KDB_ENTER();
+ return 0;
+}
+
+static struct notifier_block kdb_block = { kdb_panic, NULL, 0 };
+
+#ifdef CONFIG_SYSCTL
+static int proc_do_kdb(ctl_table *table, int write, struct file *filp,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ if (KDB_FLAG(NO_CONSOLE) && write) {
+ printk(KERN_ERR "kdb has no working console and has switched itself off\n");
+ return -EINVAL;
+ }
+ return proc_dointvec(table, write, filp, buffer, lenp, ppos);
+}
+
+static ctl_table kdb_kern_table[] = {
+#ifdef CONFIG_XMON
+ {
+ .ctl_name = KERN_XMON,
+ .procname = "xmon",
+ .data = &xmon_on,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+#endif /* CONFIG_XMON */
+ {
+ .ctl_name = KERN_KDB,
+ .procname = "kdb",
+ .data = &kdb_on,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_do_kdb,
+ },
+ {}
+};
+
+static ctl_table kdb_root_table[] = {
+ {
+ .ctl_name = CTL_KERN,
+ .procname = "kernel",
+ .mode = 0555,
+ .child = kdb_kern_table,
+ },
+ {}
+};
+#endif /* CONFIG_SYSCTL */
+
+static int
+kdb_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+ if (action == CPU_ONLINE) {
+ int cpu =(unsigned long)hcpu;
+ cpumask_t save_cpus_allowed = current->cpus_allowed;
+ cpumask_t new_cpus_allowed = cpumask_of_cpu(cpu);
+ set_cpus_allowed(current, new_cpus_allowed);
+ kdb(KDB_REASON_CPU_UP, 0, NULL); /* do kdb setup on this cpu */
+ set_cpus_allowed(current, save_cpus_allowed);
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block kdb_cpu_nfb = {
+ .notifier_call = kdb_cpu_callback
+};
+
+/*
+ * kdb_init
+ *
+ * Initialize the kernel debugger environment.
+ *
+ * Parameters:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * None.
+ * Remarks:
+ * None.
+ */
+
+void __init
+kdb_init(void)
+{
+ kdb_initial_cpu = smp_processor_id();
+ /*
+ * This must be called before any calls to kdb_printf.
+ */
+ kdb_io_init();
+
+ kdb_inittab(); /* Initialize Command Table */
+ kdb_initbptab(); /* Initialize Breakpoint Table */
+ kdb_id_init(); /* Initialize Disassembler */
+ kdba_init(); /* Architecture Dependent Initialization */
+
+ /*
+ * Use printk() to get message in log_buf[];
+ */
+ printk("kdb version %d.%d%s by Keith Owens, Scott Lurndal. "\
+ "Copyright SGI, All Rights Reserved\n",
+ KDB_MAJOR_VERSION, KDB_MINOR_VERSION, KDB_TEST_VERSION);
+
+ kdb_cmd_init(); /* Preset commands from kdb_cmds */
+ kdb_initial_cpu = -1; /* Avoid recursion problems */
+ kdb(KDB_REASON_CPU_UP, 0, NULL); /* do kdb setup on boot cpu */
+ kdb_initial_cpu = smp_processor_id();
+ atomic_notifier_chain_register(&panic_notifier_list, &kdb_block);
+ register_cpu_notifier(&kdb_cpu_nfb);
+
+#ifdef kdba_setjmp
+ kdbjmpbuf = vmalloc(NR_CPUS * sizeof(*kdbjmpbuf));
+ if (!kdbjmpbuf)
+ printk(KERN_ERR "Cannot allocate kdbjmpbuf, no kdb recovery will be possible\n");
+#endif /* kdba_setjmp */
+
+ kdb_initial_cpu = -1;
+ kdb_wait_for_cpus_secs = max(10, 2*num_online_cpus());
+}
+
+#ifdef CONFIG_SYSCTL
+static int __init
+kdb_late_init(void)
+{
+ register_sysctl_table(kdb_root_table, 0);
+ return 0;
+}
+
+__initcall(kdb_late_init);
+#endif
+
+EXPORT_SYMBOL(kdb_register);
+EXPORT_SYMBOL(kdb_register_repeat);
+EXPORT_SYMBOL(kdb_unregister);
+EXPORT_SYMBOL(kdb_getarea_size);
+EXPORT_SYMBOL(kdb_putarea_size);
+EXPORT_SYMBOL(kdb_getuserarea_size);
+EXPORT_SYMBOL(kdb_putuserarea_size);
+EXPORT_SYMBOL(kdbgetularg);
+EXPORT_SYMBOL(kdbgetenv);
+EXPORT_SYMBOL(kdbgetintenv);
+EXPORT_SYMBOL(kdbgetaddrarg);
+EXPORT_SYMBOL(kdb);
+EXPORT_SYMBOL(kdb_on);
+EXPORT_SYMBOL(kdb_seqno);
+EXPORT_SYMBOL(kdb_initial_cpu);
+EXPORT_SYMBOL(kdbnearsym);
+EXPORT_SYMBOL(kdb_printf);
+EXPORT_SYMBOL(kdb_symbol_print);
+EXPORT_SYMBOL(kdb_running_process);
--- /dev/null
+/*
+ * Kernel Debugger Architecture Independent Support Functions
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ * 03/02/13 added new 2.5 kallsyms <xavier.bru@bull.net>
+ */
+
+#include <stdarg.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/kallsyms.h>
+#include <linux/stddef.h>
+#include <linux/vmalloc.h>
+#include <linux/ptrace.h>
+#include <linux/module.h>
+#include <linux/highmem.h>
+#include <linux/hugetlb.h>
+#include <linux/hardirq.h>
+#include <linux/delay.h>
+
+#include <asm/uaccess.h>
+
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+
+#ifdef CONFIG_MODULES
+extern struct list_head *kdb_modules;
+#endif
+
+/*
+ * Symbol table functions.
+ */
+
+/*
+ * kdbgetsymval
+ *
+ * Return the address of the given symbol.
+ *
+ * Parameters:
+ * symname Character string containing symbol name
+ * symtab Structure to receive results
+ * Outputs:
+ * Returns:
+ * 0 Symbol not found, symtab zero filled
+ * 1 Symbol mapped to module/symbol/section, data in symtab
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+int
+kdbgetsymval(const char *symname, kdb_symtab_t *symtab)
+{
+ memset(symtab, 0, sizeof(*symtab));
+ symtab->sym_start = kallsyms_lookup_name(symname);
+ return symtab->sym_start != 0;
+}
+
+/*
+ * kdbnearsym
+ *
+ * Return the name of the symbol with the nearest address
+ * less than 'addr'.
+ *
+ * Parameters:
+ * addr Address to check for symbol near
+ * symtab Structure to receive results
+ * Outputs:
+ * Returns:
+ * 0 No sections contain this address, symtab zero filled
+ * 1 Address mapped to module/symbol, data in symtab
+ * Locking:
+ * None.
+ * Remarks:
+ */
+
+int
+kdbnearsym(unsigned long addr, kdb_symtab_t *symtab)
+{
+ static char namebuf[KSYM_NAME_LEN+1];
+ unsigned long offset;
+
+ memset(symtab, 0, sizeof(*symtab));
+ symtab->sym_name = kallsyms_lookup(addr, &symtab->sym_end,
+ &offset, (char **)&symtab->mod_name, namebuf);
+ if (symtab->sym_name == NULL)
+ return 0;
+ symtab->value = addr;
+ symtab->sym_start = addr - offset;
+ symtab->sym_end += symtab->sym_start;
+ if (symtab->mod_name == NULL)
+ symtab->mod_name = "kernel";
+ return 1;
+}
+
+/*
+ * kallsyms_symbol_complete
+ *
+ * Parameters:
+ * prefix_name prefix of a symbol name to lookup
+ * max_len maximum length that can be returned
+ * Returns:
+ * Number of symbols which match the given prefix.
+ * Notes:
+ * prefix_name is changed to contain the longest unique prefix that
+ * starts with this prefix (tab completion).
+ */
+
+static char ks_namebuf[KSYM_NAME_LEN+1], ks_namebuf_prev[KSYM_NAME_LEN+1];
+
+int kallsyms_symbol_complete(char *prefix_name, int max_len)
+{
+ loff_t pos = 0;
+ int prefix_len = strlen(prefix_name), prev_len = 0;
+ int i, number = 0;
+ const char *name;
+
+ while ((name = kdb_walk_kallsyms(&pos))) {
+ if (strncmp(name, prefix_name, prefix_len) == 0) {
+ strcpy(ks_namebuf, name);
+ /* Work out the longest name that matches the prefix */
+ if (++number == 1) {
+ prev_len = min_t(int, max_len-1, strlen(ks_namebuf));
+ memcpy(ks_namebuf_prev, ks_namebuf, prev_len);
+ ks_namebuf_prev[prev_len] = '\0';
+ } else for (i = 0; i < prev_len; ++i) {
+ if (ks_namebuf[i] != ks_namebuf_prev[i]) {
+ prev_len = i;
+ ks_namebuf_prev[i] = '\0';
+ break;
+ }
+ }
+ }
+ }
+ if (prev_len > prefix_len)
+ memcpy(prefix_name, ks_namebuf_prev, prev_len+1);
+ return number;
+}
+
+/*
+ * kallsyms_symbol_next
+ *
+ * Parameters:
+ * prefix_name prefix of a symbol name to lookup
+ * flag 0 means search from the head, 1 means continue search.
+ * Returns:
+ * 1 if a symbol matches the given prefix.
+ * 0 if no string found
+ */
+
+int kallsyms_symbol_next(char *prefix_name, int flag)
+{
+ int prefix_len = strlen(prefix_name);
+ static loff_t pos;
+ const char *name;
+
+ if (!flag)
+ pos = 0;
+
+ while ((name = kdb_walk_kallsyms(&pos))) {
+ if (strncmp(name, prefix_name, prefix_len) == 0) {
+ strncpy(prefix_name, name, strlen(name)+1);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+#if defined(CONFIG_SMP)
+/*
+ * kdb_ipi
+ *
+ * This function is called from the non-maskable interrupt
+ * handler to handle a kdb IPI instruction.
+ *
+ * Inputs:
+ * regs = Exception frame pointer
+ * Outputs:
+ * None.
+ * Returns:
+ * 0 - Did not handle NMI
+ * 1 - Handled NMI
+ * Locking:
+ * None.
+ * Remarks:
+ * Initially one processor is invoked in the kdb() code. That
+ * processor sends an ipi which drives this routine on the other
+ * processors. All this does is call kdb() with reason SWITCH.
+ * This puts all processors into the kdb() routine and all the
+ * code for breakpoints etc. is in one place.
+ * One problem with the way the kdb NMI is sent, the NMI has no
+ * identification that says it came from kdb. If the cpu's kdb state is
+ * marked as "waiting for kdb_ipi" then the NMI is treated as coming from
+ * kdb, otherwise it is assumed to be for another reason and is ignored.
+ */
+
+int
+kdb_ipi(struct pt_regs *regs, void (*ack_interrupt)(void))
+{
+ /* Do not print before checking and clearing WAIT_IPI, IPIs are
+ * going all the time.
+ */
+ if (KDB_STATE(WAIT_IPI)) {
+ /*
+ * Stopping other processors via smp_kdb_stop().
+ */
+ if (ack_interrupt)
+ (*ack_interrupt)(); /* Acknowledge the interrupt */
+ KDB_STATE_CLEAR(WAIT_IPI);
+ KDB_DEBUG_STATE("kdb_ipi 1", 0);
+ kdb(KDB_REASON_SWITCH, 0, regs); /* Spin in kdb() */
+ KDB_DEBUG_STATE("kdb_ipi 2", 0);
+ return 1;
+ }
+ return 0;
+}
+#endif /* CONFIG_SMP */
+
+/*
+ * kdb_symbol_print
+ *
+ * Standard method for printing a symbol name and offset.
+ * Inputs:
+ * addr Address to be printed.
+ * symtab Address of symbol data, if NULL this routine does its
+ * own lookup.
+ * punc Punctuation for string, bit field.
+ * Outputs:
+ * None.
+ * Returns:
+ * Always 0.
+ * Locking:
+ * none.
+ * Remarks:
+ * The string and its punctuation is only printed if the address
+ * is inside the kernel, except that the value is always printed
+ * when requested.
+ */
+
+void
+kdb_symbol_print(kdb_machreg_t addr, const kdb_symtab_t *symtab_p, unsigned int punc)
+{
+ kdb_symtab_t symtab, *symtab_p2;
+ if (symtab_p) {
+ symtab_p2 = (kdb_symtab_t *)symtab_p;
+ }
+ else {
+ symtab_p2 = &symtab;
+ kdbnearsym(addr, symtab_p2);
+ }
+ if (symtab_p2->sym_name || (punc & KDB_SP_VALUE)) {
+ ; /* drop through */
+ }
+ else {
+ return;
+ }
+ if (punc & KDB_SP_SPACEB) {
+ kdb_printf(" ");
+ }
+ if (punc & KDB_SP_VALUE) {
+ kdb_printf(kdb_machreg_fmt0, addr);
+ }
+ if (symtab_p2->sym_name) {
+ if (punc & KDB_SP_VALUE) {
+ kdb_printf(" ");
+ }
+ if (punc & KDB_SP_PAREN) {
+ kdb_printf("(");
+ }
+ if (strcmp(symtab_p2->mod_name, "kernel")) {
+ kdb_printf("[%s]", symtab_p2->mod_name);
+ }
+ kdb_printf("%s", symtab_p2->sym_name);
+ if (addr != symtab_p2->sym_start) {
+ kdb_printf("+0x%lx", addr - symtab_p2->sym_start);
+ }
+ if (punc & KDB_SP_SYMSIZE) {
+ kdb_printf("/0x%lx", symtab_p2->sym_end - symtab_p2->sym_start);
+ }
+ if (punc & KDB_SP_PAREN) {
+ kdb_printf(")");
+ }
+ }
+ if (punc & KDB_SP_SPACEA) {
+ kdb_printf(" ");
+ }
+ if (punc & KDB_SP_NEWLINE) {
+ kdb_printf("\n");
+ }
+}
+
+/*
+ * kdb_getarea_size
+ *
+ * Read an area of data. The kdb equivalent of copy_from_user, with
+ * kdb messages for invalid addresses.
+ * Inputs:
+ * res Pointer to the area to receive the result.
+ * addr Address of the area to copy.
+ * size Size of the area.
+ * Outputs:
+ * none.
+ * Returns:
+ * 0 for success, < 0 for error.
+ * Locking:
+ * none.
+ */
+
+int kdb_getarea_size(void *res, unsigned long addr, size_t size)
+{
+ int ret = kdba_getarea_size(res, addr, size);
+ if (ret) {
+ if (!KDB_STATE(SUPPRESS)) {
+ kdb_printf("kdb_getarea: Bad address 0x%lx\n", addr);
+ KDB_STATE_SET(SUPPRESS);
+ }
+ ret = KDB_BADADDR;
+ }
+ else {
+ KDB_STATE_CLEAR(SUPPRESS);
+ }
+ return(ret);
+}
+
+/*
+ * kdb_putarea_size
+ *
+ * Write an area of data. The kdb equivalent of copy_to_user, with
+ * kdb messages for invalid addresses.
+ * Inputs:
+ * addr Address of the area to write to.
+ * res Pointer to the area holding the data.
+ * size Size of the area.
+ * Outputs:
+ * none.
+ * Returns:
+ * 0 for success, < 0 for error.
+ * Locking:
+ * none.
+ */
+
+int kdb_putarea_size(unsigned long addr, void *res, size_t size)
+{
+ int ret = kdba_putarea_size(addr, res, size);
+ if (ret) {
+ if (!KDB_STATE(SUPPRESS)) {
+ kdb_printf("kdb_putarea: Bad address 0x%lx\n", addr);
+ KDB_STATE_SET(SUPPRESS);
+ }
+ ret = KDB_BADADDR;
+ }
+ else {
+ KDB_STATE_CLEAR(SUPPRESS);
+ }
+ return(ret);
+}
+
+/*
+ * kdb_getphys
+ *
+ * Read data from a physical address. Validate the address is in range,
+ * use kmap_atomic() to get data
+ *
+ * Similar to kdb_getarea() - but for phys addresses
+ *
+ * Inputs:
+ * res Pointer to the word to receive the result
+ * addr Physical address of the area to copy
+ * size Size of the area
+ * Outputs:
+ * none.
+ * Returns:
+ * 0 for success, < 0 for error.
+ * Locking:
+ * none.
+ */
+static int kdb_getphys(void *res, unsigned long addr, size_t size)
+{
+ unsigned long pfn;
+ void *vaddr;
+ struct page *page;
+
+ pfn = (addr >> PAGE_SHIFT);
+ if (!pfn_valid(pfn))
+ return 1;
+ page = pfn_to_page(pfn);
+ vaddr = kmap_atomic(page, KM_KDB);
+ memcpy(res, vaddr + (addr & (PAGE_SIZE -1)), size);
+ kunmap_atomic(vaddr, KM_KDB);
+
+ return 0;
+}
+
+/*
+ * kdb_getphysword
+ *
+ * Inputs:
+ * word Pointer to the word to receive the result.
+ * addr Address of the area to copy.
+ * size Size of the area.
+ * Outputs:
+ * none.
+ * Returns:
+ * 0 for success, < 0 for error.
+ * Locking:
+ * none.
+ */
+int kdb_getphysword(unsigned long *word, unsigned long addr, size_t size)
+{
+ int diag;
+ __u8 w1;
+ __u16 w2;
+ __u32 w4;
+ __u64 w8;
+ *word = 0; /* Default value if addr or size is invalid */
+
+ switch (size) {
+ case 1:
+ if (!(diag = kdb_getphys(&w1, addr, sizeof(w1))))
+ *word = w1;
+ break;
+ case 2:
+ if (!(diag = kdb_getphys(&w2, addr, sizeof(w2))))
+ *word = w2;
+ break;
+ case 4:
+ if (!(diag = kdb_getphys(&w4, addr, sizeof(w4))))
+ *word = w4;
+ break;
+ case 8:
+ if (size <= sizeof(*word)) {
+ if (!(diag = kdb_getphys(&w8, addr, sizeof(w8))))
+ *word = w8;
+ break;
+ }
+ /* drop through */
+ default:
+ diag = KDB_BADWIDTH;
+ kdb_printf("kdb_getphysword: bad width %ld\n", (long) size);
+ }
+ return(diag);
+}
+
+/*
+ * kdb_getword
+ *
+ * Read a binary value. Unlike kdb_getarea, this treats data as numbers.
+ * Inputs:
+ * word Pointer to the word to receive the result.
+ * addr Address of the area to copy.
+ * size Size of the area.
+ * Outputs:
+ * none.
+ * Returns:
+ * 0 for success, < 0 for error.
+ * Locking:
+ * none.
+ */
+
+int kdb_getword(unsigned long *word, unsigned long addr, size_t size)
+{
+ int diag;
+ __u8 w1;
+ __u16 w2;
+ __u32 w4;
+ __u64 w8;
+ *word = 0; /* Default value if addr or size is invalid */
+ switch (size) {
+ case 1:
+ if (!(diag = kdb_getarea(w1, addr)))
+ *word = w1;
+ break;
+ case 2:
+ if (!(diag = kdb_getarea(w2, addr)))
+ *word = w2;
+ break;
+ case 4:
+ if (!(diag = kdb_getarea(w4, addr)))
+ *word = w4;
+ break;
+ case 8:
+ if (size <= sizeof(*word)) {
+ if (!(diag = kdb_getarea(w8, addr)))
+ *word = w8;
+ break;
+ }
+ /* drop through */
+ default:
+ diag = KDB_BADWIDTH;
+ kdb_printf("kdb_getword: bad width %ld\n", (long) size);
+ }
+ return(diag);
+}
+
+/*
+ * kdb_putword
+ *
+ * Write a binary value. Unlike kdb_putarea, this treats data as numbers.
+ * Inputs:
+ * addr Address of the area to write to..
+ * word The value to set.
+ * size Size of the area.
+ * Outputs:
+ * none.
+ * Returns:
+ * 0 for success, < 0 for error.
+ * Locking:
+ * none.
+ */
+
+int kdb_putword(unsigned long addr, unsigned long word, size_t size)
+{
+ int diag;
+ __u8 w1;
+ __u16 w2;
+ __u32 w4;
+ __u64 w8;
+ switch (size) {
+ case 1:
+ w1 = word;
+ diag = kdb_putarea(addr, w1);
+ break;
+ case 2:
+ w2 = word;
+ diag = kdb_putarea(addr, w2);
+ break;
+ case 4:
+ w4 = word;
+ diag = kdb_putarea(addr, w4);
+ break;
+ case 8:
+ if (size <= sizeof(word)) {
+ w8 = word;
+ diag = kdb_putarea(addr, w8);
+ break;
+ }
+ /* drop through */
+ default:
+ diag = KDB_BADWIDTH;
+ kdb_printf("kdb_putword: bad width %ld\n", (long) size);
+ }
+ return(diag);
+}
+
+/*
+ * kdb_task_state_string
+ *
+ * Convert a string containing any of the letters DRSTCZEUIMA to a mask
+ * for the process state field and return the value. If no argument is
+ * supplied, return the mask that corresponds to environment variable PS,
+ * DRSTCZEU by default.
+ * Inputs:
+ * s String to convert
+ * Outputs:
+ * none.
+ * Returns:
+ * Mask for process state.
+ * Locking:
+ * none.
+ * Notes:
+ * The mask folds data from several sources into a single long value, so
+ * be carefull not to overlap the bits. TASK_* bits are in the LSB,
+ * special cases like UNRUNNABLE are in the MSB. As of 2.6.10-rc1 there
+ * is no overlap between TASK_* and EXIT_* but that may not always be
+ * true, so EXIT_* bits are shifted left 16 bits before being stored in
+ * the mask.
+ */
+
+#define UNRUNNABLE (1UL << (8*sizeof(unsigned long) - 1)) /* unrunnable is < 0 */
+#define RUNNING (1UL << (8*sizeof(unsigned long) - 2))
+#define IDLE (1UL << (8*sizeof(unsigned long) - 3))
+#define DAEMON (1UL << (8*sizeof(unsigned long) - 4))
+
+unsigned long
+kdb_task_state_string(const char *s)
+{
+ long res = 0;
+ if (!s && !(s = kdbgetenv("PS"))) {
+ s = "DRSTCZEU"; /* default value for ps */
+ }
+ while (*s) {
+ switch (*s) {
+ case 'D': res |= TASK_UNINTERRUPTIBLE; break;
+ case 'R': res |= RUNNING; break;
+ case 'S': res |= TASK_INTERRUPTIBLE; break;
+ case 'T': res |= TASK_STOPPED; break;
+ case 'C': res |= TASK_TRACED; break;
+ case 'Z': res |= EXIT_ZOMBIE << 16; break;
+ case 'E': res |= EXIT_DEAD << 16; break;
+ case 'U': res |= UNRUNNABLE; break;
+ case 'I': res |= IDLE; break;
+ case 'M': res |= DAEMON; break;
+ case 'A': res = ~0UL; break;
+ default:
+ kdb_printf("%s: unknown flag '%c' ignored\n", __FUNCTION__, *s);
+ break;
+ }
+ ++s;
+ }
+ return res;
+}
+
+/*
+ * kdb_task_state_char
+ *
+ * Return the character that represents the task state.
+ * Inputs:
+ * p struct task for the process
+ * Outputs:
+ * none.
+ * Returns:
+ * One character to represent the task state.
+ * Locking:
+ * none.
+ */
+
+char
+kdb_task_state_char (const struct task_struct *p)
+{
+ int cpu = kdb_process_cpu(p);
+ struct kdb_running_process *krp = kdb_running_process + cpu;
+ char state = (p->state == 0) ? 'R' :
+ (p->state < 0) ? 'U' :
+ (p->state & TASK_UNINTERRUPTIBLE) ? 'D' :
+ (p->state & TASK_STOPPED) ? 'T' :
+ (p->state & TASK_TRACED) ? 'C' :
+ (p->exit_state & EXIT_ZOMBIE) ? 'Z' :
+ (p->exit_state & EXIT_DEAD) ? 'E' :
+ (p->state & TASK_INTERRUPTIBLE) ? 'S' : '?';
+ if (p->pid == 0) {
+ /* Idle task. Is it really idle, apart from the kdb interrupt? */
+ if (!task_curr(p) || krp->irq_depth == 1) {
+ /* There is a corner case when the idle task takes an
+ * interrupt and dies in the interrupt code. It has an
+ * interrupt count of 1 but that did not come from kdb.
+ * This corner case can only occur on the initial cpu,
+ * all the others were entered via the kdb IPI.
+ */
+ if (cpu != kdb_initial_cpu || KDB_STATE_CPU(KEYBOARD, cpu))
+ state = 'I'; /* idle task */
+ }
+ }
+ else if (!p->mm && state == 'S') {
+ state = 'M'; /* sleeping system daemon */
+ }
+ return state;
+}
+
+/*
+ * kdb_task_state
+ *
+ * Return true if a process has the desired state given by the mask.
+ * Inputs:
+ * p struct task for the process
+ * mask mask from kdb_task_state_string to select processes
+ * Outputs:
+ * none.
+ * Returns:
+ * True if the process matches at least one criteria defined by the mask.
+ * Locking:
+ * none.
+ */
+
+unsigned long
+kdb_task_state(const struct task_struct *p, unsigned long mask)
+{
+ char state[] = { kdb_task_state_char(p), '\0' };
+ return (mask & kdb_task_state_string(state)) != 0;
+}
+
+struct kdb_running_process kdb_running_process[NR_CPUS];
+
+/*
+ * kdb_save_running
+ *
+ * Save the state of a running process. This is invoked on the current
+ * process on each cpu (assuming the cpu is responding).
+ * Inputs:
+ * regs struct pt_regs for the process
+ * Outputs:
+ * Updates kdb_running_process[] for this cpu.
+ * Returns:
+ * none.
+ * Locking:
+ * none.
+ */
+
+void
+kdb_save_running(struct pt_regs *regs)
+{
+ struct kdb_running_process *krp = kdb_running_process + smp_processor_id();
+ krp->p = current;
+ krp->regs = regs;
+ krp->seqno = kdb_seqno;
+ krp->irq_depth = hardirq_count() >> HARDIRQ_SHIFT;
+ kdba_save_running(&(krp->arch), regs);
+}
+
+/*
+ * kdb_unsave_running
+ *
+ * Reverse the effect of kdb_save_running.
+ * Inputs:
+ * regs struct pt_regs for the process
+ * Outputs:
+ * Updates kdb_running_process[] for this cpu.
+ * Returns:
+ * none.
+ * Locking:
+ * none.
+ */
+
+void
+kdb_unsave_running(struct pt_regs *regs)
+{
+ struct kdb_running_process *krp = kdb_running_process + smp_processor_id();
+ kdba_unsave_running(&(krp->arch), regs);
+ krp->seqno = 0;
+}
+
+/*
+ * kdb_print_nameval
+ *
+ * Print a name and its value, converting the value to a symbol lookup
+ * if possible.
+ * Inputs:
+ * name field name to print
+ * val value of field
+ * Outputs:
+ * none.
+ * Returns:
+ * none.
+ * Locking:
+ * none.
+ */
+
+void
+kdb_print_nameval(const char *name, unsigned long val)
+{
+ kdb_symtab_t symtab;
+ kdb_printf(" %-11.11s ", name);
+ if (kdbnearsym(val, &symtab))
+ kdb_symbol_print(val, &symtab, KDB_SP_VALUE|KDB_SP_SYMSIZE|KDB_SP_NEWLINE);
+ else
+ kdb_printf("0x%lx\n", val);
+}
+
+static struct page *kdb_follow_page(struct mm_struct *mm, unsigned long address)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *ptep, pte;
+ unsigned long pfn;
+ struct page *page;
+
+ if (!mm)
+ return NULL;
+
+ page = follow_huge_addr(mm, address, 0);
+ if (!IS_ERR(page))
+ return page;
+
+ pgd = pgd_offset(mm, address);
+ if (pgd_none(*pgd) || pgd_bad(*pgd))
+ return NULL;
+
+ pud = pud_offset(pgd, address);
+ if (pud_none(*pud) || pud_bad(*pud))
+ return NULL;
+
+ pmd = pmd_offset(pud, address);
+ if (pmd_none(*pmd) || pmd_bad(*pmd))
+ return NULL;
+
+ if (pmd_huge(*pmd))
+ return follow_huge_pmd(mm, address, pmd, 0);
+
+#define KM_PTE0 KM_KDB
+ ptep = pte_offset_map(pmd, address);
+ if (!ptep)
+ return NULL;
+ pte = *ptep;
+ pte_unmap(ptep);
+#undef KM_PTE0
+
+ if (!pte_present(pte))
+ return NULL;
+
+ pfn = pte_pfn(pte);
+ if (!pfn_valid(pfn))
+ return NULL;
+
+ return pfn_to_page(pfn);
+}
+
+int kdb_getuserarea_size(void *to, unsigned long from, size_t size)
+{
+ struct page *page;
+ void *vaddr;
+ size_t offset = from & (PAGE_SIZE - 1);
+ size_t len;
+
+ while (size) {
+ page = kdb_follow_page(kdb_current_task->mm, from);
+ if (!page)
+ return size;
+
+ len = PAGE_SIZE - offset;
+ if (len > size)
+ len = size;
+
+ vaddr = kmap_atomic(page, KM_KDB);
+ memcpy(to, vaddr + offset, len);
+ kunmap_atomic(vaddr, KM_KDB);
+
+ to += len;
+ from += len;
+ size -= len;
+ offset = 0;
+ }
+ return 0;
+}
+
+int kdb_putuserarea_size(unsigned long to, void *from, size_t size)
+{
+ struct page *page;
+ void *vaddr;
+ size_t offset = to & (PAGE_SIZE - 1);
+ size_t len;
+
+ while (size) {
+ page = kdb_follow_page(kdb_current_task->mm, to);
+ if (!page)
+ return size;
+
+ len = PAGE_SIZE - offset;
+ if (len > size)
+ len = size;
+
+ vaddr = kmap_atomic(page, KM_KDB);
+ memcpy(vaddr + offset, from, len);
+ kunmap_atomic(vaddr, KM_KDB);
+
+ to += len;
+ from += len;
+ size -= len;
+ offset = 0;
+ }
+ return 0;
+}
+
+/*
+ * kdb_send_sig_info
+ *
+ * Allows kdb to send signals.
+ *
+ * Inputs:
+ * t task
+ * siginfo signal information
+ * seqno current kdb sequence number
+ * Outputs:
+ * None.
+ * Returns:
+ * None.
+ * Locking:
+ * Checks if the required locks are available before calling the main
+ * signal code, to avoid kdb deadlocks.
+ * Remarks:
+ */
+void
+kdb_send_sig_info(struct task_struct *t, struct siginfo *info, int seqno)
+{
+ static struct task_struct *kdb_prev_t;
+ static int kdb_prev_seqno;
+ int sig, new_t;
+ if (!spin_trylock(&t->sighand->siglock)) {
+ kdb_printf("Can't do kill command now.\n"
+ "The sigmask lock is held somewhere else in kernel, try again later\n");
+ return;
+ }
+ spin_unlock(&t->sighand->siglock);
+ new_t = kdb_prev_t != t || kdb_prev_seqno != seqno;
+ kdb_prev_t = t;
+ kdb_prev_seqno = seqno;
+ if (t->state != TASK_RUNNING && new_t) {
+ kdb_printf("Process is not RUNNING, sending a signal from kdb risks deadlock\n"
+ "on the run queue locks. The signal has _not_ been sent.\n"
+ "Reissue the kill command if you want to risk the deadlock.\n");
+ return;
+ }
+ sig = info->si_signo;
+ if (send_sig_info(sig, info, t))
+ kdb_printf("Fail to deliver Signal %d to process %d.\n", sig, t->pid);
+ else
+ kdb_printf("Signal %d is sent to process %d.\n", sig, t->pid);
+}
+
+/* Maintain a small stack of kdb_flags to allow recursion without disturbing
+ * the global kdb state.
+ */
+
+static int kdb_flags_stack[4], kdb_flags_index;
+
+void
+kdb_save_flags(void)
+{
+ BUG_ON(kdb_flags_index >= ARRAY_SIZE(kdb_flags_stack));
+ kdb_flags_stack[kdb_flags_index++] = kdb_flags;
+}
+
+void
+kdb_restore_flags(void)
+{
+ BUG_ON(kdb_flags_index <= 0);
+ kdb_flags = kdb_flags_stack[--kdb_flags_index];
+}
--- /dev/null
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (c) 1999-2006 Silicon Graphics, Inc. All Rights Reserved.
+#
+
+obj-$(CONFIG_KDB_MODULES) += kdbm_pg.o kdbm_task.o kdbm_vm.o kdbm_sched.o
+ifdef CONFIG_X86
+ifndef CONFIG_X86_64
+obj-$(CONFIG_KDB_MODULES) += kdbm_x86.o
+endif
+endif
+obj-$(CONFIG_KDB_MODULES_XP) += kdbm_xpc.o
+CFLAGS_kdbm_vm.o += -I $(srctree)/drivers/scsi
--- /dev/null
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/fs.h>
+#include <linux/bio.h>
+#include <linux/buffer_head.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <linux/blkdev.h>
+#include <linux/ctype.h>
+
+MODULE_AUTHOR("SGI");
+MODULE_DESCRIPTION("Debug page information");
+MODULE_LICENSE("GPL");
+
+/* Standard Linux page stuff */
+
+/* From include/linux/page_flags.h */
+static char *pg_flag_vals[] = {
+ "locked", "error", "referenced", "uptodate",
+ "dirty", "lru", "active", "slab",
+ "checked", "arch_1", "reserved", "private",
+ "writeback", "nosave", "compound", "swapcache",
+ "mappedtodisk", "reclaim", "nosave_free", "buddy",
+ NULL };
+
+/* From include/linux/buffer_head.h */
+static char *bh_state_vals[] = {
+ "Uptodate", "Dirty", "Lock", "Req",
+ "Uptodate_Lock", "Mapped", "New", "Async_read",
+ "Async_write", "Delay", "Boundary", "Write_EIO",
+ "Ordered", "Eopnotsupp", "Private",
+ NULL };
+
+/* From include/linux/bio.h */
+static char *bio_flag_vals[] = {
+ "Uptodate", "RW_block", "EOF", "Seg_valid",
+ "Cloned", "Bounced", "User_mapped", "Eopnotsupp",
+ NULL };
+
+/* From include/linux/fs.h */
+static char *inode_flag_vals[] = {
+ "I_DIRTY_SYNC", "I_DIRTY_DATASYNC", "I_DIRTY_PAGES", "I_LOCK",
+ "I_FREEING", "I_CLEAR", "I_NEW", "I_WILL_FREE",
+ NULL };
+
+static char *map_flags(unsigned long flags, char *mapping[])
+{
+ static char buffer[300];
+ int index;
+ int offset = 12;
+
+ buffer[0] = '\0';
+
+ for (index = 0; flags && mapping[index]; flags >>= 1, index++) {
+ if (flags & 1) {
+ if ((offset + strlen(mapping[index]) + 1) >= 80) {
+ strcat(buffer, "\n ");
+ offset = 12;
+ } else if (offset > 12) {
+ strcat(buffer, " ");
+ offset++;
+ }
+ strcat(buffer, mapping[index]);
+ offset += strlen(mapping[index]);
+ }
+ }
+
+ return (buffer);
+}
+
+static int
+kdbm_buffers(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ struct buffer_head bh;
+ unsigned long addr;
+ long offset = 0;
+ int nextarg;
+ int diag;
+
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+
+ nextarg = 1;
+ if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs)) ||
+ (diag = kdb_getarea(bh, addr)))
+ return(diag);
+
+ kdb_printf("buffer_head at 0x%lx\n", addr);
+ kdb_printf(" bno %llu size %zu dev 0x%x\n",
+ (unsigned long long)bh.b_blocknr,
+ bh.b_size,
+ bh.b_bdev ? bh.b_bdev->bd_dev : 0);
+ kdb_printf(" count %d state 0x%lx [%s]\n",
+ bh.b_count.counter, bh.b_state,
+ map_flags(bh.b_state, bh_state_vals));
+ kdb_printf(" b_data 0x%p\n",
+ bh.b_data);
+ kdb_printf(" b_page 0x%p b_this_page 0x%p b_private 0x%p\n",
+ bh.b_page, bh.b_this_page, bh.b_private);
+ kdb_printf(" b_end_io ");
+ if (bh.b_end_io)
+ kdb_symbol_print(kdba_funcptr_value(bh.b_end_io), NULL, KDB_SP_VALUE);
+ else
+ kdb_printf("(NULL)");
+ kdb_printf("\n");
+
+ return 0;
+}
+
+static int
+print_biovec(struct bio_vec *vec, int vcount)
+{
+ struct bio_vec bvec;
+ unsigned long addr;
+ int diag;
+ int i;
+
+ if (vcount < 1 || vcount > BIO_MAX_PAGES) {
+ kdb_printf(" [skipped iovecs, vcnt is %d]\n", vcount);
+ return 0;
+ }
+
+ addr = (unsigned long)vec;
+ for (i = 0; i < vcount; i++) {
+ if ((diag = kdb_getarea(bvec, addr)))
+ return(diag);
+ addr += sizeof(bvec);
+ kdb_printf(" [%d] page 0x%p length=%u offset=%u\n",
+ i, bvec.bv_page, bvec.bv_len, bvec.bv_offset);
+ }
+ return 0;
+}
+
+static int
+kdbm_bio(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ struct bio bio;
+ unsigned long addr;
+ long offset = 0;
+ int nextarg;
+ int diag;
+
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+
+ nextarg = 1;
+ if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs)) ||
+ (diag = kdb_getarea(bio, addr)))
+ return(diag);
+
+ kdb_printf("bio at 0x%lx\n", addr);
+ kdb_printf(" bno %llu next 0x%p dev 0x%x\n",
+ (unsigned long long)bio.bi_sector,
+ bio.bi_next, bio.bi_bdev ? bio.bi_bdev->bd_dev : 0);
+ kdb_printf(" vcnt %u vec 0x%p rw 0x%lx flags 0x%lx [%s]\n",
+ bio.bi_vcnt, bio.bi_io_vec, bio.bi_rw, bio.bi_flags,
+ map_flags(bio.bi_flags, bio_flag_vals));
+ print_biovec(bio.bi_io_vec, bio.bi_vcnt);
+ kdb_printf(" count %d private 0x%p\n",
+ atomic_read(&bio.bi_cnt), bio.bi_private);
+ kdb_printf(" bi_end_io ");
+ if (bio.bi_end_io)
+ kdb_symbol_print(kdba_funcptr_value(bio.bi_end_io), NULL, KDB_SP_VALUE);
+ else
+ kdb_printf("(NULL)");
+ kdb_printf("\n");
+
+ return 0;
+}
+
+static char *page_flags(unsigned long flags)
+{
+ return(map_flags(flags, pg_flag_vals));
+}
+
+static int
+kdbm_page(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ struct page page;
+ unsigned long addr;
+ long offset = 0;
+ int nextarg;
+ int diag;
+
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+
+ nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
+ if (diag)
+ return diag;
+
+#ifdef __ia64__
+ if (rgn_index(addr) == 0)
+#else
+ if (addr < PAGE_OFFSET)
+#endif
+ addr = (unsigned long) pfn_to_page(addr);
+
+ if ((diag = kdb_getarea(page, addr)))
+ return(diag);
+
+ kdb_printf("struct page at 0x%lx pfn 0x%05lx virtual 0x%p",
+ addr, page_to_pfn((struct page *)addr),
+ page_address((struct page *)addr));
+ if (page_private(&page))
+ kdb_printf(" private 0x%lx", page_private(&page));
+ kdb_printf("\n next 0x%p prev 0x%p mapping 0x%p index 0x%lx\n",
+ page.lru.next, page.lru.prev, page.mapping, page.index);
+ kdb_printf(" count %d mapcount %d %s\n",
+ page_count(&page), page_mapcount(&page), page_flags(page.flags));
+
+ return 0;
+}
+
+static unsigned long
+print_request(unsigned long addr)
+{
+ struct request rq;
+
+ if (kdb_getarea(rq, addr))
+ return(0);
+
+ kdb_printf("struct request at 0x%lx\n", addr);
+ kdb_printf(" errors %d sector %llu nr_sectors %lu waiting 0x%p\n",
+ rq.errors,
+ (unsigned long long)rq.sector, rq.nr_sectors,
+ rq.waiting);
+
+ kdb_printf(" hsect %llu hnrsect %lu nrseg %u nrhwseg %u currnrsect %u\n",
+ (unsigned long long)rq.hard_sector, rq.hard_nr_sectors,
+ rq.nr_phys_segments, rq.nr_hw_segments,
+ rq.current_nr_sectors);
+
+ return (unsigned long) rq.queuelist.next;
+}
+
+static int
+kdbm_request(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ long offset = 0;
+ unsigned long addr;
+ int nextarg;
+ int diag;
+
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+
+ nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
+ if (diag)
+ return diag;
+
+ print_request(addr);
+ return 0;
+}
+
+
+static int
+kdbm_rqueue(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ struct request_queue rq;
+ unsigned long addr, head_addr, next;
+ long offset = 0;
+ int nextarg;
+ int i, diag;
+
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+
+ nextarg = 1;
+ if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs)) ||
+ (diag = kdb_getarea(rq, addr)))
+ return(diag);
+
+ kdb_printf("struct request_queue at 0x%lx\n", addr);
+ i = 0;
+ next = (unsigned long)rq.queue_head.next;
+ head_addr = addr + offsetof(struct request_queue, queue_head);
+ kdb_printf(" request queue: %s\n", next == head_addr ?
+ "empty" : "");
+ while (next != head_addr) {
+ i++;
+ next = print_request(next);
+ }
+
+ if (i)
+ kdb_printf("%d requests found\n", i);
+
+ return 0;
+}
+
+
+static void
+do_buffer(unsigned long addr)
+{
+ struct buffer_head bh;
+
+ if (kdb_getarea(bh, addr))
+ return;
+
+ kdb_printf(" bh 0x%lx bno %8llu [%s]", addr,
+ (unsigned long long)bh.b_blocknr,
+ map_flags(bh.b_state, bh_state_vals));
+}
+
+static void
+kdbm_show_page(struct page *page, int first)
+{
+ if (first)
+ kdb_printf("page_struct index cnt zone nid flags\n");
+ kdb_printf("%p%s %6lu %5d %3ld %3ld 0x%lx",
+ page_address(page), sizeof(void *) == 4 ? " " : "",
+ page->index, page_count(page),
+ page_zonenum(page), page_to_nid(page),
+ page->flags & (~0UL >> ZONES_SHIFT));
+ kdb_printf(" %s", page_flags(page->flags));
+ if (page_has_buffers(page)) {
+ struct buffer_head *head, *bh;
+ kdb_printf("\n");
+ head = bh = page_buffers(page);
+ do {
+ do_buffer((unsigned long) bh);
+ } while ((bh = bh->b_this_page) != head);
+ } else if (page_private(page)) {
+ kdb_printf(" private= 0x%lx", page_private(page));
+ }
+ /* Cannot use page_mapping(page) here, it needs swapper_space which is
+ * not exported.
+ */
+ if (page->mapping)
+ kdb_printf(" mapping= %p", page->mapping);
+ kdb_printf("\n");
+}
+
+static int
+kdbm_inode_pages(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ struct inode *inode = NULL;
+ struct address_space *ap = NULL;
+ unsigned long addr, addr1 = 0;
+ long offset = 0;
+ int nextarg;
+ int diag;
+ pgoff_t next = 0;
+ struct page *page;
+ int first;
+
+ nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
+ if (diag)
+ goto out;
+
+ if (argc == 2) {
+ nextarg = 2;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &addr1,
+ &offset, NULL, regs);
+ if (diag)
+ goto out;
+ kdb_printf("Looking for page index 0x%lx ... \n", addr1);
+ next = addr1;
+ }
+
+ if (!(inode = kmalloc(sizeof(*inode), GFP_ATOMIC))) {
+ kdb_printf("kdbm_inode_pages: cannot kmalloc inode\n");
+ goto out;
+ }
+ if (!(ap = kmalloc(sizeof(*ap), GFP_ATOMIC))) {
+ kdb_printf("kdbm_inode_pages: cannot kmalloc ap\n");
+ goto out;
+ }
+ if ((diag = kdb_getarea(*inode, addr)))
+ goto out;
+ if (!inode->i_mapping) {
+ kdb_printf("inode has no mapping\n");
+ goto out;
+ }
+ if ((diag = kdb_getarea(*ap, (unsigned long) inode->i_mapping)))
+ goto out;
+
+ /* Run the pages in the radix tree, printing the state of each page */
+ first = 1;
+ while (radix_tree_gang_lookup(&ap->page_tree, (void **)&page, next, 1)) {
+ kdbm_show_page(page, first);
+ if (addr1)
+ break;
+ first = 0;
+ next = page->index + 1;
+ }
+
+out:
+ if (inode)
+ kfree(inode);
+ if (ap)
+ kfree(ap);
+ return diag;
+}
+
+static int
+kdbm_inode(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ struct inode *inode = NULL;
+ unsigned long addr;
+ unsigned char *iaddr;
+ long offset = 0;
+ int nextarg;
+ int diag;
+
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+
+ nextarg = 1;
+ if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs)))
+ goto out;
+ if (!(inode = kmalloc(sizeof(*inode), GFP_ATOMIC))) {
+ kdb_printf("kdbm_inode: cannot kmalloc inode\n");
+ goto out;
+ }
+ if ((diag = kdb_getarea(*inode, addr)))
+ goto out;
+
+ kdb_printf("struct inode at 0x%lx\n", addr);
+
+ kdb_printf(" i_ino = %lu i_count = %u i_size %Ld\n",
+ inode->i_ino, atomic_read(&inode->i_count),
+ inode->i_size);
+
+ kdb_printf(" i_mode = 0%o i_nlink = %d i_rdev = 0x%x\n",
+ inode->i_mode, inode->i_nlink,
+ inode->i_rdev);
+
+ kdb_printf(" i_hash.nxt = 0x%p i_hash.pprev = 0x%p\n",
+ inode->i_hash.next,
+ inode->i_hash.pprev);
+
+ kdb_printf(" i_list.nxt = 0x%p i_list.prv = 0x%p\n",
+ list_entry(inode->i_list.next, struct inode, i_list),
+ list_entry(inode->i_list.prev, struct inode, i_list));
+
+ kdb_printf(" i_dentry.nxt = 0x%p i_dentry.prv = 0x%p\n",
+ list_entry(inode->i_dentry.next, struct dentry, d_alias),
+ list_entry(inode->i_dentry.prev, struct dentry, d_alias));
+
+ kdb_printf(" i_sb = 0x%p i_op = 0x%p i_data = 0x%lx nrpages = %lu\n",
+ inode->i_sb, inode->i_op,
+ addr + offsetof(struct inode, i_data),
+ inode->i_data.nrpages);
+ kdb_printf(" i_fop= 0x%p i_flock = 0x%p i_mapping = 0x%p\n",
+ inode->i_fop, inode->i_flock, inode->i_mapping);
+
+ kdb_printf(" i_flags 0x%x i_state 0x%lx [%s]",
+ inode->i_flags, inode->i_state,
+ map_flags(inode->i_state, inode_flag_vals));
+
+ iaddr = (char *)addr;
+ iaddr += offsetof(struct inode, u);
+
+ kdb_printf(" fs specific info @ 0x%p\n", iaddr);
+out:
+ if (inode)
+ kfree(inode);
+ return diag;
+}
+
+static int
+kdbm_sb(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ struct super_block *sb = NULL;
+ unsigned long addr;
+ long offset = 0;
+ int nextarg;
+ int diag;
+
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+
+ nextarg = 1;
+ if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs)))
+ goto out;
+ if (!(sb = kmalloc(sizeof(*sb), GFP_ATOMIC))) {
+ kdb_printf("kdbm_sb: cannot kmalloc sb\n");
+ goto out;
+ }
+ if ((diag = kdb_getarea(*sb, addr)))
+ goto out;
+
+ kdb_printf("struct super_block at 0x%lx\n", addr);
+ kdb_printf(" s_dev 0x%x blocksize 0x%lx\n", sb->s_dev, sb->s_blocksize);
+ kdb_printf(" s_flags 0x%lx s_root 0x%p\n", sb->s_flags, sb->s_root);
+ kdb_printf(" s_dirt %d s_dirty.next 0x%p s_dirty.prev 0x%p\n",
+ sb->s_dirt, sb->s_dirty.next, sb->s_dirty.prev);
+ kdb_printf(" s_frozen %d s_id [%s]\n", sb->s_frozen, sb->s_id);
+out:
+ if (sb)
+ kfree(sb);
+ return diag;
+}
+
+#ifndef CONFIG_DISCONTIGMEM
+static int
+kdbm_memmap(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ struct page page;
+ int i, count;
+ unsigned int slab_count = 0;
+ unsigned int dirty_count = 0;
+ unsigned int locked_count = 0;
+ unsigned int page_counts[9];
+ unsigned int buffered_count = 0;
+ int diag;
+ unsigned long addr;
+
+ addr = (unsigned long)mem_map;
+ memset(page_counts, 0, sizeof(page_counts));
+
+ for (i = 0; i < max_mapnr; i++) {
+ if ((diag = kdb_getarea(page, addr)))
+ return(diag);
+ addr += sizeof(page);
+
+ if (PageSlab(&page))
+ slab_count++;
+ if (PageDirty(&page))
+ dirty_count++;
+ if (PageLocked(&page))
+ locked_count++;
+ count = page_count(&page);
+ if (count >= 0 && count < 8)
+ page_counts[count]++;
+ else
+ page_counts[8]++;
+ if (page_has_buffers(&page))
+ buffered_count++;
+ }
+
+ kdb_printf(" Total pages: %10lu\n", max_mapnr);
+ kdb_printf(" Slab pages: %10u\n", slab_count);
+ kdb_printf(" Dirty pages: %10u\n", dirty_count);
+ kdb_printf(" Locked pages: %10u\n", locked_count);
+ kdb_printf(" Buffer pages: %10u\n", buffered_count);
+ for (i = 0; i < 8; i++) {
+ kdb_printf(" %d page count: %10u\n",
+ i, page_counts[i]);
+ }
+ kdb_printf(" high page count: %7u\n", page_counts[8]);
+ return 0;
+}
+#endif /* !CONFIG_DISCONTIGMEM */
+
+static int __init kdbm_pg_init(void)
+{
+ kdb_register("page", kdbm_page, "<vaddr>", "Display page", 0);
+ kdb_register("inode", kdbm_inode, "<vaddr>", "Display inode", 0);
+ kdb_register("sb", kdbm_sb, "<vaddr>", "Display super_block", 0);
+ kdb_register("bh", kdbm_buffers, "<buffer head address>", "Display buffer", 0);
+ kdb_register("bio", kdbm_bio, "<bio address>", "Display bio", 0);
+ kdb_register("inode_pages", kdbm_inode_pages, "<inode *>", "Display pages in an inode", 0);
+ kdb_register("req", kdbm_request, "<vaddr>", "dump request struct", 0);
+ kdb_register("rqueue", kdbm_rqueue, "<vaddr>", "dump request queue", 0);
+#ifndef CONFIG_DISCONTIGMEM
+ kdb_register("memmap", kdbm_memmap, "", "page table summary", 0);
+#endif
+
+ return 0;
+}
+
+static void __exit kdbm_pg_exit(void)
+{
+ kdb_unregister("page");
+ kdb_unregister("inode");
+ kdb_unregister("sb");
+ kdb_unregister("bh");
+ kdb_unregister("bio");
+ kdb_unregister("inode_pages");
+ kdb_unregister("req");
+ kdb_unregister("rqueue");
+#ifndef CONFIG_DISCONTIGMEM
+ kdb_unregister("memmap");
+#endif
+}
+
+module_init(kdbm_pg_init);
+module_exit(kdbm_pg_exit);
--- /dev/null
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+
+MODULE_AUTHOR("SGI");
+MODULE_DESCRIPTION("Debug scheduler information");
+MODULE_LICENSE("GPL");
+
+static int
+kdbm_runqueues(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ unsigned long cpu;
+ int ret = 0;
+
+ if (argc == 1) {
+ ret = kdbgetularg((char *)argv[1], &cpu);
+ if (!ret) {
+ if (!cpu_online(cpu)) {
+ kdb_printf("Invalid cpu number\n");
+ } else
+ kdb_runqueue(cpu, kdb_printf);
+ }
+ } else if (argc == 0) {
+ for_each_online_cpu(cpu)
+ kdb_runqueue(cpu, kdb_printf);
+ } else {
+ /* More than one arg */
+ kdb_printf("Specify one cpu number\n");
+ }
+ return ret;
+}
+
+static int __init kdbm_sched_init(void)
+{
+ kdb_register("rq", kdbm_runqueues, "<cpunum>", "Display runqueue for <cpunum>", 0);
+ kdb_register("rqa", kdbm_runqueues, "", "Display all runqueues", 0);
+ return 0;
+}
+
+static void __exit kdbm_sched_exit(void)
+{
+ kdb_unregister("rq");
+ kdb_unregister("rqa");
+}
+
+module_init(kdbm_sched_init);
+module_exit(kdbm_sched_exit);
--- /dev/null
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/blkdev.h>
+#include <linux/types.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <asm/signal.h>
+
+MODULE_AUTHOR("SGI");
+MODULE_DESCRIPTION("Debug struct task and sigset information");
+MODULE_LICENSE("GPL");
+
+static char *
+kdb_cpus_allowed_string(struct task_struct *tp)
+{
+ static char maskbuf[(NR_CPUS + 31) / 32 * 9 + 1];
+ if (cpus_full(tp->cpus_allowed))
+ strcpy(maskbuf, "ALL");
+ else if (cpus_empty(tp->cpus_allowed))
+ strcpy(maskbuf, "NONE");
+ else if (cpus_weight(tp->cpus_allowed) == 1)
+ snprintf(maskbuf, sizeof(maskbuf), "ONLY(%d)", first_cpu(tp->cpus_allowed));
+ else
+ cpumask_scnprintf(maskbuf, sizeof(maskbuf), tp->cpus_allowed);
+ return maskbuf;
+}
+
+static int
+kdbm_task(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ unsigned long addr;
+ long offset=0;
+ int nextarg;
+ int e = 0;
+ struct task_struct *tp = NULL, *tp1;
+
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+
+ nextarg = 1;
+ if ((e = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs)) != 0)
+ return(e);
+
+ if (!(tp = kmalloc(sizeof(*tp), GFP_ATOMIC))) {
+ kdb_printf("%s: cannot kmalloc tp\n", __FUNCTION__);
+ goto out;
+ }
+ if ((e = kdb_getarea(*tp, addr))) {
+ kdb_printf("%s: invalid task address\n", __FUNCTION__);
+ goto out;
+ }
+
+ tp1 = (struct task_struct *)addr;
+ kdb_printf(
+ "struct task at 0x%lx, pid=%d flags=0x%lx state=%ld comm=\"%s\"\n",
+ addr, tp->pid, tp->flags, tp->state, tp->comm);
+
+ kdb_printf(" cpu=%d policy=%lu ", kdb_process_cpu(tp), tp->policy);
+ kdb_printf(
+ "prio=%d static_prio=%d cpus_allowed=%s",
+ tp->prio, tp->static_prio, kdb_cpus_allowed_string(tp));
+ kdb_printf(" &thread=0x%p\n", &tp1->thread);
+
+ kdb_printf(" need_resched=%d ",
+ test_tsk_thread_flag(tp, TIF_NEED_RESCHED));
+ kdb_printf(
+ "timestamp=%llu time_slice=%u",
+ tp->timestamp, tp->time_slice);
+ kdb_printf(" lock_depth=%d\n", tp->lock_depth);
+
+ kdb_printf(
+ " fs=0x%p files=0x%p mm=0x%p\n",
+ tp->fs, tp->files, tp->mm);
+
+ kdb_printf(
+ " uid=%d euid=%d suid=%d fsuid=%d gid=%d egid=%d sgid=%d fsgid=%d\n",
+ tp->uid, tp->euid, tp->suid, tp->fsuid, tp->gid, tp->egid, tp->sgid, tp->fsgid);
+
+ kdb_printf(
+ " user=0x%p\n",
+ tp->user);
+
+ if (tp->sysvsem.undo_list)
+ kdb_printf(
+ " sysvsem.sem_undo refcnt %d proc_list=0x%p\n",
+ atomic_read(&tp->sysvsem.undo_list->refcnt),
+ tp->sysvsem.undo_list->proc_list);
+
+ kdb_printf(
+ " signal=0x%p &blocked=0x%p &pending=0x%p\n",
+ tp->signal, &tp1->blocked, &tp1->pending);
+
+ kdb_printf(
+ " utime=%ld stime=%ld cutime=%ld cstime=%ld\n",
+ tp->utime, tp->stime,
+ tp->signal ? tp->signal->cutime : 0L,
+ tp->signal ? tp->signal->cstime : 0L);
+
+ kdb_printf(" thread_info=0x%p\n", tp->thread_info);
+ kdb_printf(" ti flags=0x%lx\n", (unsigned long)tp->thread_info->flags);
+
+out:
+ if (tp)
+ kfree(tp);
+ return e;
+}
+
+static int
+kdbm_sigset(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ sigset_t *sp = NULL;
+ unsigned long addr;
+ long offset=0;
+ int nextarg;
+ int e = 0;
+ int i;
+ char fmt[32];
+
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+
+#ifndef _NSIG_WORDS
+ kdb_printf("unavailable on this platform, _NSIG_WORDS not defined.\n");
+#else
+ nextarg = 1;
+ if ((e = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs)) != 0)
+ return(e);
+
+ if (!(sp = kmalloc(sizeof(*sp), GFP_ATOMIC))) {
+ kdb_printf("%s: cannot kmalloc sp\n", __FUNCTION__);
+ goto out;
+ }
+ if ((e = kdb_getarea(*sp, addr))) {
+ kdb_printf("%s: invalid sigset address\n", __FUNCTION__);
+ goto out;
+ }
+
+ sprintf(fmt, "[%%d]=0x%%0%dlx ", (int)sizeof(sp->sig[0])*2);
+ kdb_printf("sigset at 0x%p : ", sp);
+ for (i=_NSIG_WORDS-1; i >= 0; i--) {
+ if (i == 0 || sp->sig[i]) {
+ kdb_printf(fmt, i, sp->sig[i]);
+ }
+ }
+ kdb_printf("\n");
+#endif /* _NSIG_WORDS */
+
+out:
+ if (sp)
+ kfree(sp);
+ return e;
+}
+
+static int __init kdbm_task_init(void)
+{
+ kdb_register("task", kdbm_task, "<vaddr>", "Display task_struct", 0);
+ kdb_register("sigset", kdbm_sigset, "<vaddr>", "Display sigset_t", 0);
+
+ return 0;
+}
+
+static void __exit kdbm_task_exit(void)
+{
+ kdb_unregister("task");
+ kdb_unregister("sigset");
+}
+
+module_init(kdbm_task_init);
+module_exit(kdbm_task_exit);
--- /dev/null
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2006 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <linux/blkdev.h>
+#include <linux/types.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+
+#include <scsi.h>
+#include <scsi/scsi_host.h>
+
+MODULE_AUTHOR("SGI");
+MODULE_DESCRIPTION("Debug VM information");
+MODULE_LICENSE("GPL");
+
+struct mm_struct copy_of_mm; /* for kdbm_pte and kdbm_rpte */
+
+struct __vmflags {
+ unsigned long mask;
+ char *name;
+};
+
+static struct __vmflags vmflags[] = {
+ { VM_READ, "VM_READ " },
+ { VM_WRITE, "VM_WRITE " },
+ { VM_EXEC, "VM_EXEC " },
+ { VM_SHARED, "VM_SHARED " },
+ { VM_MAYREAD, "VM_MAYREAD " },
+ { VM_MAYWRITE, "VM_MAYWRITE " },
+ { VM_MAYEXEC, "VM_MAYEXEC " },
+ { VM_MAYSHARE, "VM_MAYSHARE " },
+ { VM_GROWSDOWN, "VM_GROWSDOWN " },
+ { VM_GROWSUP, "VM_GROWSUP " },
+ { VM_PFNMAP, "VM_PFNMAP " },
+ { VM_DENYWRITE, "VM_DENYWRITE " },
+ { VM_EXECUTABLE, "VM_EXECUTABLE " },
+ { VM_LOCKED, "VM_LOCKED " },
+ { VM_IO, "VM_IO " },
+ { VM_SEQ_READ, "VM_SEQ_READ " },
+ { VM_RAND_READ, "VM_RAND_READ " },
+ { VM_DONTCOPY, "VM_DONTCOPY " },
+ { VM_DONTEXPAND, "VM_DONTEXPAND " },
+ { VM_RESERVED, "VM_RESERVED " },
+ { VM_ACCOUNT, "VM_ACCOUNT " },
+ { VM_HUGETLB, "VM_HUGETLB " },
+ { VM_NONLINEAR, "VM_NONLINEAR " },
+ { VM_MAPPED_COPY, "VM_MAPPED_COPY " },
+ { VM_INSERTPAGE, "VM_INSERTPAGE " },
+ { 0, "" }
+};
+
+static int
+kdbm_print_vm(struct vm_area_struct *vp, unsigned long addr, int verbose_flg)
+{
+ struct __vmflags *tp;
+
+ kdb_printf("struct vm_area_struct at 0x%lx for %d bytes\n",
+ addr, (int) sizeof (struct vm_area_struct));
+
+ kdb_printf("vm_start = 0x%p vm_end = 0x%p\n", (void *) vp->vm_start,
+ (void *) vp->vm_end);
+ kdb_printf("vm_page_prot = 0x%llx\n",
+ (unsigned long long) pgprot_val(vp->vm_page_prot));
+
+ kdb_printf("vm_flags: ");
+ for (tp = vmflags; tp->mask; tp++) {
+ if (vp->vm_flags & tp->mask) {
+ kdb_printf(" %s", tp->name);
+ }
+ }
+ kdb_printf("\n");
+
+ if (!verbose_flg)
+ return 0;
+
+ kdb_printf("vm_mm = 0x%p\n", (void *) vp->vm_mm);
+ kdb_printf("vm_next = 0x%p\n", (void *) vp->vm_next);
+ kdb_printf("shared.vm_set.list.next = 0x%p\n", (void *) vp->shared.vm_set.list.next);
+ kdb_printf("shared.vm_set.list.prev = 0x%p\n", (void *) vp->shared.vm_set.list.prev);
+ kdb_printf("shared.vm_set.parent = 0x%p\n", (void *) vp->shared.vm_set.parent);
+ kdb_printf("shared.vm_set.head = 0x%p\n", (void *) vp->shared.vm_set.head);
+ kdb_printf("anon_vma_node.next = 0x%p\n", (void *) vp->anon_vma_node.next);
+ kdb_printf("anon_vma_node.prev = 0x%p\n", (void *) vp->anon_vma_node.prev);
+ kdb_printf("vm_ops = 0x%p\n", (void *) vp->vm_ops);
+ if (vp->vm_ops != NULL) {
+ kdb_printf("vm_ops->open = 0x%p\n", vp->vm_ops->open);
+ kdb_printf("vm_ops->close = 0x%p\n", vp->vm_ops->close);
+ kdb_printf("vm_ops->nopage = 0x%p\n", vp->vm_ops->nopage);
+#ifdef HAVE_VMOP_MPROTECT
+ kdb_printf("vm_ops->mprotect = 0x%p\n", vp->vm_ops->mprotect);
+#endif
+ }
+ kdb_printf("vm_pgoff = 0x%lx\n", vp->vm_pgoff);
+ kdb_printf("vm_file = 0x%p\n", (void *) vp->vm_file);
+ kdb_printf("vm_private_data = 0x%p\n", vp->vm_private_data);
+
+ return 0;
+}
+
+static int
+kdbm_print_vmp(struct vm_area_struct *vp, int verbose_flg)
+{
+ struct __vmflags *tp;
+
+ if (verbose_flg) {
+ kdb_printf("0x%lx: ", (unsigned long) vp);
+ }
+
+ kdb_printf("0x%p 0x%p ", (void *) vp->vm_start, (void *) vp->vm_end);
+
+ for (tp = vmflags; tp->mask; tp++) {
+ if (vp->vm_flags & tp->mask) {
+ kdb_printf(" %s", tp->name);
+ }
+ }
+ kdb_printf("\n");
+
+ return 0;
+}
+
+/*
+ * kdbm_vm
+ *
+ * This function implements the 'vm' command. Print a vm_area_struct.
+ *
+ * vm [-v] <address> Print vm_area_struct at <address>
+ * vmp [-v] <pid> Print all vm_area_structs for <pid>
+ */
+
+static int
+kdbm_vm(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ unsigned long addr;
+ long offset = 0;
+ int nextarg;
+ int diag;
+ int verbose_flg = 0;
+
+ if (argc == 2) {
+ if (strcmp(argv[1], "-v") != 0) {
+ return KDB_ARGCOUNT;
+ }
+ verbose_flg = 1;
+ } else if (argc != 1) {
+ return KDB_ARGCOUNT;
+ }
+
+ if (strcmp(argv[0], "vmp") == 0) {
+ struct task_struct *tp;
+ struct vm_area_struct *vp;
+ pid_t pid;
+
+ if ((diag = kdbgetularg(argv[argc], (unsigned long *) &pid)))
+ return diag;
+
+ if (!(tp = find_task_by_pid(pid))) {
+ kdb_printf("No process with pid == %d found\n", pid);
+ return 0;
+ }
+ if (tp->mm == NULL) {
+ kdb_printf("task structure's mm field is NULL\n");
+ return 0;
+ }
+
+ if (verbose_flg)
+ kdb_printf("vm_area_struct ");
+ kdb_printf("vm_start vm_end vm_flags\n");
+ vp = tp->mm->mmap;
+ while (vp != NULL) {
+ kdbm_print_vmp(vp, verbose_flg);
+ vp = vp->vm_next;
+ }
+ } else {
+ struct vm_area_struct v;
+
+ nextarg = argc;
+ if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset,
+ NULL, regs))
+ || (diag = kdb_getarea(v, addr)))
+ return (diag);
+
+ kdbm_print_vm(&v, addr, verbose_flg);
+ }
+
+ return 0;
+}
+
+static int
+kdbm_print_pte(pte_t * pte)
+{
+ kdb_printf("0x%08llx ", (unsigned long long) pte_val(*pte));
+
+ if (pte_present(*pte)) {
+ if (pte_exec(*pte))
+ kdb_printf("X");
+ if (pte_write(*pte))
+ kdb_printf("W");
+ if (pte_read(*pte))
+ kdb_printf("R");
+ if (pte_young(*pte))
+ kdb_printf("A");
+ if (pte_dirty(*pte))
+ kdb_printf("D");
+ }
+
+ /* final newline is output by caller of kdbm_print_pte() */
+
+ return 0;
+}
+
+/*
+ * kdbm_pte
+ *
+ * This function implements the 'pte' command. Print all pte_t structures
+ * that map to the given virtual address range (<address> through <address>
+ * plus <nbytes>) for the given process. The default value for nbytes is
+ * one.
+ *
+ * pte -m <mm> <address> [<nbytes>] Print all pte_t structures for
+ * virtual <address> in address space
+ * of <mm> which is a pointer to a
+ * mm_struct
+ * pte -p <pid> <address> [<nbytes>] Print all pte_t structures for
+ * virtual <address> in address space
+ * of <pid>
+ */
+
+static int
+kdbm_pte(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ unsigned long addr;
+ long offset = 0;
+ int nextarg;
+ unsigned long nbytes = 1;
+ long npgs;
+ int diag;
+ pid_t pid;
+ struct task_struct *tp;
+ struct mm_struct *mm;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+
+ if (argc < 3 || argc > 4) {
+ return KDB_ARGCOUNT;
+ }
+
+ if (strcmp(argv[1], "-p") == 0) {
+ if ((diag = kdbgetularg(argv[2], (unsigned long *) &pid))) {
+ return diag;
+ }
+
+ if (!(tp = find_task_by_pid(pid))) {
+ kdb_printf("No process with pid == %d found\n", pid);
+ return 0;
+ }
+ if (tp->mm == NULL) {
+ kdb_printf("task structure's mm field is NULL\n");
+ return 0;
+ }
+ mm = tp->mm;
+ } else if (strcmp(argv[1], "-m") == 0) {
+
+ nextarg = 2;
+ if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset,
+ NULL, regs))
+ || (diag = kdb_getarea(copy_of_mm, addr)))
+ return (diag);
+ mm = ©_of_mm;
+ } else {
+ return KDB_ARGCOUNT;
+ }
+
+ if ((diag = kdbgetularg(argv[3], &addr))) {
+ return diag;
+ }
+
+ if (argc == 4) {
+ if ((diag = kdbgetularg(argv[4], &nbytes))) {
+ return diag;
+ }
+ }
+
+ kdb_printf("vaddr pte\n");
+
+ npgs = ((((addr & ~PAGE_MASK) + nbytes) + ~PAGE_MASK) >> PAGE_SHIFT);
+ while (npgs-- > 0) {
+
+ kdb_printf("0x%p ", (void *) (addr & PAGE_MASK));
+
+ pgd = pgd_offset(mm, addr);
+ if (pgd_present(*pgd)) {
+ pud = pud_offset(pgd, addr);
+ if (pud_present(*pud)) {
+ pmd = pmd_offset(pud, addr);
+ if (pmd_present(*pmd)) {
+#define KM_PTE0 KM_KDB
+ pte = pte_offset_map(pmd, addr);
+ if (pte_present(*pte)) {
+ kdbm_print_pte(pte);
+ }
+ pte_unmap(pte);
+#undef KM_PTE0
+ }
+ }
+ }
+
+ kdb_printf("\n");
+ addr += PAGE_SIZE;
+ }
+
+ return 0;
+}
+
+/*
+ * kdbm_rpte
+ *
+ * This function implements the 'rpte' command. Print all pte_t structures
+ * that contain the given physical page range (<pfn> through <pfn>
+ * plus <npages>) for the given process. The default value for npages is
+ * one.
+ *
+ * rpte -m <mm> <pfn> [<npages>] Print all pte_t structures for
+ * physical page <pfn> in address space
+ * of <mm> which is a pointer to a
+ * mm_struct
+ * rpte -p <pid> <pfn> [<npages>] Print all pte_t structures for
+ * physical page <pfn> in address space
+ * of <pid>
+ */
+
+static int
+kdbm_rpte(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ unsigned long addr;
+ unsigned long pfn;
+ long offset = 0;
+ int nextarg;
+ unsigned long npages = 1;
+ int diag;
+ int found;
+ pid_t pid;
+ struct task_struct *tp;
+ struct mm_struct *mm;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+ unsigned long g, u, m, t;
+
+ if (argc < 3 || argc > 4) {
+ return KDB_ARGCOUNT;
+ }
+
+ if (strcmp(argv[1], "-p") == 0) {
+ if ((diag = kdbgetularg(argv[2], (unsigned long *) &pid))) {
+ return diag;
+ }
+
+ found = 0;
+ for_each_process(tp) {
+ if (tp->pid == pid) {
+ if (tp->mm != NULL) {
+ found = 1;
+ break;
+ }
+ kdb_printf("task structure's mm field is NULL\n");
+ return 0;
+ }
+ }
+
+ if (!found) {
+ kdb_printf("No process with pid == %d found\n", pid);
+ return 0;
+ }
+ mm = tp->mm;
+ } else if (strcmp(argv[1], "-m") == 0) {
+
+
+ nextarg = 2;
+ if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset,
+ NULL, regs))
+ || (diag = kdb_getarea(copy_of_mm, addr)))
+ return (diag);
+ mm = ©_of_mm;
+ } else {
+ return KDB_ARGCOUNT;
+ }
+
+ if ((diag = kdbgetularg(argv[3], &pfn))) {
+ return diag;
+ }
+
+ if (argc == 4) {
+ if ((diag = kdbgetularg(argv[4], &npages))) {
+ return diag;
+ }
+ }
+
+ /* spaces after vaddr depends on sizeof(unsigned long) */
+ kdb_printf("pfn vaddr%*s pte\n",
+ (int)(2*sizeof(unsigned long) + 2 - 5), " ");
+
+ for (g = 0, pgd = pgd_offset(mm, 0UL); g < PTRS_PER_PGD; ++g, ++pgd) {
+ if (pgd_none(*pgd) || pgd_bad(*pgd))
+ continue;
+ for (u = 0, pud = pud_offset(pgd, 0UL); u < PTRS_PER_PUD; ++u, ++pud) {
+ if (pud_none(*pud) || pud_bad(*pud))
+ continue;
+ for (m = 0, pmd = pmd_offset(pud, 0UL); m < PTRS_PER_PMD; ++m, ++pmd) {
+ if (pmd_none(*pmd) || pmd_bad(*pmd))
+ continue;
+#define KM_PTE0 KM_KDB
+ pte = pte_offset_map(pmd, 0UL);
+ for (t = 0; t < PTRS_PER_PTE; ++t, ++pte) {
+ if (pte_none(*pte))
+ continue;
+ if (pte_pfn(*pte) < pfn || pte_pfn(*pte) >= (pfn + npages))
+ continue;
+ addr = g << PGDIR_SHIFT;
+#ifdef __ia64__
+ /* IA64 plays tricks with the pgd mapping to save space.
+ * This reverses pgd_index().
+ */
+ {
+ unsigned long region = g >> (PAGE_SHIFT - 6);
+ unsigned long l1index = g - (region << (PAGE_SHIFT - 6));
+ addr = (region << 61) + (l1index << PGDIR_SHIFT);
+ }
+#endif
+ addr += (m << PMD_SHIFT) + (t << PAGE_SHIFT);
+ kdb_printf("0x%-14lx " kdb_bfd_vma_fmt0 " ",
+ pte_pfn(*pte), addr);
+ kdbm_print_pte(pte);
+ kdb_printf("\n");
+ }
+ pte_unmap(pte - 1);
+#undef KM_PTE0
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int
+kdbm_print_dentry(unsigned long daddr)
+{
+ struct dentry d;
+ int diag;
+ char buf[256];
+
+ kdb_printf("Dentry at 0x%lx\n", daddr);
+ if ((diag = kdb_getarea(d, (unsigned long)daddr)))
+ return diag;
+
+ if ((d.d_name.len > sizeof(buf)) || (diag = kdb_getarea_size(buf, (unsigned long)(d.d_name.name), d.d_name.len)))
+ kdb_printf(" d_name.len = %d d_name.name = 0x%p\n",
+ d.d_name.len, d.d_name.name);
+ else
+ kdb_printf(" d_name.len = %d d_name.name = 0x%p <%.*s>\n",
+ d.d_name.len, d.d_name.name,
+ (int)(d.d_name.len), d.d_name.name);
+
+ kdb_printf(" d_count = %d d_flags = 0x%x d_inode = 0x%p\n",
+ atomic_read(&d.d_count), d.d_flags, d.d_inode);
+
+ kdb_printf(" d_parent = 0x%p\n", d.d_parent);
+
+ kdb_printf(" d_hash.nxt = 0x%p d_hash.prv = 0x%p\n",
+ d.d_hash.next, d.d_hash.pprev);
+
+ kdb_printf(" d_lru.nxt = 0x%p d_lru.prv = 0x%p\n",
+ d.d_lru.next, d.d_lru.prev);
+
+ kdb_printf(" d_child.nxt = 0x%p d_child.prv = 0x%p\n",
+ d.d_u.d_child.next, d.d_u.d_child.prev);
+
+ kdb_printf(" d_subdirs.nxt = 0x%p d_subdirs.prv = 0x%p\n",
+ d.d_subdirs.next, d.d_subdirs.prev);
+
+ kdb_printf(" d_alias.nxt = 0x%p d_alias.prv = 0x%p\n",
+ d.d_alias.next, d.d_alias.prev);
+
+ kdb_printf(" d_op = 0x%p d_sb = 0x%p d_fsdata = 0x%p\n",
+ d.d_op, d.d_sb, d.d_fsdata);
+
+ kdb_printf(" d_iname = %s\n",
+ d.d_iname);
+
+ if (d.d_inode) {
+ struct inode i;
+ kdb_printf("\nInode Entry at 0x%p\n", d.d_inode);
+ if ((diag = kdb_getarea(i, (unsigned long)d.d_inode)))
+ return diag;
+ kdb_printf(" i_mode = 0%o i_nlink = %d i_rdev = 0x%x\n",
+ i.i_mode, i.i_nlink, i.i_rdev);
+
+ kdb_printf(" i_ino = %ld i_count = %d\n",
+ i.i_ino, atomic_read(&i.i_count));
+
+ kdb_printf(" i_hash.nxt = 0x%p i_hash.prv = 0x%p\n",
+ i.i_hash.next, i.i_hash.pprev);
+
+ kdb_printf(" i_list.nxt = 0x%p i_list.prv = 0x%p\n",
+ i.i_list.next, i.i_list.prev);
+
+ kdb_printf(" i_dentry.nxt = 0x%p i_dentry.prv = 0x%p\n",
+ i.i_dentry.next, i.i_dentry.prev);
+
+ }
+ kdb_printf("\n");
+ return 0;
+}
+
+static int
+kdbm_filp(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ struct file f;
+ int nextarg;
+ unsigned long addr;
+ long offset;
+ int diag;
+
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+
+ nextarg = 1;
+ if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs)) ||
+ (diag = kdb_getarea(f, addr)))
+ return diag;
+
+ kdb_printf("File Pointer at 0x%lx\n", addr);
+
+ kdb_printf(" fu_list.nxt = 0x%p fu_list.prv = 0x%p\n",
+ f.f_u.fu_list.next, f.f_u.fu_list.prev);
+
+ kdb_printf(" f_dentry = 0x%p f_vfsmnt = 0x%p f_op = 0x%p\n",
+ f.f_dentry, f.f_vfsmnt, f.f_op);
+
+ kdb_printf(" f_count = %d f_flags = 0x%x f_mode = 0x%x\n",
+ atomic_read(&f.f_count), f.f_flags, f.f_mode);
+
+ kdb_printf(" f_pos = %Ld security = 0x%p\n",
+ f.f_pos, f.f_security);
+
+ kdb_printf(" private_data = 0x%p f_mapping = 0x%p\n\n",
+ f.private_data, f.f_mapping);
+
+ return kdbm_print_dentry((unsigned long)f.f_dentry);
+}
+
+static int
+kdbm_fl(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ struct file_lock fl;
+ int nextarg;
+ unsigned long addr;
+ long offset;
+ int diag;
+
+
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+
+ nextarg = 1;
+ if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs)) ||
+ (diag = kdb_getarea(fl, addr)))
+ return diag;
+
+ kdb_printf("File_lock at 0x%lx\n", addr);
+
+ kdb_printf(" fl_next = 0x%p fl_link.nxt = 0x%p fl_link.prv = 0x%p\n",
+ fl.fl_next, fl.fl_link.next, fl.fl_link.prev);
+ kdb_printf(" fl_block.nxt = 0x%p fl_block.prv = 0x%p\n",
+ fl.fl_block.next, fl.fl_block.prev);
+ kdb_printf(" fl_owner = 0x%p fl_pid = %d fl_wait = 0x%p\n",
+ fl.fl_owner, fl.fl_pid, &fl.fl_wait);
+ kdb_printf(" fl_file = 0x%p fl_flags = 0x%x\n",
+ fl.fl_file, fl.fl_flags);
+ kdb_printf(" fl_type = %d fl_start = 0x%llx fl_end = 0x%llx\n",
+ fl.fl_type, fl.fl_start, fl.fl_end);
+
+ kdb_printf(" file_lock_operations");
+ if (fl.fl_ops)
+ kdb_printf("\n fl_insert = 0x%p fl_remove = 0x%p fl_copy_lock = 0x%p fl_release_private = 0x%p\n",
+ fl.fl_ops->fl_insert, fl.fl_ops->fl_remove,
+ fl.fl_ops->fl_copy_lock, fl.fl_ops->fl_release_private);
+ else
+ kdb_printf(" empty\n");
+
+ kdb_printf(" lock_manager_operations");
+ if (fl.fl_lmops)
+ kdb_printf("\n fl_compare_owner = 0x%p fl_notify = 0x%p\n",
+ fl.fl_lmops->fl_compare_owner, fl.fl_lmops->fl_notify);
+ else
+ kdb_printf(" empty\n");
+
+ kdb_printf(" fl_fasync = 0x%p fl_break 0x%lx\n",
+ fl.fl_fasync, fl.fl_break_time);
+
+ return 0;
+}
+
+
+static int
+kdbm_dentry(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int nextarg;
+ unsigned long addr;
+ long offset;
+ int diag;
+
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+
+ nextarg = 1;
+ if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs)))
+ return diag;
+
+ return kdbm_print_dentry(addr);
+}
+
+static int
+kdbm_kobject(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ struct kobject k;
+ int nextarg;
+ unsigned long addr;
+ long offset;
+ int diag;
+
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+
+ nextarg = 1;
+ if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs)) ||
+ (diag = kdb_getarea(k, addr)))
+ return diag;
+
+
+ kdb_printf("kobject at 0x%lx\n", addr);
+
+ if (k.k_name) {
+ char c;
+ kdb_printf(" k_name 0x%p", k.k_name);
+ if (kdb_getarea(c, (unsigned long)k.k_name) == 0)
+ kdb_printf(" '%s'", k.k_name);
+ kdb_printf("\n");
+ }
+
+ if (k.k_name != ((struct kobject *)addr)->name)
+ kdb_printf(" name '%." __stringify(KOBJ_NAME_LEN) "s'\n", k.k_name);
+
+ kdb_printf(" kref.refcount %d'\n", atomic_read(&k.kref.refcount));
+
+ kdb_printf(" entry.next = 0x%p entry.prev = 0x%p\n",
+ k.entry.next, k.entry.prev);
+
+ kdb_printf(" parent = 0x%p kset = 0x%p ktype = 0x%p dentry = 0x%p\n",
+ k.parent, k.kset, k.ktype, k.dentry);
+
+ return 0;
+}
+
+static int
+kdbm_sh(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int diag;
+ int nextarg;
+ unsigned long addr;
+ long offset = 0L;
+ struct Scsi_Host sh;
+
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+
+ nextarg = 1;
+ if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs)) ||
+ (diag = kdb_getarea(sh, addr)))
+ return diag;
+
+ kdb_printf("Scsi_Host at 0x%lx\n", addr);
+ kdb_printf("host_queue = 0x%p\n", sh.__devices.next);
+ kdb_printf("ehandler = 0x%p eh_action = 0x%p\n",
+ sh.ehandler, sh.eh_action);
+ kdb_printf("host_wait = 0x%p hostt = 0x%p\n",
+ &sh.host_wait, sh.hostt);
+ kdb_printf("host_failed = %d host_no = %d resetting = %d\n",
+ sh.host_failed, sh.host_no, sh.resetting);
+ kdb_printf("max id/lun/channel = [%d/%d/%d] this_id = %d\n",
+ sh.max_id, sh.max_lun, sh.max_channel, sh.this_id);
+ kdb_printf("can_queue = %d cmd_per_lun = %d sg_tablesize = %d u_isa_dma = %d\n",
+ sh.can_queue, sh.cmd_per_lun, sh.sg_tablesize, sh.unchecked_isa_dma);
+ kdb_printf("host_blocked = %d reverse_ordering = %d \n",
+ sh.host_blocked, sh.reverse_ordering);
+
+ return 0;
+}
+
+static int
+kdbm_sd(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int diag;
+ int nextarg;
+ unsigned long addr;
+ long offset = 0L;
+ struct scsi_device *sd = NULL;
+
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+
+ nextarg = 1;
+ if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs)))
+ goto out;
+ if (!(sd = kmalloc(sizeof(*sd), GFP_ATOMIC))) {
+ kdb_printf("kdbm_sd: cannot kmalloc sd\n");
+ goto out;
+ }
+ if ((diag = kdb_getarea(*sd, addr)))
+ goto out;
+
+ kdb_printf("scsi_device at 0x%lx\n", addr);
+ kdb_printf("next = 0x%p prev = 0x%p host = 0x%p\n",
+ sd->siblings.next, sd->siblings.prev, sd->host);
+ kdb_printf("device_busy = %d current_cmnd 0x%p\n",
+ sd->device_busy, sd->current_cmnd);
+ kdb_printf("id/lun/chan = [%d/%d/%d] single_lun = %d device_blocked = %d\n",
+ sd->id, sd->lun, sd->channel, sd->single_lun, sd->device_blocked);
+ kdb_printf("queue_depth = %d current_tag = %d scsi_level = %d\n",
+ sd->queue_depth, sd->current_tag, sd->scsi_level);
+ kdb_printf("%8.8s %16.16s %4.4s\n", sd->vendor, sd->model, sd->rev);
+out:
+ if (sd)
+ kfree(sd);
+ return diag;
+}
+
+static int
+kdbm_sc(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int diag;
+ int nextarg;
+ unsigned long addr;
+ long offset = 0L;
+ struct scsi_cmnd *sc = NULL;
+
+ if (argc != 1)
+ return KDB_ARGCOUNT;
+
+ nextarg = 1;
+ if ((diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs)))
+ goto out;
+ if (!(sc = kmalloc(sizeof(*sc), GFP_ATOMIC))) {
+ kdb_printf("kdbm_sc: cannot kmalloc sc\n");
+ goto out;
+ }
+ if ((diag = kdb_getarea(*sc, addr)))
+ goto out;
+
+ kdb_printf("scsi_cmnd at 0x%lx\n", addr);
+ kdb_printf("device = 0x%p next = 0x%p done = 0x%p\n",
+ sc->device, sc->list.next, sc->done);
+ kdb_printf("serial_number = %ld retries = %d\n",
+ sc->serial_number, sc->retries);
+ kdb_printf("cmd_len = %d\n", sc->cmd_len);
+ kdb_printf("cmnd = [%2.2x/%2.2x/%2.2x/%2.2x/%2.2x/%2.2x/%2.2x/%2.2x/%2.2x/%2.2x/%2.2x/%2.2x]\n",
+ sc->cmnd[0], sc->cmnd[1], sc->cmnd[2], sc->cmnd[3], sc->cmnd[4],
+ sc->cmnd[5], sc->cmnd[6], sc->cmnd[7], sc->cmnd[8], sc->cmnd[9],
+ sc->cmnd[10], sc->cmnd[11]);
+ kdb_printf("request_buffer = 0x%p request_bufflen = %d\n",
+ sc->request_buffer, sc->request_bufflen);
+ kdb_printf("use_sg = %d sglist_len = %d\n",
+ sc->use_sg, sc->sglist_len);
+ kdb_printf("underflow = %d transfersize = %d\n",
+ sc->underflow, sc->transfersize);
+ kdb_printf("tag = %d pid = %ld\n",
+ sc->tag, sc->pid);
+
+out:
+ if (sc)
+ kfree(sc);
+ return diag;
+}
+
+static int __init kdbm_vm_init(void)
+{
+ kdb_register("vm", kdbm_vm, "[-v] <vaddr>", "Display vm_area_struct", 0);
+ kdb_register("vmp", kdbm_vm, "[-v] <pid>", "Display all vm_area_struct for <pid>", 0);
+ kdb_register("pte", kdbm_pte, "( -m <mm> | -p <pid> ) <vaddr> [<nbytes>]", "Display pte_t for mm_struct or pid", 0);
+ kdb_register("rpte", kdbm_rpte, "( -m <mm> | -p <pid> ) <pfn> [<npages>]", "Find pte_t containing pfn for mm_struct or pid", 0);
+ kdb_register("dentry", kdbm_dentry, "<dentry>", "Display interesting dentry stuff", 0);
+ kdb_register("kobject", kdbm_kobject, "<kobject>", "Display interesting kobject stuff", 0);
+ kdb_register("filp", kdbm_filp, "<filp>", "Display interesting filp stuff", 0);
+ kdb_register("fl", kdbm_fl, "<fl>", "Display interesting file_lock stuff", 0);
+ kdb_register("sh", kdbm_sh, "<vaddr>", "Show scsi_host", 0);
+ kdb_register("sd", kdbm_sd, "<vaddr>", "Show scsi_device", 0);
+ kdb_register("sc", kdbm_sc, "<vaddr>", "Show scsi_cmnd", 0);
+
+ return 0;
+}
+
+static void __exit kdbm_vm_exit(void)
+{
+ kdb_unregister("vm");
+ kdb_unregister("vmp");
+ kdb_unregister("pte");
+ kdb_unregister("rpte");
+ kdb_unregister("dentry");
+ kdb_unregister("kobject");
+ kdb_unregister("filp");
+ kdb_unregister("fl");
+ kdb_unregister("sh");
+ kdb_unregister("sd");
+ kdb_unregister("sc");
+}
+
+module_init(kdbm_vm_init);
+module_exit(kdbm_vm_exit);
--- /dev/null
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Author: Vamsi Krishna S. <vamsi_krishna@in.ibm.com>
+ * (C) 2003 IBM Corporation.
+ */
+
+#include <linux/types.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/swapops.h>
+#include <linux/highmem.h>
+
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/desc.h>
+#include <asm/debugreg.h>
+#include <asm/pgtable.h>
+
+MODULE_AUTHOR("Vamsi Krishna S./IBM");
+MODULE_DESCRIPTION("x86 specific information (gdt/idt/ldt/page tables)");
+MODULE_LICENSE("GPL");
+
+typedef struct _kdb_desc {
+ unsigned short limit;
+ unsigned short base;
+ unsigned char base_h1;
+ unsigned char type:4;
+ unsigned char seg:1;
+ unsigned char dpl:2;
+ unsigned char present:1;
+ unsigned char limit_h:4;
+ unsigned char avl:2;
+ unsigned char db:1;
+ unsigned char g:1; /* granularity */
+ unsigned char base_h2;
+} kdb_desc_t;
+
+typedef struct _kdb_gate_desc {
+ unsigned short offset;
+ unsigned short sel;
+ unsigned char res;
+ unsigned char type:4;
+ unsigned char seg:1;
+ unsigned char dpl:2;
+ unsigned char present:1;
+ unsigned short offset_h;
+} kdb_gate_desc_t;
+
+#define KDB_SEL_MAX 0x2000
+#define KDB_IDT_MAX 0x100
+#define KDB_SYS_DESC_TYPE_TSS 0x01
+#define KDB_SYS_DESC_TYPE_LDT 0x02
+#define KDB_SYS_DESC_TYPE_TSSB 0x03
+#define KDB_SYS_DESC_TYPE_CALLG 0x04
+#define KDB_SYS_DESC_TYPE_TASKG 0x05
+#define KDB_SYS_DESC_TYPE_INTG 0x06
+#define KDB_SYS_DESC_TYPE_TRAPG 0x07
+
+#define KDB_SYS_DESC_TYPE_TSS32 0x09
+#define KDB_SYS_DESC_TYPE_TSS32B 0x0b
+#define KDB_SYS_DESC_TYPE_CALLG32 0x0c
+#define KDB_SYS_DESC_TYPE_INTG32 0x0e
+#define KDB_SYS_DESC_TYPE_TRAPG32 0x0f
+
+#define KDB_SYS_DESC_OFFSET(d) ((unsigned long)(d->offset_h << 16 | d->offset))
+#define KDB_SYS_DESC_CALLG_COUNT(d) ((unsigned int)(d->res & 0x0F))
+
+#define KDB_SEG_DESC_TYPE_CODE 0x08
+#define KDB_SEG_DESC_TYPE_CODE_R 0x02
+#define KDB_SEG_DESC_TYPE_DATA_W 0x02
+#define KDB_SEG_DESC_TYPE_CODE_C 0x02 /* conforming */
+#define KDB_SEG_DESC_TYPE_DATA_D 0x02 /* expand-down */
+#define KDB_SEG_DESC_TYPE_A 0x01 /* accessed */
+
+#define KDB_SEG_DESC_BASE(d) ((unsigned long)(d->base_h2 << 24 | d->base_h1 << 16 | d->base))
+#define _LIMIT(d) ((unsigned long)(d->limit_h << 16 | d->limit))
+#define KDB_SEG_DESC_LIMIT(d) (d->g ? ((_LIMIT(d)+1) << 12) -1 : _LIMIT(d))
+
+/* helper functions to display system registers in verbose mode */
+static void display_gdtr(void)
+{
+ struct Xgt_desc_struct gdtr;
+
+ __asm__ __volatile__ ("sgdt %0\n\t" : "=m"(gdtr));
+ kdb_printf("gdtr.address = 0x%8.8lx, gdtr.size = 0x%x\n", gdtr.address, gdtr.size);
+
+ return;
+}
+
+static void display_ldtr(void)
+{
+ struct Xgt_desc_struct gdtr;
+ unsigned long ldtr;
+
+ __asm__ __volatile__ ("sgdt %0\n\t" : "=m"(gdtr));
+ __asm__ __volatile__ ("sldt %0\n\t" : "=m"(ldtr));
+
+ kdb_printf("ldtr = 0x%8.8lx ", ldtr);
+
+ if (ldtr < gdtr.size) {
+ kdb_desc_t *ldt_desc = (kdb_desc_t *)(gdtr.address + (ldtr & ~7));
+ kdb_printf("base=0x%8.8lx, limit=0x%8.8lx\n", KDB_SEG_DESC_BASE(ldt_desc),
+ KDB_SEG_DESC_LIMIT(ldt_desc));
+ } else {
+ kdb_printf("invalid\n");
+ }
+
+ return;
+}
+
+static void display_idtr(void)
+{
+ struct Xgt_desc_struct idtr;
+ __asm__ __volatile__ ("sidt %0\n\t" : "=m"(idtr));
+ kdb_printf("idtr.address = 0x%8.8lx, idtr.size = 0x%x\n", idtr.address, idtr.size);
+ return;
+}
+
+static char *cr0_flags[] = {
+ "pe", "mp", "em", "ts", "et", "ne", NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "wp", NULL, "am", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, "nw", "cd", "pg"};
+
+static void display_cr0(void)
+{
+ kdb_machreg_t cr0;
+ int i;
+ __asm__ ("movl %%cr0,%0\n\t":"=r"(cr0));
+ kdb_printf("cr0 = 0x%08lx ", cr0);
+ for (i = 0; i < 32; i++) {
+ if (test_bit(i, &cr0) && cr0_flags[i])
+ kdb_printf("%s ", cr0_flags[i]);
+ }
+ kdb_printf("\n");
+ return;
+}
+
+static void display_cr3(void)
+{
+ kdb_machreg_t cr3;
+ __asm__ ("movl %%cr3,%0\n\t":"=r"(cr3));
+ kdb_printf("cr3 = 0x%08lx ", cr3);
+ if (cr3 & 0x08)
+ kdb_printf("pwt ");
+ if (cr3 & 0x10)
+ kdb_printf("pcd ");
+ kdb_printf("pgdir=%8.8lx\n", cr3 & PAGE_MASK);
+ return;
+}
+
+static char *cr4_flags[] = {
+ "vme", "pvi", "tsd", "de", "pse", "pae", "mce", "pge", "pce"};
+
+static void display_cr4(void)
+{
+ kdb_machreg_t cr4;
+ int i;
+ __asm__ ("movl %%cr4,%0\n\t":"=r"(cr4));
+ kdb_printf("cr4 = 0x%08lx ", cr4);
+ for (i = 0; i < 9; i++) {
+ if (test_bit(i, &cr4))
+ kdb_printf("%s ", cr4_flags[i]);
+ }
+ kdb_printf("\n");
+ return;
+}
+
+static char *dr_type_name[] = { "exec", "write", "io", "rw" };
+
+static void display_dr_status(int nr, int enabled, int local, int len, int type)
+{
+ if (!enabled) {
+ kdb_printf("debug register %d: not enabled\n", nr);
+ return;
+ }
+
+ kdb_printf("debug register %d: %s, len = %d, type = %s\n",
+ nr,
+ local? " local":"global",
+ len,
+ dr_type_name[type]);
+}
+
+static void display_dr(void)
+{
+ kdb_machreg_t dr0, dr1, dr2, dr3, dr6, dr7;
+ int dbnr, set;
+
+ __asm__ ("movl %%db0,%0\n\t":"=r"(dr0));
+ __asm__ ("movl %%db1,%0\n\t":"=r"(dr1));
+ __asm__ ("movl %%db2,%0\n\t":"=r"(dr2));
+ __asm__ ("movl %%db3,%0\n\t":"=r"(dr3));
+ __asm__ ("movl %%db6,%0\n\t":"=r"(dr6));
+ __asm__ ("movl %%db7,%0\n\t":"=r"(dr7));
+
+ kdb_printf("dr0 = 0x%08lx dr1 = 0x%08lx dr2 = 0x%08lx dr3 = 0x%08lx\n",
+ dr0, dr1, dr2, dr3);
+ kdb_printf("dr6 = 0x%08lx ", dr6);
+ dbnr = dr6 & DR6_DR_MASK;
+ if (dbnr) {
+ int nr;
+ switch(dbnr) {
+ case 1:
+ nr = 0; break;
+ case 2:
+ nr = 1; break;
+ case 4:
+ nr = 2; break;
+ default:
+ nr = 3; break;
+ }
+ kdb_printf("debug register hit = %d", nr);
+ } else if (dr6 & DR_STEP) {
+ kdb_printf("single step");
+ } else if (dr6 & DR_SWITCH) {
+ kdb_printf("task switch");
+ }
+ kdb_printf("\n");
+
+ kdb_printf("dr7 = 0x%08lx\n", dr7);
+ set = DR7_L0(dr7) || DR7_G0(dr7);
+ display_dr_status(0, set, DR7_L0(dr7), DR7_LEN0(dr7), DR7_RW0(dr7));
+ set = DR7_L1(dr7) || DR7_G1(dr7);
+ display_dr_status(1, set, DR7_L1(dr7), DR7_LEN1(dr7), DR7_RW1(dr7));
+ set = DR7_L2(dr7) || DR7_G2(dr7);
+ display_dr_status(2, set, DR7_L2(dr7), DR7_LEN2(dr7), DR7_RW2(dr7));
+ set = DR7_L3(dr7) || DR7_G3(dr7);
+ display_dr_status(3, set, DR7_L3(dr7), DR7_LEN3(dr7), DR7_RW3(dr7));
+}
+
+static char *set_eflags[] = {
+ "carry", NULL, "parity", NULL, "adjust", NULL, "zero", "sign",
+ "trace", "intr-on", "dir", "overflow", NULL, NULL, "nestedtask", NULL,
+ "resume", "vm", "align", "vif", "vip", "id", NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+
+static void display_eflags(unsigned long ef)
+{
+ int i, iopl;
+ kdb_printf("eflags = 0x%08lx ", ef);
+ for (i = 0; i < 22; i++) {
+ if (test_bit(i, &ef) && set_eflags[i])
+ kdb_printf("%s ", set_eflags[i]);
+ }
+
+ iopl = ((unsigned long)(ef & 0x00003000)) >> 12;
+ kdb_printf("iopl=%c\n", '0'+iopl);
+ return;
+}
+
+static void display_tss(struct tss_struct *t)
+{
+ kdb_printf(" cs = %04x, eip = 0x%8.8lx\n", t->es, t->eip);
+ kdb_printf(" ss = %04x, esp = 0x%8.8lx\n", t->ss, t->esp);
+ kdb_printf(" ss0 = %04x, esp0 = 0x%8.8lx\n", t->ss0, t->esp0);
+ kdb_printf(" ss1 = %04x, esp1 = 0x%8.8lx\n", t->ss1, t->esp1);
+ kdb_printf(" ss2 = %04x, esp2 = 0x%8.8lx\n", t->ss2, t->esp2);
+ kdb_printf(" ldt = %04x, cr3 = 0x%8.8lx\n", t->ldt, t->__cr3);
+ kdb_printf(" ds = %04x, es = %04x fs = %04x gs = %04x\n",
+ t->ds, t->es, t->fs, t->gs);
+ kdb_printf(" eax = 0x%8.8lx, ebx = 0x%8.8lx ecx = 0x%8.8lx edx = 0x%8.8lx\n",
+ t->eax, t->ebx, t->ecx, t->edx);
+ kdb_printf(" esi = 0x%8.8lx, edi = 0x%8.8lx ebp = 0x%8.8lx\n",
+ t->esi, t->edi, t->ebp);
+}
+
+static char *gate_desc_types[] = {
+ "invalid", "tss-avlb", "ldt", "tss-busy",
+ "callgate", "taskgate", "intgate", "trapgate",
+ "invalid", "tss32-avlb", "invalid", "tss32-busy",
+ "callgate32", "invalid", "intgate32", "trapgate32",
+ NULL };
+
+static int
+display_gate_desc(kdb_gate_desc_t * d)
+{
+ kdb_printf("%-11s ", gate_desc_types[d->type]);
+
+ switch(d->type) {
+ case KDB_SYS_DESC_TYPE_LDT:
+ kdb_printf("base=0x%8.8lx limit=0x%8.8lx dpl=%d\n",
+ KDB_SEG_DESC_BASE(((kdb_desc_t *)d)),
+ KDB_SEG_DESC_LIMIT(((kdb_desc_t *)d)), d->dpl);
+ break;
+ case KDB_SYS_DESC_TYPE_TSS32:
+ case KDB_SYS_DESC_TYPE_TSS32B:
+ {
+ struct tss_struct *tss = (struct tss_struct *)KDB_SEG_DESC_BASE(((kdb_desc_t *)d));
+ kdb_printf("base=0x%8.8lx limit=0x%8.8lx dpl=%d\n",
+ (unsigned long)tss,
+ KDB_SEG_DESC_LIMIT(((kdb_desc_t *)d)), d->dpl);
+ display_tss(tss);
+ break;
+ }
+ case KDB_SYS_DESC_TYPE_CALLG:
+ kdb_printf("sel=0x%4.4x off=0x%8.8lx dpl=%d wc=%d\n",
+ d->sel, KDB_SYS_DESC_OFFSET(d), d->dpl,
+ KDB_SYS_DESC_CALLG_COUNT(d));
+ break;
+ case KDB_SYS_DESC_TYPE_CALLG32:
+ kdb_printf("sel=0x%4.4x off=0x%8.8lx dpl=%d dwc=%d\n",
+ d->sel, KDB_SYS_DESC_OFFSET(d), d->dpl,
+ KDB_SYS_DESC_CALLG_COUNT(d));
+ break;
+ default:
+ kdb_printf("sel=0x%4.4x off=0x%8.8lx dpl=%d\n",
+ d->sel, KDB_SYS_DESC_OFFSET(d), d->dpl);
+ break;
+ }
+
+ return 0;
+}
+
+static int
+display_seg_desc(kdb_desc_t * d)
+{
+ unsigned char type = d->type;
+
+ if (type & KDB_SEG_DESC_TYPE_CODE) {
+ kdb_printf("%-7s base=0x%8.8lx limit=0x%8.8lx dpl=%d %c%c%c %s %s %s \n",
+ "code",
+ KDB_SEG_DESC_BASE(d), KDB_SEG_DESC_LIMIT(d),
+ d->dpl,
+ (type & KDB_SEG_DESC_TYPE_CODE_R)?'r':'-',
+ '-', 'x',
+ d->db ? "32b" : "16b",
+ (type & KDB_SEG_DESC_TYPE_A)?"ac":"",
+ (type & KDB_SEG_DESC_TYPE_CODE_C)?"conf":"");
+ }
+ else {
+ kdb_printf("%-7s base=0x%8.8lx limit=0x%8.8lx dpl=%d %c%c%c %s %s %s \n",
+ "data",
+ KDB_SEG_DESC_BASE(d), KDB_SEG_DESC_LIMIT(d),
+ d->dpl,
+ 'r',
+ (type & KDB_SEG_DESC_TYPE_DATA_W)?'w':'-',
+ '-',
+ d->db ? "32b" : "16b",
+ (type & KDB_SEG_DESC_TYPE_A)?"ac":"",
+ (type & KDB_SEG_DESC_TYPE_DATA_D)?"down":"");
+ }
+
+ return 0;
+}
+
+static int
+kdb_parse_two_numbers(int argc, const char **argv, int *sel, int *count, int *last_sel, int *last_count)
+{
+ int diag;
+
+ if (argc > 2)
+ return KDB_ARGCOUNT;
+
+ kdbgetintenv("MDCOUNT", count);
+
+ if (argc == 0) {
+ *sel = *last_sel;
+ if (*last_count)
+ *count = *last_count;
+ } else {
+ unsigned long val;
+
+ if (argc >= 1) {
+ diag = kdbgetularg(argv[1], &val);
+ if (diag)
+ return diag;
+ *sel = val;
+ }
+ if (argc >= 2) {
+ diag = kdbgetularg(argv[2], &val);
+ if (diag)
+ return diag;
+ *count = (int) val;
+ *last_count = (int) val;
+ } else if (*last_count) {
+ *count = *last_count;
+ }
+ }
+ return 0;
+}
+
+/*
+ * kdb_gdt
+ *
+ * This function implements the 'gdt' command.
+ *
+ * gdt [<selector> [<line count>]]
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ */
+static int
+kdb_gdt(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int sel = 0;
+ struct Xgt_desc_struct gdtr;
+ int diag, count = 8;
+ kdb_desc_t * gdt;
+ unsigned int max_sel;
+ static int last_sel = 0, last_count = 0;
+
+ diag = kdb_parse_two_numbers(argc, argv, &sel, &count, &last_sel, &last_count);
+ if (diag)
+ return diag;
+
+ __asm__ __volatile__ ("sgdt %0\n\t" : "=m"(gdtr));
+ gdt = (kdb_desc_t *) gdtr.address;
+
+ max_sel = (gdtr.size + 1) / sizeof(kdb_desc_t);
+ if (sel >= max_sel) {
+ sel = 0;
+ }
+
+ if (sel + count > max_sel)
+ count = max_sel - sel;
+
+ while (count--) {
+ kdb_desc_t * d = &gdt[sel];
+ kdb_printf("0x%4.4x ", sel++);
+
+ if (!d->present) {
+ kdb_printf("not present\n");
+ continue;
+ }
+ if (d->seg)
+ display_seg_desc(d);
+ else
+ display_gate_desc((kdb_gate_desc_t *)d);
+ }
+
+ last_sel = sel;
+ return 0;
+}
+
+/*
+ * kdb_ldt
+ *
+ * This function implements the 'ldt' command.
+ *
+ * ldt [<selector> [<line count>]]
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ */
+static int
+kdb_ldt(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int sel = 0;
+ struct Xgt_desc_struct gdtr;
+ unsigned long ldtr = 0;
+ int diag, count = 8;
+ kdb_desc_t * ldt, *ldt_desc;
+ unsigned int max_sel;
+ static int last_sel = 0, last_count = 0;
+
+ diag = kdb_parse_two_numbers(argc, argv, &sel, &count, &last_sel, &last_count);
+ if (diag)
+ return diag;
+
+ if (strcmp(argv[0], "ldtp") == 0) {
+ kdb_printf("pid=%d, process=%s\n", kdb_current_task->pid, kdb_current_task->comm);
+ if (!kdb_current_task->mm || !kdb_current_task->mm->context.size) {
+ kdb_printf("no special LDT for this process\n");
+ return 0;
+ }
+ ldt = kdb_current_task->mm->context.ldt;
+ max_sel = kdb_current_task->mm->context.size;
+ } else {
+
+ /* sldt gives the GDT selector for the segment containing LDT */
+ __asm__ __volatile__ ("sgdt %0\n\t" : "=m"(gdtr));
+ __asm__ __volatile__ ("sldt %0\n\t" : "=m"(ldtr));
+
+ if (ldtr > gdtr.size+1) {
+ kdb_printf("invalid ldtr\n");
+ return 0;
+ }
+
+ ldt_desc = (kdb_desc_t *)(gdtr.address + (ldtr & ~7));
+ ldt = (kdb_desc_t *) KDB_SEG_DESC_BASE(ldt_desc);
+ max_sel = (KDB_SEG_DESC_LIMIT(ldt_desc)+1) / sizeof(kdb_desc_t);
+ }
+
+ if (sel >= max_sel) {
+ sel = 0;
+ }
+
+ if (sel + count > max_sel)
+ count = max_sel - sel;
+
+ while (count--) {
+ kdb_desc_t * d = &ldt[sel];
+ kdb_printf("0x%4.4x ", sel++);
+
+ if (d->seg)
+ display_seg_desc(d);
+ else
+ display_gate_desc((kdb_gate_desc_t *)d);
+ }
+
+ last_sel = sel;
+ return 0;
+}
+
+/*
+ * kdb_idt
+ *
+ * This function implements the 'idt' command.
+ *
+ * idt [<vector> [<line count>]]
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ */
+static int
+kdb_idt(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ int vec = 0;
+ struct Xgt_desc_struct idtr;
+ int diag, count = 8;
+ kdb_gate_desc_t * idt;
+ unsigned int max_entries;
+ static int last_vec = 0, last_count = 0;
+
+ diag = kdb_parse_two_numbers(argc, argv, &vec, &count, &last_vec, &last_count);
+ if (diag)
+ return diag;
+
+ __asm__ __volatile__ ("sidt %0\n\t" : "=m"(idtr));
+ idt = (kdb_gate_desc_t *) idtr.address;
+
+ max_entries = (idtr.size+1) / sizeof(kdb_gate_desc_t);
+ if (vec >= max_entries) {
+ vec = 0;
+ }
+
+ if (vec + count > max_entries)
+ count = max_entries - vec;
+
+ while (count--) {
+ kdb_gate_desc_t * d = &idt[vec];
+ kdb_printf("0x%4.4x ", vec++);
+ if (!d->present) {
+ kdb_printf("not present\n");
+ continue;
+ }
+ if (d->seg) {
+ kdb_printf("invalid\n");
+ continue;
+ }
+ display_gate_desc(d);
+ }
+
+ last_vec = vec;
+
+ return 0;
+}
+
+static int
+get_pagetables(unsigned long addr, pgd_t **pgdir, pmd_t **pgmiddle, pte_t **pte)
+{
+ pgd_t * d;
+ pud_t * u;
+ pmd_t * m;
+ pte_t * t;
+
+ *pgdir = NULL;
+ *pgmiddle = NULL;
+ *pte = NULL;
+
+ if (addr >= PAGE_OFFSET || !kdb_current_task->mm)
+ d = pgd_offset_k(addr);
+ else
+ d = pgd_offset(kdb_current_task->mm, addr);
+
+ if (pgd_none(*d) || pgd_bad(*d))
+ return 0;
+
+ *pgdir = d;
+
+ u = pud_offset(d, addr);
+ if (pud_none(*u) || pud_bad(*u))
+ return 0;
+
+ /* if _PAGE_PSE is set, pgdir points directly to the page. */
+ if (pud_val(*u) & _PAGE_PSE)
+ return 0;
+
+ m = pmd_offset(u, addr);
+ if (pmd_none(*m) || pmd_bad(*m))
+ return 0;
+
+ *pgmiddle = m;
+
+ t = (pte_t *)kmap_atomic(pmd_page(*m), KM_KDB) + pte_index(addr);
+ if (pte_none(*t)) {
+ kunmap_atomic((char *)t, KM_KDB);
+ return 0;
+ }
+
+ *pte = t;
+
+ kdb_printf("\naddr=%08lx, pgd=%08llx, pmd=%08llx, pte=%08llx\n",
+ addr,
+ (unsigned long long) pgd_val(*d),
+ (unsigned long long) pmd_val(*m),
+ (unsigned long long) pte_val(*t));
+ return 0;
+}
+
+#ifdef CONFIG_X86_PAE
+#define HUGE "2M"
+#else
+#define HUGE "4M"
+#endif
+
+#define FORMAT_PGDIR(entry) \
+ kdb_printf("frame=%05llx %c %s %c %c %c %s %c %s %s \n",\
+ (entry >> PAGE_SHIFT), \
+ (entry & _PAGE_PRESENT)?'p':'n', \
+ (entry & _PAGE_RW)?"rw":"ro", \
+ (entry & _PAGE_USER)?'u':'s', \
+ (entry & _PAGE_ACCESSED)?'a':' ', \
+ ' ', \
+ (entry & _PAGE_PSE)?HUGE:"4K", \
+ (entry & _PAGE_GLOBAL)?'g':' ', \
+ (entry & _PAGE_PWT)?"wt":"wb", \
+ (entry & _PAGE_PCD)?"cd":" ");
+
+#define FORMAT_PTE(p, entry) \
+ kdb_printf("frame=%05llx %c%c%c %c %c %c %s %c %s %s %s\n",\
+ ((entry & ~_PAGE_NX) >> PAGE_SHIFT), \
+ (pte_read(p))? 'r':'-', \
+ (pte_write(p))? 'w':'-', \
+ (pte_exec(p))? 'x':'-', \
+ (pte_dirty(p))? 'd':' ', \
+ (pte_young(p))? 'a':' ', \
+ (entry & _PAGE_USER)? 'u':'s', \
+ " ", \
+ (entry & _PAGE_GLOBAL)? 'g':' ', \
+ (entry & _PAGE_PWT)? "wt":"wb", \
+ (entry & _PAGE_PCD)? "cd":" ", \
+ (entry & _PAGE_NX)? "nx":"");
+
+static void
+display_pgdir(unsigned long addr, pgd_t *pgdir, int count)
+{
+ unsigned long long entry;
+ int i;
+ int index = pgdir - ((pgd_t *)(((unsigned long)pgdir) & PAGE_MASK));
+
+ count = min(count, PTRS_PER_PGD - index);
+ addr &= ~(PGDIR_SIZE-1);
+
+ for (i = 0; i < count; i++, pgdir++) {
+ entry = pgd_val(*pgdir);
+ kdb_printf("pgd: addr=%08lx ", addr);
+ if (pgd_none(*pgdir)) {
+ kdb_printf("pgdir not present\n");
+ } else {
+ FORMAT_PGDIR(entry);
+ }
+ addr += PGDIR_SIZE;
+ }
+}
+
+static void
+display_pgmiddle(unsigned long addr, pmd_t *pgmiddle, int count)
+{
+#ifdef CONFIG_X86_PAE
+ unsigned long long entry;
+ int i;
+ int index = pgmiddle - ((pmd_t *)(((unsigned long)pgmiddle) & PAGE_MASK));
+
+ count = min(count, PTRS_PER_PMD - index);
+ addr &= ~(PMD_SIZE-1);
+
+ for (i = 0; i < count; i++, pgmiddle++) {
+ entry = pmd_val(*pgmiddle);
+ kdb_printf("pmd: addr=%08lx ", addr);
+ if (pmd_none(*pgmiddle)) {
+ kdb_printf("pgmiddle not present\n");
+ } else {
+ FORMAT_PGDIR(entry);
+ }
+ addr += PMD_SIZE;
+ }
+#endif
+}
+
+static int
+display_pte(unsigned long addr, pte_t *pte, int count)
+{
+ unsigned long long entry;
+ int i;
+ int index = pte - ((pte_t *)(((unsigned long)pte) & PAGE_MASK));
+
+ count = min(count, PTRS_PER_PTE - index);
+ addr &= PAGE_MASK;
+
+ for (i = 0; i < count; i++, pte++) {
+ entry = pte_val(*pte);
+ kdb_printf("pte: addr=%08lx ", addr);
+ if (pte_none(*pte)) {
+ kdb_printf("pte not present\n");
+ } else if (!pte_present(*pte)) {
+ if (pte_file(*pte))
+ kdb_printf("page swapped out to file\n");
+ else {
+ kdb_printf("page swapped out. swp_offset=%08lx ",
+ swp_offset(pte_to_swp_entry(*pte)));
+ kdb_printf("swp_type=%x\n",
+ swp_type(pte_to_swp_entry(*pte)));
+ }
+ } else {
+ FORMAT_PTE(*pte, entry);
+ }
+ addr += PAGE_SIZE;
+ }
+ return i;
+}
+
+/*
+ * kdb_pte
+ *
+ * This function implements the 'pte' command.
+ *
+ * pte <addr arg> [<line count>]
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ */
+static int
+kdb_pte(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ static unsigned long last_addr = 0, last_count = 0;
+ int count = 8;
+ unsigned long addr;
+ long offset = 0;
+ pgd_t *pgdir;
+ pmd_t *pgmiddle;
+ pte_t *pte;
+
+ kdbgetintenv("MDCOUNT", &count);
+
+ if (argc == 0) {
+ if (last_addr == 0)
+ return KDB_ARGCOUNT;
+ addr = last_addr;
+ if (last_count)
+ count = last_count;
+ } else {
+ kdb_machreg_t val;
+ int diag, nextarg = 1;
+ diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
+ if (diag)
+ return diag;
+ if (argc > nextarg+1)
+ return KDB_ARGCOUNT;
+
+ if (argc >= nextarg) {
+ diag = kdbgetularg(argv[nextarg], &val);
+ if (!diag) {
+ count = (int) val;
+ last_count = count;
+ } else if (last_count) {
+ count = last_count;
+ }
+ }
+ }
+
+ /*
+ * round off the addr to a page boundary.
+ */
+ addr &= PAGE_MASK;
+
+ get_pagetables(addr, &pgdir, &pgmiddle, &pte);
+
+ if (pgdir)
+ display_pgdir(addr, pgdir, 1);
+ if (pgmiddle)
+ display_pgmiddle(addr, pgmiddle, 1);
+ if (pte) {
+ int displayed;
+ displayed = display_pte(addr, pte, count);
+ addr += (displayed << PAGE_SHIFT);
+ kunmap_atomic((char *)pte, KM_KDB);
+ }
+ last_addr = addr;
+ return 0;
+}
+
+/*
+ * kdb_rdv
+ *
+ * This function implements the 'rdv' command.
+ * It displays all registers of the current processor
+ * included control registers in verbose mode.
+ *
+ * Inputs:
+ * argc argument count
+ * argv argument vector
+ * envp environment vector
+ * regs registers at time kdb was entered.
+ * Outputs:
+ * None.
+ * Returns:
+ * zero for success, a kdb diagnostic if error
+ * Locking:
+ * none.
+ * Remarks:
+ * This should have been an option to rd command say "rd v",
+ * but it is here as it is a non-essential x86-only command,
+ * that need not clutter arch/i386/kdb/kdbasupport.c.
+ */
+static int
+kdb_rdv(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+ kdba_dumpregs(regs, NULL, NULL);
+ display_eflags(regs->eflags);
+ kdb_printf("\n");
+ display_gdtr();
+ display_idtr();
+ display_ldtr();
+ kdb_printf("\n");
+ display_cr0();
+ display_cr3();
+ display_cr4();
+ kdb_printf("\n");
+ display_dr();
+ return 0;
+}
+
+static int __init kdbm_x86_init(void)
+{
+ kdb_register("rdv", kdb_rdv, "", "Display registers in verbose mode", 0);
+ kdb_register_repeat("gdt", kdb_gdt, "<sel> [<count>]", "Display GDT", 0, KDB_REPEAT_NO_ARGS);
+ kdb_register_repeat("idt", kdb_idt, "<int> [<count>]", "Display IDT", 0, KDB_REPEAT_NO_ARGS);
+ kdb_register_repeat("ldt", kdb_ldt, "<sel> [<count>]", "Display LDT", 0, KDB_REPEAT_NO_ARGS);
+ kdb_register_repeat("ptex", kdb_pte, "<addr> [<count>]", "Display pagetables", 0, KDB_REPEAT_NO_ARGS);
+ kdb_register_repeat("ldtp", kdb_ldt, "<sel> [<count>]", "Display Process LDT", 0, KDB_REPEAT_NO_ARGS);
+ return 0;
+}
+
+static void __exit kdbm_x86_exit(void)
+{
+ kdb_unregister("rdv");
+ kdb_unregister("gdt");
+ kdb_unregister("ldt");
+ kdb_unregister("idt");
+ kdb_unregister("ptex");
+ kdb_unregister("ldtp");
+}
+
+module_init(kdbm_x86_init);
+module_exit(kdbm_x86_exit);
--- /dev/null
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2006 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+
+/*
+ * Cross Partition Communication (XPC) kdb support.
+ *
+ * This provides kdb commands for debugging XPC.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#include <asm/sn/sn_sal.h>
+#include <asm/sn/xpc.h>
+
+
+MODULE_AUTHOR("SGI");
+MODULE_DESCRIPTION("Debug XPC information");
+MODULE_LICENSE("GPL");
+
+
+static int
+kdbm_xpc_down(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ if (xpc_rsvd_page == NULL) {
+ kdb_printf("Reserved Page has not been initialized.\n");
+
+ } else if (xpc_kdebug_force_disengage()) {
+ kdb_printf("Unable to force XPC disengage.\n");
+ }
+ return 0;
+}
+
+
+static char *
+kdbm_xpc_get_ascii_reason_code(enum xpc_retval reason)
+{
+ switch (reason) {
+ case xpcSuccess: return "";
+ case xpcNotConnected: return "xpcNotConnected";
+ case xpcConnected: return "xpcConnected";
+ case xpcRETIRED1: return "xpcRETIRED1";
+ case xpcMsgReceived: return "xpcMsgReceived";
+ case xpcMsgDelivered: return "xpcMsgDelivered";
+ case xpcRETIRED2: return "xpcRETIRED2";
+ case xpcNoWait: return "xpcNoWait";
+ case xpcRetry: return "xpcRetry";
+ case xpcTimeout: return "xpcTimeout";
+ case xpcInterrupted: return "xpcInterrupted";
+ case xpcUnequalMsgSizes: return "xpcUnequalMsgSizes";
+ case xpcInvalidAddress: return "xpcInvalidAddress";
+ case xpcNoMemory: return "xpcNoMemory";
+ case xpcLackOfResources: return "xpcLackOfResources";
+ case xpcUnregistered: return "xpcUnregistered";
+ case xpcAlreadyRegistered: return "xpcAlreadyRegistered";
+ case xpcPartitionDown: return "xpcPartitionDown";
+ case xpcNotLoaded: return "xpcNotLoaded";
+ case xpcUnloading: return "xpcUnloading";
+ case xpcBadMagic: return "xpcBadMagic";
+ case xpcReactivating: return "xpcReactivating";
+ case xpcUnregistering: return "xpcUnregistering";
+ case xpcOtherUnregistering: return "xpcOtherUnregistering";
+ case xpcCloneKThread: return "xpcCloneKThread";
+ case xpcCloneKThreadFailed: return "xpcCloneKThreadFailed";
+ case xpcNoHeartbeat: return "xpcNoHeartbeat";
+ case xpcPioReadError: return "xpcPioReadError";
+ case xpcPhysAddrRegFailed: return "xpcPhysAddrRegFailed";
+ case xpcBteDirectoryError: return "xpcBteDirectoryError";
+ case xpcBtePoisonError: return "xpcBtePoisonError";
+ case xpcBteWriteError: return "xpcBteWriteError";
+ case xpcBteAccessError: return "xpcBteAccessError";
+ case xpcBtePWriteError: return "xpcBtePWriteError";
+ case xpcBtePReadError: return "xpcBtePReadError";
+ case xpcBteTimeOutError: return "xpcBteTimeOutError";
+ case xpcBteXtalkError: return "xpcBteXtalkError";
+ case xpcBteNotAvailable: return "xpcBteNotAvailable";
+ case xpcBteUnmappedError: return "xpcBteUnmappedError";
+ case xpcBadVersion: return "xpcBadVersion";
+ case xpcVarsNotSet: return "xpcVarsNotSet";
+ case xpcNoRsvdPageAddr: return "xpcNoRsvdPageAddr";
+ case xpcInvalidPartid: return "xpcInvalidPartid";
+ case xpcLocalPartid: return "xpcLocalPartid";
+ case xpcOtherGoingDown: return "xpcOtherGoingDown";
+ case xpcSystemGoingDown: return "xpcSystemGoingDown";
+ case xpcSystemHalt: return "xpcSystemHalt";
+ case xpcSystemReboot: return "xpcSystemReboot";
+ case xpcSystemPoweroff: return "xpcSystemPoweroff";
+ case xpcDisconnecting: return "xpcDisconnecting";
+ case xpcOpenCloseError: return "xpcOpenCloseError";
+ case xpcUnknownReason: return "xpcUnknownReason";
+ default: return "undefined reason code";
+ }
+}
+
+
+/*
+ * Display the reserved page used by XPC.
+ *
+ * xpcrp
+ */
+static int
+kdbm_xpc_rsvd_page(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ struct xpc_rsvd_page *rp = (struct xpc_rsvd_page *) xpc_rsvd_page;
+
+
+ if (argc > 0) {
+ return KDB_ARGCOUNT;
+ }
+
+ if (rp == NULL) {
+ kdb_printf("Reserved Page has not been initialized.\n");
+ return 0;
+ }
+
+ kdb_printf("struct xpc_rsvd_page @ (0x%p):\n", (void *) rp);
+ kdb_printf("\tSAL_signature=0x%lx\n", rp->SAL_signature);
+ kdb_printf("\tSAL_version=0x%lx\n", rp->SAL_version);
+ kdb_printf("\tpartid=%d\n", rp->partid);
+ kdb_printf("\tversion=0x%x %d.%d\n", rp->version,
+ XPC_VERSION_MAJOR(rp->version),
+ XPC_VERSION_MINOR(rp->version));
+ kdb_printf("\tvars_pa=0x%lx\n", rp->vars_pa);
+ kdb_printf("\tstamp=0x%lx:0x%lx\n",
+ rp->stamp.tv_sec, rp->stamp.tv_nsec);
+ kdb_printf("\tnasids_size=%ld\n", rp->nasids_size);
+
+ return 0;
+}
+
+
+static void
+kdbm_xpc_print_vars_part(struct xpc_vars_part *vars_part, partid_t partid)
+{
+ kdb_printf("struct xpc_vars_part @ (0x%p) [partid=%d]:\n",
+ (void *) vars_part, partid);
+ kdb_printf("\tmagic=0x%lx ", vars_part->magic);
+ if (vars_part->magic != 0) {
+ kdb_printf("%s", (char *) &vars_part->magic);
+ }
+ kdb_printf("\n");
+ kdb_printf("\tGPs_pa=0x%lx\n", vars_part->GPs_pa);
+ kdb_printf("\topenclose_args_pa=0x%lx\n",
+ vars_part->openclose_args_pa);
+ kdb_printf("\tIPI_amo_pa=0x%lx\n", vars_part->IPI_amo_pa);
+ kdb_printf("\tIPI_nasid=0x%x\n", vars_part->IPI_nasid);
+ kdb_printf("\tIPI_phys_cpuid=0x%x\n", vars_part->IPI_phys_cpuid);
+ kdb_printf("\tnchannels=%d\n", vars_part->nchannels);
+}
+
+
+/*
+ * Display XPC variables.
+ *
+ * xpcvars [ <partid> ]
+ *
+ * no partid - displays xpc_vars structure
+ * partid=0 - displays all initialized xpc_vars_part structures
+ * partid=i - displays xpc_vars_part structure for specified
+ * partition, if initialized
+ */
+static int
+kdbm_xpc_variables(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ int ret;
+ unsigned long ulong_partid;
+ partid_t partid;
+ struct xpc_vars_part *vars_part;
+
+
+ if (xpc_rsvd_page == NULL) {
+ kdb_printf("Reserved Page has not been initialized.\n");
+ return 0;
+ }
+ DBUG_ON(xpc_vars == NULL);
+
+ if (argc == 0) {
+
+ /* just display the xpc_vars structure */
+
+ kdb_printf("struct xpc_vars @ (0x%p):\n", (void *) xpc_vars);
+ kdb_printf("\tversion=0x%x %d.%d\n", xpc_vars->version,
+ XPC_VERSION_MAJOR(xpc_vars->version),
+ XPC_VERSION_MINOR(xpc_vars->version));
+ kdb_printf("\theartbeat=%ld\n", xpc_vars->heartbeat);
+ kdb_printf("\theartbeating_to_mask=0x%lx",
+ xpc_vars->heartbeating_to_mask);
+ for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
+ if (xpc_hb_allowed(partid, xpc_vars)) {
+ kdb_printf(" %d", partid);
+ }
+ }
+ kdb_printf("\n");
+ kdb_printf("\theartbeat_offline=0x%lx\n",
+ xpc_vars->heartbeat_offline);
+ kdb_printf("\tact_nasid=0x%x\n", xpc_vars->act_nasid);
+ kdb_printf("\tact_phys_cpuid=0x%x\n",
+ xpc_vars->act_phys_cpuid);
+ kdb_printf("\tvars_part_pa=0x%lx\n", xpc_vars->vars_part_pa);
+ kdb_printf("\tamos_page_pa=0x%lx\n", xpc_vars->amos_page_pa);
+ kdb_printf("\tamos_page=0x%p\n", (void *) xpc_vars->amos_page);
+ return 0;
+
+ } else if (argc != 1) {
+ return KDB_ARGCOUNT;
+ }
+
+ ret = kdbgetularg(argv[1], (unsigned long *) &ulong_partid);
+ if (ret) {
+ return ret;
+ }
+ partid = (partid_t) ulong_partid;
+ if (partid < 0 || partid >= XP_MAX_PARTITIONS) {
+ kdb_printf("invalid partid\n");
+ return KDB_BADINT;
+ }
+
+ vars_part = (struct xpc_vars_part *) __va(xpc_vars->vars_part_pa);
+ DBUG_ON(vars_part == NULL);
+
+ if (partid == 0) {
+
+ /* display all initialized xpc_vars_part structure */
+
+ for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
+ if (vars_part[partid].magic == 0) {
+ continue;
+ }
+ kdbm_xpc_print_vars_part(&vars_part[partid], partid);
+ }
+
+ } else {
+
+ /* display specified xpc_vars_part structure */
+
+ if (vars_part[partid].magic != 0) {
+ kdbm_xpc_print_vars_part(&vars_part[partid], partid);
+ } else {
+ kdb_printf("struct xpc_vars_part for partid %d not "
+ "initialized\n", partid);
+ }
+ }
+
+ return 0;
+}
+
+
+static void
+kdbm_xpc_print_engaged(char *string, u64 mask, int verbose)
+{
+ partid_t partid;
+
+
+ kdb_printf("%s=0x%lx", string, mask);
+
+ if (verbose) {
+ partid = 0;
+ while (mask != 0) {
+ if (mask & 1UL) {
+ kdb_printf(" %d", partid);
+ }
+ partid++;
+ mask >>= 1;
+ }
+ }
+ kdb_printf("\n");
+}
+
+
+/*
+ * Display XPC's 'engaged partitions' and 'disengage request' AMOs.
+ *
+ * xpcengaged [ -v ]
+ *
+ * -v - verbose mode, displays partition numbers.
+ */
+static int
+kdbm_xpc_engaged(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ int nextarg = 1;
+ int verbose = 0;
+ u64 mask;
+
+
+ if (argc > 1) {
+ return KDB_ARGCOUNT;
+ }
+ if (argc == 1) {
+ if (strcmp(argv[nextarg], "-v") != 0) {
+ return KDB_ARGCOUNT;
+ }
+ verbose = 1;
+ }
+
+ mask = xpc_partition_engaged(-1UL);
+ kdbm_xpc_print_engaged("engaged partitions", mask, verbose);
+
+ mask = xpc_partition_disengage_requested(-1UL);
+ kdbm_xpc_print_engaged("disengage request", mask, verbose);
+
+ return 0;
+}
+
+
+static void
+kdbm_xpc_print_IPI_flags_for_channel(u8 IPI_flags)
+{
+ if (IPI_flags & XPC_IPI_MSGREQUEST) kdb_printf(" MSGREQUEST");
+ if (IPI_flags & XPC_IPI_OPENREPLY) kdb_printf(" OPENREPLY");
+ if (IPI_flags & XPC_IPI_OPENREQUEST) kdb_printf(" OPENREQUEST");
+ if (IPI_flags & XPC_IPI_CLOSEREPLY) kdb_printf(" CLOSEREPLY");
+ if (IPI_flags & XPC_IPI_CLOSEREQUEST) kdb_printf(" CLOSEREQUEST");
+}
+
+
+static void
+kdbm_xpc_print_IPI_flags(u64 IPI_amo)
+{
+ int ch_number;
+ u8 IPI_flags;
+
+
+ for (ch_number = 0; ch_number < XPC_NCHANNELS; ch_number++) {
+
+ /* get the IPI flags for the specific channel */
+ IPI_flags = XPC_GET_IPI_FLAGS(IPI_amo, ch_number);
+ if (IPI_flags == 0) {
+ continue;
+ }
+
+ kdb_printf("\t channel_%d=0x%x", ch_number, IPI_flags);
+ kdbm_xpc_print_IPI_flags_for_channel(IPI_flags);
+ kdb_printf("\n");
+ }
+}
+
+
+static void
+kdbm_xpc_print_part(struct xpc_partition *part, partid_t partid)
+{
+ kdb_printf("xpc_partitions[partid=%d] (0x%p):\n", partid,
+ (void *) part);
+ kdb_printf("\tremote_rp_version=0x%x %d.%d\n", part->remote_rp_version,
+ XPC_VERSION_MAJOR(part->remote_rp_version),
+ XPC_VERSION_MINOR(part->remote_rp_version));
+ kdb_printf("\tremote_rp_stamp=0x%lx:0x%lx\n",
+ part->remote_rp_stamp.tv_sec, part->remote_rp_stamp.tv_nsec);
+ kdb_printf("\tremote_rp_pa=0x%lx\n", part->remote_rp_pa);
+ kdb_printf("\tremote_vars_pa=0x%lx\n", part->remote_vars_pa);
+ kdb_printf("\tremote_vars_part_pa=0x%lx\n", part->remote_vars_part_pa);
+ kdb_printf("\tlast_heartbeat=%ld\n", part->last_heartbeat);
+ kdb_printf("\tremote_amos_page_pa=0x%lx\n", part->remote_amos_page_pa);
+ kdb_printf("\tremote_act_nasid=0x%x\n", part->remote_act_nasid);
+ kdb_printf("\tremote_act_phys_cpuid=0x%x\n",
+ part->remote_act_phys_cpuid);
+ kdb_printf("\tact_IRQ_rcvd=%d\n", part->act_IRQ_rcvd);
+ kdb_printf("\tact_state=%d", part->act_state);
+ switch (part->act_state) {
+ case XPC_P_INACTIVE: kdb_printf(" INACTIVE\n"); break;
+ case XPC_P_ACTIVATION_REQ: kdb_printf(" ACTIVATION_REQ\n"); break;
+ case XPC_P_ACTIVATING: kdb_printf(" ACTIVATING\n"); break;
+ case XPC_P_ACTIVE: kdb_printf(" ACTIVE\n"); break;
+ case XPC_P_DEACTIVATING: kdb_printf(" DEACTIVATING\n"); break;
+ default: kdb_printf(" unknown\n");
+ }
+ kdb_printf("\tremote_vars_version=0x%x %d.%d\n",
+ part->remote_vars_version,
+ XPC_VERSION_MAJOR(part->remote_vars_version),
+ XPC_VERSION_MINOR(part->remote_vars_version));
+ kdb_printf("\treactivate_nasid=%d\n", part->reactivate_nasid);
+ kdb_printf("\treason=%d %s\n", part->reason,
+ kdbm_xpc_get_ascii_reason_code(part->reason));
+ kdb_printf("\treason_line=%d\n", part->reason_line);
+
+ kdb_printf("\tdisengage_request_timeout=0x%lx\n",
+ part->disengage_request_timeout);
+ kdb_printf("\t&disengage_request_timer=0x%p\n",
+ (void *) &part->disengage_request_timer);
+
+ kdb_printf("\tsetup_state=%d", part->setup_state);
+ switch (part->setup_state) {
+ case XPC_P_UNSET: kdb_printf(" UNSET\n"); break;
+ case XPC_P_SETUP: kdb_printf(" SETUP\n"); break;
+ case XPC_P_WTEARDOWN: kdb_printf(" WTEARDOWN\n"); break;
+ case XPC_P_TORNDOWN: kdb_printf(" TORNDOWN\n"); break;
+ default: kdb_printf(" unknown\n");
+ }
+ kdb_printf("\treferences=%d\n", atomic_read(&part->references));
+ kdb_printf("\tnchannels=%d\n", part->nchannels);
+ kdb_printf("\tnchannels_active=%d\n",
+ atomic_read(&part->nchannels_active));
+ kdb_printf("\tnchannels_engaged=%d\n",
+ atomic_read(&part->nchannels_engaged));
+ kdb_printf("\tchannels=0x%p\n", (void *) part->channels);
+ kdb_printf("\tlocal_GPs=0x%p\n", (void *) part->local_GPs);
+ kdb_printf("\tremote_GPs=0x%p\n", (void *) part->remote_GPs);
+ kdb_printf("\tremote_GPs_pa=0x%lx\n", part->remote_GPs_pa);
+ kdb_printf("\tlocal_openclose_args=0x%p\n",
+ (void *) part->local_openclose_args);
+ kdb_printf("\tremote_openclose_args=0x%p\n",
+ (void *) part->remote_openclose_args);
+ kdb_printf("\tremote_openclose_args_pa=0x%lx\n",
+ part->remote_openclose_args_pa);
+ kdb_printf("\tremote_IPI_nasid=0x%x\n", part->remote_IPI_nasid);
+ kdb_printf("\tremote_IPI_phys_cpuid=0x%x\n",
+ part->remote_IPI_phys_cpuid);
+ kdb_printf("\tremote_IPI_amo_va=0x%p\n",
+ (void *) part->remote_IPI_amo_va);
+ kdb_printf("\tlocal_IPI_amo_va=0x%p\n",
+ (void *) part->local_IPI_amo_va);
+ kdb_printf("\tlocal_IPI_amo=0x%lx\n", part->local_IPI_amo);
+ kdbm_xpc_print_IPI_flags(part->local_IPI_amo);
+ kdb_printf("\tIPI_owner=%s\n", part->IPI_owner);
+ kdb_printf("\t&dropped_IPI_timer=0x%p\n",
+ (void *) &part->dropped_IPI_timer);
+
+ kdb_printf("\tchannel_mgr_requests=%d\n", atomic_read(&part->
+ channel_mgr_requests));
+}
+
+
+/*
+ * Display XPC partitions.
+ *
+ * xpcpart [ <vaddr> | <partid> ]
+ */
+static int
+kdbm_xpc_partitions(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ int ret;
+ int nextarg = 1;
+ long offset = 0;
+ unsigned long addr;
+ struct xpc_partition *part;
+ partid_t partid;
+
+
+ if (argc > 1) {
+ return KDB_ARGCOUNT;
+
+ } else if (argc == 1) {
+ ret = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset,
+ NULL, regs);
+ if (ret) {
+ return ret;
+ }
+ if (addr > 0 && addr < XP_MAX_PARTITIONS) {
+ partid = (partid_t) addr;
+ part = &xpc_partitions[partid];
+ } else {
+ part = (struct xpc_partition *) addr;
+ partid = part - &xpc_partitions[0];
+ if (partid <= 0 || partid >= XP_MAX_PARTITIONS ||
+ part != &xpc_partitions[partid]) {
+ kdb_printf("invalid partition entry address\n");
+ return KDB_BADADDR;
+ }
+ }
+ kdbm_xpc_print_part(part, partid);
+
+ } else {
+ for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
+ part = &xpc_partitions[partid];
+ if (part->setup_state == XPC_P_UNSET &&
+ part->reason == 0) {
+ continue;
+ }
+ kdbm_xpc_print_part(part, partid);
+ }
+ }
+ return 0;
+}
+
+
+static void
+kdbm_xpc_print_channel_flags(u32 flags)
+{
+ kdb_printf("\tflags=0x%x", flags);
+
+ if (flags & XPC_C_WDISCONNECT) kdb_printf(" WDISCONNECT");
+ if (flags & XPC_C_DISCONNECTINGCALLOUT_MADE) kdb_printf(" DISCONNECTINGCALLOUT_MADE");
+ if (flags & XPC_C_DISCONNECTINGCALLOUT) kdb_printf(" DISCONNECTINGCALLOUT");
+ if (flags & XPC_C_DISCONNECTING) kdb_printf(" DISCONNECTING");
+ if (flags & XPC_C_DISCONNECTED) kdb_printf(" DISCONNECTED");
+
+ if (flags & XPC_C_CLOSEREQUEST) kdb_printf(" CLOSEREQUEST");
+ if (flags & XPC_C_RCLOSEREQUEST) kdb_printf(" RCLOSEREQUEST");
+ if (flags & XPC_C_CLOSEREPLY) kdb_printf(" CLOSEREPLY");
+ if (flags & XPC_C_RCLOSEREPLY) kdb_printf(" RCLOSEREPLY");
+
+ if (flags & XPC_C_CONNECTING) kdb_printf(" CONNECTING");
+ if (flags & XPC_C_CONNECTED) kdb_printf(" CONNECTED");
+ if (flags & XPC_C_CONNECTEDCALLOUT_MADE) kdb_printf(" CONNECTEDCALLOUT_MADE");
+ if (flags & XPC_C_CONNECTEDCALLOUT) kdb_printf(" CONNECTEDCALLOUT");
+ if (flags & XPC_C_SETUP) kdb_printf(" SETUP");
+
+ if (flags & XPC_C_OPENREQUEST) kdb_printf(" OPENREQUEST");
+ if (flags & XPC_C_ROPENREQUEST) kdb_printf(" ROPENREQUEST");
+ if (flags & XPC_C_OPENREPLY) kdb_printf(" OPENREPLY");
+ if (flags & XPC_C_ROPENREPLY) kdb_printf(" ROPENREPLY");
+
+ if (flags & XPC_C_WASCONNECTED) kdb_printf(" WASCONNECTED");
+
+ kdb_printf("\n");
+}
+
+
+static void
+kdbm_xpc_print_channel(struct xpc_channel *ch)
+{
+ kdb_printf("channel %d (0x%p):\n", ch->number, (void *) ch);
+ kdb_printf("\tpartid=%d\n", ch->partid);
+
+ kdbm_xpc_print_channel_flags(ch->flags);
+
+ kdb_printf("\treason=%d %s\n", ch->reason,
+ kdbm_xpc_get_ascii_reason_code(ch->reason));
+ kdb_printf("\treason_line=%d\n", ch->reason_line);
+ kdb_printf("\tnumber=%d\n", ch->number);
+ kdb_printf("\tmsg_size=%d\n", ch->msg_size);
+ kdb_printf("\tlocal_nentries=%d\n", ch->local_nentries);
+ kdb_printf("\tremote_nentries=%d\n", ch->remote_nentries);
+ kdb_printf("\tlocal_msgqueue=0x%p\n", (void *) ch->local_msgqueue);
+ kdb_printf("\tremote_msgqueue_pa=0x%lx\n", ch->remote_msgqueue_pa);
+ kdb_printf("\tremote_msgqueue=0x%p\n",
+ (void *) ch->remote_msgqueue);
+ kdb_printf("\treferences=%d\n", atomic_read(&ch->references));
+ kdb_printf("\tn_on_msg_allocate_wq=%d\n",
+ atomic_read(&ch->n_on_msg_allocate_wq));
+ kdb_printf("\t&msg_allocate_wq=0x%p\n",
+ (void *) &ch->msg_allocate_wq);
+
+ kdb_printf("\tdelayed_IPI_flags=0x%x", ch->delayed_IPI_flags);
+ kdbm_xpc_print_IPI_flags_for_channel(ch->delayed_IPI_flags);
+ kdb_printf("\n");
+
+ kdb_printf("\tn_to_notify=%d\n", atomic_read(&ch->n_to_notify));
+ kdb_printf("\tnotify_queue=0x%p\n", (void *) ch->notify_queue);
+ kdb_printf("\tfunc=0x%p\n", (void *) ch->func);
+ kdb_printf("\tkey=0x%p\n", ch->key);
+ kdb_printf("\t&msg_to_pull_mutex=0x%p\n",
+ (void *) &ch->msg_to_pull_mutex);
+ kdb_printf("\t&wdisconnect_wait=0x%p\n",
+ (void *) &ch->wdisconnect_wait);
+ kdb_printf("\tlocal_GP=0x%p (%ld:%ld)\n", (void *) ch->local_GP,
+ ch->local_GP->get,
+ ch->local_GP->put);
+ kdb_printf("\tremote_GP=%ld:%ld\n", ch->remote_GP.get,
+ ch->remote_GP.put);
+ kdb_printf("\tw_local_GP=%ld:%ld\n", ch->w_local_GP.get,
+ ch->w_local_GP.put);
+ kdb_printf("\tw_remote_GP=%ld:%ld\n", ch->w_remote_GP.get,
+ ch->w_remote_GP.put);
+ kdb_printf("\tnext_msg_to_pull=%ld\n", ch->next_msg_to_pull);
+ kdb_printf("\tkthreads_assigned=%d\n",
+ atomic_read(&ch->kthreads_assigned));
+ kdb_printf("\tkthreads_assigned_limit=%d\n",
+ ch->kthreads_assigned_limit);
+ kdb_printf("\tkthreads_idle=%d\n",
+ atomic_read(&ch->kthreads_idle));
+ kdb_printf("\tkthreads_idle_limit=%d\n", ch->kthreads_idle_limit);
+ kdb_printf("\tkthreads_active=%d\n",
+ atomic_read(&ch->kthreads_active));
+ kdb_printf("\tkthreads_created=%d\n", ch->kthreads_created);
+ kdb_printf("\t&idle_wq=0x%p\n", (void *) &ch->idle_wq);
+
+ if (ch->flags & XPC_C_CONNECTED) {
+ kdb_printf("\n\t#of local msg queue entries available =%ld\n",
+ ch->local_nentries - (ch->w_local_GP.put -
+ ch->w_remote_GP.get));
+
+ kdb_printf("\t#of local msgs allocated !sent =%ld\n",
+ ch->w_local_GP.put - ch->local_GP->put);
+ kdb_printf("\t#of local msgs allocated sent !ACK'd =%ld\n",
+ ch->local_GP->put - ch->remote_GP.get);
+ kdb_printf("\t#of local msgs allocated sent ACK'd !notified ="
+ "%ld\n", ch->remote_GP.get - ch->w_remote_GP.get);
+
+ kdb_printf("\t#of remote msgs sent !pulled =%ld\n",
+ ch->w_remote_GP.put - ch->next_msg_to_pull);
+ kdb_printf("\t#of remote msgs sent !delivered =%ld\n",
+ ch->next_msg_to_pull - ch->w_local_GP.get);
+ kdb_printf("\t#of remote msgs sent delivered !received =%ld\n",
+ ch->w_local_GP.get - ch->local_GP->get);
+ }
+}
+
+
+/*
+ * Display a XPC partition's channels.
+ *
+ * xpcchan <vaddr> | <partid> [ <channel> ]
+ */
+static int
+kdbm_xpc_channels(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ int ret;
+ int nextarg = 1;
+ long offset = 0;
+ unsigned long addr;
+ partid_t partid;
+ struct xpc_partition *part;
+ int ch_number;
+ struct xpc_channel *ch;
+
+
+ if (argc < 1 || argc > 2) {
+ return KDB_ARGCOUNT;
+ }
+
+ ret = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
+ if (ret) {
+ return ret;
+ }
+ if (addr > 0 && addr < XP_MAX_PARTITIONS) {
+ partid = (partid_t) addr;
+ part = &xpc_partitions[partid];
+ if (part->setup_state == XPC_P_UNSET) {
+ kdb_printf("partition is UNSET\n");
+ return 0;
+ }
+ if (part->setup_state == XPC_P_TORNDOWN) {
+ kdb_printf("partition is TORNDOWN\n");
+ return 0;
+ }
+
+ if (argc == 2) {
+ ret = kdbgetularg(argv[2],
+ (unsigned long *) &ch_number);
+ if (ret) {
+ return ret;
+ }
+ if (ch_number < 0 || ch_number >= part->nchannels) {
+ kdb_printf("invalid channel #\n");
+ return KDB_BADINT;
+ }
+ kdbm_xpc_print_channel(&part->channels[ch_number]);
+ } else {
+ for (ch_number = 0; ch_number < part->nchannels;
+ ch_number++) {
+ kdbm_xpc_print_channel(&part->
+ channels[ch_number]);
+ }
+ }
+
+ } else {
+ ch = (struct xpc_channel *) addr;
+
+ for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
+ part = &xpc_partitions[partid];
+ if (part->setup_state != XPC_P_UNSET &&
+ part->setup_state != XPC_P_TORNDOWN &&
+ ch >= part->channels) {
+ ch_number = ch - part->channels;
+ if (ch_number < part->nchannels &&
+ ch == &part->channels[ch_number]) {
+ break;
+ }
+ }
+ }
+ if (partid == XP_MAX_PARTITIONS) {
+ kdb_printf("invalid channel address\n");
+ return KDB_BADADDR;
+ }
+ kdbm_xpc_print_channel(ch);
+ }
+
+ return 0;
+}
+
+
+static void
+kdbm_xpc_print_local_msgqueue(struct xpc_channel *ch)
+{
+ int i;
+ char *prefix;
+ struct xpc_msg *msg = ch->local_msgqueue;
+ s64 w_remote_GP_get = ch->w_remote_GP.get % ch->local_nentries;
+ s64 remote_GP_get = ch->remote_GP.get % ch->local_nentries;
+ s64 local_GP_put = ch->local_GP->put % ch->local_nentries;
+ s64 w_local_GP_put = ch->w_local_GP.put % ch->local_nentries;
+
+
+ kdb_printf("local message queue (0x%p):\n\n", (void *) msg);
+
+ for (i = 0; i < ch->local_nentries; i++) {
+ kdb_printf("0x%p: flags=0x%x number=%ld", (void *) msg,
+ msg->flags, msg->number);
+
+ prefix = " <--";
+
+ if (i == w_remote_GP_get) {
+ kdb_printf("%s w_remote_GP.get", prefix);
+ prefix = ",";
+ }
+ if (i == remote_GP_get) {
+ kdb_printf("%s remote_GP.get", prefix);
+ prefix = ",";
+ }
+ if (i == local_GP_put) {
+ kdb_printf("%s local_GP->put", prefix);
+ prefix = ",";
+ }
+ if (i == w_local_GP_put) {
+ kdb_printf("%s w_local_GP.put", prefix);
+ }
+ kdb_printf("\n");
+
+ msg = (struct xpc_msg *) ((u64) msg + ch->msg_size);
+ }
+}
+
+
+static void
+kdbm_xpc_print_remote_msgqueue(struct xpc_channel *ch)
+{
+ int i;
+ char *prefix;
+ struct xpc_msg *msg = ch->remote_msgqueue;
+ s64 local_GP_get = ch->local_GP->get % ch->remote_nentries;
+ s64 w_local_GP_get = ch->w_local_GP.get % ch->remote_nentries;
+ s64 next_msg_to_pull = ch->next_msg_to_pull % ch->remote_nentries;
+ s64 w_remote_GP_put = ch->w_remote_GP.put % ch->remote_nentries;
+ s64 remote_GP_put = ch->remote_GP.put % ch->remote_nentries;
+
+
+ kdb_printf("cached remote message queue (0x%p):\n\n", (void *) msg);
+
+ for (i = 0; i < ch->remote_nentries; i++) {
+ kdb_printf("0x%p: flags=0x%x number=%ld", (void *) msg,
+ msg->flags, msg->number);
+
+ prefix = " <--";
+
+ if (i == local_GP_get) {
+ kdb_printf("%s local_GP->get", prefix);
+ prefix = ",";
+ }
+ if (i == w_local_GP_get) {
+ kdb_printf("%s w_local_GP.get", prefix);
+ prefix = ",";
+ }
+ if (i == next_msg_to_pull) {
+ kdb_printf("%s next_msg_to_pull", prefix);
+ prefix = ",";
+ }
+ if (i == w_remote_GP_put) {
+ kdb_printf("%s w_remote_GP.put", prefix);
+ prefix = ",";
+ }
+ if (i == remote_GP_put) {
+ kdb_printf("%s remote_GP.put", prefix);
+ }
+ kdb_printf("\n");
+
+ msg = (struct xpc_msg *) ((u64) msg + ch->msg_size);
+ }
+}
+
+
+/*
+ * Display XPC specified message queue.
+ *
+ * xpcmque <partid> <channel> local|remote
+ */
+static int
+kdbm_xpc_msgqueue(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ int ret, ch_number;
+ unsigned long ulong_partid;
+ partid_t partid;
+ struct xpc_partition *part;
+ struct xpc_channel *ch;
+
+
+ if (argc != 3) {
+ return KDB_ARGCOUNT;
+ }
+
+ ret = kdbgetularg(argv[1], (unsigned long *) &ulong_partid);
+ if (ret) {
+ return ret;
+ }
+ partid = (partid_t) ulong_partid;
+ if (partid <= 0 || partid >= XP_MAX_PARTITIONS) {
+ kdb_printf("invalid partid\n");
+ return KDB_BADINT;
+ }
+
+ ret = kdbgetularg(argv[2], (unsigned long *) &ch_number);
+ if (ret) {
+ return ret;
+ }
+ if (ch_number < 0 || ch_number >= XPC_NCHANNELS) {
+ kdb_printf("invalid channel #\n");
+ return KDB_BADINT;
+ }
+
+ part = &xpc_partitions[partid];
+
+ if (part->setup_state == XPC_P_UNSET) {
+ kdb_printf("partition is UNSET\n");
+ return 0;
+ }
+ if (part->setup_state == XPC_P_TORNDOWN) {
+ kdb_printf("partition is TORNDOWN\n");
+ return 0;
+ }
+
+ if (ch_number >= part->nchannels) {
+ kdb_printf("unsupported channel #\n");
+ return KDB_BADINT;
+ }
+
+ ch = &part->channels[ch_number];
+
+ if (!(ch->flags & XPC_C_SETUP)) {
+ kdb_printf("message queues are not SETUP\n");
+ return 0;
+ }
+
+ if (strcmp(argv[3], "r") == 0 || strcmp(argv[3], "remote") == 0) {
+ kdbm_xpc_print_remote_msgqueue(ch);
+ } else if (strcmp(argv[3], "l") == 0 || strcmp(argv[3], "local") == 0) {
+ kdbm_xpc_print_local_msgqueue(ch);
+ } else {
+ kdb_printf("unknown msg queue selected\n");
+ return KDB_BADINT;
+ }
+
+ return 0;
+}
+
+
+static void
+kdbm_xpc_print_msg_flags(u8 flags)
+{
+ kdb_printf("\tflags=0x%x", flags);
+
+ if (flags & XPC_M_INTERRUPT) kdb_printf(" INTERRUPT");
+ if (flags & XPC_M_READY) kdb_printf(" READY");
+ if (flags & XPC_M_DONE) kdb_printf(" DONE");
+
+ kdb_printf("\n");
+}
+
+
+/*
+ * Display XPC message.
+ *
+ * xpcmsg <vaddr>
+ */
+static int
+kdbm_xpc_msg(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ int ret, nextarg = argc;
+ long offset = 0;
+ unsigned long addr;
+ struct xpc_msg *msg;
+
+
+ if (argc != 1) {
+ return KDB_ARGCOUNT;
+ }
+
+ ret = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
+ if (ret) {
+ return ret;
+ }
+
+ msg = (struct xpc_msg *) addr;
+ kdb_printf("msg (0x%p):\n", (void *) msg);
+ kdbm_xpc_print_msg_flags(msg->flags);
+ kdb_printf("\tnumber=%ld\n", msg->number);
+ kdb_printf("\t&payload=0x%p\n", (void *) &msg->payload);
+
+ return 0;
+}
+
+
+static void
+kdbm_xpc_print_notify_queue(struct xpc_channel *ch)
+{
+ int i;
+ char *prefix;
+ struct xpc_notify *notify = ch->notify_queue;
+ s64 w_remote_GP_get = ch->w_remote_GP.get % ch->local_nentries;
+ s64 remote_GP_get = ch->remote_GP.get % ch->local_nentries;
+ s64 local_GP_put = ch->local_GP->put % ch->local_nentries;
+ s64 w_local_GP_put = ch->w_local_GP.put % ch->local_nentries;
+
+
+ kdb_printf("notify queue (0x%p):\n\n", (void *) notify);
+
+ for (i = 0; i < ch->local_nentries; i++) {
+ kdb_printf("0x%p: type=0x%x", (void *) notify, notify->type);
+
+ if (notify->type == XPC_N_CALL) {
+ kdb_printf(" CALL func=0x%p key=0x%p",
+ (void *) notify->func, notify->key);
+ }
+
+ prefix = " <--";
+
+ if (i == w_remote_GP_get) {
+ kdb_printf("%s w_remote_GP.get", prefix);
+ prefix = ",";
+ }
+ if (i == remote_GP_get) {
+ kdb_printf("%s remote_GP.get", prefix);
+ prefix = ",";
+ }
+ if (i == local_GP_put) {
+ kdb_printf("%s local_GP->put", prefix);
+ prefix = ",";
+ }
+ if (i == w_local_GP_put) {
+ kdb_printf("%s w_local_GP.put", prefix);
+ }
+ kdb_printf("\n");
+
+ notify++;
+ }
+}
+
+
+/*
+ * Display XPC specified notify queue.
+ *
+ * xpcnque <partid> <channel>
+ */
+static int
+kdbm_xpc_notify_queue(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ int ret, ch_number;
+ unsigned long ulong_partid;
+ partid_t partid;
+ struct xpc_partition *part;
+ struct xpc_channel *ch;
+
+
+ if (argc != 2) {
+ return KDB_ARGCOUNT;
+ }
+
+ ret = kdbgetularg(argv[1], (unsigned long *) &ulong_partid);
+ if (ret) {
+ return ret;
+ }
+ partid = (partid_t) ulong_partid;
+ if (partid <= 0 || partid >= XP_MAX_PARTITIONS) {
+ kdb_printf("invalid partid\n");
+ return KDB_BADINT;
+ }
+
+ ret = kdbgetularg(argv[2], (unsigned long *) &ch_number);
+ if (ret) {
+ return ret;
+ }
+ if (ch_number < 0 || ch_number >= XPC_NCHANNELS) {
+ kdb_printf("invalid channel #\n");
+ return KDB_BADINT;
+ }
+
+ part = &xpc_partitions[partid];
+
+ if (part->setup_state == XPC_P_UNSET) {
+ kdb_printf("partition is UNSET\n");
+ return 0;
+ }
+ if (part->setup_state == XPC_P_TORNDOWN) {
+ kdb_printf("partition is TORNDOWN\n");
+ return 0;
+ }
+
+ if (ch_number >= part->nchannels) {
+ kdb_printf("unsupported channel #\n");
+ return KDB_BADINT;
+ }
+
+ ch = &part->channels[ch_number];
+
+ if (!(ch->flags & XPC_C_SETUP)) {
+ kdb_printf("notify queue is not SETUP\n");
+ return 0;
+ }
+
+ kdbm_xpc_print_notify_queue(ch);
+
+ return 0;
+}
+
+
+static void
+kdbm_xpc_print_users(struct xpc_registration *registration, int ch_number)
+{
+ kdb_printf("xpc_registrations[channel=%d] (0x%p):\n", ch_number,
+ (void *) registration);
+
+ kdb_printf("\t&mutex=0x%p\n", (void *) ®istration->mutex);
+ kdb_printf("\tfunc=0x%p\n", (void *) registration->func);
+ kdb_printf("\tkey=0x%p\n", registration->key);
+ kdb_printf("\tnentries=%d\n", registration->nentries);
+ kdb_printf("\tmsg_size=%d\n", registration->msg_size);
+ kdb_printf("\tassigned_limit=%d\n", registration->assigned_limit);
+ kdb_printf("\tidle_limit=%d\n", registration->idle_limit);
+}
+
+
+/*
+ * Display current XPC users who have registered via xpc_connect().
+ *
+ * xpcusers [ <channel> ]
+ */
+static int
+kdbm_xpc_users(int argc, const char **argv, const char **envp,
+ struct pt_regs *regs)
+{
+ int ret;
+ struct xpc_registration *registration;
+ int ch_number;
+
+
+ if (argc > 1) {
+ return KDB_ARGCOUNT;
+
+ } else if (argc == 1) {
+ ret = kdbgetularg(argv[1], (unsigned long *) &ch_number);
+ if (ret) {
+ return ret;
+ }
+ if (ch_number < 0 || ch_number >= XPC_NCHANNELS) {
+ kdb_printf("invalid channel #\n");
+ return KDB_BADINT;
+ }
+ registration = &xpc_registrations[ch_number];
+ kdbm_xpc_print_users(registration, ch_number);
+
+ } else {
+ for (ch_number = 0; ch_number < XPC_NCHANNELS; ch_number++) {
+ registration = &xpc_registrations[ch_number];
+
+ /* if !XPC_CHANNEL_REGISTERED(ch_number) */
+ if (registration->func == NULL) {
+ continue;
+ }
+ kdbm_xpc_print_users(registration, ch_number);
+ }
+ }
+ return 0;
+}
+
+
+static int __init
+kdbm_xpc_register(void)
+{
+ (void) kdb_register("xpcdown", kdbm_xpc_down, "",
+ "Mark this partition as being down", 0);
+ (void) kdb_register("xpcrp", kdbm_xpc_rsvd_page, "",
+ "Display XPC reserved page", 0);
+ (void) kdb_register("xpcvars", kdbm_xpc_variables, "[<partid>]",
+ "Display XPC variables", 0);
+ (void) kdb_register("xpcengaged", kdbm_xpc_engaged, "[-v]",
+ "Display XPC engaged partitions AMOs", 0);
+ (void) kdb_register("xpcpart", kdbm_xpc_partitions, "[<vaddr>|"
+ "<partid>]", "Display struct xpc_partition entries", 0);
+ (void) kdb_register("xpcchan", kdbm_xpc_channels, "<vaddr> | <partid> "
+ "[<channel>]", "Display struct xpc_channel entries", 0);
+ (void) kdb_register("xpcmque", kdbm_xpc_msgqueue, "<partid> <channel> "
+ "local|remote", "Display local or remote msg queue", 0);
+ (void) kdb_register("xpcmsg", kdbm_xpc_msg, "<vaddr>",
+ "Display struct xpc_msg", 0);
+ (void) kdb_register("xpcnque", kdbm_xpc_notify_queue, "<partid> "
+ "<channel>", "Display notify queue", 0);
+ (void) kdb_register("xpcusers", kdbm_xpc_users, "[ <channel> ]",
+ "Display struct xpc_registration entries", 0);
+ return 0;
+}
+
+
+static void __exit
+kdbm_xpc_unregister(void)
+{
+ (void) kdb_unregister("xpcdown");
+ (void) kdb_unregister("xpcrp");
+ (void) kdb_unregister("xpcvars");
+ (void) kdb_unregister("xpcengaged");
+ (void) kdb_unregister("xpcpart");
+ (void) kdb_unregister("xpcchan");
+ (void) kdb_unregister("xpcmque");
+ (void) kdb_unregister("xpcmsg");
+ (void) kdb_unregister("xpcnque");
+ (void) kdb_unregister("xpcusers");
+}
+
+
+module_init(kdbm_xpc_register);
+module_exit(kdbm_xpc_unregister);
+
/*
* Now kill the IRQ
*/
- printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
+ printk("Disabling IRQ #%d\n", irq);
desc->status |= IRQ_DISABLED;
desc->depth = 1;
desc->chip->disable(irq);
EXPORT_SYMBOL(__print_symbol);
EXPORT_SYMBOL_GPL(sprint_symbol);
+
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+
+const char *kdb_walk_kallsyms(loff_t *pos)
+{
+ static struct kallsym_iter kdb_walk_kallsyms_iter;
+ if (*pos == 0) {
+ memset(&kdb_walk_kallsyms_iter, 0, sizeof(kdb_walk_kallsyms_iter));
+ reset_iter(&kdb_walk_kallsyms_iter, 0);
+ }
+ while (1) {
+ if (!update_iter(&kdb_walk_kallsyms_iter, *pos))
+ return NULL;
+ ++*pos;
+ /* Some debugging symbols have no name. Ignore them. */
+ if (kdb_walk_kallsyms_iter.name[0])
+ return kdb_walk_kallsyms_iter.name;
+ }
+}
+#endif /* CONFIG_KDB */
return NULL;
}
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
+#endif /* CONFIG_KDB */
+
struct module *module_get_kallsym(unsigned int symnum, unsigned long *value,
char *type, char *name, size_t namelen)
{
struct module *mod;
+#ifdef CONFIG_KDB
+ int get_lock = !KDB_IS_RUNNING();
+#else
+#define get_lock 1
+#endif
- mutex_lock(&module_mutex);
+ if (get_lock)
+ mutex_lock(&module_mutex);
list_for_each_entry(mod, &modules, list) {
if (symnum < mod->num_symtab) {
*value = mod->symtab[symnum].st_value;
*type = mod->symtab[symnum].st_info;
strlcpy(name, mod->strtab + mod->symtab[symnum].st_name,
namelen);
- mutex_unlock(&module_mutex);
+ if (get_lock)
+ mutex_unlock(&module_mutex);
return mod;
}
symnum -= mod->num_symtab;
}
- mutex_unlock(&module_mutex);
+ if (get_lock)
+ mutex_unlock(&module_mutex);
return NULL;
}
#include <linux/security.h>
#include <linux/bootmem.h>
#include <linux/syscalls.h>
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#endif
#include <asm/uaccess.h>
return do_syslog(type, buf, len);
}
+#ifdef CONFIG_KDB
+/* kdb dmesg command needs access to the syslog buffer. do_syslog() uses locks
+ * so it cannot be used during debugging. Just tell kdb where the start and
+ * end of the physical and logical logs are. This is equivalent to do_syslog(3).
+ */
+void kdb_syslog_data(char *syslog_data[4])
+{
+ syslog_data[0] = log_buf;
+ syslog_data[1] = log_buf + log_buf_len;
+ syslog_data[2] = log_buf + log_end - (logged_chars < log_buf_len ? logged_chars : log_buf_len);
+ syslog_data[3] = log_buf + log_end;
+}
+#endif /* CONFIG_KDB */
+
/*
* Call the console drivers on a range of log_buf
*/
int is_console_locked(void)
{
+#ifdef CONFIG_KDB
+ return console_locked || KDB_STATE(PRINTF_LOCK);
+#else
return console_locked;
+#endif
}
EXPORT_UNUSED_SYMBOL(is_console_locked); /* June 2006 */
#endif /* CONFIG_MAGIC_SYSRQ */
-#ifdef CONFIG_IA64
+#if defined(CONFIG_IA64) || defined(CONFIG_KDB)
/*
* These functions are only useful for the IA64 MCA handling.
*
}
#endif
+
+#ifdef CONFIG_KDB
+
+#include <linux/kdb.h>
+
+static void
+kdb_prio(char *name, struct prio_array *array, kdb_printf_t xxx_printf)
+{
+ int pri;
+
+ xxx_printf(" %s nr_active:%d bitmap: 0x%lx 0x%lx 0x%lx\n",
+ name, array->nr_active,
+ array->bitmap[0], array->bitmap[1], array->bitmap[2]);
+
+ pri = sched_find_first_bit(array->bitmap);
+ if (pri != MAX_PRIO) {
+ xxx_printf(" bitmap priorities:");
+ while (pri != MAX_PRIO) {
+ xxx_printf(" %d", pri);
+ pri++;
+ pri = find_next_bit(array->bitmap, MAX_PRIO, pri);
+ }
+ xxx_printf("\n");
+ }
+
+ for (pri = 0; pri < MAX_PRIO; pri++) {
+ int printed_hdr = 0;
+ struct list_head *head, *curr;
+
+ head = array->queue + pri;
+ curr = head->next;
+ while(curr != head) {
+ struct task_struct *task;
+ if (!printed_hdr) {
+ xxx_printf(" queue at priority=%d\n", pri);
+ printed_hdr = 1;
+ }
+ task = list_entry(curr, struct task_struct, run_list);
+ xxx_printf(" 0x%p %d %s time_slice:%d\n",
+ task, task->pid, task->comm,
+ task->time_slice);
+ curr = curr->next;
+ }
+ }
+}
+
+/* This code must be in sched.c because struct rq is only defined in this
+ * source. To allow most of kdb to be modular, this code cannot call any kdb
+ * functions directly, any external functions that it needs must be passed in
+ * as parameters.
+ */
+
+void
+kdb_runqueue(unsigned long cpu, kdb_printf_t xxx_printf)
+{
+ struct rq *rq;
+
+ rq = cpu_rq(cpu);
+
+ xxx_printf("CPU%ld lock:%s curr:0x%p(%d)(%s)",
+ cpu, (spin_is_locked(&rq->lock))?"LOCKED":"free",
+ rq->curr, rq->curr->pid, rq->curr->comm);
+ if (rq->curr == rq->idle)
+ xxx_printf(" is idle");
+ xxx_printf("\n ");
+#ifdef CONFIG_SMP
+ xxx_printf(" cpu_load:%lu %lu %lu",
+ rq->cpu_load[0], rq->cpu_load[1], rq->cpu_load[2]);
+#endif
+ xxx_printf(" nr_running:%lu nr_switches:%llu\n",
+ rq->nr_running, rq->nr_switches);
+ kdb_prio("active", rq->active, xxx_printf);
+ kdb_prio("expired", rq->expired, xxx_printf);
+}
+EXPORT_SYMBOL(kdb_runqueue);
+
+#endif /* CONFIG_KDB */
#include <linux/kthread.h>
#include <linux/rcupdate.h>
#include <linux/smp.h>
-
+#ifdef CONFIG_KDB
+#include <linux/kdb.h>
+#include <linux/kdbprivate.h>
+#else
+#define KDB_STATE(x) 0
+#endif
#include <asm/irq.h>
/*
- No shared variables, all the data are CPU local.
{
unsigned long flags;
- WARN_ON_ONCE(in_irq());
+ WARN_ON_ONCE(in_irq() && !KDB_STATE(KDB));
raw_local_irq_save(flags);
add_preempt_count(SOFTIRQ_OFFSET);
void __local_bh_enable(void)
{
- WARN_ON_ONCE(in_irq());
+ WARN_ON_ONCE(in_irq() && !KDB_STATE(KDB));
/*
* softirqs should never be enabled by __local_bh_enable(),
unsigned long arg0; /* An argument to the callback */
struct list_head list; /* On pdflush_list, when idle */
unsigned long when_i_went_to_sleep;
+ int resident; /* Started at init, never stopped */
};
static int __pdflush(struct pdflush_work *my_work)
current->flags |= PF_FLUSHER | PF_SWAPWRITE;
my_work->fn = NULL;
my_work->who = current;
+ my_work->resident = (nr_pdflush_threads < MIN_PDFLUSH_THREADS);
INIT_LIST_HEAD(&my_work->list);
spin_lock_irq(&pdflush_lock);
* Thread destruction: For how long has the sleepiest
* thread slept?
*/
- if (list_empty(&pdflush_list))
+ if (my_work->resident)
continue;
- if (nr_pdflush_threads <= MIN_PDFLUSH_THREADS)
+ if (list_empty(&pdflush_list))
continue;
pdf = list_entry(pdflush_list.prev, struct pdflush_work, list);
if (jiffies - pdf->when_i_went_to_sleep > 1 * HZ) {