- more 2.6.17 port work (still does not build)
[linux-flexiantxendom0-3.2.10.git] / arch / i386 / kdb / kdba_id.c
1 /*
2  * Kernel Debugger Architecture Dependent Instruction Disassembly
3  *
4  * This file is subject to the terms and conditions of the GNU General Public
5  * License.  See the file "COPYING" in the main directory of this archive
6  * for more details.
7  *
8  * Copyright (c) 1999-2004 Silicon Graphics, Inc.  All Rights Reserved.
9  */
10
11 #include <stdarg.h>
12 #include <linux/kernel.h>
13 #include <linux/init.h>
14 #include <linux/ctype.h>
15 #include <linux/string.h>
16 #include <linux/kdb.h>
17 #include <linux/kdbprivate.h>
18
19 /*
20  * kdba_dis_getsym
21  *
22  *      Get a symbol for the disassembler.
23  *
24  * Parameters:
25  *      addr    Address for which to get symbol
26  *      dip     Pointer to disassemble_info
27  * Returns:
28  *      0
29  * Locking:
30  * Remarks:
31  *      Not used for kdb.
32  */
33
34 /* ARGSUSED */
35 static int
36 kdba_dis_getsym(bfd_vma addr, disassemble_info *dip)
37 {
38
39         return 0;
40 }
41
42 /*
43  * kdba_printaddress
44  *
45  *      Print (symbolically) an address.
46  *
47  * Parameters:
48  *      addr    Address for which to get symbol
49  *      dip     Pointer to disassemble_info
50  *      flag    True if a ":<tab>" sequence should follow the address
51  * Returns:
52  *      0
53  * Locking:
54  * Remarks:
55  *
56  */
57
58 /* ARGSUSED */
59 static void
60 kdba_printaddress(kdb_machreg_t addr, disassemble_info *dip, int flag)
61 {
62         kdb_symtab_t symtab;
63         int spaces = 5;
64         unsigned int offset;
65
66         /*
67          * Print a symbol name or address as necessary.
68          */
69         kdbnearsym(addr, &symtab);
70         if (symtab.sym_name) {
71                 /* Do not use kdb_symbol_print here, it always does
72                  * kdb_printf but we want dip->fprintf_func.
73                  */
74                 dip->fprintf_func(dip->stream,
75                         "0x%0*lx %s",
76                         2*sizeof(addr), addr, symtab.sym_name);
77                 if ((offset = addr - symtab.sym_start) == 0) {
78                         spaces += 4;
79                 }
80                 else {
81                         unsigned int o = offset;
82                         while (o >>= 4)
83                                 --spaces;
84                         dip->fprintf_func(dip->stream, "+0x%x", offset);
85                 }
86
87         } else {
88                 dip->fprintf_func(dip->stream, "0x%x", addr);
89         }
90
91         if (flag) {
92                 if (spaces < 1) {
93                         spaces = 1;
94                 }
95                 dip->fprintf_func(dip->stream, ":%*s", spaces, " ");
96         }
97 }
98
99 /*
100  * kdba_dis_printaddr
101  *
102  *      Print (symbolically) an address.  Called by GNU disassembly
103  *      code via disassemble_info structure.
104  *
105  * Parameters:
106  *      addr    Address for which to get symbol
107  *      dip     Pointer to disassemble_info
108  * Returns:
109  *      0
110  * Locking:
111  * Remarks:
112  *      This function will never append ":<tab>" to the printed
113  *      symbolic address.
114  */
115
116 static void
117 kdba_dis_printaddr(bfd_vma addr, disassemble_info *dip)
118 {
119         kdba_printaddress(addr, dip, 0);
120 }
121
122 /*
123  * kdba_dis_getmem
124  *
125  *      Fetch 'length' bytes from 'addr' into 'buf'.
126  *
127  * Parameters:
128  *      addr    Address for which to get symbol
129  *      buf     Address of buffer to fill with bytes from 'addr'
130  *      length  Number of bytes to fetch
131  *      dip     Pointer to disassemble_info
132  * Returns:
133  *      0 if data is available, otherwise error.
134  * Locking:
135  * Remarks:
136  *
137  */
138
139 /* ARGSUSED */
140 static int
141 kdba_dis_getmem(bfd_vma addr, bfd_byte *buf, unsigned int length, disassemble_info *dip)
142 {
143         return kdb_getarea_size(buf, addr, length);
144 }
145
146 /*
147  * kdba_id_parsemode
148  *
149  *      Parse IDMODE environment variable string and
150  *      set appropriate value into "disassemble_info" structure.
151  *
152  * Parameters:
153  *      mode    Mode string
154  *      dip     Disassemble_info structure pointer
155  * Returns:
156  * Locking:
157  * Remarks:
158  *      We handle the values 'x86' and '8086' to enable either
159  *      32-bit instruction set or 16-bit legacy instruction set.
160  */
161
162 int
163 kdba_id_parsemode(const char *mode, disassemble_info *dip)
164 {
165
166         if (mode) {
167                 if (strcmp(mode, "x86") == 0) {
168                         dip->mach = bfd_mach_i386_i386;
169                 } else if (strcmp(mode, "8086") == 0) {
170                         dip->mach = bfd_mach_i386_i8086;
171                 } else {
172                         return KDB_BADMODE;
173                 }
174         }
175
176         return 0;
177 }
178
179 /*
180  * kdba_check_pc
181  *
182  *      Check that the pc is satisfactory.
183  *
184  * Parameters:
185  *      pc      Program Counter Value.
186  * Returns:
187  *      None
188  * Locking:
189  *      None.
190  * Remarks:
191  *      Can change pc.
192  */
193
194 void
195 kdba_check_pc(kdb_machreg_t *pc)
196 {
197         /* No action */
198 }
199
200 /*
201  * kdba_id_printinsn
202  *
203  *      Format and print a single instruction at 'pc'. Return the
204  *      length of the instruction.
205  *
206  * Parameters:
207  *      pc      Program Counter Value.
208  *      dip     Disassemble_info structure pointer
209  * Returns:
210  *      Length of instruction, -1 for error.
211  * Locking:
212  *      None.
213  * Remarks:
214  *      Depends on 'IDMODE' environment variable.
215  */
216
217 int
218 kdba_id_printinsn(kdb_machreg_t pc, disassemble_info *dip)
219 {
220         kdba_printaddress(pc, dip, 1);
221         return print_insn_i386_att(pc, dip);
222 }
223
224 /*
225  * kdba_id_init
226  *
227  *      Initialize the architecture dependent elements of
228  *      the disassembly information structure
229  *      for the GNU disassembler.
230  *
231  * Parameters:
232  *      None.
233  * Outputs:
234  *      None.
235  * Returns:
236  *      None.
237  * Locking:
238  *      None.
239  * Remarks:
240  */
241
242 void __init
243 kdba_id_init(disassemble_info *dip)
244 {
245         dip->read_memory_func       = kdba_dis_getmem;
246         dip->print_address_func     = kdba_dis_printaddr;
247         dip->symbol_at_address_func = kdba_dis_getsym;
248
249         dip->flavour                = bfd_target_elf_flavour;
250         dip->arch                   = bfd_arch_i386;
251         dip->mach                   = bfd_mach_i386_i386;
252         dip->endian                 = BFD_ENDIAN_LITTLE;
253
254         dip->display_endian         = BFD_ENDIAN_LITTLE;
255 }