]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: SGI KDB Development <kdb@oss.sgi.com> |
2 | Subject: kdb-v4.4-2.6.27-rc8-x86-1 | |
3 | References: FATE#303971 | |
4 | X-URL: ftp://oss.sgi.com/www/projects/kdb/download/v4.4/ | |
5 | ||
6 | The KDB x86 code. | |
7 | ||
8 | Acked-by: Bernhard Walle <bwalle@suse.de> | |
9 | ||
10 | --- | |
11 | arch/x86/Kconfig.debug | 88 | |
12 | arch/x86/Makefile | 3 | |
13 | arch/x86/kdb/ChangeLog | 230 + | |
14 | arch/x86/kdb/ChangeLog_32 | 865 ++++++ | |
15 | arch/x86/kdb/ChangeLog_64 | 447 +++ | |
16 | arch/x86/kdb/Makefile | 5 | |
17 | arch/x86/kdb/Makefile_32 | 25 | |
18 | arch/x86/kdb/Makefile_64 | 25 | |
19 | arch/x86/kdb/i386-dis.c | 4686 +++++++++++++++++++++++++++++++++++ | |
20 | arch/x86/kdb/kdb_cmds_32 | 17 | |
21 | arch/x86/kdb/kdb_cmds_64 | 18 | |
22 | arch/x86/kdb/kdba_bp_32.c | 914 ++++++ | |
23 | arch/x86/kdb/kdba_bp_64.c | 912 ++++++ | |
24 | arch/x86/kdb/kdba_bt.c | 5597 ++++++++++++++++++++++++++++++++++++++++++ | |
25 | arch/x86/kdb/kdba_id.c | 261 + | |
26 | arch/x86/kdb/kdba_io.c | 609 ++++ | |
27 | arch/x86/kdb/kdba_support.c | 59 | |
28 | arch/x86/kdb/kdbasupport_32.c | 1072 ++++++++ | |
29 | arch/x86/kdb/kdbasupport_64.c | 1022 +++++++ | |
30 | arch/x86/kdb/pc_keyb.h | 137 + | |
31 | arch/x86/kdb/x86_64-dis.c | 4686 +++++++++++++++++++++++++++++++++++ | |
32 | arch/x86/kernel/crash.c | 110 | |
33 | arch/x86/kernel/entry_32.S | 20 | |
34 | arch/x86/kernel/entry_64.S | 27 | |
35 | arch/x86/kernel/io_apic_32.c | 8 | |
36 | arch/x86/kernel/io_apic_64.c | 8 | |
37 | arch/x86/kernel/reboot.c | 11 | |
38 | arch/x86/kernel/traps_32.c | 48 | |
39 | arch/x86/kernel/traps_64.c | 2 | |
40 | include/asm-x86/ansidecl.h | 5 | |
41 | include/asm-x86/ansidecl_32.h | 383 ++ | |
42 | include/asm-x86/ansidecl_64.h | 383 ++ | |
43 | include/asm-x86/bfd.h | 5 | |
44 | include/asm-x86/bfd_32.h | 4921 ++++++++++++++++++++++++++++++++++++ | |
45 | include/asm-x86/bfd_64.h | 4917 ++++++++++++++++++++++++++++++++++++ | |
46 | include/asm-x86/irq_vectors.h | 6 | |
47 | include/asm-x86/kdb.h | 134 + | |
48 | include/asm-x86/kdbprivate.h | 241 + | |
49 | include/asm-x86/kdebug.h | 2 | |
50 | include/asm-x86/kmap_types.h | 3 | |
51 | include/asm-x86/ptrace.h | 23 | |
52 | 41 files changed, 32930 insertions(+), 5 deletions(-) | |
53 | ||
54 | --- a/arch/x86/Kconfig.debug | |
55 | +++ b/arch/x86/Kconfig.debug | |
56 | @@ -302,5 +302,91 @@ config OPTIMIZE_INLINING | |
57 | ||
58 | If unsure, say N. | |
59 | ||
60 | -endmenu | |
61 | +config KDB | |
62 | + bool "Built-in Kernel Debugger support" | |
63 | + depends on DEBUG_KERNEL | |
64 | + select KALLSYMS | |
65 | + select KALLSYMS_ALL | |
66 | + help | |
67 | + This option provides a built-in kernel debugger. The built-in | |
68 | + kernel debugger contains commands which allow memory to be examined, | |
69 | + instructions to be disassembled and breakpoints to be set. For details, | |
70 | + see Documentation/kdb/kdb.mm and the manual pages kdb_bt, kdb_ss, etc. | |
71 | + Kdb can also be used via the serial port. Set up the system to | |
72 | + have a serial console (see Documentation/serial-console.txt). | |
73 | + The key sequence <escape>KDB on the serial port will cause the | |
74 | + kernel debugger to be entered with input from the serial port and | |
75 | + output to the serial console. If unsure, say N. | |
76 | + | |
77 | +config KDB_MODULES | |
78 | + tristate "KDB modules" | |
79 | + depends on KDB | |
80 | + help | |
81 | + KDB can be extended by adding your own modules, in directory | |
82 | + kdb/modules. This option selects the way that these modules should | |
83 | + be compiled, as free standing modules (select M) or built into the | |
84 | + kernel (select Y). If unsure say M. | |
85 | + | |
86 | +config KDB_OFF | |
87 | + bool "KDB off by default" | |
88 | + depends on KDB | |
89 | + help | |
90 | + Normally kdb is activated by default, as long as CONFIG_KDB is set. | |
91 | + If you want to ship a kernel with kdb support but only have kdb | |
92 | + turned on when the user requests it then select this option. When | |
93 | + compiled with CONFIG_KDB_OFF, kdb ignores all events unless you boot | |
94 | + with kdb=on or you echo "1" > /proc/sys/kernel/kdb. This option also | |
95 | + works in reverse, if kdb is normally activated, you can boot with | |
96 | + kdb=off or echo "0" > /proc/sys/kernel/kdb to deactivate kdb. If | |
97 | + unsure, say N. | |
98 | + | |
99 | +config KDB_CONTINUE_CATASTROPHIC | |
100 | + int "KDB continues after catastrophic errors" | |
101 | + depends on KDB | |
102 | + default "0" | |
103 | + help | |
104 | + This integer controls the behaviour of kdb when the kernel gets a | |
105 | + catastrophic error, i.e. for a panic, oops, NMI or other watchdog | |
106 | + tripping. CONFIG_KDB_CONTINUE_CATASTROPHIC interacts with | |
107 | + /proc/sys/kernel/kdb and CONFIG_LKCD_DUMP (if your kernel has the | |
108 | + LKCD patch). | |
109 | + When KDB is active (/proc/sys/kernel/kdb == 1) and a catastrophic | |
110 | + error occurs, nothing extra happens until you type 'go'. | |
111 | + CONFIG_KDB_CONTINUE_CATASTROPHIC == 0 (default). The first time | |
112 | + you type 'go', kdb warns you. The second time you type 'go', KDB | |
113 | + tries to continue - no guarantees that the kernel is still usable. | |
114 | + CONFIG_KDB_CONTINUE_CATASTROPHIC == 1. KDB tries to continue - no | |
115 | + guarantees that the kernel is still usable. | |
116 | + CONFIG_KDB_CONTINUE_CATASTROPHIC == 2. If your kernel has the LKCD | |
117 | + patch and LKCD is configured to take a dump then KDB forces a dump. | |
118 | + Whether or not a dump is taken, KDB forces a reboot. | |
119 | + When KDB is not active (/proc/sys/kernel/kdb == 0) and a catastrophic | |
120 | + error occurs, the following steps are automatic, no human | |
121 | + intervention is required. | |
122 | + CONFIG_KDB_CONTINUE_CATASTROPHIC == 0 (default) or 1. KDB attempts | |
123 | + to continue - no guarantees that the kernel is still usable. | |
124 | + CONFIG_KDB_CONTINUE_CATASTROPHIC == 2. If your kernel has the LKCD | |
125 | + patch and LKCD is configured to take a dump then KDB automatically | |
126 | + forces a dump. Whether or not a dump is taken, KDB forces a | |
127 | + reboot. | |
128 | + If you are not sure, say 0. Read Documentation/kdb/dump.txt before | |
129 | + setting to 2. | |
130 | ||
131 | +config KDB_USB | |
132 | + bool "Support for USB Keyboard in KDB (OHCI and/or EHCI only)" | |
133 | + depends on KDB && (USB_OHCI_HCD || USB_EHCI_HCD) | |
134 | + help | |
135 | + If you want to use kdb from USB keyboards then say Y here. If you | |
136 | + say N then kdb can only be used from a PC (AT) keyboard or a serial | |
137 | + console. | |
138 | + | |
139 | +config KDB_KDUMP | |
140 | + bool "Support for Kdump in KDB" | |
141 | + depends on KDB | |
142 | + select KEXEC | |
143 | + default N | |
144 | + help | |
145 | + If you want to take Kdump kernel vmcore from KDB then say Y here. | |
146 | + Of imsire. say N. | |
147 | + | |
148 | +endmenu | |
149 | --- /dev/null | |
150 | +++ b/arch/x86/kdb/ChangeLog | |
151 | @@ -0,0 +1,230 @@ | |
152 | +2008-09-30 Jay Lan <jlan@sgi.com> | |
153 | + | |
154 | + * kdb-v4.4-2.6.27-rc8-x86-1. | |
155 | + | |
156 | +2008-09-22 Jay Lan <jlan@sgi.com> | |
157 | + | |
158 | + * kdb-v4.4-2.6.27-rc7-x86-1. | |
159 | + | |
160 | +2008-09-03 Jay Lan <jlan@sgi.com> | |
161 | + | |
162 | + * kdb-v4.4-2.6.27-rc5-x86-1. | |
163 | + | |
164 | +2008-08-19 Jay Lan <jlan@sgi.com> | |
165 | + | |
166 | + * kdb-v4.4-2.6.27-rc3-x86-1. | |
167 | + | |
168 | +2008-08-14 Jay Lan <jlan@sgi.com> | |
169 | + | |
170 | + * Support 'kdump' command to take a kdump vmcore from KDB, | |
171 | + Dan Aloni (da-x@monatomic.org), | |
172 | + Jason Xiao (jidong.xiao@gmail.com), | |
173 | + Jay Lan (jlan@sgi.com) | |
174 | + * kdb-v4.4-2.6.27-rc2-x86-2. | |
175 | + | |
176 | +2008-08-06 Jay Lan <jlan@sgi.com> | |
177 | + | |
178 | + * Fix up the NULL pointer deference issue in ohci_kdb_poll_char, | |
179 | + Jason Xiao <jidong.xiao@gmail.com> | |
180 | + * Backtrace on x86_64 and i386 were incomplete since 2.6.27-rc2. | |
181 | + * kdb-v4.4-2.6.27-rc2-x86-1. | |
182 | + | |
183 | +2008-07-18 Jay Lan <jlan@sgi.com> | |
184 | + | |
185 | + * support Hardware Breakpoint (bph/bpha) commands | |
186 | + IA64: Greg Banks <gnb@sgi.com> | |
187 | + X86: Konstantin Baydarov <kbaidarov@ru.mvista.com> | |
188 | + * kdb-v4.4-2.6.26-x86-2. | |
189 | + | |
190 | +2008-07-14 Jay Lan <jlan@sgi.com> | |
191 | + | |
192 | + * kdb-v4.4-2.6.26-x86-1. | |
193 | + | |
194 | +2008-07-11 Jay Lan <jlan@sgi.com> | |
195 | + | |
196 | + * New commands and some fixups and enhancements, | |
197 | + Joe Korty <joe.korty@ccur.com> | |
198 | + John Blackwood <john.blackwood@ccur.com> | |
199 | + Jim Houston <jim.houston@ccur.com> | |
200 | + - Use the non-sleeping copy_from_user_atomic. | |
201 | + - Enhance kdb_cmderror diagnostic output. | |
202 | + - Expand the KDB 'duplicate command' error message. | |
203 | + - Touch NMI watchdog in various KDB busy-loops. | |
204 | + - Support IMB HS20 Blade 8843 platform. | |
205 | + - Display exactly which cpus needed an NMI to get them into kdb. | |
206 | + - Better document that kdb's 'ps A' command can be used to show | |
207 | + _all_ processes and threads | |
208 | + - Suppress KDB boottime INFO messages if quiet boot. | |
209 | + - Add a KDB breakpoint to the OOPs path. | |
210 | + - Add CONFIG_DISCONTIGMEM support to kdbm_memmap. | |
211 | + - Extend the KDB task command to handle CONFIG_NUMA fields. | |
212 | + - Extend the KDB vm command to support NUMA stuff. | |
213 | + - Create the KDB mempolicy command. | |
214 | + - Create a pgdat command for KDB. | |
215 | + - Fix a hang on boot on some i386 systems. | |
216 | + * kdb-v4.4-2.6.26-rc9-x86-1. | |
217 | + | |
218 | +2008-06-30 Jay Lan <jlan@sgi.com> | |
219 | + | |
220 | + * kdb-v4.4-2.6.26-rc8-x86-1. | |
221 | + | |
222 | +2008-06-25 Jay Lan <jlan@sgi.com> | |
223 | + | |
224 | + * kdb-v4.4-2.6.26-rc7-x86-1. | |
225 | + | |
226 | +2008-06-06 Jay Lan <jlan@sgi.com> | |
227 | + | |
228 | + * kdb-v4.4-2.6.26-rc5-x86-1. | |
229 | + | |
230 | +2008-05-30 Jay Lan <jlan@sgi.com> | |
231 | + | |
232 | + * kdb-v4.4-2.6.26-rc4-x86-1. | |
233 | + | |
234 | +2008-05-20 Jay Lan <jlan@sgi.com> | |
235 | + | |
236 | + * Merged <asm-x86/kdb_32.h> and <asm-x86/kdb_64.h> to <asm-x86/kdb.h>. | |
237 | + * Merged <asm-x86/kdbprivate_32.h> and <asm-x86/kdbprivate_64.h> to | |
238 | + <asm-x86/kdbprivate.h>. | |
239 | + * kdb-v4.4-2.6.26-rc3-x86-1. | |
240 | + | |
241 | +2008-05-15 Jay Lan <jlan@sgi.com> | |
242 | + | |
243 | + * Fixed the i386 backtrace problem where KDB failed to find stacks | |
244 | + in the kernel space. | |
245 | + * kdb-v4.4-2.6.26-rc1-x86-3. | |
246 | + | |
247 | +2008-05-14 Jay Lan <jlan@sgi.com> | |
248 | + | |
249 | + * Fixed a bug that bb_all scans only odd number entries of kallsyms. | |
250 | + * kdb-v4.4-2.6.26-rc1-x86-2. | |
251 | + | |
252 | +2008-05-13 Jay Lan <jlan@sgi.com> | |
253 | + | |
254 | + * Known problem: backtrace for i386 is broken since 2.6.25-rc1. | |
255 | + * kdb-v4.4-2.6.26-rc1-x86-1. | |
256 | + | |
257 | +2008-05-13 Jay Lan <jlan@sgi.com> | |
258 | + | |
259 | + * Known problem: backtrace for i386 is broken since 2.6.25-rc1. | |
260 | + * Fixed a couple of x86_64 problems: | |
261 | + - "iret_label" are replaced by "irq_return". | |
262 | + - bb1 failure on ia32_sysenter_target() & ia32_cstar_target() | |
263 | + * kdb-v4.4-2.6.25-x86-2. | |
264 | + | |
265 | +2008-04-17 Jay Lan <jlan@sgi.com> | |
266 | + | |
267 | + * Known problem: backtrace for i386 is broken since 2.6.25-rc1. | |
268 | + * kdb-v4.4-2.6.25-x86-1. | |
269 | + | |
270 | +2008-03-19 Jay Lan <jlan@sgi.com> | |
271 | + | |
272 | + * i386: systenter_entry was replaced with ia32_sysenter_target since | |
273 | + 2.6.25-rc1, Jay Lan <jlan@sgi.com> | |
274 | + * Known problem: backtrace for i386 is broken since 2.6.25-rc1. | |
275 | + * kdb-v4.4-2.6.25-rc6-x86-2. | |
276 | + | |
277 | +2008-03-16 Jay Lan <jlan@sgi.com> | |
278 | + | |
279 | + * Known problem: backtrace for i386 is broken since 2.6.25-rc1. | |
280 | + * kdb-v4.4-2.6.25-rc6-x86-1. | |
281 | + | |
282 | +2008-03-03 Jay Lan <jlan@sgi.com> | |
283 | + | |
284 | + * Known problem: backtrace for i386 is broken since 2.6.25-rc1. | |
285 | + * kdb-v4.4-2.6.25-rc3-x86-1. | |
286 | + | |
287 | +2008-02-26 Jay Lan <jlan@sgi.com> | |
288 | + | |
289 | + * remove 'fastcall' from kdb code. | |
290 | + * Known problem: backtrace for i386 is broken since 2.6.25-rc1. | |
291 | + * kdb-v4.4-2.6.25-rc2-x86-1. | |
292 | + | |
293 | +2008-02-19 Jay Lan <jlan@sgi.com> | |
294 | + | |
295 | + * Known problem: backtrace for i386 is broken. | |
296 | + * kdb-v4.4-2.6.25-rc1-x86-1. | |
297 | + | |
298 | +2008-02-01 Jay Lan <jlan@sgi.com> | |
299 | + | |
300 | + * Backed out USB UHCI support since it caused dropped characters and | |
301 | + broke OHCI. | |
302 | + * Restored "archkdbcommon" commands for x86. It was lost at the x86 | |
303 | + merge. | |
304 | + * Detecting if the HC was "busy", Aaron Young <ayoung@sgi.com> | |
305 | + * kdb-v4.4-2.6.24-x86-2. | |
306 | + | |
307 | +2008-01-29 Jay Lan <jlan@sgi.com> | |
308 | + | |
309 | + * kdb-v4.4-2.6.24-x86-1. | |
310 | + | |
311 | +2008-01-22 Jay Lan <jlan@sgi.com> | |
312 | + | |
313 | + * USB UHCI kdb support, Konstantin Baydarov <kbaidarov@ru.mvista.com> | |
314 | + * kdb-v4.4-2.6.24-rc8-x86-3. | |
315 | + | |
316 | +2008-01-18 Jay Lan <jlan@sgi.com> | |
317 | + | |
318 | + * USB EHCI kdb support, Aaron Young <ayoung@sgi.com> | |
319 | + * kdb-v4.4-2.6.24-rc8-x86-2. | |
320 | + | |
321 | +2008-01-18 Jay Lan <jlan@sgi.com> | |
322 | + | |
323 | + * kdb-v4.4-2.6.24-rc8-x86-1. | |
324 | + | |
325 | +2008-01-09 Jay Lan <jlan@sgi.com> | |
326 | + | |
327 | + * Merge arch/x86/kdb/kdba_io_64.c and arch/x86/kdb/kdba_io_32.c to | |
328 | + arch/x86/kdb/kdba_io.c | |
329 | + * Merge arch/x86/kdb/kdba_id_64.c and arch/x86/kdb/kdba_id_32.c to | |
330 | + arch/x86/kdb/kdba_id.c | |
331 | + * Merge arch/x86/kdb/pc_keyb_64.h and arch/x86/kdb/pc_keyb_32.h to | |
332 | + arch/x86/kdb/pc_keyb.h | |
333 | + * kdb-v4.4-2.6.24-rc7-x86-2. | |
334 | + | |
335 | +2008-01-07 Jay Lan <jlan@sgi.com> | |
336 | + | |
337 | + * kdb-v4.4-2.6.24-rc7-x86-1. | |
338 | + | |
339 | +2007-12-21 Jay Lan <jlan@sgi.com> | |
340 | + | |
341 | + * Renamed kdb/kdba_bt_x86.c to arch/x86/kdba_bt.c. | |
342 | + * Find gcc options 'no-optimize-sibling-calls' & 'regparm' from | |
343 | + $(KBUILD_CFLAGS) in arch/x86/kdb/Makefile_{32,64}. We used to | |
344 | + get them from $(CFLAGS). | |
345 | + * Default regparm to 3 on x86_32 if not defined. | |
346 | + * kdb v4.4-2.6.24-rc6-x86-1. | |
347 | + | |
348 | +2007-12-12 Jay Lan <jlan@sgi.com> | |
349 | + | |
350 | + * Fixed a Makefile_32 error. | |
351 | + * kdb v4.4-2.6.24-rc5-x86-1. | |
352 | + | |
353 | +2007-12-05 Jay Lan <jlan@sgi.com> | |
354 | + | |
355 | + * Fixed a 'sysctl table check failed' problem. | |
356 | + * kdb v4.4-2.6.24-rc4-x86-1. | |
357 | + | |
358 | +2007-11-26 Jay Lan <jlan@sgi.com> | |
359 | + | |
360 | + * kdb v4.4-2.6.24-rc3-x86-1. | |
361 | + | |
362 | +2007-11-13 Jay Lan <jlan@sgi.com> | |
363 | + | |
364 | + * Back ported "New KDB USB interface" from Aaron Young in | |
365 | + v4.4-2.6.23-{i386,x86_64}-2 to 2.6.24 kdb patchset. | |
366 | + * Fixed a make problem at arch/x86/Makefile_{32,64}. | |
367 | + * kdb v4.4-2.6.24-rc2-x86-2. | |
368 | + | |
369 | +2007-11-12 Jay Lan <jlan@sgi.com> | |
370 | + | |
371 | + * kdb v4.4-2.6.24-rc2-x86-1. | |
372 | + | |
373 | +2007-11-09 Jay Lan <jlan@sgi.com> | |
374 | + | |
375 | + * Rebase to 2.6.24-rc1 kernel | |
376 | + * - merged kdb-v4.4-2.6.23-i386-1 and kdb-v4.4-2.6.23-x86_64-1 | |
377 | + * into kdb-v4.4-2.6.24-rc1-x86-1 | |
378 | + * - Fields "done", "sglist_len", and "pid" are removed from | |
379 | + * struct scsi_cmnd. Thus, these fields are no longer displayed | |
380 | + * on "sc" command. | |
381 | + * kdb v4.4-2.6.24-rc1-x86-1. | |
382 | --- /dev/null | |
383 | +++ b/arch/x86/kdb/ChangeLog_32 | |
384 | @@ -0,0 +1,865 @@ | |
385 | +2007-11-08 Jay Lan <jlan@sgi.com> | |
386 | + | |
387 | + * New KDB USB interface, Aaron Young <ayoung@sgi.com> | |
388 | + * 1. This patch allows KDB to work with any Host Contoller driver | |
389 | + * and call the correct HC driver poll routine (as long as the | |
390 | + * HC driver provides a .kdb_poll_char routine via it's | |
391 | + * associated hc_driver struct). | |
392 | + * 2. Hotplugged keyboards are now recognized by KDB. | |
393 | + * 3. Currently KDB can only make use of 1 USB type keyboard. | |
394 | + * New code can handle up to 8 attached keyboards - input is | |
395 | + * multiplexed from all of them while in kdb. | |
396 | + * kdb v4.4-2.6.23-common-2. | |
397 | + | |
398 | +2007-10-24 Jay Lan <jlan@sgi.com> | |
399 | + | |
400 | + * kdb v4.4-2.6.23-i386-1. | |
401 | + | |
402 | +2007-09-26 Jay Lan <jlan@sgi.com> | |
403 | + | |
404 | + * kdb v4.4-2.6.23-rc8-i386-1. | |
405 | + | |
406 | +2007-09-21 Jay Lan <jlan@sgi.com> | |
407 | + | |
408 | + * kdb v4.4-2.6.23-rc7-i386-1. | |
409 | + | |
410 | +2007-09-12 Jay Lan <jlan@sgi.com> | |
411 | + | |
412 | + * kdb v4.4-2.6.23-rc6-i386-1. | |
413 | + | |
414 | +2007-09-06 Jay Lan <jlan@sgi.com> | |
415 | + | |
416 | + * kdb v4.4-2.6.23-rc5-i386-1. | |
417 | + | |
418 | +2007-08-30 Keith Owens <kaos@sgi.com> | |
419 | + | |
420 | + * New i386/x86_64 backtrace requires that kdb_save_running() does not | |
421 | + exit until after kdb_main_loop() has completed. | |
422 | + * kdb v4.4-2.6.23-rc4-i386-2. | |
423 | + | |
424 | +2007-08-30 Jay Lan <jlan@sgi.com> | |
425 | + | |
426 | + * kdb v4.4-2.6.23-rc4-i386-1. | |
427 | + | |
428 | +2007-08-24 Keith Owens <kaos@sgi.com> | |
429 | + | |
430 | + * kdb v4.4-2.6.23-rc3-i386-1. | |
431 | + | |
432 | +2007-08-07 Jay Lan <jlan@sgi.com> | |
433 | + | |
434 | + * kdb v4.4-2.6.23-rc2-i386-1. | |
435 | + | |
436 | +2007-07-31 Keith Owens <kaos@sgi.com> | |
437 | + | |
438 | + * Delete obsolete kdba_bt.c. | |
439 | + * kdb v4.4-2.6.23-rc1-i386-2. | |
440 | + | |
441 | +2007-07-30 Keith Owens <kaos@sgi.com> | |
442 | + | |
443 | + * kdb v4.4-2.6.23-rc1-i386-1. | |
444 | + | |
445 | +2007-07-26 Keith Owens <kaos@sgi.com> | |
446 | + | |
447 | + * New x86 backtrace code. | |
448 | + * kdb v4.4-2.6.22-i386-2. | |
449 | + | |
450 | +2007-07-09 Keith Owens <kaos@sgi.com> | |
451 | + | |
452 | + * kdb v4.4-2.6.22-i386-1. | |
453 | + | |
454 | +2007-07-02 Keith Owens <kaos@sgi.com> | |
455 | + | |
456 | + * kdb v4.4-2.6.22-rc7-i386-1. | |
457 | + | |
458 | +2007-06-20 Keith Owens <kaos@sgi.com> | |
459 | + | |
460 | + * kdb v4.4-2.6.22-rc5-i386-1. | |
461 | + | |
462 | +2007-06-08 Keith Owens <kaos@sgi.com> | |
463 | + | |
464 | + * kdb v4.4-2.6.22-rc4-i386-1. | |
465 | + | |
466 | +2007-05-28 Keith Owens <kaos@sgi.com> | |
467 | + | |
468 | + * kdb v4.4-2.6.22-rc3-i386-1. | |
469 | + | |
470 | +2007-05-22 Keith Owens <kaos@sgi.com> | |
471 | + | |
472 | + * Register KDBENTER_VECTOR early on the boot cpu. | |
473 | + * kdb v4.4-2.6.22-rc2-i386-2. | |
474 | + | |
475 | +2007-05-22 Keith Owens <kaos@sgi.com> | |
476 | + | |
477 | + * kdb v4.4-2.6.22-rc2-i386-1. | |
478 | + | |
479 | +2007-05-22 Keith Owens <kaos@sgi.com> | |
480 | + | |
481 | + * kdb v4.4-2.6.22-rc1-i386-1. | |
482 | + | |
483 | +2007-05-17 Keith Owens <kaos@sgi.com> | |
484 | + | |
485 | + * Update dumpregs comments for rdmsr and wrmsr commands. | |
486 | + Bernardo Innocenti. | |
487 | + * kdb v4.4-2.6.21-i386-3. | |
488 | + | |
489 | +2007-05-15 Keith Owens <kaos@sgi.com> | |
490 | + | |
491 | + * Change kdba_late_init to kdba_arch_init so KDB_ENTER() can be used | |
492 | + earlier. | |
493 | + * kdb v4.4-2.6.21-i386-2. | |
494 | + | |
495 | +2007-04-29 Keith Owens <kaos@sgi.com> | |
496 | + | |
497 | + * kdb v4.4-2.6.21-i386-1. | |
498 | + | |
499 | +2007-04-16 Keith Owens <kaos@sgi.com> | |
500 | + | |
501 | + * kdb v4.4-2.6.21-rc7-i386-1. | |
502 | + | |
503 | +2007-04-10 Keith Owens <kaos@sgi.com> | |
504 | + | |
505 | + * kdb v4.4-2.6.21-rc6-i386-1. | |
506 | + | |
507 | +2007-04-02 Keith Owens <kaos@sgi.com> | |
508 | + | |
509 | + * kdb v4.4-2.6.21-rc5-i386-1. | |
510 | + | |
511 | +2007-03-19 Keith Owens <kaos@sgi.com> | |
512 | + | |
513 | + * kdb v4.4-2.6.21-rc4-i386-1. | |
514 | + | |
515 | +2007-03-14 Keith Owens <kaos@sgi.com> | |
516 | + | |
517 | + * kdb v4.4-2.6.21-rc3-i386-1. | |
518 | + | |
519 | +2007-03-14 Keith Owens <kaos@sgi.com> | |
520 | + | |
521 | + * kdb v4.4-2.6.21-rc2-i386-1. | |
522 | + | |
523 | +2007-03-01 Keith Owens <kaos@sgi.com> | |
524 | + | |
525 | + * kdb v4.4-2.6.21-rc1-i386-1. | |
526 | + | |
527 | +2007-03-01 Keith Owens <kaos@sgi.com> | |
528 | + | |
529 | + * Remove sparse warnings. | |
530 | + * kdb v4.4-2.6.20-i386-3. | |
531 | + | |
532 | +2007-02-16 Keith Owens <kaos@sgi.com> | |
533 | + | |
534 | + * Initialise variable bits of struct disassemble_info each time. | |
535 | + * kdb v4.4-2.6.20-i386-2. | |
536 | + | |
537 | +2007-02-06 Keith Owens <kaos@sgi.com> | |
538 | + | |
539 | + * kdb v4.4-2.6.20-i386-1. | |
540 | + | |
541 | +2007-02-01 Keith Owens <kaos@sgi.com> | |
542 | + | |
543 | + * kdb v4.4-2.6.20-rc7-i386-1. | |
544 | + | |
545 | +2007-01-08 Keith Owens <kaos@sgi.com> | |
546 | + | |
547 | + * kdb v4.4-2.6.20-rc4-i386-1. | |
548 | + | |
549 | +2007-01-02 Keith Owens <kaos@sgi.com> | |
550 | + | |
551 | + * kdb v4.4-2.6.20-rc3-i386-1. | |
552 | + | |
553 | +2006-12-20 Keith Owens <kaos@sgi.com> | |
554 | + | |
555 | + * kdb v4.4-2.6.20-rc1-i386-1. | |
556 | + | |
557 | +2006-11-30 Keith Owens <kaos@sgi.com> | |
558 | + | |
559 | + * kdb v4.4-2.6.19-i386-1. | |
560 | + | |
561 | +2006-11-27 Keith Owens <kaos@sgi.com> | |
562 | + | |
563 | + * Only use VT keyboard if the command line allows it and ACPI indicates | |
564 | + that there is an i8042. | |
565 | + * kdb v4.4-2.6.19-rc6-i386-2. | |
566 | + | |
567 | +2006-11-20 Keith Owens <kaos@sgi.com> | |
568 | + | |
569 | + * kdb v4.4-2.6.19-rc6-i386-1. | |
570 | + | |
571 | +2006-11-09 Keith Owens <kaos@sgi.com> | |
572 | + | |
573 | + * Change kdb() to fastcall. | |
574 | + * Add unwind info to kdb_call(). Steve Lord. | |
575 | + * Only use VT console if the command line allows it. | |
576 | + * kdb v4.4-2.6.19-rc5-i386-2. | |
577 | + | |
578 | +2006-11-08 Keith Owens <kaos@sgi.com> | |
579 | + | |
580 | + * kdb v4.4-2.6.19-rc5-i386-1. | |
581 | + | |
582 | +2006-11-01 Keith Owens <kaos@sgi.com> | |
583 | + | |
584 | + * kdb v4.4-2.6.19-rc4-i386-1. | |
585 | + | |
586 | +2006-10-24 Keith Owens <kaos@sgi.com> | |
587 | + | |
588 | + * kdb v4.4-2.6.19-rc3-i386-1. | |
589 | + | |
590 | +2006-10-24 Keith Owens <kaos@sgi.com> | |
591 | + | |
592 | + * Remove redundant regs and envp parameters. | |
593 | + * kdb v4.4-2.6.19-rc2-i386-2. | |
594 | + | |
595 | +2006-10-18 Keith Owens <kaos@sgi.com> | |
596 | + | |
597 | + * kdb v4.4-2.6.19-rc2-i386-1. | |
598 | + | |
599 | +2006-10-11 Keith Owens <kaos@sgi.com> | |
600 | + | |
601 | + * Move kdbm_x86.c from the i386 to the common KDB patch. | |
602 | + * Make the KDBENTER_VECTOR an interrupt gate instead of a trap gate, it | |
603 | + simplifies the code and disables interrupts on KDBENTER(). | |
604 | + * Exclude the KDBENTER_VECTOR from irq assignment. | |
605 | + * kdb v4.4-2.6.19-rc1-i386-2. | |
606 | + | |
607 | +2006-10-09 Keith Owens <kaos@sgi.com> | |
608 | + | |
609 | + * kdb v4.4-2.6.19-rc1-i386-1. | |
610 | + | |
611 | +2006-10-06 Keith Owens <kaos@sgi.com> | |
612 | + | |
613 | + * Remove #include <linux/config.h> | |
614 | + * kdb v4.4-2.6.18-i386-2. | |
615 | + | |
616 | +2006-09-20 Keith Owens <kaos@sgi.com> | |
617 | + | |
618 | + * kdb v4.4-2.6.18-i386-1. | |
619 | + | |
620 | +2006-09-15 Keith Owens <kaos@sgi.com> | |
621 | + | |
622 | + * kdb v4.4-2.6.18-rc7-i386-1. | |
623 | + | |
624 | +2006-08-30 Keith Owens <kaos@sgi.com> | |
625 | + | |
626 | + * Add warning for problems when following alternate stacks. | |
627 | + * kdb v4.4-2.6.18-rc5-i386-3. | |
628 | + | |
629 | +2006-08-29 Keith Owens <kaos@sgi.com> | |
630 | + | |
631 | + * Rewrite all backtrace code. | |
632 | + * kdb v4.4-2.6.18-rc5-i386-2. | |
633 | + | |
634 | +2006-08-28 Keith Owens <kaos@sgi.com> | |
635 | + | |
636 | + * kdb v4.4-2.6.18-rc5-i386-1. | |
637 | + | |
638 | +2006-08-08 Keith Owens <kaos@sgi.com> | |
639 | + | |
640 | + * kdb v4.4-2.6.18-rc4-i386-1. | |
641 | + | |
642 | +2006-08-04 Keith Owens <kaos@sgi.com> | |
643 | + | |
644 | + * kdb v4.4-2.6.18-rc3-i386-1. | |
645 | + | |
646 | +2006-07-18 Keith Owens <kaos@sgi.com> | |
647 | + | |
648 | + * kdb v4.4-2.6.18-rc2-i386-1. | |
649 | + | |
650 | +2006-07-12 Keith Owens <kaos@sgi.com> | |
651 | + | |
652 | + * Remove dead KDB_REASON codes. | |
653 | + * sparse cleanups. | |
654 | + * kdb v4.4-2.6.18-rc1-i386-2. | |
655 | + | |
656 | +2006-07-07 Keith Owens <kaos@sgi.com> | |
657 | + | |
658 | + * kdb v4.4-2.6.18-rc1-i386-1. | |
659 | + | |
660 | +2006-07-04 Keith Owens <kaos@sgi.com> | |
661 | + | |
662 | + * Make KDB rendezvous on i386 a two stage approach. | |
663 | + * Clean up generation of KDB interrupt code. | |
664 | + * Move smp_kdb_stop() and smp_kdb_interrupt() to kdbasupport.c. | |
665 | + * Move setting of interrupt traps to kdbasupport.c. | |
666 | + * Remove KDB hooks from arch/i386/kernel smp.c, smpboot.c, i8259.c, | |
667 | + io_apic.c. | |
668 | + * Add KDB_REASON_CPU_UP support. | |
669 | + * Move per cpu setup to kdba_cpu_up(). | |
670 | + * Rework support for 4K stacks to make backtrace more accurate. | |
671 | + * Add BTSP option to get the full backtrace, including kdb routines. | |
672 | + * Delete kdba_enable_mce, architectures now do their own setup. | |
673 | + * Delete kdba_enable_lbr, kdba_disable_lbr, kdba_print_lbr, | |
674 | + page_fault_mca. Only ever implemented on x86, difficult to maintain | |
675 | + and rarely used in the field. | |
676 | + * Replace #ifdef KDB_HAVE_LONGJMP with #ifdef kdba_setjmp. | |
677 | + * kdb v4.4-2.6.17-i386-2. | |
678 | + | |
679 | +2006-06-19 Keith Owens <kaos@sgi.com> | |
680 | + | |
681 | + * kdb v4.4-2.6.17-i386-1. | |
682 | + | |
683 | +2006-05-25 Keith Owens <kaos@sgi.com> | |
684 | + | |
685 | + * kdb v4.4-2.6.17-rc5-i386-1. | |
686 | + | |
687 | +2006-05-15 Keith Owens <kaos@sgi.com> | |
688 | + | |
689 | + * Refresh bfd related files from binutils 2.16.91.0.2. | |
690 | + * kdb v4.4-2.6.17-rc4-i386-2. | |
691 | + | |
692 | +2006-05-12 Keith Owens <kaos@sgi.com> | |
693 | + | |
694 | + * kdb v4.4-2.6.17-rc4-i386-1. | |
695 | + | |
696 | +2006-04-28 Keith Owens <kaos@sgi.com> | |
697 | + | |
698 | + * kdb v4.4-2.6.17-rc3-i386-1. | |
699 | + | |
700 | +2006-04-22 Keith Owens <kaos@sgi.com> | |
701 | + | |
702 | + * kdb v4.4-2.6.17-rc2-i386-1. | |
703 | + | |
704 | +2006-04-11 Keith Owens <kaos@sgi.com> | |
705 | + | |
706 | + * kdb v4.4-2.6.17-rc1-i386-1. | |
707 | + | |
708 | +2006-03-30 Keith Owens <kaos@sgi.com> | |
709 | + | |
710 | + * Change CONFIG_LKCD to CONFIG_LKCD_DUMP. | |
711 | + * kdb v4.4-2.6.16-i386-3. | |
712 | + | |
713 | +2006-03-24 Keith Owens <kaos@sgi.com> | |
714 | + | |
715 | + * Define a dummy kdba_wait_for_cpus(). | |
716 | + * kdb v4.4-2.6.16-i386-2. | |
717 | + | |
718 | +2006-03-21 Keith Owens <kaos@sgi.com> | |
719 | + | |
720 | + * kdb v4.4-2.6.16-i386-1. | |
721 | + | |
722 | +2006-03-14 Nathan Scott <nathans@sgi.com> | |
723 | + | |
724 | + * kdb v4.4-2.6.16-rc6-i386-1. | |
725 | + | |
726 | +2006-02-28 Nathan Scott <nathans@sgi.com> | |
727 | + | |
728 | + * kdb v4.4-2.6.16-rc5-i386-1. | |
729 | + | |
730 | +2006-02-20 Nathan Scott <nathans@sgi.com> | |
731 | + | |
732 | + * kdb v4.4-2.6.16-rc4-i386-1. | |
733 | + | |
734 | +2006-02-06 Keith Owens <kaos@sgi.com> | |
735 | + | |
736 | + * Change CONFIG_CRASH_DUMP to CONFIG_LKCD. | |
737 | + * kdb v4.4-2.6.16-rc2-i386-2. | |
738 | + | |
739 | +2006-02-06 Keith Owens <kaos@sgi.com> | |
740 | + | |
741 | + * kdb v4.4-2.6.16-rc2-i386-1. | |
742 | + | |
743 | +2006-01-18 Keith Owens <kaos@sgi.com> | |
744 | + | |
745 | + * kdb v4.4-2.6.16-rc1-i386-1. | |
746 | + | |
747 | +2006-01-08 Keith Owens <kaos@sgi.com> | |
748 | + | |
749 | + * Add DIE_KDEBUG_ENTER and DIE_KDEBUG_LEAVE to notify_die. | |
750 | + * kdb v4.4-2.6.15-i386-2. | |
751 | + | |
752 | +2006-01-04 Keith Owens <kaos@sgi.com> | |
753 | + | |
754 | + * Remove some inlines and the last vestige of CONFIG_NUMA_REPLICATE. | |
755 | + * Read the keyboard acknowledgment after sending a character. SuSE | |
756 | + Bugzilla 60240. | |
757 | + * kdb v4.4-2.6.15-i386-1. | |
758 | + | |
759 | +2005-12-25 Keith Owens <kaos@sgi.com> | |
760 | + | |
761 | + * kdb v4.4-2.6.15-rc7-i386-1. | |
762 | + | |
763 | +2005-12-20 Keith Owens <kaos@sgi.com> | |
764 | + | |
765 | + * kdb v4.4-2.6.15-rc6-i386-1. | |
766 | + | |
767 | +2005-12-05 Keith Owens <kaos@sgi.com> | |
768 | + | |
769 | + * kdb v4.4-2.6.15-rc5-i386-1. | |
770 | + | |
771 | +2005-12-02 Keith Owens <kaos@sgi.com> | |
772 | + | |
773 | + * kdb v4.4-2.6.15-rc4-i386-1. | |
774 | + | |
775 | +2005-11-30 Keith Owens <kaos@sgi.com> | |
776 | + | |
777 | + * kdb v4.4-2.6.15-rc3-i386-1. | |
778 | + | |
779 | +2005-11-21 Keith Owens <kaos@sgi.com> | |
780 | + | |
781 | + * kdb v4.4-2.6.15-rc2-i386-1. | |
782 | + | |
783 | +2005-11-15 Keith Owens <kaos@sgi.com> | |
784 | + | |
785 | + * kdb v4.4-2.6.15-rc1-i386-1. | |
786 | + | |
787 | +2005-10-28 Keith Owens <kaos@sgi.com> | |
788 | + | |
789 | + * kdb v4.4-2.6.14-i386-1. | |
790 | + | |
791 | +2005-10-21 Keith Owens <kaos@sgi.com> | |
792 | + | |
793 | + * kdb v4.4-2.6.14-rc5-i386-1. | |
794 | + | |
795 | +2005-10-11 Keith Owens <kaos@sgi.com> | |
796 | + | |
797 | + * kdb v4.4-2.6.14-rc4-i386-1. | |
798 | + | |
799 | +2005-10-04 Keith Owens <kaos@sgi.com> | |
800 | + | |
801 | + * kdb v4.4-2.6.14-rc3-i386-1. | |
802 | + | |
803 | +2005-09-21 Keith Owens <kaos@sgi.com> | |
804 | + | |
805 | + * Support kdb_current_task in register display and modify commands. | |
806 | + * kdb v4.4-2.6.14-rc2-i386-1. | |
807 | + | |
808 | +2005-09-20 Keith Owens <kaos@sgi.com> | |
809 | + | |
810 | + * Remove use of __STDC_VERSION__ in ansidecl.h. | |
811 | + * kdb v4.4-2.6.14-rc1-i386-1. | |
812 | + | |
813 | +2005-08-29 Keith Owens <kaos@sgi.com> | |
814 | + | |
815 | + * kdb v4.4-2.6.13-i386-1. | |
816 | + | |
817 | +2005-08-24 Keith Owens <kaos@sgi.com> | |
818 | + | |
819 | + * kdb v4.4-2.6.13-rc7-i386-1. | |
820 | + | |
821 | +2005-08-08 Keith Owens <kaos@sgi.com> | |
822 | + | |
823 | + * kdb v4.4-2.6.13-rc6-i386-1. | |
824 | + | |
825 | +2005-08-02 Keith Owens <kaos@sgi.com> | |
826 | + | |
827 | + * kdb v4.4-2.6.13-rc5-i386-1. | |
828 | + | |
829 | +2005-07-30 Keith Owens <kaos@sgi.com> | |
830 | + | |
831 | + * kdb v4.4-2.6.13-rc4-i386-1. | |
832 | + | |
833 | +2005-07-22 Keith Owens <kaos@sgi.com> | |
834 | + | |
835 | + * Compile fix for kprobes. | |
836 | + * kdb v4.4-2.6.13-rc3-i386-2. | |
837 | + | |
838 | +2005-07-19 Keith Owens <kaos@sgi.com> | |
839 | + | |
840 | + * Add support for USB keyboard (OHCI only). Aaron Young, SGI. | |
841 | + * kdb v4.4-2.6.13-rc3-i386-1. | |
842 | + | |
843 | +2005-07-08 Keith Owens <kaos@sgi.com> | |
844 | + | |
845 | + * kdb v4.4-2.6.13-rc2-i386-1. | |
846 | + | |
847 | +2005-07-01 Keith Owens <kaos@sgi.com> | |
848 | + | |
849 | + * kdb v4.4-2.6.13-rc1-i386-1. | |
850 | + | |
851 | +2005-06-19 Keith Owens <kaos@sgi.com> | |
852 | + | |
853 | + * gcc 4 compile fix, remove extern kdb_hardbreaks. Steve Lord. | |
854 | + * kdb v4.4-2.6.12-i386-2. | |
855 | + | |
856 | +2005-06-18 Keith Owens <kaos@sgi.com> | |
857 | + | |
858 | + * kdb v4.4-2.6.12-i386-1. | |
859 | + | |
860 | +2005-06-08 Keith Owens <kaos@sgi.com> | |
861 | + | |
862 | + * kdb v4.4-2.6.12-rc6-i386-1. | |
863 | + | |
864 | +2005-05-25 Keith Owens <kaos@sgi.com> | |
865 | + | |
866 | + * kdb v4.4-2.6.12-rc5-i386-1. | |
867 | + | |
868 | +2005-05-08 Keith Owens <kaos@sgi.com> | |
869 | + | |
870 | + * kdb v4.4-2.6.12-rc4-i386-1. | |
871 | + | |
872 | +2005-04-21 Keith Owens <kaos@sgi.com> | |
873 | + | |
874 | + * kdb v4.4-2.6.12-rc3-i386-1. | |
875 | + | |
876 | +2005-04-06 Keith Owens <kaos@sgi.com> | |
877 | + | |
878 | + * kdb v4.4-2.6.12-rc2-i386-1. | |
879 | + | |
880 | +2005-03-29 Keith Owens <kaos@sgi.com> | |
881 | + | |
882 | + * Replace __copy_to_user with __copy_to_user_inatomic. | |
883 | + * kdb v4.4-2.6.12-rc1-i386-1. | |
884 | + | |
885 | +2005-03-08 Keith Owens <kaos@sgi.com> | |
886 | + | |
887 | + * Coexistence patches for lkcd. | |
888 | + * kdb v4.4-2.6.11-i386-2. | |
889 | + | |
890 | +2005-03-03 Keith Owens <kaos@sgi.com> | |
891 | + | |
892 | + * kdb v4.4-2.6.11-i386-1. | |
893 | + | |
894 | +2005-02-14 Keith Owens <kaos@sgi.com> | |
895 | + | |
896 | + * kdb v4.4-2.6.11-rc4-i386-1. | |
897 | + | |
898 | +2005-02-08 Keith Owens <kaos@sgi.com> | |
899 | + | |
900 | + * kdb v4.4-2.6.11-rc3-bk4-i386-1. | |
901 | + | |
902 | +2005-02-03 Keith Owens <kaos@sgi.com> | |
903 | + | |
904 | + * kdb v4.4-2.6.11-rc3-i386-1. | |
905 | + | |
906 | +2005-01-27 Keith Owens <kaos@sgi.com> | |
907 | + | |
908 | + * kdb v4.4-2.6.11-rc2-i386-1. | |
909 | + | |
910 | +2005-01-12 Keith Owens <kaos@sgi.com> | |
911 | + | |
912 | + * kdb v4.4-2.6.11-rc1-i386-1. | |
913 | + | |
914 | +2004-12-25 Keith Owens <kaos@sgi.com> | |
915 | + | |
916 | + * kdb v4.4-2.6.10-i386-1. | |
917 | + | |
918 | +2004-12-07 Keith Owens <kaos@sgi.com> | |
919 | + | |
920 | + * kdb v4.4-2.6.10-rc3-i386-1. | |
921 | + | |
922 | +2004-11-23 Keith Owens <kaos@sgi.com> | |
923 | + | |
924 | + * Coexist with asmlinkage/fastcall changes. | |
925 | + * kdb v4.4-2.6.10-rc2-i386-1. | |
926 | + | |
927 | +2004-10-29 Keith Owens <kaos@sgi.com> | |
928 | + | |
929 | + * Handle change defintions for hard and soft irq context. | |
930 | + * Make stack switch in kdb backtrace look more like the oops output. | |
931 | + * kdb v4.4-2.6.10-rc1-i386-1. | |
932 | + | |
933 | +2004-10-19 Keith Owens <kaos@sgi.com> | |
934 | + | |
935 | + * kdb v4.4-2.6.9-i386-1. | |
936 | + | |
937 | +2004-10-12 Keith Owens <kaos@sgi.com> | |
938 | + | |
939 | + * kdb v4.4-2.6.9-rc4-i386-1. | |
940 | + | |
941 | +2004-10-01 Keith Owens <kaos@sgi.com> | |
942 | + | |
943 | + * kdb v4.4-2.6.9-rc3-i386-1. | |
944 | + | |
945 | +2004-09-30 Keith Owens <kaos@sgi.com> | |
946 | + | |
947 | + * Add stackdepth command. | |
948 | + * Handle backtrace with separate soft and hard irq stacks | |
949 | + (CONFIG_4KSTACKS). | |
950 | + * Work around RESTORE_ALL macro, which can only be used once. | |
951 | + * Export kdba_dumpregs. Bryan Cardillo, UPenn. | |
952 | + * kdb v4.4-2.6.9-rc2-i386-2. | |
953 | + | |
954 | +2004-09-14 Keith Owens <kaos@sgi.com> | |
955 | + | |
956 | + * kdb v4.4-2.6.9-rc2-i386-1. | |
957 | + | |
958 | +2004-08-27 Keith Owens <kaos@sgi.com> | |
959 | + | |
960 | + * kdb v4.4-2.6.9-rc1-i386-1. | |
961 | + | |
962 | +2004-08-14 Keith Owens <kaos@sgi.com> | |
963 | + | |
964 | + * kdb v4.4-2.6.8-i386-1. | |
965 | + | |
966 | +2004-08-12 Keith Owens <kaos@sgi.com> | |
967 | + | |
968 | + * kdb v4.4-2.6.8-rc4-i386-1. | |
969 | + | |
970 | +2004-08-04 Keith Owens <kaos@sgi.com> | |
971 | + | |
972 | + * kdb v4.4-2.6.8-rc3-i386-1. | |
973 | + | |
974 | +2004-07-18 Keith Owens <kaos@sgi.com> | |
975 | + | |
976 | + * kdb v4.4-2.6.8-rc2-i386-1. | |
977 | + | |
978 | +2004-07-12 Keith Owens <kaos@sgi.com> | |
979 | + | |
980 | + * kdb v4.4-2.6.8-rc1-i386-1. | |
981 | + | |
982 | +2004-06-16 Keith Owens <kaos@sgi.com> | |
983 | + | |
984 | + * kdb v4.4-2.6.7-i386-1. | |
985 | + | |
986 | +2004-06-10 Keith Owens <kaos@sgi.com> | |
987 | + | |
988 | + * kdb v4.4-2.6.7-rc3-i386-1. | |
989 | + | |
990 | +2004-06-09 Keith Owens <kaos@sgi.com> | |
991 | + | |
992 | + * Namespace clean up. Mark code/variables as static when it is only | |
993 | + used in one file, delete dead code/variables. | |
994 | + * kdb v4.4-2.6.7-rc2-i386-3. | |
995 | + | |
996 | +2004-06-08 Keith Owens <kaos@sgi.com> | |
997 | + | |
998 | + * Whitespace clean up, no code changes. | |
999 | + * kdb v4.4-2.6.7-rc2-i386-2. | |
1000 | + | |
1001 | +2004-06-07 Keith Owens <kaos@sgi.com> | |
1002 | + | |
1003 | + * Force KALLSYMS and KALLSYMS_ALL for CONFIG_KDB. | |
1004 | + * kdb v4.4-2.6.7-rc2-i386-1. | |
1005 | + | |
1006 | +2004-06-06 Keith Owens <kaos@sgi.com> | |
1007 | + | |
1008 | + * Correct Kconfig help text. | |
1009 | + * Coexist with CONFIG_REGPARM. | |
1010 | + * Add standard archkdb commands. | |
1011 | + * Move kdb_{get,put}userarea_size definitions to linux/kdb.h. | |
1012 | + * kdb v4.4-2.6.6-i386-2. | |
1013 | + | |
1014 | +2004-05-23 Keith Owens <kaos@sgi.com> | |
1015 | + | |
1016 | + * Move bfd.h and ansidecl.h from arch/$(ARCH)/kdb to include/asm-$(ARCH). | |
1017 | + * Update copyright notices. | |
1018 | + * kdb v4.4-2.6.6-i386-1. | |
1019 | + | |
1020 | +2004-05-10 Keith Owens <kaos@sgi.com> | |
1021 | + | |
1022 | + * kdb v4.3-2.6.6-i386-1. | |
1023 | + | |
1024 | +2004-05-06 Keith Owens <kaos@sgi.com> | |
1025 | + | |
1026 | + * kdb v4.3-2.6.6-rc3-i386-1. | |
1027 | + | |
1028 | +2004-05-06 Keith Owens <kaos@sgi.com> | |
1029 | + | |
1030 | + * kdb v4.3-2.6.6-rc2-i386-1. | |
1031 | + | |
1032 | +2004-04-30 Keith Owens <kaos@sgi.com> | |
1033 | + | |
1034 | + * kdb v4.3-2.6.6-rc1-i386-1. | |
1035 | + | |
1036 | +2004-04-05 Keith Owens <kaos@sgi.com> | |
1037 | + | |
1038 | + * kdb v4.3-2.6-5-i386-1. | |
1039 | + | |
1040 | +2004-02-29 Keith Owens <kaos@sgi.com> | |
1041 | + | |
1042 | + * kdb v4.3-2.6-4-rc1-i386-1. | |
1043 | + | |
1044 | +2004-02-18 Keith Owens <kaos@sgi.com> | |
1045 | + | |
1046 | + * kdb v4.3-2.6-3-i386-1. | |
1047 | + | |
1048 | +2004-02-17 Keith Owens <kaos@sgi.com> | |
1049 | + | |
1050 | + * Pick up changes from Jim Houston for 2.6. | |
1051 | + * Sync with kdb v4.3-2.4.25-rc1-i386-1. | |
1052 | + * Adjust for LDT changes in i386 mainline. | |
1053 | + * Convert longjmp buffers from static to dynamic allocation, for large | |
1054 | + cpu counts. | |
1055 | + * Do not use USB keyboard if it has not been probed. | |
1056 | + * Do not print section data, 2.6 kallsyms does not support sections :(. | |
1057 | + * kdb v4.3-2.6-3-rc3-i386-1. | |
1058 | + | |
1059 | +2003-08-29 Keith Owens <kaos@sgi.com> | |
1060 | + | |
1061 | + * kdb v4.3-2.4.22-i386-1. | |
1062 | + | |
1063 | +2003-08-05 Keith Owens <kaos@sgi.com> | |
1064 | + | |
1065 | + * Remove duplicate setting of trap for machine_check. | |
1066 | + * Only reset keyboard when CONFIG_VT_CONSOLE is defined. | |
1067 | + | |
1068 | +2003-07-27 Keith Owens <kaos@sgi.com> | |
1069 | + | |
1070 | + * kdb v4.3-2.4.22-pre8-i386-5. | |
1071 | + | |
1072 | +2003-07-20 Keith Owens <kaos@sgi.com> | |
1073 | + | |
1074 | + * Remove compile warning on x86 commands. | |
1075 | + * kdb v4.3-2.4.21-i386-5. | |
1076 | + | |
1077 | +2003-07-08 Keith Owens <kaos@sgi.com> | |
1078 | + | |
1079 | + * Add new x86 commands - rdv, gdt, idt, ldt, ldtp, ptex. | |
1080 | + Vamsi Krishna S., IBM. | |
1081 | + * kdb v4.3-2.4.21-i386-4. | |
1082 | + | |
1083 | +2003-07-01 Keith Owens <kaos@sgi.com> | |
1084 | + | |
1085 | + * Convert kdba_find_return() to two passes to reduce false positives. | |
1086 | + * Correct jmp disp8 offset calculation for out of line lock code. | |
1087 | + * Use NMI for kdb IPI in clustered APIC mode. Sachin Sant, IBM. | |
1088 | + * kdb v4.3-2.4.21-i386-3. | |
1089 | + | |
1090 | +2003-06-23 Keith Owens <kaos@sgi.com> | |
1091 | + | |
1092 | + * Sync with XFS 2.4.21 tree. | |
1093 | + * kdb v4.3-2.4.21-i386-2. | |
1094 | + | |
1095 | +2003-06-20 Keith Owens <kaos@sgi.com> | |
1096 | + | |
1097 | + * kdb v4.3-2.4.21-i386-1. | |
1098 | + | |
1099 | +2003-06-20 Keith Owens <kaos@sgi.com> | |
1100 | + | |
1101 | + * Add CONFIG_KDB_CONTINUE_CATASTROPHIC. | |
1102 | + * Correct KDB_ENTER() definition. | |
1103 | + * kdb v4.3-2.4.20-i386-1. | |
1104 | + | |
1105 | +2003-05-02 Keith Owens <kaos@sgi.com> | |
1106 | + | |
1107 | + * Add kdba_fp_value(). | |
1108 | + * Limit backtrace size to catch loops. | |
1109 | + * Add read/write access to user pages. Vamsi Krishna S., IBM | |
1110 | + * Clean up USB keyboard support. Steven Dake. | |
1111 | + * kdb v4.2-2.4.20-i386-1. | |
1112 | + | |
1113 | +2003-04-04 Keith Owens <kaos@sgi.com> | |
1114 | + | |
1115 | + * Workarounds for scheduler bugs. | |
1116 | + * kdb v4.1-2.4.20-i386-1. | |
1117 | + | |
1118 | +2003-03-16 Keith Owens <kaos@sgi.com> | |
1119 | + | |
1120 | + * Each cpu saves its state as it enters kdb or before it enters code | |
1121 | + which cannot call kdb, converting kdb from a pull to a push model. | |
1122 | + * Clean up kdb interaction with CONFIG_SERIAL_CONSOLE. | |
1123 | + * Removal of special cases for i386 backtrace from common code | |
1124 | + simplifies the architecture code. | |
1125 | + * Add command to dump i386 struct pt_regs. | |
1126 | + * kdb v4.0-2.4.20-i386-1. | |
1127 | + | |
1128 | +2003-02-03 Keith Owens <kaos@sgi.com> | |
1129 | + | |
1130 | + * Register kdb commands early. | |
1131 | + * Handle KDB_ENTER() when kdb=off. | |
1132 | + * Optimize __kdba_getarea_size when width is a constant. | |
1133 | + * Decode oops via kallsyms if it is available. | |
1134 | + * Update copyright notices to 2003. | |
1135 | + * Handle call *disp32(%reg) in backtrace. | |
1136 | + * Correct keyboard freeze. Ashish Kalra. | |
1137 | + * Add command history and editing. Sonic Zhang. | |
1138 | + * kdb_toggleled is conditional on KDB_BLINK_LED. Bernhard Fischer. | |
1139 | + * Allow tab on serial line for symbol completion. | |
1140 | + * Ignore KDB_ENTER() when kdb is already running. | |
1141 | + * kdb v3.0-2.4.20-i386-1. | |
1142 | + | |
1143 | +2002-11-29 Keith Owens <kaos@sgi.com> | |
1144 | + | |
1145 | + * Upgrade to 2.4.20. | |
1146 | + * kdb v2.5-2.4.20-i386-1. | |
1147 | + | |
1148 | +2002-11-14 Keith Owens <kaos@sgi.com> | |
1149 | + | |
1150 | + * Upgrade to 2.4.20-rc1. | |
1151 | + * kdb v2.5-2.4.20-rc1-i386-1. | |
1152 | + | |
1153 | +2002-11-14 Keith Owens <kaos@sgi.com> | |
1154 | + | |
1155 | + * General clean up of handling for breakpoints and single stepping over | |
1156 | + software breakpoints. | |
1157 | + * Accept ff 1x as well as ff dx for call *(%reg) in backtrace. | |
1158 | + * kdb v2.5-2.4.19-i386-1. | |
1159 | + | |
1160 | +2002-11-01 Keith Owens <kaos@sgi.com> | |
1161 | + | |
1162 | + * Prevent SMP IRQ overwriting KDB_ENTER(). | |
1163 | + * kdb v2.4-2.4.19-i386-2. | |
1164 | + | |
1165 | +2002-10-31 Keith Owens <kaos@sgi.com> | |
1166 | + | |
1167 | + * Avoid KDB_VECTOR conflict with DUMP_VECTOR. | |
1168 | + * Remove kdb_eframe_t. | |
1169 | + * Sanity check if we have pt_regs. | |
1170 | + * Remove kdba_getcurrentframe(). | |
1171 | + * Reinstate missing nmi_watchdog/kdb hook. | |
1172 | + * kdb v2.4-2.4.19-i386-1. | |
1173 | + | |
1174 | +2002-10-17 Keith Owens <kaos@sgi.com> | |
1175 | + | |
1176 | + * Correct compile with CONFIG_VT_CONSOLE=n. | |
1177 | + * kdb v2.3-2.4.19-i386-5. | |
1178 | + | |
1179 | +2002-10-04 Keith Owens <kaos@sgi.com> | |
1180 | + | |
1181 | + * Add USB keyboard option. | |
1182 | + * Minimize differences between patches for 2.4 and 2.5 kernels. | |
1183 | + * kdb v2.3-2.4.19-i386-4. | |
1184 | + | |
1185 | +2002-08-10 Keith Owens <kaos@sgi.com> | |
1186 | + | |
1187 | + * Replace kdb_port with kdb_serial to support memory mapped I/O. | |
1188 | + Note: This needs kdb v2.3-2.4.19-common-2 or later. | |
1189 | + * kdb v2.3-2.4.19-i386-3. | |
1190 | + | |
1191 | +2002-08-09 Keith Owens <kaos@sgi.com> | |
1192 | + | |
1193 | + * Use -fno-optimize-sibling-calls for kdb if gcc supports it. | |
1194 | + * .text.lock does not consume an activation frame. | |
1195 | + * kdb v2.3-2.4.19-i386-2. | |
1196 | + | |
1197 | +2002-08-07 Keith Owens <kaos@sgi.com> | |
1198 | + | |
1199 | + * Upgrade to 2.4.19. | |
1200 | + * Remove individual SGI copyrights, the general SGI copyright applies. | |
1201 | + * New .text.lock name. Hugh Dickins. | |
1202 | + * Set KERNEL_CS in kdba_getcurrentframe. Hugh Dickins. | |
1203 | + * Clean up disassembly layout. Hugh Dickins, Keith Owens. | |
1204 | + * Replace hard coded stack size with THREAD_SIZE. Hugh Dickins. | |
1205 | + * Better stack layout on bt with no frame pointers. Hugh Dickins. | |
1206 | + * Make i386 IO breakpoints (bpha <address> IO) work again. | |
1207 | + Martin Wilck, Keith Owens. | |
1208 | + * Remove fixed KDB_MAX_COMMANDS size. | |
1209 | + * Add set_fs() around __copy_to_user on kernel addresses. | |
1210 | + Randolph Chung. | |
1211 | + * Position i386 for CONFIG_NUMA_REPLICATE. | |
1212 | + * kdb v2.3-2.4.19-i386-1. | |
1213 | + | |
1214 | +2002-07-09 Keith Owens <kaos@sgi.com> | |
1215 | + | |
1216 | + * Upgrade to 2.4.19-rc1. | |
1217 | + | |
1218 | +2002-06-14 Keith Owens <kaos@sgi.com> | |
1219 | + | |
1220 | + * Upgrade to 2.4.19-pre10. | |
1221 | + * kdb v2.1-2.4.19-pre10-i386-1. | |
1222 | + | |
1223 | +2002-04-09 Keith Owens <kaos@sgi.com> | |
1224 | + | |
1225 | + * Upgrade to 2.4.19-pre6. | |
1226 | + * kdb v2.1-2.4.19-pre6-i386-1. | |
1227 | + | |
1228 | +2002-02-26 Keith Owens <kaos@sgi.com> | |
1229 | + | |
1230 | + * Upgrade to 2.4.18. | |
1231 | + * kdb v2.1-2.4.18-i386-1. | |
1232 | + | |
1233 | +2002-01-18 Keith Owens <kaos@sgi.com> | |
1234 | + | |
1235 | + * Use new kdb_get/put functions. | |
1236 | + * Define kdba_{get,put}area_size functions for i386. | |
1237 | + * Remove over-engineered dblist callback functions. | |
1238 | + * Correctly handle failing call disp32 in backtrace. | |
1239 | + * Remove bp_instvalid flag, redundant code. | |
1240 | + * Remove dead code. | |
1241 | + * kdb v2.1-2.4.17-i386-1. | |
1242 | + | |
1243 | +2002-01-04 Keith Owens <kaos@sgi.com> | |
1244 | + | |
1245 | + * Sync xfs <-> kdb i386 code. | |
1246 | + | |
1247 | +2001-12-22 Keith Owens <kaos@sgi.com> | |
1248 | + | |
1249 | + * Split kdb for i386 as kdb v2.0-2.4.17-i386-1. | |
1250 | --- /dev/null | |
1251 | +++ b/arch/x86/kdb/ChangeLog_64 | |
1252 | @@ -0,0 +1,447 @@ | |
1253 | +2007-11-08 Jay Lan <jlan@sgi.com> | |
1254 | + | |
1255 | + * New KDB USB interface, Aaron Young <ayoung@sgi.com> | |
1256 | + * 1. This patch allows KDB to work with any Host Contoller driver | |
1257 | + * and call the correct HC driver poll routine (as long as the | |
1258 | + * HC driver provides a .kdb_poll_char routine via it's | |
1259 | + * associated hc_driver struct). | |
1260 | + * 2. Hotplugged keyboards are now recognized by KDB. | |
1261 | + * 3. Currently KDB can only make use of 1 USB type keyboard. | |
1262 | + * New code can handle up to 8 attached keyboards - input is | |
1263 | + * multiplexed from all of them while in kdb. | |
1264 | + * kdb v4.4-2.6.23-common-2. | |
1265 | + | |
1266 | +2007-10-24 Jay Lan <jlan@sgi.com> | |
1267 | + | |
1268 | + * kdb v4.4-2.6.23-x86_64-1. | |
1269 | + | |
1270 | +2007-09-26 Jay Lan <jlan@sgi.com> | |
1271 | + | |
1272 | + * kdb v4.4-2.6.23-rc8-x86_64-1. | |
1273 | + | |
1274 | +2007-09-21 Jay Lan <jlan@sgi.com> | |
1275 | + | |
1276 | + * kdb v4.4-2.6.23-rc7-x86_64-1. | |
1277 | + | |
1278 | +2007-09-12 Jay Lan <jlan@sgi.com> | |
1279 | + | |
1280 | + * kdb v4.4-2.6.23-rc6-x86_64-1. | |
1281 | + | |
1282 | +2007-09-06 Jay Lan <jlan@sgi.com> | |
1283 | + | |
1284 | + * kdb v4.4-2.6.23-rc5-x86_64-1. | |
1285 | + | |
1286 | +2007-08-30 Keith Owens <kaos@sgi.com> | |
1287 | + | |
1288 | + * New i386/x86_64 backtrace requires that kdb_save_running() does not | |
1289 | + exit until after kdb_main_loop() has completed. | |
1290 | + * kdb v4.4-2.6.23-rc4-x86_64-2. | |
1291 | + | |
1292 | +2007-08-30 Jay Lan <jlan@sgi.com> | |
1293 | + | |
1294 | + * kdb v4.4-2.6.23-rc4-x86_64-1. | |
1295 | + | |
1296 | +2007-08-24 Keith Owens <kaos@sgi.com> | |
1297 | + | |
1298 | + * kdb v4.4-2.6.23-rc3-x86_64-1. | |
1299 | + | |
1300 | +2007-08-07 Jay Lan <jlan@sgi.com> | |
1301 | + | |
1302 | + * v4.4-2.6.23-rc2-x86_64-1. | |
1303 | + | |
1304 | +2007-07-31 Keith Owens <kaos@sgi.com> | |
1305 | + | |
1306 | + * Delete obsolete kdba_bt.c. | |
1307 | + * kdb v4.4-2.6.23-rc1-x86_64-2. | |
1308 | + | |
1309 | +2007-07-30 Keith Owens <kaos@sgi.com> | |
1310 | + | |
1311 | + * kdb v4.4-2.6.23-rc1-x86_64-1. | |
1312 | + | |
1313 | +2007-07-26 Keith Owens <kaos@sgi.com> | |
1314 | + | |
1315 | + * New x86 backtrace code. | |
1316 | + * kdb v4.4-2.6.22-x86_64-2. | |
1317 | + | |
1318 | +2007-07-09 Keith Owens <kaos@sgi.com> | |
1319 | + | |
1320 | + * kdb v4.4-2.6.22-x86_64-1. | |
1321 | + | |
1322 | +2007-07-02 Keith Owens <kaos@sgi.com> | |
1323 | + | |
1324 | + * kdb v4.4-2.6.22-rc7-x86_64-1. | |
1325 | + | |
1326 | +2007-06-25 Keith Owens <kaos@sgi.com> | |
1327 | + | |
1328 | + * Hook into DIE_NMIWATCHDOG. | |
1329 | + * kdb v4.4-2.6.22-rc5-x86_64-2. | |
1330 | + | |
1331 | +2007-06-20 Keith Owens <kaos@sgi.com> | |
1332 | + | |
1333 | + * kdb v4.4-2.6.22-rc5-x86_64-1. | |
1334 | + | |
1335 | +2007-06-08 Keith Owens <kaos@sgi.com> | |
1336 | + | |
1337 | + * kdb v4.4-2.6.22-rc4-x86_64-1. | |
1338 | + | |
1339 | +2007-05-28 Keith Owens <kaos@sgi.com> | |
1340 | + | |
1341 | + * kdb v4.4-2.6.22-rc3-x86_64-1. | |
1342 | + | |
1343 | +2007-05-22 Keith Owens <kaos@sgi.com> | |
1344 | + | |
1345 | + * Register KDBENTER_VECTOR early on the boot cpu. | |
1346 | + * kdb v4.4-2.6.22-rc2-x86_64-2. | |
1347 | + | |
1348 | +2007-05-22 Keith Owens <kaos@sgi.com> | |
1349 | + | |
1350 | + * kdb v4.4-2.6.22-rc2-x86_64-1. | |
1351 | + | |
1352 | +2007-05-22 Keith Owens <kaos@sgi.com> | |
1353 | + | |
1354 | + * kdb v4.4-2.6.22-rc1-x86_64-1. | |
1355 | + | |
1356 | +2007-05-17 Keith Owens <kaos@sgi.com> | |
1357 | + | |
1358 | + * Update dumpregs comments for rdmsr and wrmsr commands. | |
1359 | + Bernardo Innocenti. | |
1360 | + * kdb v4.4-2.6.21-x86_64-3. | |
1361 | + | |
1362 | +2007-05-15 Keith Owens <kaos@sgi.com> | |
1363 | + | |
1364 | + * Change kdba_late_init to kdba_arch_init so KDB_ENTER() can be used | |
1365 | + earlier. | |
1366 | + * kdb v4.4-2.6.21-x86_64-2. | |
1367 | + | |
1368 | +2007-04-29 Keith Owens <kaos@sgi.com> | |
1369 | + | |
1370 | + * kdb v4.4-2.6.21-x86_64-1. | |
1371 | + | |
1372 | +2007-04-16 Keith Owens <kaos@sgi.com> | |
1373 | + | |
1374 | + * Select KALLSYMS and KALLSYMS_ALL when KDB is selected. | |
1375 | + * kdb v4.4-2.6.21-rc7-x86_64-2. | |
1376 | + | |
1377 | +2007-04-16 Keith Owens <kaos@sgi.com> | |
1378 | + | |
1379 | + * kdb v4.4-2.6.21-rc7-x86_64-1. | |
1380 | + | |
1381 | +2007-04-10 Keith Owens <kaos@sgi.com> | |
1382 | + | |
1383 | + * kdb v4.4-2.6.21-rc6-x86_64-1. | |
1384 | + | |
1385 | +2007-04-02 Keith Owens <kaos@sgi.com> | |
1386 | + | |
1387 | + * kdb v4.4-2.6.21-rc5-x86_64-1. | |
1388 | + | |
1389 | +2007-03-19 Keith Owens <kaos@sgi.com> | |
1390 | + | |
1391 | + * kdb v4.4-2.6.21-rc4-x86_64-1. | |
1392 | + | |
1393 | +2007-03-14 Keith Owens <kaos@sgi.com> | |
1394 | + | |
1395 | + * kdb v4.4-2.6.21-rc3-x86_64-1. | |
1396 | + | |
1397 | +2007-03-14 Keith Owens <kaos@sgi.com> | |
1398 | + | |
1399 | + * kdb v4.4-2.6.21-rc2-x86_64-1. | |
1400 | + | |
1401 | +2007-03-01 Keith Owens <kaos@sgi.com> | |
1402 | + | |
1403 | + * kdb v4.4-2.6.21-rc1-x86_64-1. | |
1404 | + | |
1405 | +2007-03-01 Keith Owens <kaos@sgi.com> | |
1406 | + | |
1407 | + * Remove sparse warnings. | |
1408 | + * kdb v4.4-2.6.20-x86_64-3. | |
1409 | + | |
1410 | +2007-02-16 Keith Owens <kaos@sgi.com> | |
1411 | + | |
1412 | + * Initialise variable bits of struct disassemble_info each time. | |
1413 | + * kdb v4.4-2.6.20-x86_64-2. | |
1414 | + | |
1415 | +2007-02-06 Keith Owens <kaos@sgi.com> | |
1416 | + | |
1417 | + * kdb v4.4-2.6.20-x86_64-1. | |
1418 | + | |
1419 | +2007-02-01 Keith Owens <kaos@sgi.com> | |
1420 | + | |
1421 | + * kdb v4.4-2.6.20-rc7-x86_64-1. | |
1422 | + | |
1423 | +2007-01-10 Keith Owens <kaos@sgi.com> | |
1424 | + | |
1425 | + * Correct setjmp for the FRAME_POINTER=y case. | |
1426 | + * Remove duplicate longjmp code for FRAME_POINTER=n/y. | |
1427 | + * kdb v4.4-2.6.20-rc4-x86_64-2. | |
1428 | + | |
1429 | +2007-01-08 Keith Owens <kaos@sgi.com> | |
1430 | + | |
1431 | + * kdb v4.4-2.6.20-rc4-x86_64-1. | |
1432 | + | |
1433 | +2007-01-02 Keith Owens <kaos@sgi.com> | |
1434 | + | |
1435 | + * kdb v4.4-2.6.20-rc3-x86_64-1. | |
1436 | + | |
1437 | +2006-12-20 Keith Owens <kaos@sgi.com> | |
1438 | + | |
1439 | + * kdb v4.4-2.6.20-rc1-x86_64-1. | |
1440 | + | |
1441 | +2006-12-07 Keith Owens <kaos@sgi.com> | |
1442 | + | |
1443 | + * Export kdba_dumpregs. | |
1444 | + * kdb v4.4-2.6.19-x86_64-2. | |
1445 | + | |
1446 | +2006-11-30 Keith Owens <kaos@sgi.com> | |
1447 | + | |
1448 | + * kdb v4.4-2.6.19-x86_64-1. | |
1449 | + | |
1450 | +2006-11-27 Keith Owens <kaos@sgi.com> | |
1451 | + | |
1452 | + * Only use VT keyboard if the command line allows it and ACPI indicates | |
1453 | + that there is an i8042. | |
1454 | + * kdb v4.4-2.6.19-rc6-x86_64-2. | |
1455 | + | |
1456 | +2006-11-20 Keith Owens <kaos@sgi.com> | |
1457 | + | |
1458 | + * kdb v4.4-2.6.19-rc6-x86_64-1. | |
1459 | + | |
1460 | +2006-11-09 Keith Owens <kaos@sgi.com> | |
1461 | + | |
1462 | + * Only use VT console if the command line allows it. | |
1463 | + * kdb v4.4-2.6.19-rc5-x86_64-2. | |
1464 | + | |
1465 | +2006-11-08 Keith Owens <kaos@sgi.com> | |
1466 | + | |
1467 | + * kdb v4.4-2.6.19-rc5-x86_64-1. | |
1468 | + | |
1469 | +2006-11-01 Keith Owens <kaos@sgi.com> | |
1470 | + | |
1471 | + * kdb v4.4-2.6.19-rc4-x86_64-1. | |
1472 | + | |
1473 | +2006-10-24 Keith Owens <kaos@sgi.com> | |
1474 | + | |
1475 | + * kdb v4.4-2.6.19-rc3-x86_64-1. | |
1476 | + | |
1477 | +2006-10-24 Keith Owens <kaos@sgi.com> | |
1478 | + | |
1479 | + * Remove redundant regs and envp parameters. | |
1480 | + * kdb v4.4-2.6.19-rc2-x86_64-2. | |
1481 | + | |
1482 | +2006-10-18 Keith Owens <kaos@sgi.com> | |
1483 | + | |
1484 | + * kdb v4.4-2.6.19-rc2-x86_64-1. | |
1485 | + | |
1486 | +2006-10-11 Keith Owens <kaos@sgi.com> | |
1487 | + | |
1488 | + * Make the KDBENTER_VECTOR an interrupt gate instead of a trap gate, it | |
1489 | + simplifies the code and disables interrupts on KDB_ENTER(). | |
1490 | + * Exclude the KDBENTER_VECTOR from irq assignment. | |
1491 | + * Enable KDB_ENTER() again. | |
1492 | + * kdb v4.4-2.6.19-rc1-x86_64-2. | |
1493 | + | |
1494 | +2006-10-09 Keith Owens <kaos@sgi.com> | |
1495 | + | |
1496 | + * KDB_ENTER() is getting spurious activations on some x86_64 hardware. | |
1497 | + Deactivate KDB_ENTER() until it is fixed. | |
1498 | + * kdb v4.4-2.6.19-rc1-x86_64-1. | |
1499 | + | |
1500 | +2006-10-06 Keith Owens <kaos@sgi.com> | |
1501 | + | |
1502 | + * Remove #include <linux/config.h> | |
1503 | + * kdb v4.4-2.6.18-x86_64-2. | |
1504 | + | |
1505 | +2006-09-20 Keith Owens <kaos@sgi.com> | |
1506 | + | |
1507 | + * kdb v4.4-2.6.18-x86_64-1. | |
1508 | + | |
1509 | +2006-09-15 Keith Owens <kaos@sgi.com> | |
1510 | + | |
1511 | + * kdb v4.4-2.6.18-rc7-x86_64-1. | |
1512 | + | |
1513 | +2006-08-30 Keith Owens <kaos@sgi.com> | |
1514 | + | |
1515 | + * Do not print debugstackptr in cpu_pda, it will be deleted soon. | |
1516 | + * Add KDB_ENTER(). | |
1517 | + * Add warning for problems when following alternate stacks. | |
1518 | + * kdb v4.4-2.6.18-rc5-x86_64-3. | |
1519 | + | |
1520 | +2006-08-29 Keith Owens <kaos@sgi.com> | |
1521 | + | |
1522 | + * Rewrite all backtrace code. | |
1523 | + * Add pt_regs and cpu_pda commands. | |
1524 | + * Include patch to define orig_ist, to be removed once that patch is in | |
1525 | + the community tree. | |
1526 | + * kdb v4.4-2.6.18-rc5-x86_64-2. | |
1527 | + | |
1528 | +2006-08-28 Keith Owens <kaos@sgi.com> | |
1529 | + | |
1530 | + * kdb v4.4-2.6.18-rc5-x86_64-1. | |
1531 | + | |
1532 | +2006-08-08 Keith Owens <kaos@sgi.com> | |
1533 | + | |
1534 | + * kdb v4.4-2.6.18-rc4-x86_64-1. | |
1535 | + | |
1536 | +2006-08-04 Keith Owens <kaos@sgi.com> | |
1537 | + | |
1538 | + * kdb v4.4-2.6.18-rc3-x86_64-1. | |
1539 | + | |
1540 | +2006-07-18 Keith Owens <kaos@sgi.com> | |
1541 | + | |
1542 | + * kdb v4.4-2.6.18-rc2-x86_64-1. | |
1543 | + | |
1544 | +2006-07-12 Keith Owens <kaos@sgi.com> | |
1545 | + | |
1546 | + * sparse cleanups | |
1547 | + * kdb v4.4-2.6.18-rc1-x86_64-2. | |
1548 | + | |
1549 | +2006-07-07 Keith Owens <kaos@sgi.com> | |
1550 | + | |
1551 | + * kdb v4.4-2.6.18-rc1-x86_64-1. | |
1552 | + | |
1553 | +2006-07-04 Keith Owens <kaos@sgi.com> | |
1554 | + | |
1555 | + * Make KDB rendezvous on x86_64 a two stage approach. | |
1556 | + * Move smp_kdb_stop() and smp_kdb_interrupt() to kdbasupport.c. | |
1557 | + * Move setting of interrupt traps to kdbasupport.c. | |
1558 | + * Add KDB_REASON_CPU_UP support. | |
1559 | + * Move per cpu setup to kdba_cpu_up(). | |
1560 | + * Delete kdba_enable_mce, architectures now do their own setup. | |
1561 | + * Delete kdba_enable_lbr, kdba_disable_lbr, kdba_print_lbr, | |
1562 | + page_fault_mca. Only ever implemented on x86, difficult to maintain | |
1563 | + and rarely used in the field. | |
1564 | + * Replace #ifdef KDB_HAVE_LONGJMP with #ifdef kdba_setjmp. | |
1565 | + * kdb v4.4-2.6.17-x86_64-2. | |
1566 | + | |
1567 | +2006-06-19 Keith Owens <kaos@sgi.com> | |
1568 | + | |
1569 | + * kdb v4.4-2.6.17-x86_64-1. | |
1570 | + | |
1571 | +2006-05-31 Keith Owens <kaos@sgi.com> | |
1572 | + | |
1573 | + * Define arch/x86_64/kdb/kdb_cmds. | |
1574 | + * kdb v4.4-2.6.17-rc5-x86_64-2. | |
1575 | + | |
1576 | +2006-05-25 Keith Owens <kaos@sgi.com> | |
1577 | + | |
1578 | + * kdb v4.4-2.6.17-rc5-x86_64-1. | |
1579 | + | |
1580 | +2006-05-15 Keith Owens <kaos@sgi.com> | |
1581 | + | |
1582 | + * Refresh bfd related files from binutils 2.16.91.0.2. | |
1583 | + * kdb v4.4-2.6.17-rc4-x86_64-2. | |
1584 | + | |
1585 | +2006-05-12 Keith Owens <kaos@sgi.com> | |
1586 | + | |
1587 | + * kdb v4.4-2.6-17-rc4-x86_64-1. | |
1588 | + | |
1589 | +2006-04-22 Keith Owens <kaos@sgi.com> | |
1590 | + | |
1591 | + * kdb v4.4-2.6-17-rc2-x86_64-1. | |
1592 | + | |
1593 | +2006-04-13 Keith Owens <kaos@sgi.com> | |
1594 | + | |
1595 | + * Remove trailing white space. | |
1596 | + * kdb v4.4-2.6-17-rc1-x86_64-1. | |
1597 | + | |
1598 | +2006-03-25 Jack F. Vogel <jfv@bluesong.net> | |
1599 | + * Sync with Keith's changes for 2.6.16 | |
1600 | + * code from Andi Kleen to support above | |
1601 | + | |
1602 | +2005-09-30 Jack F. Vogel <jfv@bluesong.net> | |
1603 | + * Port to 2.6.14-rc2 | |
1604 | + * sync with a couple changes from Keith | |
1605 | + * Add backtrace code from Jim Houston | |
1606 | + (thanks Jim) | |
1607 | + | |
1608 | +2005-08-31 Jack F. Vogel <jfv@bluesong.net> | |
1609 | + * Change to linker script for kexec | |
1610 | + thanks to Steven Dake <sdake@mvista.com> | |
1611 | + | |
1612 | +2005-08-30 Jack F. Vogel <jfv@bluesong.net> | |
1613 | + * Notify struct should not be devinit | |
1614 | + thanks IWAMOTO Toshihiro <iwamoto@valinux.co.jp> | |
1615 | + | |
1616 | +2005-08-25 Jack F. Vogel <jfv@bluesong.net> | |
1617 | + * Update to 2.6.11 | |
1618 | + * Fix to synchronize with the notify changes | |
1619 | + thanks to Jim Houston. | |
1620 | + | |
1621 | +2004-09-30 Keith Owens <kaos@sgi.com> | |
1622 | + * Port to 2.6.9-rc2 | |
1623 | + * Fix line editting characters. Jim Houston, Comcast. | |
1624 | + * kdb v4.4-2.6.9-rc2-x86-64-1. | |
1625 | + | |
1626 | +2004-08-15 Jack F. Vogel <jfv@bluesong.net> | |
1627 | + * Port to 2.6.8 | |
1628 | + * tighten up the code, using the built-in | |
1629 | + die_chain notify interface, thanks to | |
1630 | + Andi Kleen for pointing this out. | |
1631 | + | |
1632 | +2004-05-15 Jack F. Vogel <jfv@bluesong.net> | |
1633 | + * port to 2.6.6 for x86_64 | |
1634 | + | |
1635 | +2003-12-15 Cliff Neighbors <cliff@fabric7.com> | |
1636 | + * initial port from i386 to x86_64 | |
1637 | + | |
1638 | +2002-08-10 Keith Owens <kaos@sgi.com> | |
1639 | + | |
1640 | + * Replace kdb_port with kdb_serial to support memory mapped I/O. | |
1641 | + Note: This needs kdb v2.3-2.4.19-common-2 or later. | |
1642 | + * kdb v2.3-2.4.19-i386-3. | |
1643 | + | |
1644 | +2002-08-09 Keith Owens <kaos@sgi.com> | |
1645 | + | |
1646 | + * Use -fno-optimize-sibling-calls for kdb if gcc supports it. | |
1647 | + * .text.lock does not consume an activation frame. | |
1648 | + * kdb v2.3-2.4.19-i386-2. | |
1649 | + | |
1650 | +2002-08-07 Keith Owens <kaos@sgi.com> | |
1651 | + | |
1652 | + * Upgrade to 2.4.19. | |
1653 | + * Remove individual SGI copyrights, the general SGI copyright applies. | |
1654 | + * New .text.lock name. Hugh Dickins. | |
1655 | + * Set KERNEL_CS in kdba_getcurrentframe. Hugh Dickins. | |
1656 | + * Clean up disassembly layout. Hugh Dickins, Keith Owens. | |
1657 | + * Replace hard coded stack size with THREAD_SIZE. Hugh Dickins. | |
1658 | + * Better stack layout on bt with no frame pointers. Hugh Dickins. | |
1659 | + * Make i386 IO breakpoints (bpha <address> IO) work again. | |
1660 | + Martin Wilck, Keith Owens. | |
1661 | + * Remove fixed KDB_MAX_COMMANDS size. | |
1662 | + * Add set_fs() around __copy_to_user on kernel addresses. | |
1663 | + Randolph Chung. | |
1664 | + * Position i386 for CONFIG_NUMA_REPLICATE. | |
1665 | + * kdb v2.3-2.4.19-i386-1. | |
1666 | + | |
1667 | +2002-07-09 Keith Owens <kaos@sgi.com> | |
1668 | + | |
1669 | + * Upgrade to 2.4.19-rc1. | |
1670 | + | |
1671 | +2002-06-14 Keith Owens <kaos@sgi.com> | |
1672 | + | |
1673 | + * Upgrade to 2.4.19-pre10. | |
1674 | + * kdb v2.1-2.4.19-pre10-i386-1. | |
1675 | + | |
1676 | +2002-04-09 Keith Owens <kaos@sgi.com> | |
1677 | + | |
1678 | + * Upgrade to 2.4.19-pre6. | |
1679 | + * kdb v2.1-2.4.19-pre6-i386-1. | |
1680 | + | |
1681 | +2002-02-26 Keith Owens <kaos@sgi.com> | |
1682 | + | |
1683 | + * Upgrade to 2.4.18. | |
1684 | + * kdb v2.1-2.4.18-i386-1. | |
1685 | + | |
1686 | +2002-01-18 Keith Owens <kaos@sgi.com> | |
1687 | + | |
1688 | + * Use new kdb_get/put functions. | |
1689 | + * Define kdba_{get,put}area_size functions for i386. | |
1690 | + * Remove over-engineered dblist callback functions. | |
1691 | + * Correctly handle failing call disp32 in backtrace. | |
1692 | + * Remove bp_instvalid flag, redundant code. | |
1693 | + * Remove dead code. | |
1694 | + * kdb v2.1-2.4.17-i386-1. | |
1695 | + | |
1696 | +2002-01-04 Keith Owens <kaos@sgi.com> | |
1697 | + | |
1698 | + * Sync xfs <-> kdb i386 code. | |
1699 | + | |
1700 | --- /dev/null | |
1701 | +++ b/arch/x86/kdb/i386-dis.c | |
1702 | @@ -0,0 +1,4686 @@ | |
1703 | +/* Print i386 instructions for GDB, the GNU debugger. | |
1704 | + Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, | |
1705 | + 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. | |
1706 | + | |
1707 | + This file is part of GDB. | |
1708 | + | |
1709 | + This program is free software; you can redistribute it and/or modify | |
1710 | + it under the terms of the GNU General Public License as published by | |
1711 | + the Free Software Foundation; either version 2 of the License, or | |
1712 | + (at your option) any later version. | |
1713 | + | |
1714 | + This program is distributed in the hope that it will be useful, | |
1715 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
1716 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
1717 | + GNU General Public License for more details. | |
1718 | + | |
1719 | + You should have received a copy of the GNU General Public License | |
1720 | + along with this program; if not, write to the Free Software | |
1721 | + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ | |
1722 | + | |
1723 | +/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use. | |
1724 | + * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as | |
1725 | + * required. | |
1726 | + * Keith Owens <kaos@sgi.com> 15 May 2006 | |
1727 | + */ | |
1728 | + | |
1729 | +/* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu) | |
1730 | + July 1988 | |
1731 | + modified by John Hassey (hassey@dg-rtp.dg.com) | |
1732 | + x86-64 support added by Jan Hubicka (jh@suse.cz) | |
1733 | + VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */ | |
1734 | + | |
1735 | +/* The main tables describing the instructions is essentially a copy | |
1736 | + of the "Opcode Map" chapter (Appendix A) of the Intel 80386 | |
1737 | + Programmers Manual. Usually, there is a capital letter, followed | |
1738 | + by a small letter. The capital letter tell the addressing mode, | |
1739 | + and the small letter tells about the operand size. Refer to | |
1740 | + the Intel manual for details. */ | |
1741 | + | |
1742 | +#ifdef __KERNEL__ | |
1743 | +#include <linux/kernel.h> | |
1744 | +#include <linux/string.h> | |
1745 | +#include <linux/dis-asm.h> | |
1746 | +#include <linux/kdb.h> | |
1747 | +#define abort() BUG() | |
1748 | +#else /* __KERNEL__ */ | |
1749 | +#include "dis-asm.h" | |
1750 | +#include "sysdep.h" | |
1751 | +#include "opintl.h" | |
1752 | +#endif /* __KERNEL__ */ | |
1753 | + | |
1754 | +#define MAXLEN 20 | |
1755 | + | |
1756 | +#ifndef __KERNEL__ | |
1757 | +#include <setjmp.h> | |
1758 | +#endif /* __KERNEL__ */ | |
1759 | + | |
1760 | +#ifndef UNIXWARE_COMPAT | |
1761 | +/* Set non-zero for broken, compatible instructions. Set to zero for | |
1762 | + non-broken opcodes. */ | |
1763 | +#define UNIXWARE_COMPAT 1 | |
1764 | +#endif | |
1765 | + | |
1766 | +static int fetch_data (struct disassemble_info *, bfd_byte *); | |
1767 | +static void ckprefix (void); | |
1768 | +static const char *prefix_name (int, int); | |
1769 | +static int print_insn (bfd_vma, disassemble_info *); | |
1770 | +static void dofloat (int); | |
1771 | +static void OP_ST (int, int); | |
1772 | +static void OP_STi (int, int); | |
1773 | +static int putop (const char *, int); | |
1774 | +static void oappend (const char *); | |
1775 | +static void append_seg (void); | |
1776 | +static void OP_indirE (int, int); | |
1777 | +static void print_operand_value (char *, int, bfd_vma); | |
1778 | +static void OP_E (int, int); | |
1779 | +static void OP_G (int, int); | |
1780 | +static bfd_vma get64 (void); | |
1781 | +static bfd_signed_vma get32 (void); | |
1782 | +static bfd_signed_vma get32s (void); | |
1783 | +static int get16 (void); | |
1784 | +static void set_op (bfd_vma, int); | |
1785 | +static void OP_REG (int, int); | |
1786 | +static void OP_IMREG (int, int); | |
1787 | +static void OP_I (int, int); | |
1788 | +static void OP_I64 (int, int); | |
1789 | +static void OP_sI (int, int); | |
1790 | +static void OP_J (int, int); | |
1791 | +static void OP_SEG (int, int); | |
1792 | +static void OP_DIR (int, int); | |
1793 | +static void OP_OFF (int, int); | |
1794 | +static void OP_OFF64 (int, int); | |
1795 | +static void ptr_reg (int, int); | |
1796 | +static void OP_ESreg (int, int); | |
1797 | +static void OP_DSreg (int, int); | |
1798 | +static void OP_C (int, int); | |
1799 | +static void OP_D (int, int); | |
1800 | +static void OP_T (int, int); | |
1801 | +static void OP_Rd (int, int); | |
1802 | +static void OP_MMX (int, int); | |
1803 | +static void OP_XMM (int, int); | |
1804 | +static void OP_EM (int, int); | |
1805 | +static void OP_EX (int, int); | |
1806 | +static void OP_MS (int, int); | |
1807 | +static void OP_XS (int, int); | |
1808 | +static void OP_M (int, int); | |
1809 | +static void OP_VMX (int, int); | |
1810 | +static void OP_0fae (int, int); | |
1811 | +static void OP_0f07 (int, int); | |
1812 | +static void NOP_Fixup (int, int); | |
1813 | +static void OP_3DNowSuffix (int, int); | |
1814 | +static void OP_SIMD_Suffix (int, int); | |
1815 | +static void SIMD_Fixup (int, int); | |
1816 | +static void PNI_Fixup (int, int); | |
1817 | +static void SVME_Fixup (int, int); | |
1818 | +static void INVLPG_Fixup (int, int); | |
1819 | +static void BadOp (void); | |
1820 | +static void SEG_Fixup (int, int); | |
1821 | +static void VMX_Fixup (int, int); | |
1822 | + | |
1823 | +struct dis_private { | |
1824 | + /* Points to first byte not fetched. */ | |
1825 | + bfd_byte *max_fetched; | |
1826 | + bfd_byte the_buffer[MAXLEN]; | |
1827 | + bfd_vma insn_start; | |
1828 | + int orig_sizeflag; | |
1829 | +#ifndef __KERNEL__ | |
1830 | + jmp_buf bailout; | |
1831 | +#endif /* __KERNEL__ */ | |
1832 | +}; | |
1833 | + | |
1834 | +/* The opcode for the fwait instruction, which we treat as a prefix | |
1835 | + when we can. */ | |
1836 | +#define FWAIT_OPCODE (0x9b) | |
1837 | + | |
1838 | +/* Set to 1 for 64bit mode disassembly. */ | |
1839 | +static int mode_64bit; | |
1840 | + | |
1841 | +/* Flags for the prefixes for the current instruction. See below. */ | |
1842 | +static int prefixes; | |
1843 | + | |
1844 | +/* REX prefix the current instruction. See below. */ | |
1845 | +static int rex; | |
1846 | +/* Bits of REX we've already used. */ | |
1847 | +static int rex_used; | |
1848 | +#define REX_MODE64 8 | |
1849 | +#define REX_EXTX 4 | |
1850 | +#define REX_EXTY 2 | |
1851 | +#define REX_EXTZ 1 | |
1852 | +/* Mark parts used in the REX prefix. When we are testing for | |
1853 | + empty prefix (for 8bit register REX extension), just mask it | |
1854 | + out. Otherwise test for REX bit is excuse for existence of REX | |
1855 | + only in case value is nonzero. */ | |
1856 | +#define USED_REX(value) \ | |
1857 | + { \ | |
1858 | + if (value) \ | |
1859 | + rex_used |= (rex & value) ? (value) | 0x40 : 0; \ | |
1860 | + else \ | |
1861 | + rex_used |= 0x40; \ | |
1862 | + } | |
1863 | + | |
1864 | +/* Flags for prefixes which we somehow handled when printing the | |
1865 | + current instruction. */ | |
1866 | +static int used_prefixes; | |
1867 | + | |
1868 | +/* Flags stored in PREFIXES. */ | |
1869 | +#define PREFIX_REPZ 1 | |
1870 | +#define PREFIX_REPNZ 2 | |
1871 | +#define PREFIX_LOCK 4 | |
1872 | +#define PREFIX_CS 8 | |
1873 | +#define PREFIX_SS 0x10 | |
1874 | +#define PREFIX_DS 0x20 | |
1875 | +#define PREFIX_ES 0x40 | |
1876 | +#define PREFIX_FS 0x80 | |
1877 | +#define PREFIX_GS 0x100 | |
1878 | +#define PREFIX_DATA 0x200 | |
1879 | +#define PREFIX_ADDR 0x400 | |
1880 | +#define PREFIX_FWAIT 0x800 | |
1881 | + | |
1882 | +/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) | |
1883 | + to ADDR (exclusive) are valid. Returns 1 for success, longjmps | |
1884 | + on error. */ | |
1885 | +#define FETCH_DATA(info, addr) \ | |
1886 | + ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \ | |
1887 | + ? 1 : fetch_data ((info), (addr))) | |
1888 | + | |
1889 | +static int | |
1890 | +fetch_data (struct disassemble_info *info, bfd_byte *addr) | |
1891 | +{ | |
1892 | + int status; | |
1893 | + struct dis_private *priv = (struct dis_private *) info->private_data; | |
1894 | + bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer); | |
1895 | + | |
1896 | + status = (*info->read_memory_func) (start, | |
1897 | + priv->max_fetched, | |
1898 | + addr - priv->max_fetched, | |
1899 | + info); | |
1900 | + if (status != 0) | |
1901 | + { | |
1902 | + /* If we did manage to read at least one byte, then | |
1903 | + print_insn_i386 will do something sensible. Otherwise, print | |
1904 | + an error. We do that here because this is where we know | |
1905 | + STATUS. */ | |
1906 | + if (priv->max_fetched == priv->the_buffer) | |
1907 | + (*info->memory_error_func) (status, start, info); | |
1908 | +#ifndef __KERNEL__ | |
1909 | + longjmp (priv->bailout, 1); | |
1910 | +#else /* __KERNEL__ */ | |
1911 | + /* XXX - what to do? */ | |
1912 | + kdb_printf("Hmm. longjmp.\n"); | |
1913 | +#endif /* __KERNEL__ */ | |
1914 | + } | |
1915 | + else | |
1916 | + priv->max_fetched = addr; | |
1917 | + return 1; | |
1918 | +} | |
1919 | + | |
1920 | +#define XX NULL, 0 | |
1921 | + | |
1922 | +#define Eb OP_E, b_mode | |
1923 | +#define Ev OP_E, v_mode | |
1924 | +#define Ed OP_E, d_mode | |
1925 | +#define Eq OP_E, q_mode | |
1926 | +#define Edq OP_E, dq_mode | |
1927 | +#define Edqw OP_E, dqw_mode | |
1928 | +#define indirEv OP_indirE, branch_v_mode | |
1929 | +#define indirEp OP_indirE, f_mode | |
1930 | +#define Em OP_E, m_mode | |
1931 | +#define Ew OP_E, w_mode | |
1932 | +#define Ma OP_E, v_mode | |
1933 | +#define M OP_M, 0 /* lea, lgdt, etc. */ | |
1934 | +#define Mp OP_M, f_mode /* 32 or 48 bit memory operand for LDS, LES etc */ | |
1935 | +#define Gb OP_G, b_mode | |
1936 | +#define Gv OP_G, v_mode | |
1937 | +#define Gd OP_G, d_mode | |
1938 | +#define Gdq OP_G, dq_mode | |
1939 | +#define Gm OP_G, m_mode | |
1940 | +#define Gw OP_G, w_mode | |
1941 | +#define Rd OP_Rd, d_mode | |
1942 | +#define Rm OP_Rd, m_mode | |
1943 | +#define Ib OP_I, b_mode | |
1944 | +#define sIb OP_sI, b_mode /* sign extened byte */ | |
1945 | +#define Iv OP_I, v_mode | |
1946 | +#define Iq OP_I, q_mode | |
1947 | +#define Iv64 OP_I64, v_mode | |
1948 | +#define Iw OP_I, w_mode | |
1949 | +#define I1 OP_I, const_1_mode | |
1950 | +#define Jb OP_J, b_mode | |
1951 | +#define Jv OP_J, v_mode | |
1952 | +#define Cm OP_C, m_mode | |
1953 | +#define Dm OP_D, m_mode | |
1954 | +#define Td OP_T, d_mode | |
1955 | +#define Sv SEG_Fixup, v_mode | |
1956 | + | |
1957 | +#define RMeAX OP_REG, eAX_reg | |
1958 | +#define RMeBX OP_REG, eBX_reg | |
1959 | +#define RMeCX OP_REG, eCX_reg | |
1960 | +#define RMeDX OP_REG, eDX_reg | |
1961 | +#define RMeSP OP_REG, eSP_reg | |
1962 | +#define RMeBP OP_REG, eBP_reg | |
1963 | +#define RMeSI OP_REG, eSI_reg | |
1964 | +#define RMeDI OP_REG, eDI_reg | |
1965 | +#define RMrAX OP_REG, rAX_reg | |
1966 | +#define RMrBX OP_REG, rBX_reg | |
1967 | +#define RMrCX OP_REG, rCX_reg | |
1968 | +#define RMrDX OP_REG, rDX_reg | |
1969 | +#define RMrSP OP_REG, rSP_reg | |
1970 | +#define RMrBP OP_REG, rBP_reg | |
1971 | +#define RMrSI OP_REG, rSI_reg | |
1972 | +#define RMrDI OP_REG, rDI_reg | |
1973 | +#define RMAL OP_REG, al_reg | |
1974 | +#define RMAL OP_REG, al_reg | |
1975 | +#define RMCL OP_REG, cl_reg | |
1976 | +#define RMDL OP_REG, dl_reg | |
1977 | +#define RMBL OP_REG, bl_reg | |
1978 | +#define RMAH OP_REG, ah_reg | |
1979 | +#define RMCH OP_REG, ch_reg | |
1980 | +#define RMDH OP_REG, dh_reg | |
1981 | +#define RMBH OP_REG, bh_reg | |
1982 | +#define RMAX OP_REG, ax_reg | |
1983 | +#define RMDX OP_REG, dx_reg | |
1984 | + | |
1985 | +#define eAX OP_IMREG, eAX_reg | |
1986 | +#define eBX OP_IMREG, eBX_reg | |
1987 | +#define eCX OP_IMREG, eCX_reg | |
1988 | +#define eDX OP_IMREG, eDX_reg | |
1989 | +#define eSP OP_IMREG, eSP_reg | |
1990 | +#define eBP OP_IMREG, eBP_reg | |
1991 | +#define eSI OP_IMREG, eSI_reg | |
1992 | +#define eDI OP_IMREG, eDI_reg | |
1993 | +#define AL OP_IMREG, al_reg | |
1994 | +#define AL OP_IMREG, al_reg | |
1995 | +#define CL OP_IMREG, cl_reg | |
1996 | +#define DL OP_IMREG, dl_reg | |
1997 | +#define BL OP_IMREG, bl_reg | |
1998 | +#define AH OP_IMREG, ah_reg | |
1999 | +#define CH OP_IMREG, ch_reg | |
2000 | +#define DH OP_IMREG, dh_reg | |
2001 | +#define BH OP_IMREG, bh_reg | |
2002 | +#define AX OP_IMREG, ax_reg | |
2003 | +#define DX OP_IMREG, dx_reg | |
2004 | +#define indirDX OP_IMREG, indir_dx_reg | |
2005 | + | |
2006 | +#define Sw OP_SEG, w_mode | |
2007 | +#define Ap OP_DIR, 0 | |
2008 | +#define Ob OP_OFF, b_mode | |
2009 | +#define Ob64 OP_OFF64, b_mode | |
2010 | +#define Ov OP_OFF, v_mode | |
2011 | +#define Ov64 OP_OFF64, v_mode | |
2012 | +#define Xb OP_DSreg, eSI_reg | |
2013 | +#define Xv OP_DSreg, eSI_reg | |
2014 | +#define Yb OP_ESreg, eDI_reg | |
2015 | +#define Yv OP_ESreg, eDI_reg | |
2016 | +#define DSBX OP_DSreg, eBX_reg | |
2017 | + | |
2018 | +#define es OP_REG, es_reg | |
2019 | +#define ss OP_REG, ss_reg | |
2020 | +#define cs OP_REG, cs_reg | |
2021 | +#define ds OP_REG, ds_reg | |
2022 | +#define fs OP_REG, fs_reg | |
2023 | +#define gs OP_REG, gs_reg | |
2024 | + | |
2025 | +#define MX OP_MMX, 0 | |
2026 | +#define XM OP_XMM, 0 | |
2027 | +#define EM OP_EM, v_mode | |
2028 | +#define EX OP_EX, v_mode | |
2029 | +#define MS OP_MS, v_mode | |
2030 | +#define XS OP_XS, v_mode | |
2031 | +#define VM OP_VMX, q_mode | |
2032 | +#define OPSUF OP_3DNowSuffix, 0 | |
2033 | +#define OPSIMD OP_SIMD_Suffix, 0 | |
2034 | + | |
2035 | +#define cond_jump_flag NULL, cond_jump_mode | |
2036 | +#define loop_jcxz_flag NULL, loop_jcxz_mode | |
2037 | + | |
2038 | +/* bits in sizeflag */ | |
2039 | +#define SUFFIX_ALWAYS 4 | |
2040 | +#define AFLAG 2 | |
2041 | +#define DFLAG 1 | |
2042 | + | |
2043 | +#define b_mode 1 /* byte operand */ | |
2044 | +#define v_mode 2 /* operand size depends on prefixes */ | |
2045 | +#define w_mode 3 /* word operand */ | |
2046 | +#define d_mode 4 /* double word operand */ | |
2047 | +#define q_mode 5 /* quad word operand */ | |
2048 | +#define t_mode 6 /* ten-byte operand */ | |
2049 | +#define x_mode 7 /* 16-byte XMM operand */ | |
2050 | +#define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */ | |
2051 | +#define cond_jump_mode 9 | |
2052 | +#define loop_jcxz_mode 10 | |
2053 | +#define dq_mode 11 /* operand size depends on REX prefixes. */ | |
2054 | +#define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */ | |
2055 | +#define f_mode 13 /* 4- or 6-byte pointer operand */ | |
2056 | +#define const_1_mode 14 | |
2057 | +#define branch_v_mode 15 /* v_mode for branch. */ | |
2058 | + | |
2059 | +#define es_reg 100 | |
2060 | +#define cs_reg 101 | |
2061 | +#define ss_reg 102 | |
2062 | +#define ds_reg 103 | |
2063 | +#define fs_reg 104 | |
2064 | +#define gs_reg 105 | |
2065 | + | |
2066 | +#define eAX_reg 108 | |
2067 | +#define eCX_reg 109 | |
2068 | +#define eDX_reg 110 | |
2069 | +#define eBX_reg 111 | |
2070 | +#define eSP_reg 112 | |
2071 | +#define eBP_reg 113 | |
2072 | +#define eSI_reg 114 | |
2073 | +#define eDI_reg 115 | |
2074 | + | |
2075 | +#define al_reg 116 | |
2076 | +#define cl_reg 117 | |
2077 | +#define dl_reg 118 | |
2078 | +#define bl_reg 119 | |
2079 | +#define ah_reg 120 | |
2080 | +#define ch_reg 121 | |
2081 | +#define dh_reg 122 | |
2082 | +#define bh_reg 123 | |
2083 | + | |
2084 | +#define ax_reg 124 | |
2085 | +#define cx_reg 125 | |
2086 | +#define dx_reg 126 | |
2087 | +#define bx_reg 127 | |
2088 | +#define sp_reg 128 | |
2089 | +#define bp_reg 129 | |
2090 | +#define si_reg 130 | |
2091 | +#define di_reg 131 | |
2092 | + | |
2093 | +#define rAX_reg 132 | |
2094 | +#define rCX_reg 133 | |
2095 | +#define rDX_reg 134 | |
2096 | +#define rBX_reg 135 | |
2097 | +#define rSP_reg 136 | |
2098 | +#define rBP_reg 137 | |
2099 | +#define rSI_reg 138 | |
2100 | +#define rDI_reg 139 | |
2101 | + | |
2102 | +#define indir_dx_reg 150 | |
2103 | + | |
2104 | +#define FLOATCODE 1 | |
2105 | +#define USE_GROUPS 2 | |
2106 | +#define USE_PREFIX_USER_TABLE 3 | |
2107 | +#define X86_64_SPECIAL 4 | |
2108 | + | |
2109 | +#define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0 | |
2110 | + | |
2111 | +#define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0 | |
2112 | +#define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0 | |
2113 | +#define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0 | |
2114 | +#define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0 | |
2115 | +#define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0 | |
2116 | +#define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0 | |
2117 | +#define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0 | |
2118 | +#define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0 | |
2119 | +#define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0 | |
2120 | +#define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0 | |
2121 | +#define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0 | |
2122 | +#define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0 | |
2123 | +#define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0 | |
2124 | +#define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0 | |
2125 | +#define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0 | |
2126 | +#define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0 | |
2127 | +#define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0 | |
2128 | +#define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0 | |
2129 | +#define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0 | |
2130 | +#define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0 | |
2131 | +#define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0 | |
2132 | +#define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0 | |
2133 | +#define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0 | |
2134 | +#define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0 | |
2135 | +#define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0 | |
2136 | + | |
2137 | +#define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0 | |
2138 | +#define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0 | |
2139 | +#define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0 | |
2140 | +#define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0 | |
2141 | +#define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0 | |
2142 | +#define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0 | |
2143 | +#define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0 | |
2144 | +#define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0 | |
2145 | +#define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0 | |
2146 | +#define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0 | |
2147 | +#define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0 | |
2148 | +#define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0 | |
2149 | +#define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0 | |
2150 | +#define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0 | |
2151 | +#define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0 | |
2152 | +#define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0 | |
2153 | +#define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0 | |
2154 | +#define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0 | |
2155 | +#define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0 | |
2156 | +#define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0 | |
2157 | +#define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0 | |
2158 | +#define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0 | |
2159 | +#define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0 | |
2160 | +#define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0 | |
2161 | +#define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0 | |
2162 | +#define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0 | |
2163 | +#define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0 | |
2164 | +#define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0 | |
2165 | +#define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0 | |
2166 | +#define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0 | |
2167 | +#define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0 | |
2168 | +#define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0 | |
2169 | +#define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0 | |
2170 | + | |
2171 | +#define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0 | |
2172 | + | |
2173 | +typedef void (*op_rtn) (int bytemode, int sizeflag); | |
2174 | + | |
2175 | +struct dis386 { | |
2176 | + const char *name; | |
2177 | + op_rtn op1; | |
2178 | + int bytemode1; | |
2179 | + op_rtn op2; | |
2180 | + int bytemode2; | |
2181 | + op_rtn op3; | |
2182 | + int bytemode3; | |
2183 | +}; | |
2184 | + | |
2185 | +/* Upper case letters in the instruction names here are macros. | |
2186 | + 'A' => print 'b' if no register operands or suffix_always is true | |
2187 | + 'B' => print 'b' if suffix_always is true | |
2188 | + 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand | |
2189 | + . size prefix | |
2190 | + 'E' => print 'e' if 32-bit form of jcxz | |
2191 | + 'F' => print 'w' or 'l' depending on address size prefix (loop insns) | |
2192 | + 'H' => print ",pt" or ",pn" branch hint | |
2193 | + 'I' => honor following macro letter even in Intel mode (implemented only | |
2194 | + . for some of the macro letters) | |
2195 | + 'J' => print 'l' | |
2196 | + 'L' => print 'l' if suffix_always is true | |
2197 | + 'N' => print 'n' if instruction has no wait "prefix" | |
2198 | + 'O' => print 'd', or 'o' | |
2199 | + 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix, | |
2200 | + . or suffix_always is true. print 'q' if rex prefix is present. | |
2201 | + 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always | |
2202 | + . is true | |
2203 | + 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode) | |
2204 | + 'S' => print 'w', 'l' or 'q' if suffix_always is true | |
2205 | + 'T' => print 'q' in 64bit mode and behave as 'P' otherwise | |
2206 | + 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise | |
2207 | + 'W' => print 'b' or 'w' ("w" or "de" in intel mode) | |
2208 | + 'X' => print 's', 'd' depending on data16 prefix (for XMM) | |
2209 | + 'Y' => 'q' if instruction has an REX 64bit overwrite prefix | |
2210 | + | |
2211 | + Many of the above letters print nothing in Intel mode. See "putop" | |
2212 | + for the details. | |
2213 | + | |
2214 | + Braces '{' and '}', and vertical bars '|', indicate alternative | |
2215 | + mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel | |
2216 | + modes. In cases where there are only two alternatives, the X86_64 | |
2217 | + instruction is reserved, and "(bad)" is printed. | |
2218 | +*/ | |
2219 | + | |
2220 | +static const struct dis386 dis386[] = { | |
2221 | + /* 00 */ | |
2222 | + { "addB", Eb, Gb, XX }, | |
2223 | + { "addS", Ev, Gv, XX }, | |
2224 | + { "addB", Gb, Eb, XX }, | |
2225 | + { "addS", Gv, Ev, XX }, | |
2226 | + { "addB", AL, Ib, XX }, | |
2227 | + { "addS", eAX, Iv, XX }, | |
2228 | + { "push{T|}", es, XX, XX }, | |
2229 | + { "pop{T|}", es, XX, XX }, | |
2230 | + /* 08 */ | |
2231 | + { "orB", Eb, Gb, XX }, | |
2232 | + { "orS", Ev, Gv, XX }, | |
2233 | + { "orB", Gb, Eb, XX }, | |
2234 | + { "orS", Gv, Ev, XX }, | |
2235 | + { "orB", AL, Ib, XX }, | |
2236 | + { "orS", eAX, Iv, XX }, | |
2237 | + { "push{T|}", cs, XX, XX }, | |
2238 | + { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */ | |
2239 | + /* 10 */ | |
2240 | + { "adcB", Eb, Gb, XX }, | |
2241 | + { "adcS", Ev, Gv, XX }, | |
2242 | + { "adcB", Gb, Eb, XX }, | |
2243 | + { "adcS", Gv, Ev, XX }, | |
2244 | + { "adcB", AL, Ib, XX }, | |
2245 | + { "adcS", eAX, Iv, XX }, | |
2246 | + { "push{T|}", ss, XX, XX }, | |
2247 | + { "popT|}", ss, XX, XX }, | |
2248 | + /* 18 */ | |
2249 | + { "sbbB", Eb, Gb, XX }, | |
2250 | + { "sbbS", Ev, Gv, XX }, | |
2251 | + { "sbbB", Gb, Eb, XX }, | |
2252 | + { "sbbS", Gv, Ev, XX }, | |
2253 | + { "sbbB", AL, Ib, XX }, | |
2254 | + { "sbbS", eAX, Iv, XX }, | |
2255 | + { "push{T|}", ds, XX, XX }, | |
2256 | + { "pop{T|}", ds, XX, XX }, | |
2257 | + /* 20 */ | |
2258 | + { "andB", Eb, Gb, XX }, | |
2259 | + { "andS", Ev, Gv, XX }, | |
2260 | + { "andB", Gb, Eb, XX }, | |
2261 | + { "andS", Gv, Ev, XX }, | |
2262 | + { "andB", AL, Ib, XX }, | |
2263 | + { "andS", eAX, Iv, XX }, | |
2264 | + { "(bad)", XX, XX, XX }, /* SEG ES prefix */ | |
2265 | + { "daa{|}", XX, XX, XX }, | |
2266 | + /* 28 */ | |
2267 | + { "subB", Eb, Gb, XX }, | |
2268 | + { "subS", Ev, Gv, XX }, | |
2269 | + { "subB", Gb, Eb, XX }, | |
2270 | + { "subS", Gv, Ev, XX }, | |
2271 | + { "subB", AL, Ib, XX }, | |
2272 | + { "subS", eAX, Iv, XX }, | |
2273 | + { "(bad)", XX, XX, XX }, /* SEG CS prefix */ | |
2274 | + { "das{|}", XX, XX, XX }, | |
2275 | + /* 30 */ | |
2276 | + { "xorB", Eb, Gb, XX }, | |
2277 | + { "xorS", Ev, Gv, XX }, | |
2278 | + { "xorB", Gb, Eb, XX }, | |
2279 | + { "xorS", Gv, Ev, XX }, | |
2280 | + { "xorB", AL, Ib, XX }, | |
2281 | + { "xorS", eAX, Iv, XX }, | |
2282 | + { "(bad)", XX, XX, XX }, /* SEG SS prefix */ | |
2283 | + { "aaa{|}", XX, XX, XX }, | |
2284 | + /* 38 */ | |
2285 | + { "cmpB", Eb, Gb, XX }, | |
2286 | + { "cmpS", Ev, Gv, XX }, | |
2287 | + { "cmpB", Gb, Eb, XX }, | |
2288 | + { "cmpS", Gv, Ev, XX }, | |
2289 | + { "cmpB", AL, Ib, XX }, | |
2290 | + { "cmpS", eAX, Iv, XX }, | |
2291 | + { "(bad)", XX, XX, XX }, /* SEG DS prefix */ | |
2292 | + { "aas{|}", XX, XX, XX }, | |
2293 | + /* 40 */ | |
2294 | + { "inc{S|}", RMeAX, XX, XX }, | |
2295 | + { "inc{S|}", RMeCX, XX, XX }, | |
2296 | + { "inc{S|}", RMeDX, XX, XX }, | |
2297 | + { "inc{S|}", RMeBX, XX, XX }, | |
2298 | + { "inc{S|}", RMeSP, XX, XX }, | |
2299 | + { "inc{S|}", RMeBP, XX, XX }, | |
2300 | + { "inc{S|}", RMeSI, XX, XX }, | |
2301 | + { "inc{S|}", RMeDI, XX, XX }, | |
2302 | + /* 48 */ | |
2303 | + { "dec{S|}", RMeAX, XX, XX }, | |
2304 | + { "dec{S|}", RMeCX, XX, XX }, | |
2305 | + { "dec{S|}", RMeDX, XX, XX }, | |
2306 | + { "dec{S|}", RMeBX, XX, XX }, | |
2307 | + { "dec{S|}", RMeSP, XX, XX }, | |
2308 | + { "dec{S|}", RMeBP, XX, XX }, | |
2309 | + { "dec{S|}", RMeSI, XX, XX }, | |
2310 | + { "dec{S|}", RMeDI, XX, XX }, | |
2311 | + /* 50 */ | |
2312 | + { "pushS", RMrAX, XX, XX }, | |
2313 | + { "pushS", RMrCX, XX, XX }, | |
2314 | + { "pushS", RMrDX, XX, XX }, | |
2315 | + { "pushS", RMrBX, XX, XX }, | |
2316 | + { "pushS", RMrSP, XX, XX }, | |
2317 | + { "pushS", RMrBP, XX, XX }, | |
2318 | + { "pushS", RMrSI, XX, XX }, | |
2319 | + { "pushS", RMrDI, XX, XX }, | |
2320 | + /* 58 */ | |
2321 | + { "popS", RMrAX, XX, XX }, | |
2322 | + { "popS", RMrCX, XX, XX }, | |
2323 | + { "popS", RMrDX, XX, XX }, | |
2324 | + { "popS", RMrBX, XX, XX }, | |
2325 | + { "popS", RMrSP, XX, XX }, | |
2326 | + { "popS", RMrBP, XX, XX }, | |
2327 | + { "popS", RMrSI, XX, XX }, | |
2328 | + { "popS", RMrDI, XX, XX }, | |
2329 | + /* 60 */ | |
2330 | + { "pusha{P|}", XX, XX, XX }, | |
2331 | + { "popa{P|}", XX, XX, XX }, | |
2332 | + { "bound{S|}", Gv, Ma, XX }, | |
2333 | + { X86_64_0 }, | |
2334 | + { "(bad)", XX, XX, XX }, /* seg fs */ | |
2335 | + { "(bad)", XX, XX, XX }, /* seg gs */ | |
2336 | + { "(bad)", XX, XX, XX }, /* op size prefix */ | |
2337 | + { "(bad)", XX, XX, XX }, /* adr size prefix */ | |
2338 | + /* 68 */ | |
2339 | + { "pushT", Iq, XX, XX }, | |
2340 | + { "imulS", Gv, Ev, Iv }, | |
2341 | + { "pushT", sIb, XX, XX }, | |
2342 | + { "imulS", Gv, Ev, sIb }, | |
2343 | + { "ins{b||b|}", Yb, indirDX, XX }, | |
2344 | + { "ins{R||R|}", Yv, indirDX, XX }, | |
2345 | + { "outs{b||b|}", indirDX, Xb, XX }, | |
2346 | + { "outs{R||R|}", indirDX, Xv, XX }, | |
2347 | + /* 70 */ | |
2348 | + { "joH", Jb, XX, cond_jump_flag }, | |
2349 | + { "jnoH", Jb, XX, cond_jump_flag }, | |
2350 | + { "jbH", Jb, XX, cond_jump_flag }, | |
2351 | + { "jaeH", Jb, XX, cond_jump_flag }, | |
2352 | + { "jeH", Jb, XX, cond_jump_flag }, | |
2353 | + { "jneH", Jb, XX, cond_jump_flag }, | |
2354 | + { "jbeH", Jb, XX, cond_jump_flag }, | |
2355 | + { "jaH", Jb, XX, cond_jump_flag }, | |
2356 | + /* 78 */ | |
2357 | + { "jsH", Jb, XX, cond_jump_flag }, | |
2358 | + { "jnsH", Jb, XX, cond_jump_flag }, | |
2359 | + { "jpH", Jb, XX, cond_jump_flag }, | |
2360 | + { "jnpH", Jb, XX, cond_jump_flag }, | |
2361 | + { "jlH", Jb, XX, cond_jump_flag }, | |
2362 | + { "jgeH", Jb, XX, cond_jump_flag }, | |
2363 | + { "jleH", Jb, XX, cond_jump_flag }, | |
2364 | + { "jgH", Jb, XX, cond_jump_flag }, | |
2365 | + /* 80 */ | |
2366 | + { GRP1b }, | |
2367 | + { GRP1S }, | |
2368 | + { "(bad)", XX, XX, XX }, | |
2369 | + { GRP1Ss }, | |
2370 | + { "testB", Eb, Gb, XX }, | |
2371 | + { "testS", Ev, Gv, XX }, | |
2372 | + { "xchgB", Eb, Gb, XX }, | |
2373 | + { "xchgS", Ev, Gv, XX }, | |
2374 | + /* 88 */ | |
2375 | + { "movB", Eb, Gb, XX }, | |
2376 | + { "movS", Ev, Gv, XX }, | |
2377 | + { "movB", Gb, Eb, XX }, | |
2378 | + { "movS", Gv, Ev, XX }, | |
2379 | + { "movQ", Sv, Sw, XX }, | |
2380 | + { "leaS", Gv, M, XX }, | |
2381 | + { "movQ", Sw, Sv, XX }, | |
2382 | + { "popU", Ev, XX, XX }, | |
2383 | + /* 90 */ | |
2384 | + { "nop", NOP_Fixup, 0, XX, XX }, | |
2385 | + { "xchgS", RMeCX, eAX, XX }, | |
2386 | + { "xchgS", RMeDX, eAX, XX }, | |
2387 | + { "xchgS", RMeBX, eAX, XX }, | |
2388 | + { "xchgS", RMeSP, eAX, XX }, | |
2389 | + { "xchgS", RMeBP, eAX, XX }, | |
2390 | + { "xchgS", RMeSI, eAX, XX }, | |
2391 | + { "xchgS", RMeDI, eAX, XX }, | |
2392 | + /* 98 */ | |
2393 | + { "cW{tR||tR|}", XX, XX, XX }, | |
2394 | + { "cR{tO||tO|}", XX, XX, XX }, | |
2395 | + { "Jcall{T|}", Ap, XX, XX }, | |
2396 | + { "(bad)", XX, XX, XX }, /* fwait */ | |
2397 | + { "pushfT", XX, XX, XX }, | |
2398 | + { "popfT", XX, XX, XX }, | |
2399 | + { "sahf{|}", XX, XX, XX }, | |
2400 | + { "lahf{|}", XX, XX, XX }, | |
2401 | + /* a0 */ | |
2402 | + { "movB", AL, Ob64, XX }, | |
2403 | + { "movS", eAX, Ov64, XX }, | |
2404 | + { "movB", Ob64, AL, XX }, | |
2405 | + { "movS", Ov64, eAX, XX }, | |
2406 | + { "movs{b||b|}", Yb, Xb, XX }, | |
2407 | + { "movs{R||R|}", Yv, Xv, XX }, | |
2408 | + { "cmps{b||b|}", Xb, Yb, XX }, | |
2409 | + { "cmps{R||R|}", Xv, Yv, XX }, | |
2410 | + /* a8 */ | |
2411 | + { "testB", AL, Ib, XX }, | |
2412 | + { "testS", eAX, Iv, XX }, | |
2413 | + { "stosB", Yb, AL, XX }, | |
2414 | + { "stosS", Yv, eAX, XX }, | |
2415 | + { "lodsB", AL, Xb, XX }, | |
2416 | + { "lodsS", eAX, Xv, XX }, | |
2417 | + { "scasB", AL, Yb, XX }, | |
2418 | + { "scasS", eAX, Yv, XX }, | |
2419 | + /* b0 */ | |
2420 | + { "movB", RMAL, Ib, XX }, | |
2421 | + { "movB", RMCL, Ib, XX }, | |
2422 | + { "movB", RMDL, Ib, XX }, | |
2423 | + { "movB", RMBL, Ib, XX }, | |
2424 | + { "movB", RMAH, Ib, XX }, | |
2425 | + { "movB", RMCH, Ib, XX }, | |
2426 | + { "movB", RMDH, Ib, XX }, | |
2427 | + { "movB", RMBH, Ib, XX }, | |
2428 | + /* b8 */ | |
2429 | + { "movS", RMeAX, Iv64, XX }, | |
2430 | + { "movS", RMeCX, Iv64, XX }, | |
2431 | + { "movS", RMeDX, Iv64, XX }, | |
2432 | + { "movS", RMeBX, Iv64, XX }, | |
2433 | + { "movS", RMeSP, Iv64, XX }, | |
2434 | + { "movS", RMeBP, Iv64, XX }, | |
2435 | + { "movS", RMeSI, Iv64, XX }, | |
2436 | + { "movS", RMeDI, Iv64, XX }, | |
2437 | + /* c0 */ | |
2438 | + { GRP2b }, | |
2439 | + { GRP2S }, | |
2440 | + { "retT", Iw, XX, XX }, | |
2441 | + { "retT", XX, XX, XX }, | |
2442 | + { "les{S|}", Gv, Mp, XX }, | |
2443 | + { "ldsS", Gv, Mp, XX }, | |
2444 | + { "movA", Eb, Ib, XX }, | |
2445 | + { "movQ", Ev, Iv, XX }, | |
2446 | + /* c8 */ | |
2447 | + { "enterT", Iw, Ib, XX }, | |
2448 | + { "leaveT", XX, XX, XX }, | |
2449 | + { "lretP", Iw, XX, XX }, | |
2450 | + { "lretP", XX, XX, XX }, | |
2451 | + { "int3", XX, XX, XX }, | |
2452 | + { "int", Ib, XX, XX }, | |
2453 | + { "into{|}", XX, XX, XX }, | |
2454 | + { "iretP", XX, XX, XX }, | |
2455 | + /* d0 */ | |
2456 | + { GRP2b_one }, | |
2457 | + { GRP2S_one }, | |
2458 | + { GRP2b_cl }, | |
2459 | + { GRP2S_cl }, | |
2460 | + { "aam{|}", sIb, XX, XX }, | |
2461 | + { "aad{|}", sIb, XX, XX }, | |
2462 | + { "(bad)", XX, XX, XX }, | |
2463 | + { "xlat", DSBX, XX, XX }, | |
2464 | + /* d8 */ | |
2465 | + { FLOAT }, | |
2466 | + { FLOAT }, | |
2467 | + { FLOAT }, | |
2468 | + { FLOAT }, | |
2469 | + { FLOAT }, | |
2470 | + { FLOAT }, | |
2471 | + { FLOAT }, | |
2472 | + { FLOAT }, | |
2473 | + /* e0 */ | |
2474 | + { "loopneFH", Jb, XX, loop_jcxz_flag }, | |
2475 | + { "loopeFH", Jb, XX, loop_jcxz_flag }, | |
2476 | + { "loopFH", Jb, XX, loop_jcxz_flag }, | |
2477 | + { "jEcxzH", Jb, XX, loop_jcxz_flag }, | |
2478 | + { "inB", AL, Ib, XX }, | |
2479 | + { "inS", eAX, Ib, XX }, | |
2480 | + { "outB", Ib, AL, XX }, | |
2481 | + { "outS", Ib, eAX, XX }, | |
2482 | + /* e8 */ | |
2483 | + { "callT", Jv, XX, XX }, | |
2484 | + { "jmpT", Jv, XX, XX }, | |
2485 | + { "Jjmp{T|}", Ap, XX, XX }, | |
2486 | + { "jmp", Jb, XX, XX }, | |
2487 | + { "inB", AL, indirDX, XX }, | |
2488 | + { "inS", eAX, indirDX, XX }, | |
2489 | + { "outB", indirDX, AL, XX }, | |
2490 | + { "outS", indirDX, eAX, XX }, | |
2491 | + /* f0 */ | |
2492 | + { "(bad)", XX, XX, XX }, /* lock prefix */ | |
2493 | + { "icebp", XX, XX, XX }, | |
2494 | + { "(bad)", XX, XX, XX }, /* repne */ | |
2495 | + { "(bad)", XX, XX, XX }, /* repz */ | |
2496 | + { "hlt", XX, XX, XX }, | |
2497 | + { "cmc", XX, XX, XX }, | |
2498 | + { GRP3b }, | |
2499 | + { GRP3S }, | |
2500 | + /* f8 */ | |
2501 | + { "clc", XX, XX, XX }, | |
2502 | + { "stc", XX, XX, XX }, | |
2503 | + { "cli", XX, XX, XX }, | |
2504 | + { "sti", XX, XX, XX }, | |
2505 | + { "cld", XX, XX, XX }, | |
2506 | + { "std", XX, XX, XX }, | |
2507 | + { GRP4 }, | |
2508 | + { GRP5 }, | |
2509 | +}; | |
2510 | + | |
2511 | +static const struct dis386 dis386_twobyte[] = { | |
2512 | + /* 00 */ | |
2513 | + { GRP6 }, | |
2514 | + { GRP7 }, | |
2515 | + { "larS", Gv, Ew, XX }, | |
2516 | + { "lslS", Gv, Ew, XX }, | |
2517 | + { "(bad)", XX, XX, XX }, | |
2518 | + { "syscall", XX, XX, XX }, | |
2519 | + { "clts", XX, XX, XX }, | |
2520 | + { "sysretP", XX, XX, XX }, | |
2521 | + /* 08 */ | |
2522 | + { "invd", XX, XX, XX }, | |
2523 | + { "wbinvd", XX, XX, XX }, | |
2524 | + { "(bad)", XX, XX, XX }, | |
2525 | + { "ud2a", XX, XX, XX }, | |
2526 | + { "(bad)", XX, XX, XX }, | |
2527 | + { GRPAMD }, | |
2528 | + { "femms", XX, XX, XX }, | |
2529 | + { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix. */ | |
2530 | + /* 10 */ | |
2531 | + { PREGRP8 }, | |
2532 | + { PREGRP9 }, | |
2533 | + { PREGRP30 }, | |
2534 | + { "movlpX", EX, XM, SIMD_Fixup, 'h' }, | |
2535 | + { "unpcklpX", XM, EX, XX }, | |
2536 | + { "unpckhpX", XM, EX, XX }, | |
2537 | + { PREGRP31 }, | |
2538 | + { "movhpX", EX, XM, SIMD_Fixup, 'l' }, | |
2539 | + /* 18 */ | |
2540 | + { GRP14 }, | |
2541 | + { "(bad)", XX, XX, XX }, | |
2542 | + { "(bad)", XX, XX, XX }, | |
2543 | + { "(bad)", XX, XX, XX }, | |
2544 | + { "(bad)", XX, XX, XX }, | |
2545 | + { "(bad)", XX, XX, XX }, | |
2546 | + { "(bad)", XX, XX, XX }, | |
2547 | + { "(bad)", XX, XX, XX }, | |
2548 | + /* 20 */ | |
2549 | + { "movL", Rm, Cm, XX }, | |
2550 | + { "movL", Rm, Dm, XX }, | |
2551 | + { "movL", Cm, Rm, XX }, | |
2552 | + { "movL", Dm, Rm, XX }, | |
2553 | + { "movL", Rd, Td, XX }, | |
2554 | + { "(bad)", XX, XX, XX }, | |
2555 | + { "movL", Td, Rd, XX }, | |
2556 | + { "(bad)", XX, XX, XX }, | |
2557 | + /* 28 */ | |
2558 | + { "movapX", XM, EX, XX }, | |
2559 | + { "movapX", EX, XM, XX }, | |
2560 | + { PREGRP2 }, | |
2561 | + { "movntpX", Ev, XM, XX }, | |
2562 | + { PREGRP4 }, | |
2563 | + { PREGRP3 }, | |
2564 | + { "ucomisX", XM,EX, XX }, | |
2565 | + { "comisX", XM,EX, XX }, | |
2566 | + /* 30 */ | |
2567 | + { "wrmsr", XX, XX, XX }, | |
2568 | + { "rdtsc", XX, XX, XX }, | |
2569 | + { "rdmsr", XX, XX, XX }, | |
2570 | + { "rdpmc", XX, XX, XX }, | |
2571 | + { "sysenter", XX, XX, XX }, | |
2572 | + { "sysexit", XX, XX, XX }, | |
2573 | + { "(bad)", XX, XX, XX }, | |
2574 | + { "(bad)", XX, XX, XX }, | |
2575 | + /* 38 */ | |
2576 | + { "(bad)", XX, XX, XX }, | |
2577 | + { "(bad)", XX, XX, XX }, | |
2578 | + { "(bad)", XX, XX, XX }, | |
2579 | + { "(bad)", XX, XX, XX }, | |
2580 | + { "(bad)", XX, XX, XX }, | |
2581 | + { "(bad)", XX, XX, XX }, | |
2582 | + { "(bad)", XX, XX, XX }, | |
2583 | + { "(bad)", XX, XX, XX }, | |
2584 | + /* 40 */ | |
2585 | + { "cmovo", Gv, Ev, XX }, | |
2586 | + { "cmovno", Gv, Ev, XX }, | |
2587 | + { "cmovb", Gv, Ev, XX }, | |
2588 | + { "cmovae", Gv, Ev, XX }, | |
2589 | + { "cmove", Gv, Ev, XX }, | |
2590 | + { "cmovne", Gv, Ev, XX }, | |
2591 | + { "cmovbe", Gv, Ev, XX }, | |
2592 | + { "cmova", Gv, Ev, XX }, | |
2593 | + /* 48 */ | |
2594 | + { "cmovs", Gv, Ev, XX }, | |
2595 | + { "cmovns", Gv, Ev, XX }, | |
2596 | + { "cmovp", Gv, Ev, XX }, | |
2597 | + { "cmovnp", Gv, Ev, XX }, | |
2598 | + { "cmovl", Gv, Ev, XX }, | |
2599 | + { "cmovge", Gv, Ev, XX }, | |
2600 | + { "cmovle", Gv, Ev, XX }, | |
2601 | + { "cmovg", Gv, Ev, XX }, | |
2602 | + /* 50 */ | |
2603 | + { "movmskpX", Gdq, XS, XX }, | |
2604 | + { PREGRP13 }, | |
2605 | + { PREGRP12 }, | |
2606 | + { PREGRP11 }, | |
2607 | + { "andpX", XM, EX, XX }, | |
2608 | + { "andnpX", XM, EX, XX }, | |
2609 | + { "orpX", XM, EX, XX }, | |
2610 | + { "xorpX", XM, EX, XX }, | |
2611 | + /* 58 */ | |
2612 | + { PREGRP0 }, | |
2613 | + { PREGRP10 }, | |
2614 | + { PREGRP17 }, | |
2615 | + { PREGRP16 }, | |
2616 | + { PREGRP14 }, | |
2617 | + { PREGRP7 }, | |
2618 | + { PREGRP5 }, | |
2619 | + { PREGRP6 }, | |
2620 | + /* 60 */ | |
2621 | + { "punpcklbw", MX, EM, XX }, | |
2622 | + { "punpcklwd", MX, EM, XX }, | |
2623 | + { "punpckldq", MX, EM, XX }, | |
2624 | + { "packsswb", MX, EM, XX }, | |
2625 | + { "pcmpgtb", MX, EM, XX }, | |
2626 | + { "pcmpgtw", MX, EM, XX }, | |
2627 | + { "pcmpgtd", MX, EM, XX }, | |
2628 | + { "packuswb", MX, EM, XX }, | |
2629 | + /* 68 */ | |
2630 | + { "punpckhbw", MX, EM, XX }, | |
2631 | + { "punpckhwd", MX, EM, XX }, | |
2632 | + { "punpckhdq", MX, EM, XX }, | |
2633 | + { "packssdw", MX, EM, XX }, | |
2634 | + { PREGRP26 }, | |
2635 | + { PREGRP24 }, | |
2636 | + { "movd", MX, Edq, XX }, | |
2637 | + { PREGRP19 }, | |
2638 | + /* 70 */ | |
2639 | + { PREGRP22 }, | |
2640 | + { GRP10 }, | |
2641 | + { GRP11 }, | |
2642 | + { GRP12 }, | |
2643 | + { "pcmpeqb", MX, EM, XX }, | |
2644 | + { "pcmpeqw", MX, EM, XX }, | |
2645 | + { "pcmpeqd", MX, EM, XX }, | |
2646 | + { "emms", XX, XX, XX }, | |
2647 | + /* 78 */ | |
2648 | + { "vmread", Em, Gm, XX }, | |
2649 | + { "vmwrite", Gm, Em, XX }, | |
2650 | + { "(bad)", XX, XX, XX }, | |
2651 | + { "(bad)", XX, XX, XX }, | |
2652 | + { PREGRP28 }, | |
2653 | + { PREGRP29 }, | |
2654 | + { PREGRP23 }, | |
2655 | + { PREGRP20 }, | |
2656 | + /* 80 */ | |
2657 | + { "joH", Jv, XX, cond_jump_flag }, | |
2658 | + { "jnoH", Jv, XX, cond_jump_flag }, | |
2659 | + { "jbH", Jv, XX, cond_jump_flag }, | |
2660 | + { "jaeH", Jv, XX, cond_jump_flag }, | |
2661 | + { "jeH", Jv, XX, cond_jump_flag }, | |
2662 | + { "jneH", Jv, XX, cond_jump_flag }, | |
2663 | + { "jbeH", Jv, XX, cond_jump_flag }, | |
2664 | + { "jaH", Jv, XX, cond_jump_flag }, | |
2665 | + /* 88 */ | |
2666 | + { "jsH", Jv, XX, cond_jump_flag }, | |
2667 | + { "jnsH", Jv, XX, cond_jump_flag }, | |
2668 | + { "jpH", Jv, XX, cond_jump_flag }, | |
2669 | + { "jnpH", Jv, XX, cond_jump_flag }, | |
2670 | + { "jlH", Jv, XX, cond_jump_flag }, | |
2671 | + { "jgeH", Jv, XX, cond_jump_flag }, | |
2672 | + { "jleH", Jv, XX, cond_jump_flag }, | |
2673 | + { "jgH", Jv, XX, cond_jump_flag }, | |
2674 | + /* 90 */ | |
2675 | + { "seto", Eb, XX, XX }, | |
2676 | + { "setno", Eb, XX, XX }, | |
2677 | + { "setb", Eb, XX, XX }, | |
2678 | + { "setae", Eb, XX, XX }, | |
2679 | + { "sete", Eb, XX, XX }, | |
2680 | + { "setne", Eb, XX, XX }, | |
2681 | + { "setbe", Eb, XX, XX }, | |
2682 | + { "seta", Eb, XX, XX }, | |
2683 | + /* 98 */ | |
2684 | + { "sets", Eb, XX, XX }, | |
2685 | + { "setns", Eb, XX, XX }, | |
2686 | + { "setp", Eb, XX, XX }, | |
2687 | + { "setnp", Eb, XX, XX }, | |
2688 | + { "setl", Eb, XX, XX }, | |
2689 | + { "setge", Eb, XX, XX }, | |
2690 | + { "setle", Eb, XX, XX }, | |
2691 | + { "setg", Eb, XX, XX }, | |
2692 | + /* a0 */ | |
2693 | + { "pushT", fs, XX, XX }, | |
2694 | + { "popT", fs, XX, XX }, | |
2695 | + { "cpuid", XX, XX, XX }, | |
2696 | + { "btS", Ev, Gv, XX }, | |
2697 | + { "shldS", Ev, Gv, Ib }, | |
2698 | + { "shldS", Ev, Gv, CL }, | |
2699 | + { GRPPADLCK2 }, | |
2700 | + { GRPPADLCK1 }, | |
2701 | + /* a8 */ | |
2702 | + { "pushT", gs, XX, XX }, | |
2703 | + { "popT", gs, XX, XX }, | |
2704 | + { "rsm", XX, XX, XX }, | |
2705 | + { "btsS", Ev, Gv, XX }, | |
2706 | + { "shrdS", Ev, Gv, Ib }, | |
2707 | + { "shrdS", Ev, Gv, CL }, | |
2708 | + { GRP13 }, | |
2709 | + { "imulS", Gv, Ev, XX }, | |
2710 | + /* b0 */ | |
2711 | + { "cmpxchgB", Eb, Gb, XX }, | |
2712 | + { "cmpxchgS", Ev, Gv, XX }, | |
2713 | + { "lssS", Gv, Mp, XX }, | |
2714 | + { "btrS", Ev, Gv, XX }, | |
2715 | + { "lfsS", Gv, Mp, XX }, | |
2716 | + { "lgsS", Gv, Mp, XX }, | |
2717 | + { "movz{bR|x|bR|x}", Gv, Eb, XX }, | |
2718 | + { "movz{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movzww ! */ | |
2719 | + /* b8 */ | |
2720 | + { "(bad)", XX, XX, XX }, | |
2721 | + { "ud2b", XX, XX, XX }, | |
2722 | + { GRP8 }, | |
2723 | + { "btcS", Ev, Gv, XX }, | |
2724 | + { "bsfS", Gv, Ev, XX }, | |
2725 | + { "bsrS", Gv, Ev, XX }, | |
2726 | + { "movs{bR|x|bR|x}", Gv, Eb, XX }, | |
2727 | + { "movs{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movsww ! */ | |
2728 | + /* c0 */ | |
2729 | + { "xaddB", Eb, Gb, XX }, | |
2730 | + { "xaddS", Ev, Gv, XX }, | |
2731 | + { PREGRP1 }, | |
2732 | + { "movntiS", Ev, Gv, XX }, | |
2733 | + { "pinsrw", MX, Edqw, Ib }, | |
2734 | + { "pextrw", Gdq, MS, Ib }, | |
2735 | + { "shufpX", XM, EX, Ib }, | |
2736 | + { GRP9 }, | |
2737 | + /* c8 */ | |
2738 | + { "bswap", RMeAX, XX, XX }, | |
2739 | + { "bswap", RMeCX, XX, XX }, | |
2740 | + { "bswap", RMeDX, XX, XX }, | |
2741 | + { "bswap", RMeBX, XX, XX }, | |
2742 | + { "bswap", RMeSP, XX, XX }, | |
2743 | + { "bswap", RMeBP, XX, XX }, | |
2744 | + { "bswap", RMeSI, XX, XX }, | |
2745 | + { "bswap", RMeDI, XX, XX }, | |
2746 | + /* d0 */ | |
2747 | + { PREGRP27 }, | |
2748 | + { "psrlw", MX, EM, XX }, | |
2749 | + { "psrld", MX, EM, XX }, | |
2750 | + { "psrlq", MX, EM, XX }, | |
2751 | + { "paddq", MX, EM, XX }, | |
2752 | + { "pmullw", MX, EM, XX }, | |
2753 | + { PREGRP21 }, | |
2754 | + { "pmovmskb", Gdq, MS, XX }, | |
2755 | + /* d8 */ | |
2756 | + { "psubusb", MX, EM, XX }, | |
2757 | + { "psubusw", MX, EM, XX }, | |
2758 | + { "pminub", MX, EM, XX }, | |
2759 | + { "pand", MX, EM, XX }, | |
2760 | + { "paddusb", MX, EM, XX }, | |
2761 | + { "paddusw", MX, EM, XX }, | |
2762 | + { "pmaxub", MX, EM, XX }, | |
2763 | + { "pandn", MX, EM, XX }, | |
2764 | + /* e0 */ | |
2765 | + { "pavgb", MX, EM, XX }, | |
2766 | + { "psraw", MX, EM, XX }, | |
2767 | + { "psrad", MX, EM, XX }, | |
2768 | + { "pavgw", MX, EM, XX }, | |
2769 | + { "pmulhuw", MX, EM, XX }, | |
2770 | + { "pmulhw", MX, EM, XX }, | |
2771 | + { PREGRP15 }, | |
2772 | + { PREGRP25 }, | |
2773 | + /* e8 */ | |
2774 | + { "psubsb", MX, EM, XX }, | |
2775 | + { "psubsw", MX, EM, XX }, | |
2776 | + { "pminsw", MX, EM, XX }, | |
2777 | + { "por", MX, EM, XX }, | |
2778 | + { "paddsb", MX, EM, XX }, | |
2779 | + { "paddsw", MX, EM, XX }, | |
2780 | + { "pmaxsw", MX, EM, XX }, | |
2781 | + { "pxor", MX, EM, XX }, | |
2782 | + /* f0 */ | |
2783 | + { PREGRP32 }, | |
2784 | + { "psllw", MX, EM, XX }, | |
2785 | + { "pslld", MX, EM, XX }, | |
2786 | + { "psllq", MX, EM, XX }, | |
2787 | + { "pmuludq", MX, EM, XX }, | |
2788 | + { "pmaddwd", MX, EM, XX }, | |
2789 | + { "psadbw", MX, EM, XX }, | |
2790 | + { PREGRP18 }, | |
2791 | + /* f8 */ | |
2792 | + { "psubb", MX, EM, XX }, | |
2793 | + { "psubw", MX, EM, XX }, | |
2794 | + { "psubd", MX, EM, XX }, | |
2795 | + { "psubq", MX, EM, XX }, | |
2796 | + { "paddb", MX, EM, XX }, | |
2797 | + { "paddw", MX, EM, XX }, | |
2798 | + { "paddd", MX, EM, XX }, | |
2799 | + { "(bad)", XX, XX, XX } | |
2800 | +}; | |
2801 | + | |
2802 | +static const unsigned char onebyte_has_modrm[256] = { | |
2803 | + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | |
2804 | + /* ------------------------------- */ | |
2805 | + /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */ | |
2806 | + /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */ | |
2807 | + /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */ | |
2808 | + /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */ | |
2809 | + /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */ | |
2810 | + /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */ | |
2811 | + /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */ | |
2812 | + /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */ | |
2813 | + /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */ | |
2814 | + /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */ | |
2815 | + /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */ | |
2816 | + /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */ | |
2817 | + /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */ | |
2818 | + /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */ | |
2819 | + /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */ | |
2820 | + /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */ | |
2821 | + /* ------------------------------- */ | |
2822 | + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | |
2823 | +}; | |
2824 | + | |
2825 | +static const unsigned char twobyte_has_modrm[256] = { | |
2826 | + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | |
2827 | + /* ------------------------------- */ | |
2828 | + /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */ | |
2829 | + /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */ | |
2830 | + /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */ | |
2831 | + /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */ | |
2832 | + /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */ | |
2833 | + /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */ | |
2834 | + /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */ | |
2835 | + /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */ | |
2836 | + /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */ | |
2837 | + /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */ | |
2838 | + /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */ | |
2839 | + /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */ | |
2840 | + /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */ | |
2841 | + /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */ | |
2842 | + /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */ | |
2843 | + /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */ | |
2844 | + /* ------------------------------- */ | |
2845 | + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | |
2846 | +}; | |
2847 | + | |
2848 | +static const unsigned char twobyte_uses_SSE_prefix[256] = { | |
2849 | + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | |
2850 | + /* ------------------------------- */ | |
2851 | + /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */ | |
2852 | + /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */ | |
2853 | + /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */ | |
2854 | + /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */ | |
2855 | + /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */ | |
2856 | + /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */ | |
2857 | + /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */ | |
2858 | + /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, /* 7f */ | |
2859 | + /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */ | |
2860 | + /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */ | |
2861 | + /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */ | |
2862 | + /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */ | |
2863 | + /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */ | |
2864 | + /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */ | |
2865 | + /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */ | |
2866 | + /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */ | |
2867 | + /* ------------------------------- */ | |
2868 | + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | |
2869 | +}; | |
2870 | + | |
2871 | +static char obuf[100]; | |
2872 | +static char *obufp; | |
2873 | +static char scratchbuf[100]; | |
2874 | +static unsigned char *start_codep; | |
2875 | +static unsigned char *insn_codep; | |
2876 | +static unsigned char *codep; | |
2877 | +static disassemble_info *the_info; | |
2878 | +static int mod; | |
2879 | +static int rm; | |
2880 | +static int reg; | |
2881 | +static unsigned char need_modrm; | |
2882 | + | |
2883 | +/* If we are accessing mod/rm/reg without need_modrm set, then the | |
2884 | + values are stale. Hitting this abort likely indicates that you | |
2885 | + need to update onebyte_has_modrm or twobyte_has_modrm. */ | |
2886 | +#define MODRM_CHECK if (!need_modrm) abort () | |
2887 | + | |
2888 | +static const char **names64; | |
2889 | +static const char **names32; | |
2890 | +static const char **names16; | |
2891 | +static const char **names8; | |
2892 | +static const char **names8rex; | |
2893 | +static const char **names_seg; | |
2894 | +static const char **index16; | |
2895 | + | |
2896 | +static const char *intel_names64[] = { | |
2897 | + "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", | |
2898 | + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" | |
2899 | +}; | |
2900 | +static const char *intel_names32[] = { | |
2901 | + "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", | |
2902 | + "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" | |
2903 | +}; | |
2904 | +static const char *intel_names16[] = { | |
2905 | + "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", | |
2906 | + "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w" | |
2907 | +}; | |
2908 | +static const char *intel_names8[] = { | |
2909 | + "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", | |
2910 | +}; | |
2911 | +static const char *intel_names8rex[] = { | |
2912 | + "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", | |
2913 | + "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" | |
2914 | +}; | |
2915 | +static const char *intel_names_seg[] = { | |
2916 | + "es", "cs", "ss", "ds", "fs", "gs", "?", "?", | |
2917 | +}; | |
2918 | +static const char *intel_index16[] = { | |
2919 | + "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx" | |
2920 | +}; | |
2921 | + | |
2922 | +static const char *att_names64[] = { | |
2923 | + "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi", | |
2924 | + "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" | |
2925 | +}; | |
2926 | +static const char *att_names32[] = { | |
2927 | + "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi", | |
2928 | + "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d" | |
2929 | +}; | |
2930 | +static const char *att_names16[] = { | |
2931 | + "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di", | |
2932 | + "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w" | |
2933 | +}; | |
2934 | +static const char *att_names8[] = { | |
2935 | + "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh", | |
2936 | +}; | |
2937 | +static const char *att_names8rex[] = { | |
2938 | + "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil", | |
2939 | + "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b" | |
2940 | +}; | |
2941 | +static const char *att_names_seg[] = { | |
2942 | + "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?", | |
2943 | +}; | |
2944 | +static const char *att_index16[] = { | |
2945 | + "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx" | |
2946 | +}; | |
2947 | + | |
2948 | +static const struct dis386 grps[][8] = { | |
2949 | + /* GRP1b */ | |
2950 | + { | |
2951 | + { "addA", Eb, Ib, XX }, | |
2952 | + { "orA", Eb, Ib, XX }, | |
2953 | + { "adcA", Eb, Ib, XX }, | |
2954 | + { "sbbA", Eb, Ib, XX }, | |
2955 | + { "andA", Eb, Ib, XX }, | |
2956 | + { "subA", Eb, Ib, XX }, | |
2957 | + { "xorA", Eb, Ib, XX }, | |
2958 | + { "cmpA", Eb, Ib, XX } | |
2959 | + }, | |
2960 | + /* GRP1S */ | |
2961 | + { | |
2962 | + { "addQ", Ev, Iv, XX }, | |
2963 | + { "orQ", Ev, Iv, XX }, | |
2964 | + { "adcQ", Ev, Iv, XX }, | |
2965 | + { "sbbQ", Ev, Iv, XX }, | |
2966 | + { "andQ", Ev, Iv, XX }, | |
2967 | + { "subQ", Ev, Iv, XX }, | |
2968 | + { "xorQ", Ev, Iv, XX }, | |
2969 | + { "cmpQ", Ev, Iv, XX } | |
2970 | + }, | |
2971 | + /* GRP1Ss */ | |
2972 | + { | |
2973 | + { "addQ", Ev, sIb, XX }, | |
2974 | + { "orQ", Ev, sIb, XX }, | |
2975 | + { "adcQ", Ev, sIb, XX }, | |
2976 | + { "sbbQ", Ev, sIb, XX }, | |
2977 | + { "andQ", Ev, sIb, XX }, | |
2978 | + { "subQ", Ev, sIb, XX }, | |
2979 | + { "xorQ", Ev, sIb, XX }, | |
2980 | + { "cmpQ", Ev, sIb, XX } | |
2981 | + }, | |
2982 | + /* GRP2b */ | |
2983 | + { | |
2984 | + { "rolA", Eb, Ib, XX }, | |
2985 | + { "rorA", Eb, Ib, XX }, | |
2986 | + { "rclA", Eb, Ib, XX }, | |
2987 | + { "rcrA", Eb, Ib, XX }, | |
2988 | + { "shlA", Eb, Ib, XX }, | |
2989 | + { "shrA", Eb, Ib, XX }, | |
2990 | + { "(bad)", XX, XX, XX }, | |
2991 | + { "sarA", Eb, Ib, XX }, | |
2992 | + }, | |
2993 | + /* GRP2S */ | |
2994 | + { | |
2995 | + { "rolQ", Ev, Ib, XX }, | |
2996 | + { "rorQ", Ev, Ib, XX }, | |
2997 | + { "rclQ", Ev, Ib, XX }, | |
2998 | + { "rcrQ", Ev, Ib, XX }, | |
2999 | + { "shlQ", Ev, Ib, XX }, | |
3000 | + { "shrQ", Ev, Ib, XX }, | |
3001 | + { "(bad)", XX, XX, XX }, | |
3002 | + { "sarQ", Ev, Ib, XX }, | |
3003 | + }, | |
3004 | + /* GRP2b_one */ | |
3005 | + { | |
3006 | + { "rolA", Eb, I1, XX }, | |
3007 | + { "rorA", Eb, I1, XX }, | |
3008 | + { "rclA", Eb, I1, XX }, | |
3009 | + { "rcrA", Eb, I1, XX }, | |
3010 | + { "shlA", Eb, I1, XX }, | |
3011 | + { "shrA", Eb, I1, XX }, | |
3012 | + { "(bad)", XX, XX, XX }, | |
3013 | + { "sarA", Eb, I1, XX }, | |
3014 | + }, | |
3015 | + /* GRP2S_one */ | |
3016 | + { | |
3017 | + { "rolQ", Ev, I1, XX }, | |
3018 | + { "rorQ", Ev, I1, XX }, | |
3019 | + { "rclQ", Ev, I1, XX }, | |
3020 | + { "rcrQ", Ev, I1, XX }, | |
3021 | + { "shlQ", Ev, I1, XX }, | |
3022 | + { "shrQ", Ev, I1, XX }, | |
3023 | + { "(bad)", XX, XX, XX}, | |
3024 | + { "sarQ", Ev, I1, XX }, | |
3025 | + }, | |
3026 | + /* GRP2b_cl */ | |
3027 | + { | |
3028 | + { "rolA", Eb, CL, XX }, | |
3029 | + { "rorA", Eb, CL, XX }, | |
3030 | + { "rclA", Eb, CL, XX }, | |
3031 | + { "rcrA", Eb, CL, XX }, | |
3032 | + { "shlA", Eb, CL, XX }, | |
3033 | + { "shrA", Eb, CL, XX }, | |
3034 | + { "(bad)", XX, XX, XX }, | |
3035 | + { "sarA", Eb, CL, XX }, | |
3036 | + }, | |
3037 | + /* GRP2S_cl */ | |
3038 | + { | |
3039 | + { "rolQ", Ev, CL, XX }, | |
3040 | + { "rorQ", Ev, CL, XX }, | |
3041 | + { "rclQ", Ev, CL, XX }, | |
3042 | + { "rcrQ", Ev, CL, XX }, | |
3043 | + { "shlQ", Ev, CL, XX }, | |
3044 | + { "shrQ", Ev, CL, XX }, | |
3045 | + { "(bad)", XX, XX, XX }, | |
3046 | + { "sarQ", Ev, CL, XX } | |
3047 | + }, | |
3048 | + /* GRP3b */ | |
3049 | + { | |
3050 | + { "testA", Eb, Ib, XX }, | |
3051 | + { "(bad)", Eb, XX, XX }, | |
3052 | + { "notA", Eb, XX, XX }, | |
3053 | + { "negA", Eb, XX, XX }, | |
3054 | + { "mulA", Eb, XX, XX }, /* Don't print the implicit %al register, */ | |
3055 | + { "imulA", Eb, XX, XX }, /* to distinguish these opcodes from other */ | |
3056 | + { "divA", Eb, XX, XX }, /* mul/imul opcodes. Do the same for div */ | |
3057 | + { "idivA", Eb, XX, XX } /* and idiv for consistency. */ | |
3058 | + }, | |
3059 | + /* GRP3S */ | |
3060 | + { | |
3061 | + { "testQ", Ev, Iv, XX }, | |
3062 | + { "(bad)", XX, XX, XX }, | |
3063 | + { "notQ", Ev, XX, XX }, | |
3064 | + { "negQ", Ev, XX, XX }, | |
3065 | + { "mulQ", Ev, XX, XX }, /* Don't print the implicit register. */ | |
3066 | + { "imulQ", Ev, XX, XX }, | |
3067 | + { "divQ", Ev, XX, XX }, | |
3068 | + { "idivQ", Ev, XX, XX }, | |
3069 | + }, | |
3070 | + /* GRP4 */ | |
3071 | + { | |
3072 | + { "incA", Eb, XX, XX }, | |
3073 | + { "decA", Eb, XX, XX }, | |
3074 | + { "(bad)", XX, XX, XX }, | |
3075 | + { "(bad)", XX, XX, XX }, | |
3076 | + { "(bad)", XX, XX, XX }, | |
3077 | + { "(bad)", XX, XX, XX }, | |
3078 | + { "(bad)", XX, XX, XX }, | |
3079 | + { "(bad)", XX, XX, XX }, | |
3080 | + }, | |
3081 | + /* GRP5 */ | |
3082 | + { | |
3083 | + { "incQ", Ev, XX, XX }, | |
3084 | + { "decQ", Ev, XX, XX }, | |
3085 | + { "callT", indirEv, XX, XX }, | |
3086 | + { "JcallT", indirEp, XX, XX }, | |
3087 | + { "jmpT", indirEv, XX, XX }, | |
3088 | + { "JjmpT", indirEp, XX, XX }, | |
3089 | + { "pushU", Ev, XX, XX }, | |
3090 | + { "(bad)", XX, XX, XX }, | |
3091 | + }, | |
3092 | + /* GRP6 */ | |
3093 | + { | |
3094 | + { "sldtQ", Ev, XX, XX }, | |
3095 | + { "strQ", Ev, XX, XX }, | |
3096 | + { "lldt", Ew, XX, XX }, | |
3097 | + { "ltr", Ew, XX, XX }, | |
3098 | + { "verr", Ew, XX, XX }, | |
3099 | + { "verw", Ew, XX, XX }, | |
3100 | + { "(bad)", XX, XX, XX }, | |
3101 | + { "(bad)", XX, XX, XX } | |
3102 | + }, | |
3103 | + /* GRP7 */ | |
3104 | + { | |
3105 | + { "sgdtIQ", VMX_Fixup, 0, XX, XX }, | |
3106 | + { "sidtIQ", PNI_Fixup, 0, XX, XX }, | |
3107 | + { "lgdt{Q|Q||}", M, XX, XX }, | |
3108 | + { "lidt{Q|Q||}", SVME_Fixup, 0, XX, XX }, | |
3109 | + { "smswQ", Ev, XX, XX }, | |
3110 | + { "(bad)", XX, XX, XX }, | |
3111 | + { "lmsw", Ew, XX, XX }, | |
3112 | + { "invlpg", INVLPG_Fixup, w_mode, XX, XX }, | |
3113 | + }, | |
3114 | + /* GRP8 */ | |
3115 | + { | |
3116 | + { "(bad)", XX, XX, XX }, | |
3117 | + { "(bad)", XX, XX, XX }, | |
3118 | + { "(bad)", XX, XX, XX }, | |
3119 | + { "(bad)", XX, XX, XX }, | |
3120 | + { "btQ", Ev, Ib, XX }, | |
3121 | + { "btsQ", Ev, Ib, XX }, | |
3122 | + { "btrQ", Ev, Ib, XX }, | |
3123 | + { "btcQ", Ev, Ib, XX }, | |
3124 | + }, | |
3125 | + /* GRP9 */ | |
3126 | + { | |
3127 | + { "(bad)", XX, XX, XX }, | |
3128 | + { "cmpxchg8b", Eq, XX, XX }, | |
3129 | + { "(bad)", XX, XX, XX }, | |
3130 | + { "(bad)", XX, XX, XX }, | |
3131 | + { "(bad)", XX, XX, XX }, | |
3132 | + { "(bad)", XX, XX, XX }, | |
3133 | + { "", VM, XX, XX }, /* See OP_VMX. */ | |
3134 | + { "vmptrst", Eq, XX, XX }, | |
3135 | + }, | |
3136 | + /* GRP10 */ | |
3137 | + { | |
3138 | + { "(bad)", XX, XX, XX }, | |
3139 | + { "(bad)", XX, XX, XX }, | |
3140 | + { "psrlw", MS, Ib, XX }, | |
3141 | + { "(bad)", XX, XX, XX }, | |
3142 | + { "psraw", MS, Ib, XX }, | |
3143 | + { "(bad)", XX, XX, XX }, | |
3144 | + { "psllw", MS, Ib, XX }, | |
3145 | + { "(bad)", XX, XX, XX }, | |
3146 | + }, | |
3147 | + /* GRP11 */ | |
3148 | + { | |
3149 | + { "(bad)", XX, XX, XX }, | |
3150 | + { "(bad)", XX, XX, XX }, | |
3151 | + { "psrld", MS, Ib, XX }, | |
3152 | + { "(bad)", XX, XX, XX }, | |
3153 | + { "psrad", MS, Ib, XX }, | |
3154 | + { "(bad)", XX, XX, XX }, | |
3155 | + { "pslld", MS, Ib, XX }, | |
3156 | + { "(bad)", XX, XX, XX }, | |
3157 | + }, | |
3158 | + /* GRP12 */ | |
3159 | + { | |
3160 | + { "(bad)", XX, XX, XX }, | |
3161 | + { "(bad)", XX, XX, XX }, | |
3162 | + { "psrlq", MS, Ib, XX }, | |
3163 | + { "psrldq", MS, Ib, XX }, | |
3164 | + { "(bad)", XX, XX, XX }, | |
3165 | + { "(bad)", XX, XX, XX }, | |
3166 | + { "psllq", MS, Ib, XX }, | |
3167 | + { "pslldq", MS, Ib, XX }, | |
3168 | + }, | |
3169 | + /* GRP13 */ | |
3170 | + { | |
3171 | + { "fxsave", Ev, XX, XX }, | |
3172 | + { "fxrstor", Ev, XX, XX }, | |
3173 | + { "ldmxcsr", Ev, XX, XX }, | |
3174 | + { "stmxcsr", Ev, XX, XX }, | |
3175 | + { "(bad)", XX, XX, XX }, | |
3176 | + { "lfence", OP_0fae, 0, XX, XX }, | |
3177 | + { "mfence", OP_0fae, 0, XX, XX }, | |
3178 | + { "clflush", OP_0fae, 0, XX, XX }, | |
3179 | + }, | |
3180 | + /* GRP14 */ | |
3181 | + { | |
3182 | + { "prefetchnta", Ev, XX, XX }, | |
3183 | + { "prefetcht0", Ev, XX, XX }, | |
3184 | + { "prefetcht1", Ev, XX, XX }, | |
3185 | + { "prefetcht2", Ev, XX, XX }, | |
3186 | + { "(bad)", XX, XX, XX }, | |
3187 | + { "(bad)", XX, XX, XX }, | |
3188 | + { "(bad)", XX, XX, XX }, | |
3189 | + { "(bad)", XX, XX, XX }, | |
3190 | + }, | |
3191 | + /* GRPAMD */ | |
3192 | + { | |
3193 | + { "prefetch", Eb, XX, XX }, | |
3194 | + { "prefetchw", Eb, XX, XX }, | |
3195 | + { "(bad)", XX, XX, XX }, | |
3196 | + { "(bad)", XX, XX, XX }, | |
3197 | + { "(bad)", XX, XX, XX }, | |
3198 | + { "(bad)", XX, XX, XX }, | |
3199 | + { "(bad)", XX, XX, XX }, | |
3200 | + { "(bad)", XX, XX, XX }, | |
3201 | + }, | |
3202 | + /* GRPPADLCK1 */ | |
3203 | + { | |
3204 | + { "xstore-rng", OP_0f07, 0, XX, XX }, | |
3205 | + { "xcrypt-ecb", OP_0f07, 0, XX, XX }, | |
3206 | + { "xcrypt-cbc", OP_0f07, 0, XX, XX }, | |
3207 | + { "xcrypt-ctr", OP_0f07, 0, XX, XX }, | |
3208 | + { "xcrypt-cfb", OP_0f07, 0, XX, XX }, | |
3209 | + { "xcrypt-ofb", OP_0f07, 0, XX, XX }, | |
3210 | + { "(bad)", OP_0f07, 0, XX, XX }, | |
3211 | + { "(bad)", OP_0f07, 0, XX, XX }, | |
3212 | + }, | |
3213 | + /* GRPPADLCK2 */ | |
3214 | + { | |
3215 | + { "montmul", OP_0f07, 0, XX, XX }, | |
3216 | + { "xsha1", OP_0f07, 0, XX, XX }, | |
3217 | + { "xsha256", OP_0f07, 0, XX, XX }, | |
3218 | + { "(bad)", OP_0f07, 0, XX, XX }, | |
3219 | + { "(bad)", OP_0f07, 0, XX, XX }, | |
3220 | + { "(bad)", OP_0f07, 0, XX, XX }, | |
3221 | + { "(bad)", OP_0f07, 0, XX, XX }, | |
3222 | + { "(bad)", OP_0f07, 0, XX, XX }, | |
3223 | + } | |
3224 | +}; | |
3225 | + | |
3226 | +static const struct dis386 prefix_user_table[][4] = { | |
3227 | + /* PREGRP0 */ | |
3228 | + { | |
3229 | + { "addps", XM, EX, XX }, | |
3230 | + { "addss", XM, EX, XX }, | |
3231 | + { "addpd", XM, EX, XX }, | |
3232 | + { "addsd", XM, EX, XX }, | |
3233 | + }, | |
3234 | + /* PREGRP1 */ | |
3235 | + { | |
3236 | + { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX. */ | |
3237 | + { "", XM, EX, OPSIMD }, | |
3238 | + { "", XM, EX, OPSIMD }, | |
3239 | + { "", XM, EX, OPSIMD }, | |
3240 | + }, | |
3241 | + /* PREGRP2 */ | |
3242 | + { | |
3243 | + { "cvtpi2ps", XM, EM, XX }, | |
3244 | + { "cvtsi2ssY", XM, Ev, XX }, | |
3245 | + { "cvtpi2pd", XM, EM, XX }, | |
3246 | + { "cvtsi2sdY", XM, Ev, XX }, | |
3247 | + }, | |
3248 | + /* PREGRP3 */ | |
3249 | + { | |
3250 | + { "cvtps2pi", MX, EX, XX }, | |
3251 | + { "cvtss2siY", Gv, EX, XX }, | |
3252 | + { "cvtpd2pi", MX, EX, XX }, | |
3253 | + { "cvtsd2siY", Gv, EX, XX }, | |
3254 | + }, | |
3255 | + /* PREGRP4 */ | |
3256 | + { | |
3257 | + { "cvttps2pi", MX, EX, XX }, | |
3258 | + { "cvttss2siY", Gv, EX, XX }, | |
3259 | + { "cvttpd2pi", MX, EX, XX }, | |
3260 | + { "cvttsd2siY", Gv, EX, XX }, | |
3261 | + }, | |
3262 | + /* PREGRP5 */ | |
3263 | + { | |
3264 | + { "divps", XM, EX, XX }, | |
3265 | + { "divss", XM, EX, XX }, | |
3266 | + { "divpd", XM, EX, XX }, | |
3267 | + { "divsd", XM, EX, XX }, | |
3268 | + }, | |
3269 | + /* PREGRP6 */ | |
3270 | + { | |
3271 | + { "maxps", XM, EX, XX }, | |
3272 | + { "maxss", XM, EX, XX }, | |
3273 | + { "maxpd", XM, EX, XX }, | |
3274 | + { "maxsd", XM, EX, XX }, | |
3275 | + }, | |
3276 | + /* PREGRP7 */ | |
3277 | + { | |
3278 | + { "minps", XM, EX, XX }, | |
3279 | + { "minss", XM, EX, XX }, | |
3280 | + { "minpd", XM, EX, XX }, | |
3281 | + { "minsd", XM, EX, XX }, | |
3282 | + }, | |
3283 | + /* PREGRP8 */ | |
3284 | + { | |
3285 | + { "movups", XM, EX, XX }, | |
3286 | + { "movss", XM, EX, XX }, | |
3287 | + { "movupd", XM, EX, XX }, | |
3288 | + { "movsd", XM, EX, XX }, | |
3289 | + }, | |
3290 | + /* PREGRP9 */ | |
3291 | + { | |
3292 | + { "movups", EX, XM, XX }, | |
3293 | + { "movss", EX, XM, XX }, | |
3294 | + { "movupd", EX, XM, XX }, | |
3295 | + { "movsd", EX, XM, XX }, | |
3296 | + }, | |
3297 | + /* PREGRP10 */ | |
3298 | + { | |
3299 | + { "mulps", XM, EX, XX }, | |
3300 | + { "mulss", XM, EX, XX }, | |
3301 | + { "mulpd", XM, EX, XX }, | |
3302 | + { "mulsd", XM, EX, XX }, | |
3303 | + }, | |
3304 | + /* PREGRP11 */ | |
3305 | + { | |
3306 | + { "rcpps", XM, EX, XX }, | |
3307 | + { "rcpss", XM, EX, XX }, | |
3308 | + { "(bad)", XM, EX, XX }, | |
3309 | + { "(bad)", XM, EX, XX }, | |
3310 | + }, | |
3311 | + /* PREGRP12 */ | |
3312 | + { | |
3313 | + { "rsqrtps", XM, EX, XX }, | |
3314 | + { "rsqrtss", XM, EX, XX }, | |
3315 | + { "(bad)", XM, EX, XX }, | |
3316 | + { "(bad)", XM, EX, XX }, | |
3317 | + }, | |
3318 | + /* PREGRP13 */ | |
3319 | + { | |
3320 | + { "sqrtps", XM, EX, XX }, | |
3321 | + { "sqrtss", XM, EX, XX }, | |
3322 | + { "sqrtpd", XM, EX, XX }, | |
3323 | + { "sqrtsd", XM, EX, XX }, | |
3324 | + }, | |
3325 | + /* PREGRP14 */ | |
3326 | + { | |
3327 | + { "subps", XM, EX, XX }, | |
3328 | + { "subss", XM, EX, XX }, | |
3329 | + { "subpd", XM, EX, XX }, | |
3330 | + { "subsd", XM, EX, XX }, | |
3331 | + }, | |
3332 | + /* PREGRP15 */ | |
3333 | + { | |
3334 | + { "(bad)", XM, EX, XX }, | |
3335 | + { "cvtdq2pd", XM, EX, XX }, | |
3336 | + { "cvttpd2dq", XM, EX, XX }, | |
3337 | + { "cvtpd2dq", XM, EX, XX }, | |
3338 | + }, | |
3339 | + /* PREGRP16 */ | |
3340 | + { | |
3341 | + { "cvtdq2ps", XM, EX, XX }, | |
3342 | + { "cvttps2dq",XM, EX, XX }, | |
3343 | + { "cvtps2dq",XM, EX, XX }, | |
3344 | + { "(bad)", XM, EX, XX }, | |
3345 | + }, | |
3346 | + /* PREGRP17 */ | |
3347 | + { | |
3348 | + { "cvtps2pd", XM, EX, XX }, | |
3349 | + { "cvtss2sd", XM, EX, XX }, | |
3350 | + { "cvtpd2ps", XM, EX, XX }, | |
3351 | + { "cvtsd2ss", XM, EX, XX }, | |
3352 | + }, | |
3353 | + /* PREGRP18 */ | |
3354 | + { | |
3355 | + { "maskmovq", MX, MS, XX }, | |
3356 | + { "(bad)", XM, EX, XX }, | |
3357 | + { "maskmovdqu", XM, EX, XX }, | |
3358 | + { "(bad)", XM, EX, XX }, | |
3359 | + }, | |
3360 | + /* PREGRP19 */ | |
3361 | + { | |
3362 | + { "movq", MX, EM, XX }, | |
3363 | + { "movdqu", XM, EX, XX }, | |
3364 | + { "movdqa", XM, EX, XX }, | |
3365 | + { "(bad)", XM, EX, XX }, | |
3366 | + }, | |
3367 | + /* PREGRP20 */ | |
3368 | + { | |
3369 | + { "movq", EM, MX, XX }, | |
3370 | + { "movdqu", EX, XM, XX }, | |
3371 | + { "movdqa", EX, XM, XX }, | |
3372 | + { "(bad)", EX, XM, XX }, | |
3373 | + }, | |
3374 | + /* PREGRP21 */ | |
3375 | + { | |
3376 | + { "(bad)", EX, XM, XX }, | |
3377 | + { "movq2dq", XM, MS, XX }, | |
3378 | + { "movq", EX, XM, XX }, | |
3379 | + { "movdq2q", MX, XS, XX }, | |
3380 | + }, | |
3381 | + /* PREGRP22 */ | |
3382 | + { | |
3383 | + { "pshufw", MX, EM, Ib }, | |
3384 | + { "pshufhw", XM, EX, Ib }, | |
3385 | + { "pshufd", XM, EX, Ib }, | |
3386 | + { "pshuflw", XM, EX, Ib }, | |
3387 | + }, | |
3388 | + /* PREGRP23 */ | |
3389 | + { | |
3390 | + { "movd", Edq, MX, XX }, | |
3391 | + { "movq", XM, EX, XX }, | |
3392 | + { "movd", Edq, XM, XX }, | |
3393 | + { "(bad)", Ed, XM, XX }, | |
3394 | + }, | |
3395 | + /* PREGRP24 */ | |
3396 | + { | |
3397 | + { "(bad)", MX, EX, XX }, | |
3398 | + { "(bad)", XM, EX, XX }, | |
3399 | + { "punpckhqdq", XM, EX, XX }, | |
3400 | + { "(bad)", XM, EX, XX }, | |
3401 | + }, | |
3402 | + /* PREGRP25 */ | |
3403 | + { | |
3404 | + { "movntq", EM, MX, XX }, | |
3405 | + { "(bad)", EM, XM, XX }, | |
3406 | + { "movntdq", EM, XM, XX }, | |
3407 | + { "(bad)", EM, XM, XX }, | |
3408 | + }, | |
3409 | + /* PREGRP26 */ | |
3410 | + { | |
3411 | + { "(bad)", MX, EX, XX }, | |
3412 | + { "(bad)", XM, EX, XX }, | |
3413 | + { "punpcklqdq", XM, EX, XX }, | |
3414 | + { "(bad)", XM, EX, XX }, | |
3415 | + }, | |
3416 | + /* PREGRP27 */ | |
3417 | + { | |
3418 | + { "(bad)", MX, EX, XX }, | |
3419 | + { "(bad)", XM, EX, XX }, | |
3420 | + { "addsubpd", XM, EX, XX }, | |
3421 | + { "addsubps", XM, EX, XX }, | |
3422 | + }, | |
3423 | + /* PREGRP28 */ | |
3424 | + { | |
3425 | + { "(bad)", MX, EX, XX }, | |
3426 | + { "(bad)", XM, EX, XX }, | |
3427 | + { "haddpd", XM, EX, XX }, | |
3428 | + { "haddps", XM, EX, XX }, | |
3429 | + }, | |
3430 | + /* PREGRP29 */ | |
3431 | + { | |
3432 | + { "(bad)", MX, EX, XX }, | |
3433 | + { "(bad)", XM, EX, XX }, | |
3434 | + { "hsubpd", XM, EX, XX }, | |
3435 | + { "hsubps", XM, EX, XX }, | |
3436 | + }, | |
3437 | + /* PREGRP30 */ | |
3438 | + { | |
3439 | + { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */ | |
3440 | + { "movsldup", XM, EX, XX }, | |
3441 | + { "movlpd", XM, EX, XX }, | |
3442 | + { "movddup", XM, EX, XX }, | |
3443 | + }, | |
3444 | + /* PREGRP31 */ | |
3445 | + { | |
3446 | + { "movhpX", XM, EX, SIMD_Fixup, 'l' }, | |
3447 | + { "movshdup", XM, EX, XX }, | |
3448 | + { "movhpd", XM, EX, XX }, | |
3449 | + { "(bad)", XM, EX, XX }, | |
3450 | + }, | |
3451 | + /* PREGRP32 */ | |
3452 | + { | |
3453 | + { "(bad)", XM, EX, XX }, | |
3454 | + { "(bad)", XM, EX, XX }, | |
3455 | + { "(bad)", XM, EX, XX }, | |
3456 | + { "lddqu", XM, M, XX }, | |
3457 | + }, | |
3458 | +}; | |
3459 | + | |
3460 | +static const struct dis386 x86_64_table[][2] = { | |
3461 | + { | |
3462 | + { "arpl", Ew, Gw, XX }, | |
3463 | + { "movs{||lq|xd}", Gv, Ed, XX }, | |
3464 | + }, | |
3465 | +}; | |
3466 | + | |
3467 | +#ifdef __KERNEL__ | |
3468 | +#define INTERNAL_DISASSEMBLER_ERROR "<internal disassembler error>" | |
3469 | +#else /* __KERNEL__ */ | |
3470 | +#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>") | |
3471 | +#endif /* __KERNEL__ */ | |
3472 | + | |
3473 | +static void | |
3474 | +ckprefix (void) | |
3475 | +{ | |
3476 | + int newrex; | |
3477 | + rex = 0; | |
3478 | + prefixes = 0; | |
3479 | + used_prefixes = 0; | |
3480 | + rex_used = 0; | |
3481 | + while (1) | |
3482 | + { | |
3483 | + FETCH_DATA (the_info, codep + 1); | |
3484 | + newrex = 0; | |
3485 | + switch (*codep) | |
3486 | + { | |
3487 | + /* REX prefixes family. */ | |
3488 | + case 0x40: | |
3489 | + case 0x41: | |
3490 | + case 0x42: | |
3491 | + case 0x43: | |
3492 | + case 0x44: | |
3493 | + case 0x45: | |
3494 | + case 0x46: | |
3495 | + case 0x47: | |
3496 | + case 0x48: | |
3497 | + case 0x49: | |
3498 | + case 0x4a: | |
3499 | + case 0x4b: | |
3500 | + case 0x4c: | |
3501 | + case 0x4d: | |
3502 | + case 0x4e: | |
3503 | + case 0x4f: | |
3504 | + if (mode_64bit) | |
3505 | + newrex = *codep; | |
3506 | + else | |
3507 | + return; | |
3508 | + break; | |
3509 | + case 0xf3: | |
3510 | + prefixes |= PREFIX_REPZ; | |
3511 | + break; | |
3512 | + case 0xf2: | |
3513 | + prefixes |= PREFIX_REPNZ; | |
3514 | + break; | |
3515 | + case 0xf0: | |
3516 | + prefixes |= PREFIX_LOCK; | |
3517 | + break; | |
3518 | + case 0x2e: | |
3519 | + prefixes |= PREFIX_CS; | |
3520 | + break; | |
3521 | + case 0x36: | |
3522 | + prefixes |= PREFIX_SS; | |
3523 | + break; | |
3524 | + case 0x3e: | |
3525 | + prefixes |= PREFIX_DS; | |
3526 | + break; | |
3527 | + case 0x26: | |
3528 | + prefixes |= PREFIX_ES; | |
3529 | + break; | |
3530 | + case 0x64: | |
3531 | + prefixes |= PREFIX_FS; | |
3532 | + break; | |
3533 | + case 0x65: | |
3534 | + prefixes |= PREFIX_GS; | |
3535 | + break; | |
3536 | + case 0x66: | |
3537 | + prefixes |= PREFIX_DATA; | |
3538 | + break; | |
3539 | + case 0x67: | |
3540 | + prefixes |= PREFIX_ADDR; | |
3541 | + break; | |
3542 | + case FWAIT_OPCODE: | |
3543 | + /* fwait is really an instruction. If there are prefixes | |
3544 | + before the fwait, they belong to the fwait, *not* to the | |
3545 | + following instruction. */ | |
3546 | + if (prefixes) | |
3547 | + { | |
3548 | + prefixes |= PREFIX_FWAIT; | |
3549 | + codep++; | |
3550 | + return; | |
3551 | + } | |
3552 | + prefixes = PREFIX_FWAIT; | |
3553 | + break; | |
3554 | + default: | |
3555 | + return; | |
3556 | + } | |
3557 | + /* Rex is ignored when followed by another prefix. */ | |
3558 | + if (rex) | |
3559 | + { | |
3560 | + oappend (prefix_name (rex, 0)); | |
3561 | + oappend (" "); | |
3562 | + } | |
3563 | + rex = newrex; | |
3564 | + codep++; | |
3565 | + } | |
3566 | +} | |
3567 | + | |
3568 | +/* Return the name of the prefix byte PREF, or NULL if PREF is not a | |
3569 | + prefix byte. */ | |
3570 | + | |
3571 | +static const char * | |
3572 | +prefix_name (int pref, int sizeflag) | |
3573 | +{ | |
3574 | + switch (pref) | |
3575 | + { | |
3576 | + /* REX prefixes family. */ | |
3577 | + case 0x40: | |
3578 | + return "rex"; | |
3579 | + case 0x41: | |
3580 | + return "rexZ"; | |
3581 | + case 0x42: | |
3582 | + return "rexY"; | |
3583 | + case 0x43: | |
3584 | + return "rexYZ"; | |
3585 | + case 0x44: | |
3586 | + return "rexX"; | |
3587 | + case 0x45: | |
3588 | + return "rexXZ"; | |
3589 | + case 0x46: | |
3590 | + return "rexXY"; | |
3591 | + case 0x47: | |
3592 | + return "rexXYZ"; | |
3593 | + case 0x48: | |
3594 | + return "rex64"; | |
3595 | + case 0x49: | |
3596 | + return "rex64Z"; | |
3597 | + case 0x4a: | |
3598 | + return "rex64Y"; | |
3599 | + case 0x4b: | |
3600 | + return "rex64YZ"; | |
3601 | + case 0x4c: | |
3602 | + return "rex64X"; | |
3603 | + case 0x4d: | |
3604 | + return "rex64XZ"; | |
3605 | + case 0x4e: | |
3606 | + return "rex64XY"; | |
3607 | + case 0x4f: | |
3608 | + return "rex64XYZ"; | |
3609 | + case 0xf3: | |
3610 | + return "repz"; | |
3611 | + case 0xf2: | |
3612 | + return "repnz"; | |
3613 | + case 0xf0: | |
3614 | + return "lock"; | |
3615 | + case 0x2e: | |
3616 | + return "cs"; | |
3617 | + case 0x36: | |
3618 | + return "ss"; | |
3619 | + case 0x3e: | |
3620 | + return "ds"; | |
3621 | + case 0x26: | |
3622 | + return "es"; | |
3623 | + case 0x64: | |
3624 | + return "fs"; | |
3625 | + case 0x65: | |
3626 | + return "gs"; | |
3627 | + case 0x66: | |
3628 | + return (sizeflag & DFLAG) ? "data16" : "data32"; | |
3629 | + case 0x67: | |
3630 | + if (mode_64bit) | |
3631 | + return (sizeflag & AFLAG) ? "addr32" : "addr64"; | |
3632 | + else | |
3633 | + return (sizeflag & AFLAG) ? "addr16" : "addr32"; | |
3634 | + case FWAIT_OPCODE: | |
3635 | + return "fwait"; | |
3636 | + default: | |
3637 | + return NULL; | |
3638 | + } | |
3639 | +} | |
3640 | + | |
3641 | +static char op1out[100], op2out[100], op3out[100]; | |
3642 | +static int op_ad, op_index[3]; | |
3643 | +static int two_source_ops; | |
3644 | +static bfd_vma op_address[3]; | |
3645 | +static bfd_vma op_riprel[3]; | |
3646 | +static bfd_vma start_pc; | |
3647 | +\f | |
3648 | +/* | |
3649 | + * On the 386's of 1988, the maximum length of an instruction is 15 bytes. | |
3650 | + * (see topic "Redundant prefixes" in the "Differences from 8086" | |
3651 | + * section of the "Virtual 8086 Mode" chapter.) | |
3652 | + * 'pc' should be the address of this instruction, it will | |
3653 | + * be used to print the target address if this is a relative jump or call | |
3654 | + * The function returns the length of this instruction in bytes. | |
3655 | + */ | |
3656 | + | |
3657 | +static char intel_syntax; | |
3658 | +static char open_char; | |
3659 | +static char close_char; | |
3660 | +static char separator_char; | |
3661 | +static char scale_char; | |
3662 | + | |
3663 | +/* Here for backwards compatibility. When gdb stops using | |
3664 | + print_insn_i386_att and print_insn_i386_intel these functions can | |
3665 | + disappear, and print_insn_i386 be merged into print_insn. */ | |
3666 | +int | |
3667 | +print_insn_i386_att (bfd_vma pc, disassemble_info *info) | |
3668 | +{ | |
3669 | + intel_syntax = 0; | |
3670 | + | |
3671 | + return print_insn (pc, info); | |
3672 | +} | |
3673 | + | |
3674 | +int | |
3675 | +print_insn_i386_intel (bfd_vma pc, disassemble_info *info) | |
3676 | +{ | |
3677 | + intel_syntax = 1; | |
3678 | + | |
3679 | + return print_insn (pc, info); | |
3680 | +} | |
3681 | + | |
3682 | +int | |
3683 | +print_insn_i386 (bfd_vma pc, disassemble_info *info) | |
3684 | +{ | |
3685 | + intel_syntax = -1; | |
3686 | + | |
3687 | + return print_insn (pc, info); | |
3688 | +} | |
3689 | + | |
3690 | +static int | |
3691 | +print_insn (bfd_vma pc, disassemble_info *info) | |
3692 | +{ | |
3693 | + const struct dis386 *dp; | |
3694 | + int i; | |
3695 | + char *first, *second, *third; | |
3696 | + int needcomma; | |
3697 | + unsigned char uses_SSE_prefix, uses_LOCK_prefix; | |
3698 | + int sizeflag; | |
3699 | + const char *p; | |
3700 | + struct dis_private priv; | |
3701 | + | |
3702 | + mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax | |
3703 | + || info->mach == bfd_mach_x86_64); | |
3704 | + | |
3705 | + if (intel_syntax == (char) -1) | |
3706 | + intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax | |
3707 | + || info->mach == bfd_mach_x86_64_intel_syntax); | |
3708 | + | |
3709 | + if (info->mach == bfd_mach_i386_i386 | |
3710 | + || info->mach == bfd_mach_x86_64 | |
3711 | + || info->mach == bfd_mach_i386_i386_intel_syntax | |
3712 | + || info->mach == bfd_mach_x86_64_intel_syntax) | |
3713 | + priv.orig_sizeflag = AFLAG | DFLAG; | |
3714 | + else if (info->mach == bfd_mach_i386_i8086) | |
3715 | + priv.orig_sizeflag = 0; | |
3716 | + else | |
3717 | + abort (); | |
3718 | + | |
3719 | + for (p = info->disassembler_options; p != NULL; ) | |
3720 | + { | |
3721 | + if (strncmp (p, "x86-64", 6) == 0) | |
3722 | + { | |
3723 | + mode_64bit = 1; | |
3724 | + priv.orig_sizeflag = AFLAG | DFLAG; | |
3725 | + } | |
3726 | + else if (strncmp (p, "i386", 4) == 0) | |
3727 | + { | |
3728 | + mode_64bit = 0; | |
3729 | + priv.orig_sizeflag = AFLAG | DFLAG; | |
3730 | + } | |
3731 | + else if (strncmp (p, "i8086", 5) == 0) | |
3732 | + { | |
3733 | + mode_64bit = 0; | |
3734 | + priv.orig_sizeflag = 0; | |
3735 | + } | |
3736 | + else if (strncmp (p, "intel", 5) == 0) | |
3737 | + { | |
3738 | + intel_syntax = 1; | |
3739 | + } | |
3740 | + else if (strncmp (p, "att", 3) == 0) | |
3741 | + { | |
3742 | + intel_syntax = 0; | |
3743 | + } | |
3744 | + else if (strncmp (p, "addr", 4) == 0) | |
3745 | + { | |
3746 | + if (p[4] == '1' && p[5] == '6') | |
3747 | + priv.orig_sizeflag &= ~AFLAG; | |
3748 | + else if (p[4] == '3' && p[5] == '2') | |
3749 | + priv.orig_sizeflag |= AFLAG; | |
3750 | + } | |
3751 | + else if (strncmp (p, "data", 4) == 0) | |
3752 | + { | |
3753 | + if (p[4] == '1' && p[5] == '6') | |
3754 | + priv.orig_sizeflag &= ~DFLAG; | |
3755 | + else if (p[4] == '3' && p[5] == '2') | |
3756 | + priv.orig_sizeflag |= DFLAG; | |
3757 | + } | |
3758 | + else if (strncmp (p, "suffix", 6) == 0) | |
3759 | + priv.orig_sizeflag |= SUFFIX_ALWAYS; | |
3760 | + | |
3761 | + p = strchr (p, ','); | |
3762 | + if (p != NULL) | |
3763 | + p++; | |
3764 | + } | |
3765 | + | |
3766 | + if (intel_syntax) | |
3767 | + { | |
3768 | + names64 = intel_names64; | |
3769 | + names32 = intel_names32; | |
3770 | + names16 = intel_names16; | |
3771 | + names8 = intel_names8; | |
3772 | + names8rex = intel_names8rex; | |
3773 | + names_seg = intel_names_seg; | |
3774 | + index16 = intel_index16; | |
3775 | + open_char = '['; | |
3776 | + close_char = ']'; | |
3777 | + separator_char = '+'; | |
3778 | + scale_char = '*'; | |
3779 | + } | |
3780 | + else | |
3781 | + { | |
3782 | + names64 = att_names64; | |
3783 | + names32 = att_names32; | |
3784 | + names16 = att_names16; | |
3785 | + names8 = att_names8; | |
3786 | + names8rex = att_names8rex; | |
3787 | + names_seg = att_names_seg; | |
3788 | + index16 = att_index16; | |
3789 | + open_char = '('; | |
3790 | + close_char = ')'; | |
3791 | + separator_char = ','; | |
3792 | + scale_char = ','; | |
3793 | + } | |
3794 | + | |
3795 | + /* The output looks better if we put 7 bytes on a line, since that | |
3796 | + puts most long word instructions on a single line. */ | |
3797 | + info->bytes_per_line = 7; | |
3798 | + | |
3799 | + info->private_data = &priv; | |
3800 | + priv.max_fetched = priv.the_buffer; | |
3801 | + priv.insn_start = pc; | |
3802 | + | |
3803 | + obuf[0] = 0; | |
3804 | + op1out[0] = 0; | |
3805 | + op2out[0] = 0; | |
3806 | + op3out[0] = 0; | |
3807 | + | |
3808 | + op_index[0] = op_index[1] = op_index[2] = -1; | |
3809 | + | |
3810 | + the_info = info; | |
3811 | + start_pc = pc; | |
3812 | + start_codep = priv.the_buffer; | |
3813 | + codep = priv.the_buffer; | |
3814 | + | |
3815 | +#ifndef __KERNEL__ | |
3816 | + if (setjmp (priv.bailout) != 0) | |
3817 | + { | |
3818 | + const char *name; | |
3819 | + | |
3820 | + /* Getting here means we tried for data but didn't get it. That | |
3821 | + means we have an incomplete instruction of some sort. Just | |
3822 | + print the first byte as a prefix or a .byte pseudo-op. */ | |
3823 | + if (codep > priv.the_buffer) | |
3824 | + { | |
3825 | + name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag); | |
3826 | + if (name != NULL) | |
3827 | + (*info->fprintf_func) (info->stream, "%s", name); | |
3828 | + else | |
3829 | + { | |
3830 | + /* Just print the first byte as a .byte instruction. */ | |
3831 | + (*info->fprintf_func) (info->stream, ".byte 0x%x", | |
3832 | + (unsigned int) priv.the_buffer[0]); | |
3833 | + } | |
3834 | + | |
3835 | + return 1; | |
3836 | + } | |
3837 | + | |
3838 | + return -1; | |
3839 | + } | |
3840 | +#endif /* __KERNEL__ */ | |
3841 | + | |
3842 | + obufp = obuf; | |
3843 | + ckprefix (); | |
3844 | + | |
3845 | + insn_codep = codep; | |
3846 | + sizeflag = priv.orig_sizeflag; | |
3847 | + | |
3848 | + FETCH_DATA (info, codep + 1); | |
3849 | + two_source_ops = (*codep == 0x62) || (*codep == 0xc8); | |
3850 | + | |
3851 | + if ((prefixes & PREFIX_FWAIT) | |
3852 | + && ((*codep < 0xd8) || (*codep > 0xdf))) | |
3853 | + { | |
3854 | + const char *name; | |
3855 | + | |
3856 | + /* fwait not followed by floating point instruction. Print the | |
3857 | + first prefix, which is probably fwait itself. */ | |
3858 | + name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag); | |
3859 | + if (name == NULL) | |
3860 | + name = INTERNAL_DISASSEMBLER_ERROR; | |
3861 | + (*info->fprintf_func) (info->stream, "%s", name); | |
3862 | + return 1; | |
3863 | + } | |
3864 | + | |
3865 | + if (*codep == 0x0f) | |
3866 | + { | |
3867 | + FETCH_DATA (info, codep + 2); | |
3868 | + dp = &dis386_twobyte[*++codep]; | |
3869 | + need_modrm = twobyte_has_modrm[*codep]; | |
3870 | + uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep]; | |
3871 | + uses_LOCK_prefix = (*codep & ~0x02) == 0x20; | |
3872 | + } | |
3873 | + else | |
3874 | + { | |
3875 | + dp = &dis386[*codep]; | |
3876 | + need_modrm = onebyte_has_modrm[*codep]; | |
3877 | + uses_SSE_prefix = 0; | |
3878 | + uses_LOCK_prefix = 0; | |
3879 | + } | |
3880 | + codep++; | |
3881 | + | |
3882 | + if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ)) | |
3883 | + { | |
3884 | + oappend ("repz "); | |
3885 | + used_prefixes |= PREFIX_REPZ; | |
3886 | + } | |
3887 | + if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ)) | |
3888 | + { | |
3889 | + oappend ("repnz "); | |
3890 | + used_prefixes |= PREFIX_REPNZ; | |
3891 | + } | |
3892 | + if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK)) | |
3893 | + { | |
3894 | + oappend ("lock "); | |
3895 | + used_prefixes |= PREFIX_LOCK; | |
3896 | + } | |
3897 | + | |
3898 | + if (prefixes & PREFIX_ADDR) | |
3899 | + { | |
3900 | + sizeflag ^= AFLAG; | |
3901 | + if (dp->bytemode3 != loop_jcxz_mode || intel_syntax) | |
3902 | + { | |
3903 | + if ((sizeflag & AFLAG) || mode_64bit) | |
3904 | + oappend ("addr32 "); | |
3905 | + else | |
3906 | + oappend ("addr16 "); | |
3907 | + used_prefixes |= PREFIX_ADDR; | |
3908 | + } | |
3909 | + } | |
3910 | + | |
3911 | + if (!uses_SSE_prefix && (prefixes & PREFIX_DATA)) | |
3912 | + { | |
3913 | + sizeflag ^= DFLAG; | |
3914 | + if (dp->bytemode3 == cond_jump_mode | |
3915 | + && dp->bytemode1 == v_mode | |
3916 | + && !intel_syntax) | |
3917 | + { | |
3918 | + if (sizeflag & DFLAG) | |
3919 | + oappend ("data32 "); | |
3920 | + else | |
3921 | + oappend ("data16 "); | |
3922 | + used_prefixes |= PREFIX_DATA; | |
3923 | + } | |
3924 | + } | |
3925 | + | |
3926 | + if (need_modrm) | |
3927 | + { | |
3928 | + FETCH_DATA (info, codep + 1); | |
3929 | + mod = (*codep >> 6) & 3; | |
3930 | + reg = (*codep >> 3) & 7; | |
3931 | + rm = *codep & 7; | |
3932 | + } | |
3933 | + | |
3934 | + if (dp->name == NULL && dp->bytemode1 == FLOATCODE) | |
3935 | + { | |
3936 | + dofloat (sizeflag); | |
3937 | + } | |
3938 | + else | |
3939 | + { | |
3940 | + int index; | |
3941 | + if (dp->name == NULL) | |
3942 | + { | |
3943 | + switch (dp->bytemode1) | |
3944 | + { | |
3945 | + case USE_GROUPS: | |
3946 | + dp = &grps[dp->bytemode2][reg]; | |
3947 | + break; | |
3948 | + | |
3949 | + case USE_PREFIX_USER_TABLE: | |
3950 | + index = 0; | |
3951 | + used_prefixes |= (prefixes & PREFIX_REPZ); | |
3952 | + if (prefixes & PREFIX_REPZ) | |
3953 | + index = 1; | |
3954 | + else | |
3955 | + { | |
3956 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
3957 | + if (prefixes & PREFIX_DATA) | |
3958 | + index = 2; | |
3959 | + else | |
3960 | + { | |
3961 | + used_prefixes |= (prefixes & PREFIX_REPNZ); | |
3962 | + if (prefixes & PREFIX_REPNZ) | |
3963 | + index = 3; | |
3964 | + } | |
3965 | + } | |
3966 | + dp = &prefix_user_table[dp->bytemode2][index]; | |
3967 | + break; | |
3968 | + | |
3969 | + case X86_64_SPECIAL: | |
3970 | + dp = &x86_64_table[dp->bytemode2][mode_64bit]; | |
3971 | + break; | |
3972 | + | |
3973 | + default: | |
3974 | + oappend (INTERNAL_DISASSEMBLER_ERROR); | |
3975 | + break; | |
3976 | + } | |
3977 | + } | |
3978 | + | |
3979 | + if (putop (dp->name, sizeflag) == 0) | |
3980 | + { | |
3981 | + obufp = op1out; | |
3982 | + op_ad = 2; | |
3983 | + if (dp->op1) | |
3984 | + (*dp->op1) (dp->bytemode1, sizeflag); | |
3985 | + | |
3986 | + obufp = op2out; | |
3987 | + op_ad = 1; | |
3988 | + if (dp->op2) | |
3989 | + (*dp->op2) (dp->bytemode2, sizeflag); | |
3990 | + | |
3991 | + obufp = op3out; | |
3992 | + op_ad = 0; | |
3993 | + if (dp->op3) | |
3994 | + (*dp->op3) (dp->bytemode3, sizeflag); | |
3995 | + } | |
3996 | + } | |
3997 | + | |
3998 | + /* See if any prefixes were not used. If so, print the first one | |
3999 | + separately. If we don't do this, we'll wind up printing an | |
4000 | + instruction stream which does not precisely correspond to the | |
4001 | + bytes we are disassembling. */ | |
4002 | + if ((prefixes & ~used_prefixes) != 0) | |
4003 | + { | |
4004 | + const char *name; | |
4005 | + | |
4006 | + name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag); | |
4007 | + if (name == NULL) | |
4008 | + name = INTERNAL_DISASSEMBLER_ERROR; | |
4009 | + (*info->fprintf_func) (info->stream, "%s", name); | |
4010 | + return 1; | |
4011 | + } | |
4012 | + if (rex & ~rex_used) | |
4013 | + { | |
4014 | + const char *name; | |
4015 | + name = prefix_name (rex | 0x40, priv.orig_sizeflag); | |
4016 | + if (name == NULL) | |
4017 | + name = INTERNAL_DISASSEMBLER_ERROR; | |
4018 | + (*info->fprintf_func) (info->stream, "%s ", name); | |
4019 | + } | |
4020 | + | |
4021 | + obufp = obuf + strlen (obuf); | |
4022 | + for (i = strlen (obuf); i < 6; i++) | |
4023 | + oappend (" "); | |
4024 | + oappend (" "); | |
4025 | + (*info->fprintf_func) (info->stream, "%s", obuf); | |
4026 | + | |
4027 | + /* The enter and bound instructions are printed with operands in the same | |
4028 | + order as the intel book; everything else is printed in reverse order. */ | |
4029 | + if (intel_syntax || two_source_ops) | |
4030 | + { | |
4031 | + first = op1out; | |
4032 | + second = op2out; | |
4033 | + third = op3out; | |
4034 | + op_ad = op_index[0]; | |
4035 | + op_index[0] = op_index[2]; | |
4036 | + op_index[2] = op_ad; | |
4037 | + } | |
4038 | + else | |
4039 | + { | |
4040 | + first = op3out; | |
4041 | + second = op2out; | |
4042 | + third = op1out; | |
4043 | + } | |
4044 | + needcomma = 0; | |
4045 | + if (*first) | |
4046 | + { | |
4047 | + if (op_index[0] != -1 && !op_riprel[0]) | |
4048 | + (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info); | |
4049 | + else | |
4050 | + (*info->fprintf_func) (info->stream, "%s", first); | |
4051 | + needcomma = 1; | |
4052 | + } | |
4053 | + if (*second) | |
4054 | + { | |
4055 | + if (needcomma) | |
4056 | + (*info->fprintf_func) (info->stream, ","); | |
4057 | + if (op_index[1] != -1 && !op_riprel[1]) | |
4058 | + (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info); | |
4059 | + else | |
4060 | + (*info->fprintf_func) (info->stream, "%s", second); | |
4061 | + needcomma = 1; | |
4062 | + } | |
4063 | + if (*third) | |
4064 | + { | |
4065 | + if (needcomma) | |
4066 | + (*info->fprintf_func) (info->stream, ","); | |
4067 | + if (op_index[2] != -1 && !op_riprel[2]) | |
4068 | + (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info); | |
4069 | + else | |
4070 | + (*info->fprintf_func) (info->stream, "%s", third); | |
4071 | + } | |
4072 | + for (i = 0; i < 3; i++) | |
4073 | + if (op_index[i] != -1 && op_riprel[i]) | |
4074 | + { | |
4075 | + (*info->fprintf_func) (info->stream, " # "); | |
4076 | + (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep | |
4077 | + + op_address[op_index[i]]), info); | |
4078 | + } | |
4079 | + return codep - priv.the_buffer; | |
4080 | +} | |
4081 | + | |
4082 | +static const char *float_mem[] = { | |
4083 | + /* d8 */ | |
4084 | + "fadd{s||s|}", | |
4085 | + "fmul{s||s|}", | |
4086 | + "fcom{s||s|}", | |
4087 | + "fcomp{s||s|}", | |
4088 | + "fsub{s||s|}", | |
4089 | + "fsubr{s||s|}", | |
4090 | + "fdiv{s||s|}", | |
4091 | + "fdivr{s||s|}", | |
4092 | + /* d9 */ | |
4093 | + "fld{s||s|}", | |
4094 | + "(bad)", | |
4095 | + "fst{s||s|}", | |
4096 | + "fstp{s||s|}", | |
4097 | + "fldenvIC", | |
4098 | + "fldcw", | |
4099 | + "fNstenvIC", | |
4100 | + "fNstcw", | |
4101 | + /* da */ | |
4102 | + "fiadd{l||l|}", | |
4103 | + "fimul{l||l|}", | |
4104 | + "ficom{l||l|}", | |
4105 | + "ficomp{l||l|}", | |
4106 | + "fisub{l||l|}", | |
4107 | + "fisubr{l||l|}", | |
4108 | + "fidiv{l||l|}", | |
4109 | + "fidivr{l||l|}", | |
4110 | + /* db */ | |
4111 | + "fild{l||l|}", | |
4112 | + "fisttp{l||l|}", | |
4113 | + "fist{l||l|}", | |
4114 | + "fistp{l||l|}", | |
4115 | + "(bad)", | |
4116 | + "fld{t||t|}", | |
4117 | + "(bad)", | |
4118 | + "fstp{t||t|}", | |
4119 | + /* dc */ | |
4120 | + "fadd{l||l|}", | |
4121 | + "fmul{l||l|}", | |
4122 | + "fcom{l||l|}", | |
4123 | + "fcomp{l||l|}", | |
4124 | + "fsub{l||l|}", | |
4125 | + "fsubr{l||l|}", | |
4126 | + "fdiv{l||l|}", | |
4127 | + "fdivr{l||l|}", | |
4128 | + /* dd */ | |
4129 | + "fld{l||l|}", | |
4130 | + "fisttp{ll||ll|}", | |
4131 | + "fst{l||l|}", | |
4132 | + "fstp{l||l|}", | |
4133 | + "frstorIC", | |
4134 | + "(bad)", | |
4135 | + "fNsaveIC", | |
4136 | + "fNstsw", | |
4137 | + /* de */ | |
4138 | + "fiadd", | |
4139 | + "fimul", | |
4140 | + "ficom", | |
4141 | + "ficomp", | |
4142 | + "fisub", | |
4143 | + "fisubr", | |
4144 | + "fidiv", | |
4145 | + "fidivr", | |
4146 | + /* df */ | |
4147 | + "fild", | |
4148 | + "fisttp", | |
4149 | + "fist", | |
4150 | + "fistp", | |
4151 | + "fbld", | |
4152 | + "fild{ll||ll|}", | |
4153 | + "fbstp", | |
4154 | + "fistp{ll||ll|}", | |
4155 | +}; | |
4156 | + | |
4157 | +static const unsigned char float_mem_mode[] = { | |
4158 | + /* d8 */ | |
4159 | + d_mode, | |
4160 | + d_mode, | |
4161 | + d_mode, | |
4162 | + d_mode, | |
4163 | + d_mode, | |
4164 | + d_mode, | |
4165 | + d_mode, | |
4166 | + d_mode, | |
4167 | + /* d9 */ | |
4168 | + d_mode, | |
4169 | + 0, | |
4170 | + d_mode, | |
4171 | + d_mode, | |
4172 | + 0, | |
4173 | + w_mode, | |
4174 | + 0, | |
4175 | + w_mode, | |
4176 | + /* da */ | |
4177 | + d_mode, | |
4178 | + d_mode, | |
4179 | + d_mode, | |
4180 | + d_mode, | |
4181 | + d_mode, | |
4182 | + d_mode, | |
4183 | + d_mode, | |
4184 | + d_mode, | |
4185 | + /* db */ | |
4186 | + d_mode, | |
4187 | + d_mode, | |
4188 | + d_mode, | |
4189 | + d_mode, | |
4190 | + 0, | |
4191 | + t_mode, | |
4192 | + 0, | |
4193 | + t_mode, | |
4194 | + /* dc */ | |
4195 | + q_mode, | |
4196 | + q_mode, | |
4197 | + q_mode, | |
4198 | + q_mode, | |
4199 | + q_mode, | |
4200 | + q_mode, | |
4201 | + q_mode, | |
4202 | + q_mode, | |
4203 | + /* dd */ | |
4204 | + q_mode, | |
4205 | + q_mode, | |
4206 | + q_mode, | |
4207 | + q_mode, | |
4208 | + 0, | |
4209 | + 0, | |
4210 | + 0, | |
4211 | + w_mode, | |
4212 | + /* de */ | |
4213 | + w_mode, | |
4214 | + w_mode, | |
4215 | + w_mode, | |
4216 | + w_mode, | |
4217 | + w_mode, | |
4218 | + w_mode, | |
4219 | + w_mode, | |
4220 | + w_mode, | |
4221 | + /* df */ | |
4222 | + w_mode, | |
4223 | + w_mode, | |
4224 | + w_mode, | |
4225 | + w_mode, | |
4226 | + t_mode, | |
4227 | + q_mode, | |
4228 | + t_mode, | |
4229 | + q_mode | |
4230 | +}; | |
4231 | + | |
4232 | +#define ST OP_ST, 0 | |
4233 | +#define STi OP_STi, 0 | |
4234 | + | |
4235 | +#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0 | |
4236 | +#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0 | |
4237 | +#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0 | |
4238 | +#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0 | |
4239 | +#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0 | |
4240 | +#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0 | |
4241 | +#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0 | |
4242 | +#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0 | |
4243 | +#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0 | |
4244 | + | |
4245 | +static const struct dis386 float_reg[][8] = { | |
4246 | + /* d8 */ | |
4247 | + { | |
4248 | + { "fadd", ST, STi, XX }, | |
4249 | + { "fmul", ST, STi, XX }, | |
4250 | + { "fcom", STi, XX, XX }, | |
4251 | + { "fcomp", STi, XX, XX }, | |
4252 | + { "fsub", ST, STi, XX }, | |
4253 | + { "fsubr", ST, STi, XX }, | |
4254 | + { "fdiv", ST, STi, XX }, | |
4255 | + { "fdivr", ST, STi, XX }, | |
4256 | + }, | |
4257 | + /* d9 */ | |
4258 | + { | |
4259 | + { "fld", STi, XX, XX }, | |
4260 | + { "fxch", STi, XX, XX }, | |
4261 | + { FGRPd9_2 }, | |
4262 | + { "(bad)", XX, XX, XX }, | |
4263 | + { FGRPd9_4 }, | |
4264 | + { FGRPd9_5 }, | |
4265 | + { FGRPd9_6 }, | |
4266 | + { FGRPd9_7 }, | |
4267 | + }, | |
4268 | + /* da */ | |
4269 | + { | |
4270 | + { "fcmovb", ST, STi, XX }, | |
4271 | + { "fcmove", ST, STi, XX }, | |
4272 | + { "fcmovbe",ST, STi, XX }, | |
4273 | + { "fcmovu", ST, STi, XX }, | |
4274 | + { "(bad)", XX, XX, XX }, | |
4275 | + { FGRPda_5 }, | |
4276 | + { "(bad)", XX, XX, XX }, | |
4277 | + { "(bad)", XX, XX, XX }, | |
4278 | + }, | |
4279 | + /* db */ | |
4280 | + { | |
4281 | + { "fcmovnb",ST, STi, XX }, | |
4282 | + { "fcmovne",ST, STi, XX }, | |
4283 | + { "fcmovnbe",ST, STi, XX }, | |
4284 | + { "fcmovnu",ST, STi, XX }, | |
4285 | + { FGRPdb_4 }, | |
4286 | + { "fucomi", ST, STi, XX }, | |
4287 | + { "fcomi", ST, STi, XX }, | |
4288 | + { "(bad)", XX, XX, XX }, | |
4289 | + }, | |
4290 | + /* dc */ | |
4291 | + { | |
4292 | + { "fadd", STi, ST, XX }, | |
4293 | + { "fmul", STi, ST, XX }, | |
4294 | + { "(bad)", XX, XX, XX }, | |
4295 | + { "(bad)", XX, XX, XX }, | |
4296 | +#if UNIXWARE_COMPAT | |
4297 | + { "fsub", STi, ST, XX }, | |
4298 | + { "fsubr", STi, ST, XX }, | |
4299 | + { "fdiv", STi, ST, XX }, | |
4300 | + { "fdivr", STi, ST, XX }, | |
4301 | +#else | |
4302 | + { "fsubr", STi, ST, XX }, | |
4303 | + { "fsub", STi, ST, XX }, | |
4304 | + { "fdivr", STi, ST, XX }, | |
4305 | + { "fdiv", STi, ST, XX }, | |
4306 | +#endif | |
4307 | + }, | |
4308 | + /* dd */ | |
4309 | + { | |
4310 | + { "ffree", STi, XX, XX }, | |
4311 | + { "(bad)", XX, XX, XX }, | |
4312 | + { "fst", STi, XX, XX }, | |
4313 | + { "fstp", STi, XX, XX }, | |
4314 | + { "fucom", STi, XX, XX }, | |
4315 | + { "fucomp", STi, XX, XX }, | |
4316 | + { "(bad)", XX, XX, XX }, | |
4317 | + { "(bad)", XX, XX, XX }, | |
4318 | + }, | |
4319 | + /* de */ | |
4320 | + { | |
4321 | + { "faddp", STi, ST, XX }, | |
4322 | + { "fmulp", STi, ST, XX }, | |
4323 | + { "(bad)", XX, XX, XX }, | |
4324 | + { FGRPde_3 }, | |
4325 | +#if UNIXWARE_COMPAT | |
4326 | + { "fsubp", STi, ST, XX }, | |
4327 | + { "fsubrp", STi, ST, XX }, | |
4328 | + { "fdivp", STi, ST, XX }, | |
4329 | + { "fdivrp", STi, ST, XX }, | |
4330 | +#else | |
4331 | + { "fsubrp", STi, ST, XX }, | |
4332 | + { "fsubp", STi, ST, XX }, | |
4333 | + { "fdivrp", STi, ST, XX }, | |
4334 | + { "fdivp", STi, ST, XX }, | |
4335 | +#endif | |
4336 | + }, | |
4337 | + /* df */ | |
4338 | + { | |
4339 | + { "ffreep", STi, XX, XX }, | |
4340 | + { "(bad)", XX, XX, XX }, | |
4341 | + { "(bad)", XX, XX, XX }, | |
4342 | + { "(bad)", XX, XX, XX }, | |
4343 | + { FGRPdf_4 }, | |
4344 | + { "fucomip",ST, STi, XX }, | |
4345 | + { "fcomip", ST, STi, XX }, | |
4346 | + { "(bad)", XX, XX, XX }, | |
4347 | + }, | |
4348 | +}; | |
4349 | + | |
4350 | +static char *fgrps[][8] = { | |
4351 | + /* d9_2 0 */ | |
4352 | + { | |
4353 | + "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", | |
4354 | + }, | |
4355 | + | |
4356 | + /* d9_4 1 */ | |
4357 | + { | |
4358 | + "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)", | |
4359 | + }, | |
4360 | + | |
4361 | + /* d9_5 2 */ | |
4362 | + { | |
4363 | + "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)", | |
4364 | + }, | |
4365 | + | |
4366 | + /* d9_6 3 */ | |
4367 | + { | |
4368 | + "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp", | |
4369 | + }, | |
4370 | + | |
4371 | + /* d9_7 4 */ | |
4372 | + { | |
4373 | + "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos", | |
4374 | + }, | |
4375 | + | |
4376 | + /* da_5 5 */ | |
4377 | + { | |
4378 | + "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", | |
4379 | + }, | |
4380 | + | |
4381 | + /* db_4 6 */ | |
4382 | + { | |
4383 | + "feni(287 only)","fdisi(287 only)","fNclex","fNinit", | |
4384 | + "fNsetpm(287 only)","(bad)","(bad)","(bad)", | |
4385 | + }, | |
4386 | + | |
4387 | + /* de_3 7 */ | |
4388 | + { | |
4389 | + "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", | |
4390 | + }, | |
4391 | + | |
4392 | + /* df_4 8 */ | |
4393 | + { | |
4394 | + "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", | |
4395 | + }, | |
4396 | +}; | |
4397 | + | |
4398 | +static void | |
4399 | +dofloat (int sizeflag) | |
4400 | +{ | |
4401 | + const struct dis386 *dp; | |
4402 | + unsigned char floatop; | |
4403 | + | |
4404 | + floatop = codep[-1]; | |
4405 | + | |
4406 | + if (mod != 3) | |
4407 | + { | |
4408 | + int fp_indx = (floatop - 0xd8) * 8 + reg; | |
4409 | + | |
4410 | + putop (float_mem[fp_indx], sizeflag); | |
4411 | + obufp = op1out; | |
4412 | + OP_E (float_mem_mode[fp_indx], sizeflag); | |
4413 | + return; | |
4414 | + } | |
4415 | + /* Skip mod/rm byte. */ | |
4416 | + MODRM_CHECK; | |
4417 | + codep++; | |
4418 | + | |
4419 | + dp = &float_reg[floatop - 0xd8][reg]; | |
4420 | + if (dp->name == NULL) | |
4421 | + { | |
4422 | + putop (fgrps[dp->bytemode1][rm], sizeflag); | |
4423 | + | |
4424 | + /* Instruction fnstsw is only one with strange arg. */ | |
4425 | + if (floatop == 0xdf && codep[-1] == 0xe0) | |
4426 | + strcpy (op1out, names16[0]); | |
4427 | + } | |
4428 | + else | |
4429 | + { | |
4430 | + putop (dp->name, sizeflag); | |
4431 | + | |
4432 | + obufp = op1out; | |
4433 | + if (dp->op1) | |
4434 | + (*dp->op1) (dp->bytemode1, sizeflag); | |
4435 | + obufp = op2out; | |
4436 | + if (dp->op2) | |
4437 | + (*dp->op2) (dp->bytemode2, sizeflag); | |
4438 | + } | |
4439 | +} | |
4440 | + | |
4441 | +static void | |
4442 | +OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
4443 | +{ | |
4444 | + oappend ("%st"); | |
4445 | +} | |
4446 | + | |
4447 | +static void | |
4448 | +OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
4449 | +{ | |
4450 | + sprintf (scratchbuf, "%%st(%d)", rm); | |
4451 | + oappend (scratchbuf + intel_syntax); | |
4452 | +} | |
4453 | + | |
4454 | +/* Capital letters in template are macros. */ | |
4455 | +static int | |
4456 | +putop (const char *template, int sizeflag) | |
4457 | +{ | |
4458 | + const char *p; | |
4459 | + int alt = 0; | |
4460 | + | |
4461 | + for (p = template; *p; p++) | |
4462 | + { | |
4463 | + switch (*p) | |
4464 | + { | |
4465 | + default: | |
4466 | + *obufp++ = *p; | |
4467 | + break; | |
4468 | + case '{': | |
4469 | + alt = 0; | |
4470 | + if (intel_syntax) | |
4471 | + alt += 1; | |
4472 | + if (mode_64bit) | |
4473 | + alt += 2; | |
4474 | + while (alt != 0) | |
4475 | + { | |
4476 | + while (*++p != '|') | |
4477 | + { | |
4478 | + if (*p == '}') | |
4479 | + { | |
4480 | + /* Alternative not valid. */ | |
4481 | + strcpy (obuf, "(bad)"); | |
4482 | + obufp = obuf + 5; | |
4483 | + return 1; | |
4484 | + } | |
4485 | + else if (*p == '\0') | |
4486 | + abort (); | |
4487 | + } | |
4488 | + alt--; | |
4489 | + } | |
4490 | + /* Fall through. */ | |
4491 | + case 'I': | |
4492 | + alt = 1; | |
4493 | + continue; | |
4494 | + case '|': | |
4495 | + while (*++p != '}') | |
4496 | + { | |
4497 | + if (*p == '\0') | |
4498 | + abort (); | |
4499 | + } | |
4500 | + break; | |
4501 | + case '}': | |
4502 | + break; | |
4503 | + case 'A': | |
4504 | + if (intel_syntax) | |
4505 | + break; | |
4506 | + if (mod != 3 || (sizeflag & SUFFIX_ALWAYS)) | |
4507 | + *obufp++ = 'b'; | |
4508 | + break; | |
4509 | + case 'B': | |
4510 | + if (intel_syntax) | |
4511 | + break; | |
4512 | + if (sizeflag & SUFFIX_ALWAYS) | |
4513 | + *obufp++ = 'b'; | |
4514 | + break; | |
4515 | + case 'C': | |
4516 | + if (intel_syntax && !alt) | |
4517 | + break; | |
4518 | + if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS)) | |
4519 | + { | |
4520 | + if (sizeflag & DFLAG) | |
4521 | + *obufp++ = intel_syntax ? 'd' : 'l'; | |
4522 | + else | |
4523 | + *obufp++ = intel_syntax ? 'w' : 's'; | |
4524 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
4525 | + } | |
4526 | + break; | |
4527 | + case 'E': /* For jcxz/jecxz */ | |
4528 | + if (mode_64bit) | |
4529 | + { | |
4530 | + if (sizeflag & AFLAG) | |
4531 | + *obufp++ = 'r'; | |
4532 | + else | |
4533 | + *obufp++ = 'e'; | |
4534 | + } | |
4535 | + else | |
4536 | + if (sizeflag & AFLAG) | |
4537 | + *obufp++ = 'e'; | |
4538 | + used_prefixes |= (prefixes & PREFIX_ADDR); | |
4539 | + break; | |
4540 | + case 'F': | |
4541 | + if (intel_syntax) | |
4542 | + break; | |
4543 | + if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS)) | |
4544 | + { | |
4545 | + if (sizeflag & AFLAG) | |
4546 | + *obufp++ = mode_64bit ? 'q' : 'l'; | |
4547 | + else | |
4548 | + *obufp++ = mode_64bit ? 'l' : 'w'; | |
4549 | + used_prefixes |= (prefixes & PREFIX_ADDR); | |
4550 | + } | |
4551 | + break; | |
4552 | + case 'H': | |
4553 | + if (intel_syntax) | |
4554 | + break; | |
4555 | + if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS | |
4556 | + || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS) | |
4557 | + { | |
4558 | + used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS); | |
4559 | + *obufp++ = ','; | |
4560 | + *obufp++ = 'p'; | |
4561 | + if (prefixes & PREFIX_DS) | |
4562 | + *obufp++ = 't'; | |
4563 | + else | |
4564 | + *obufp++ = 'n'; | |
4565 | + } | |
4566 | + break; | |
4567 | + case 'J': | |
4568 | + if (intel_syntax) | |
4569 | + break; | |
4570 | + *obufp++ = 'l'; | |
4571 | + break; | |
4572 | + case 'L': | |
4573 | + if (intel_syntax) | |
4574 | + break; | |
4575 | + if (sizeflag & SUFFIX_ALWAYS) | |
4576 | + *obufp++ = 'l'; | |
4577 | + break; | |
4578 | + case 'N': | |
4579 | + if ((prefixes & PREFIX_FWAIT) == 0) | |
4580 | + *obufp++ = 'n'; | |
4581 | + else | |
4582 | + used_prefixes |= PREFIX_FWAIT; | |
4583 | + break; | |
4584 | + case 'O': | |
4585 | + USED_REX (REX_MODE64); | |
4586 | + if (rex & REX_MODE64) | |
4587 | + *obufp++ = 'o'; | |
4588 | + else | |
4589 | + *obufp++ = 'd'; | |
4590 | + break; | |
4591 | + case 'T': | |
4592 | + if (intel_syntax) | |
4593 | + break; | |
4594 | + if (mode_64bit) | |
4595 | + { | |
4596 | + *obufp++ = 'q'; | |
4597 | + break; | |
4598 | + } | |
4599 | + /* Fall through. */ | |
4600 | + case 'P': | |
4601 | + if (intel_syntax) | |
4602 | + break; | |
4603 | + if ((prefixes & PREFIX_DATA) | |
4604 | + || (rex & REX_MODE64) | |
4605 | + || (sizeflag & SUFFIX_ALWAYS)) | |
4606 | + { | |
4607 | + USED_REX (REX_MODE64); | |
4608 | + if (rex & REX_MODE64) | |
4609 | + *obufp++ = 'q'; | |
4610 | + else | |
4611 | + { | |
4612 | + if (sizeflag & DFLAG) | |
4613 | + *obufp++ = 'l'; | |
4614 | + else | |
4615 | + *obufp++ = 'w'; | |
4616 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
4617 | + } | |
4618 | + } | |
4619 | + break; | |
4620 | + case 'U': | |
4621 | + if (intel_syntax) | |
4622 | + break; | |
4623 | + if (mode_64bit) | |
4624 | + { | |
4625 | + *obufp++ = 'q'; | |
4626 | + break; | |
4627 | + } | |
4628 | + /* Fall through. */ | |
4629 | + case 'Q': | |
4630 | + if (intel_syntax && !alt) | |
4631 | + break; | |
4632 | + USED_REX (REX_MODE64); | |
4633 | + if (mod != 3 || (sizeflag & SUFFIX_ALWAYS)) | |
4634 | + { | |
4635 | + if (rex & REX_MODE64) | |
4636 | + *obufp++ = 'q'; | |
4637 | + else | |
4638 | + { | |
4639 | + if (sizeflag & DFLAG) | |
4640 | + *obufp++ = intel_syntax ? 'd' : 'l'; | |
4641 | + else | |
4642 | + *obufp++ = 'w'; | |
4643 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
4644 | + } | |
4645 | + } | |
4646 | + break; | |
4647 | + case 'R': | |
4648 | + USED_REX (REX_MODE64); | |
4649 | + if (intel_syntax) | |
4650 | + { | |
4651 | + if (rex & REX_MODE64) | |
4652 | + { | |
4653 | + *obufp++ = 'q'; | |
4654 | + *obufp++ = 't'; | |
4655 | + } | |
4656 | + else if (sizeflag & DFLAG) | |
4657 | + { | |
4658 | + *obufp++ = 'd'; | |
4659 | + *obufp++ = 'q'; | |
4660 | + } | |
4661 | + else | |
4662 | + { | |
4663 | + *obufp++ = 'w'; | |
4664 | + *obufp++ = 'd'; | |
4665 | + } | |
4666 | + } | |
4667 | + else | |
4668 | + { | |
4669 | + if (rex & REX_MODE64) | |
4670 | + *obufp++ = 'q'; | |
4671 | + else if (sizeflag & DFLAG) | |
4672 | + *obufp++ = 'l'; | |
4673 | + else | |
4674 | + *obufp++ = 'w'; | |
4675 | + } | |
4676 | + if (!(rex & REX_MODE64)) | |
4677 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
4678 | + break; | |
4679 | + case 'S': | |
4680 | + if (intel_syntax) | |
4681 | + break; | |
4682 | + if (sizeflag & SUFFIX_ALWAYS) | |
4683 | + { | |
4684 | + if (rex & REX_MODE64) | |
4685 | + *obufp++ = 'q'; | |
4686 | + else | |
4687 | + { | |
4688 | + if (sizeflag & DFLAG) | |
4689 | + *obufp++ = 'l'; | |
4690 | + else | |
4691 | + *obufp++ = 'w'; | |
4692 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
4693 | + } | |
4694 | + } | |
4695 | + break; | |
4696 | + case 'X': | |
4697 | + if (prefixes & PREFIX_DATA) | |
4698 | + *obufp++ = 'd'; | |
4699 | + else | |
4700 | + *obufp++ = 's'; | |
4701 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
4702 | + break; | |
4703 | + case 'Y': | |
4704 | + if (intel_syntax) | |
4705 | + break; | |
4706 | + if (rex & REX_MODE64) | |
4707 | + { | |
4708 | + USED_REX (REX_MODE64); | |
4709 | + *obufp++ = 'q'; | |
4710 | + } | |
4711 | + break; | |
4712 | + /* implicit operand size 'l' for i386 or 'q' for x86-64 */ | |
4713 | + case 'W': | |
4714 | + /* operand size flag for cwtl, cbtw */ | |
4715 | + USED_REX (0); | |
4716 | + if (rex) | |
4717 | + *obufp++ = 'l'; | |
4718 | + else if (sizeflag & DFLAG) | |
4719 | + *obufp++ = 'w'; | |
4720 | + else | |
4721 | + *obufp++ = 'b'; | |
4722 | + if (intel_syntax) | |
4723 | + { | |
4724 | + if (rex) | |
4725 | + { | |
4726 | + *obufp++ = 'q'; | |
4727 | + *obufp++ = 'e'; | |
4728 | + } | |
4729 | + if (sizeflag & DFLAG) | |
4730 | + { | |
4731 | + *obufp++ = 'd'; | |
4732 | + *obufp++ = 'e'; | |
4733 | + } | |
4734 | + else | |
4735 | + { | |
4736 | + *obufp++ = 'w'; | |
4737 | + } | |
4738 | + } | |
4739 | + if (!rex) | |
4740 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
4741 | + break; | |
4742 | + } | |
4743 | + alt = 0; | |
4744 | + } | |
4745 | + *obufp = 0; | |
4746 | + return 0; | |
4747 | +} | |
4748 | + | |
4749 | +static void | |
4750 | +oappend (const char *s) | |
4751 | +{ | |
4752 | + strcpy (obufp, s); | |
4753 | + obufp += strlen (s); | |
4754 | +} | |
4755 | + | |
4756 | +static void | |
4757 | +append_seg (void) | |
4758 | +{ | |
4759 | + if (prefixes & PREFIX_CS) | |
4760 | + { | |
4761 | + used_prefixes |= PREFIX_CS; | |
4762 | + oappend ("%cs:" + intel_syntax); | |
4763 | + } | |
4764 | + if (prefixes & PREFIX_DS) | |
4765 | + { | |
4766 | + used_prefixes |= PREFIX_DS; | |
4767 | + oappend ("%ds:" + intel_syntax); | |
4768 | + } | |
4769 | + if (prefixes & PREFIX_SS) | |
4770 | + { | |
4771 | + used_prefixes |= PREFIX_SS; | |
4772 | + oappend ("%ss:" + intel_syntax); | |
4773 | + } | |
4774 | + if (prefixes & PREFIX_ES) | |
4775 | + { | |
4776 | + used_prefixes |= PREFIX_ES; | |
4777 | + oappend ("%es:" + intel_syntax); | |
4778 | + } | |
4779 | + if (prefixes & PREFIX_FS) | |
4780 | + { | |
4781 | + used_prefixes |= PREFIX_FS; | |
4782 | + oappend ("%fs:" + intel_syntax); | |
4783 | + } | |
4784 | + if (prefixes & PREFIX_GS) | |
4785 | + { | |
4786 | + used_prefixes |= PREFIX_GS; | |
4787 | + oappend ("%gs:" + intel_syntax); | |
4788 | + } | |
4789 | +} | |
4790 | + | |
4791 | +static void | |
4792 | +OP_indirE (int bytemode, int sizeflag) | |
4793 | +{ | |
4794 | + if (!intel_syntax) | |
4795 | + oappend ("*"); | |
4796 | + OP_E (bytemode, sizeflag); | |
4797 | +} | |
4798 | + | |
4799 | +static void | |
4800 | +print_operand_value (char *buf, int hex, bfd_vma disp) | |
4801 | +{ | |
4802 | + if (mode_64bit) | |
4803 | + { | |
4804 | + if (hex) | |
4805 | + { | |
4806 | + char tmp[30]; | |
4807 | + int i; | |
4808 | + buf[0] = '0'; | |
4809 | + buf[1] = 'x'; | |
4810 | + sprintf_vma (tmp, disp); | |
4811 | + for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++); | |
4812 | + strcpy (buf + 2, tmp + i); | |
4813 | + } | |
4814 | + else | |
4815 | + { | |
4816 | + bfd_signed_vma v = disp; | |
4817 | + char tmp[30]; | |
4818 | + int i; | |
4819 | + if (v < 0) | |
4820 | + { | |
4821 | + *(buf++) = '-'; | |
4822 | + v = -disp; | |
4823 | + /* Check for possible overflow on 0x8000000000000000. */ | |
4824 | + if (v < 0) | |
4825 | + { | |
4826 | + strcpy (buf, "9223372036854775808"); | |
4827 | + return; | |
4828 | + } | |
4829 | + } | |
4830 | + if (!v) | |
4831 | + { | |
4832 | + strcpy (buf, "0"); | |
4833 | + return; | |
4834 | + } | |
4835 | + | |
4836 | + i = 0; | |
4837 | + tmp[29] = 0; | |
4838 | + while (v) | |
4839 | + { | |
4840 | + tmp[28 - i] = (v % 10) + '0'; | |
4841 | + v /= 10; | |
4842 | + i++; | |
4843 | + } | |
4844 | + strcpy (buf, tmp + 29 - i); | |
4845 | + } | |
4846 | + } | |
4847 | + else | |
4848 | + { | |
4849 | + if (hex) | |
4850 | + sprintf (buf, "0x%x", (unsigned int) disp); | |
4851 | + else | |
4852 | + sprintf (buf, "%d", (int) disp); | |
4853 | + } | |
4854 | +} | |
4855 | + | |
4856 | +static void | |
4857 | +OP_E (int bytemode, int sizeflag) | |
4858 | +{ | |
4859 | + bfd_vma disp; | |
4860 | + int add = 0; | |
4861 | + int riprel = 0; | |
4862 | + USED_REX (REX_EXTZ); | |
4863 | + if (rex & REX_EXTZ) | |
4864 | + add += 8; | |
4865 | + | |
4866 | + /* Skip mod/rm byte. */ | |
4867 | + MODRM_CHECK; | |
4868 | + codep++; | |
4869 | + | |
4870 | + if (mod == 3) | |
4871 | + { | |
4872 | + switch (bytemode) | |
4873 | + { | |
4874 | + case b_mode: | |
4875 | + USED_REX (0); | |
4876 | + if (rex) | |
4877 | + oappend (names8rex[rm + add]); | |
4878 | + else | |
4879 | + oappend (names8[rm + add]); | |
4880 | + break; | |
4881 | + case w_mode: | |
4882 | + oappend (names16[rm + add]); | |
4883 | + break; | |
4884 | + case d_mode: | |
4885 | + oappend (names32[rm + add]); | |
4886 | + break; | |
4887 | + case q_mode: | |
4888 | + oappend (names64[rm + add]); | |
4889 | + break; | |
4890 | + case m_mode: | |
4891 | + if (mode_64bit) | |
4892 | + oappend (names64[rm + add]); | |
4893 | + else | |
4894 | + oappend (names32[rm + add]); | |
4895 | + break; | |
4896 | + case branch_v_mode: | |
4897 | + if (mode_64bit) | |
4898 | + oappend (names64[rm + add]); | |
4899 | + else | |
4900 | + { | |
4901 | + if ((sizeflag & DFLAG) || bytemode != branch_v_mode) | |
4902 | + oappend (names32[rm + add]); | |
4903 | + else | |
4904 | + oappend (names16[rm + add]); | |
4905 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
4906 | + } | |
4907 | + break; | |
4908 | + case v_mode: | |
4909 | + case dq_mode: | |
4910 | + case dqw_mode: | |
4911 | + USED_REX (REX_MODE64); | |
4912 | + if (rex & REX_MODE64) | |
4913 | + oappend (names64[rm + add]); | |
4914 | + else if ((sizeflag & DFLAG) || bytemode != v_mode) | |
4915 | + oappend (names32[rm + add]); | |
4916 | + else | |
4917 | + oappend (names16[rm + add]); | |
4918 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
4919 | + break; | |
4920 | + case 0: | |
4921 | + break; | |
4922 | + default: | |
4923 | + oappend (INTERNAL_DISASSEMBLER_ERROR); | |
4924 | + break; | |
4925 | + } | |
4926 | + return; | |
4927 | + } | |
4928 | + | |
4929 | + disp = 0; | |
4930 | + append_seg (); | |
4931 | + | |
4932 | + if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */ | |
4933 | + { | |
4934 | + int havesib; | |
4935 | + int havebase; | |
4936 | + int base; | |
4937 | + int index = 0; | |
4938 | + int scale = 0; | |
4939 | + | |
4940 | + havesib = 0; | |
4941 | + havebase = 1; | |
4942 | + base = rm; | |
4943 | + | |
4944 | + if (base == 4) | |
4945 | + { | |
4946 | + havesib = 1; | |
4947 | + FETCH_DATA (the_info, codep + 1); | |
4948 | + index = (*codep >> 3) & 7; | |
4949 | + if (mode_64bit || index != 0x4) | |
4950 | + /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */ | |
4951 | + scale = (*codep >> 6) & 3; | |
4952 | + base = *codep & 7; | |
4953 | + USED_REX (REX_EXTY); | |
4954 | + if (rex & REX_EXTY) | |
4955 | + index += 8; | |
4956 | + codep++; | |
4957 | + } | |
4958 | + base += add; | |
4959 | + | |
4960 | + switch (mod) | |
4961 | + { | |
4962 | + case 0: | |
4963 | + if ((base & 7) == 5) | |
4964 | + { | |
4965 | + havebase = 0; | |
4966 | + if (mode_64bit && !havesib) | |
4967 | + riprel = 1; | |
4968 | + disp = get32s (); | |
4969 | + } | |
4970 | + break; | |
4971 | + case 1: | |
4972 | + FETCH_DATA (the_info, codep + 1); | |
4973 | + disp = *codep++; | |
4974 | + if ((disp & 0x80) != 0) | |
4975 | + disp -= 0x100; | |
4976 | + break; | |
4977 | + case 2: | |
4978 | + disp = get32s (); | |
4979 | + break; | |
4980 | + } | |
4981 | + | |
4982 | + if (!intel_syntax) | |
4983 | + if (mod != 0 || (base & 7) == 5) | |
4984 | + { | |
4985 | + print_operand_value (scratchbuf, !riprel, disp); | |
4986 | + oappend (scratchbuf); | |
4987 | + if (riprel) | |
4988 | + { | |
4989 | + set_op (disp, 1); | |
4990 | + oappend ("(%rip)"); | |
4991 | + } | |
4992 | + } | |
4993 | + | |
4994 | + if (havebase || (havesib && (index != 4 || scale != 0))) | |
4995 | + { | |
4996 | + if (intel_syntax) | |
4997 | + { | |
4998 | + switch (bytemode) | |
4999 | + { | |
5000 | + case b_mode: | |
5001 | + oappend ("BYTE PTR "); | |
5002 | + break; | |
5003 | + case w_mode: | |
5004 | + case dqw_mode: | |
5005 | + oappend ("WORD PTR "); | |
5006 | + break; | |
5007 | + case branch_v_mode: | |
5008 | + case v_mode: | |
5009 | + case dq_mode: | |
5010 | + USED_REX (REX_MODE64); | |
5011 | + if (rex & REX_MODE64) | |
5012 | + oappend ("QWORD PTR "); | |
5013 | + else if ((sizeflag & DFLAG) || bytemode == dq_mode) | |
5014 | + oappend ("DWORD PTR "); | |
5015 | + else | |
5016 | + oappend ("WORD PTR "); | |
5017 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
5018 | + break; | |
5019 | + case d_mode: | |
5020 | + oappend ("DWORD PTR "); | |
5021 | + break; | |
5022 | + case q_mode: | |
5023 | + oappend ("QWORD PTR "); | |
5024 | + break; | |
5025 | + case m_mode: | |
5026 | + if (mode_64bit) | |
5027 | + oappend ("QWORD PTR "); | |
5028 | + else | |
5029 | + oappend ("DWORD PTR "); | |
5030 | + break; | |
5031 | + case f_mode: | |
5032 | + if (sizeflag & DFLAG) | |
5033 | + { | |
5034 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
5035 | + oappend ("FWORD PTR "); | |
5036 | + } | |
5037 | + else | |
5038 | + oappend ("DWORD PTR "); | |
5039 | + break; | |
5040 | + case t_mode: | |
5041 | + oappend ("TBYTE PTR "); | |
5042 | + break; | |
5043 | + case x_mode: | |
5044 | + oappend ("XMMWORD PTR "); | |
5045 | + break; | |
5046 | + default: | |
5047 | + break; | |
5048 | + } | |
5049 | + } | |
5050 | + *obufp++ = open_char; | |
5051 | + if (intel_syntax && riprel) | |
5052 | + oappend ("rip + "); | |
5053 | + *obufp = '\0'; | |
5054 | + if (havebase) | |
5055 | + oappend (mode_64bit && (sizeflag & AFLAG) | |
5056 | + ? names64[base] : names32[base]); | |
5057 | + if (havesib) | |
5058 | + { | |
5059 | + if (index != 4) | |
5060 | + { | |
5061 | + if (!intel_syntax || havebase) | |
5062 | + { | |
5063 | + *obufp++ = separator_char; | |
5064 | + *obufp = '\0'; | |
5065 | + } | |
5066 | + oappend (mode_64bit && (sizeflag & AFLAG) | |
5067 | + ? names64[index] : names32[index]); | |
5068 | + } | |
5069 | + if (scale != 0 || (!intel_syntax && index != 4)) | |
5070 | + { | |
5071 | + *obufp++ = scale_char; | |
5072 | + *obufp = '\0'; | |
5073 | + sprintf (scratchbuf, "%d", 1 << scale); | |
5074 | + oappend (scratchbuf); | |
5075 | + } | |
5076 | + } | |
5077 | + if (intel_syntax && disp) | |
5078 | + { | |
5079 | + if ((bfd_signed_vma) disp > 0) | |
5080 | + { | |
5081 | + *obufp++ = '+'; | |
5082 | + *obufp = '\0'; | |
5083 | + } | |
5084 | + else if (mod != 1) | |
5085 | + { | |
5086 | + *obufp++ = '-'; | |
5087 | + *obufp = '\0'; | |
5088 | + disp = - (bfd_signed_vma) disp; | |
5089 | + } | |
5090 | + | |
5091 | + print_operand_value (scratchbuf, mod != 1, disp); | |
5092 | + oappend (scratchbuf); | |
5093 | + } | |
5094 | + | |
5095 | + *obufp++ = close_char; | |
5096 | + *obufp = '\0'; | |
5097 | + } | |
5098 | + else if (intel_syntax) | |
5099 | + { | |
5100 | + if (mod != 0 || (base & 7) == 5) | |
5101 | + { | |
5102 | + if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS | |
5103 | + | PREFIX_ES | PREFIX_FS | PREFIX_GS)) | |
5104 | + ; | |
5105 | + else | |
5106 | + { | |
5107 | + oappend (names_seg[ds_reg - es_reg]); | |
5108 | + oappend (":"); | |
5109 | + } | |
5110 | + print_operand_value (scratchbuf, 1, disp); | |
5111 | + oappend (scratchbuf); | |
5112 | + } | |
5113 | + } | |
5114 | + } | |
5115 | + else | |
5116 | + { /* 16 bit address mode */ | |
5117 | + switch (mod) | |
5118 | + { | |
5119 | + case 0: | |
5120 | + if (rm == 6) | |
5121 | + { | |
5122 | + disp = get16 (); | |
5123 | + if ((disp & 0x8000) != 0) | |
5124 | + disp -= 0x10000; | |
5125 | + } | |
5126 | + break; | |
5127 | + case 1: | |
5128 | + FETCH_DATA (the_info, codep + 1); | |
5129 | + disp = *codep++; | |
5130 | + if ((disp & 0x80) != 0) | |
5131 | + disp -= 0x100; | |
5132 | + break; | |
5133 | + case 2: | |
5134 | + disp = get16 (); | |
5135 | + if ((disp & 0x8000) != 0) | |
5136 | + disp -= 0x10000; | |
5137 | + break; | |
5138 | + } | |
5139 | + | |
5140 | + if (!intel_syntax) | |
5141 | + if (mod != 0 || rm == 6) | |
5142 | + { | |
5143 | + print_operand_value (scratchbuf, 0, disp); | |
5144 | + oappend (scratchbuf); | |
5145 | + } | |
5146 | + | |
5147 | + if (mod != 0 || rm != 6) | |
5148 | + { | |
5149 | + *obufp++ = open_char; | |
5150 | + *obufp = '\0'; | |
5151 | + oappend (index16[rm]); | |
5152 | + if (intel_syntax && disp) | |
5153 | + { | |
5154 | + if ((bfd_signed_vma) disp > 0) | |
5155 | + { | |
5156 | + *obufp++ = '+'; | |
5157 | + *obufp = '\0'; | |
5158 | + } | |
5159 | + else if (mod != 1) | |
5160 | + { | |
5161 | + *obufp++ = '-'; | |
5162 | + *obufp = '\0'; | |
5163 | + disp = - (bfd_signed_vma) disp; | |
5164 | + } | |
5165 | + | |
5166 | + print_operand_value (scratchbuf, mod != 1, disp); | |
5167 | + oappend (scratchbuf); | |
5168 | + } | |
5169 | + | |
5170 | + *obufp++ = close_char; | |
5171 | + *obufp = '\0'; | |
5172 | + } | |
5173 | + else if (intel_syntax) | |
5174 | + { | |
5175 | + if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS | |
5176 | + | PREFIX_ES | PREFIX_FS | PREFIX_GS)) | |
5177 | + ; | |
5178 | + else | |
5179 | + { | |
5180 | + oappend (names_seg[ds_reg - es_reg]); | |
5181 | + oappend (":"); | |
5182 | + } | |
5183 | + print_operand_value (scratchbuf, 1, disp & 0xffff); | |
5184 | + oappend (scratchbuf); | |
5185 | + } | |
5186 | + } | |
5187 | +} | |
5188 | + | |
5189 | +static void | |
5190 | +OP_G (int bytemode, int sizeflag) | |
5191 | +{ | |
5192 | + int add = 0; | |
5193 | + USED_REX (REX_EXTX); | |
5194 | + if (rex & REX_EXTX) | |
5195 | + add += 8; | |
5196 | + switch (bytemode) | |
5197 | + { | |
5198 | + case b_mode: | |
5199 | + USED_REX (0); | |
5200 | + if (rex) | |
5201 | + oappend (names8rex[reg + add]); | |
5202 | + else | |
5203 | + oappend (names8[reg + add]); | |
5204 | + break; | |
5205 | + case w_mode: | |
5206 | + oappend (names16[reg + add]); | |
5207 | + break; | |
5208 | + case d_mode: | |
5209 | + oappend (names32[reg + add]); | |
5210 | + break; | |
5211 | + case q_mode: | |
5212 | + oappend (names64[reg + add]); | |
5213 | + break; | |
5214 | + case v_mode: | |
5215 | + case dq_mode: | |
5216 | + case dqw_mode: | |
5217 | + USED_REX (REX_MODE64); | |
5218 | + if (rex & REX_MODE64) | |
5219 | + oappend (names64[reg + add]); | |
5220 | + else if ((sizeflag & DFLAG) || bytemode != v_mode) | |
5221 | + oappend (names32[reg + add]); | |
5222 | + else | |
5223 | + oappend (names16[reg + add]); | |
5224 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
5225 | + break; | |
5226 | + case m_mode: | |
5227 | + if (mode_64bit) | |
5228 | + oappend (names64[reg + add]); | |
5229 | + else | |
5230 | + oappend (names32[reg + add]); | |
5231 | + break; | |
5232 | + default: | |
5233 | + oappend (INTERNAL_DISASSEMBLER_ERROR); | |
5234 | + break; | |
5235 | + } | |
5236 | +} | |
5237 | + | |
5238 | +static bfd_vma | |
5239 | +get64 (void) | |
5240 | +{ | |
5241 | + bfd_vma x; | |
5242 | +#ifdef BFD64 | |
5243 | + unsigned int a; | |
5244 | + unsigned int b; | |
5245 | + | |
5246 | + FETCH_DATA (the_info, codep + 8); | |
5247 | + a = *codep++ & 0xff; | |
5248 | + a |= (*codep++ & 0xff) << 8; | |
5249 | + a |= (*codep++ & 0xff) << 16; | |
5250 | + a |= (*codep++ & 0xff) << 24; | |
5251 | + b = *codep++ & 0xff; | |
5252 | + b |= (*codep++ & 0xff) << 8; | |
5253 | + b |= (*codep++ & 0xff) << 16; | |
5254 | + b |= (*codep++ & 0xff) << 24; | |
5255 | + x = a + ((bfd_vma) b << 32); | |
5256 | +#else | |
5257 | + abort (); | |
5258 | + x = 0; | |
5259 | +#endif | |
5260 | + return x; | |
5261 | +} | |
5262 | + | |
5263 | +static bfd_signed_vma | |
5264 | +get32 (void) | |
5265 | +{ | |
5266 | + bfd_signed_vma x = 0; | |
5267 | + | |
5268 | + FETCH_DATA (the_info, codep + 4); | |
5269 | + x = *codep++ & (bfd_signed_vma) 0xff; | |
5270 | + x |= (*codep++ & (bfd_signed_vma) 0xff) << 8; | |
5271 | + x |= (*codep++ & (bfd_signed_vma) 0xff) << 16; | |
5272 | + x |= (*codep++ & (bfd_signed_vma) 0xff) << 24; | |
5273 | + return x; | |
5274 | +} | |
5275 | + | |
5276 | +static bfd_signed_vma | |
5277 | +get32s (void) | |
5278 | +{ | |
5279 | + bfd_signed_vma x = 0; | |
5280 | + | |
5281 | + FETCH_DATA (the_info, codep + 4); | |
5282 | + x = *codep++ & (bfd_signed_vma) 0xff; | |
5283 | + x |= (*codep++ & (bfd_signed_vma) 0xff) << 8; | |
5284 | + x |= (*codep++ & (bfd_signed_vma) 0xff) << 16; | |
5285 | + x |= (*codep++ & (bfd_signed_vma) 0xff) << 24; | |
5286 | + | |
5287 | + x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31); | |
5288 | + | |
5289 | + return x; | |
5290 | +} | |
5291 | + | |
5292 | +static int | |
5293 | +get16 (void) | |
5294 | +{ | |
5295 | + int x = 0; | |
5296 | + | |
5297 | + FETCH_DATA (the_info, codep + 2); | |
5298 | + x = *codep++ & 0xff; | |
5299 | + x |= (*codep++ & 0xff) << 8; | |
5300 | + return x; | |
5301 | +} | |
5302 | + | |
5303 | +static void | |
5304 | +set_op (bfd_vma op, int riprel) | |
5305 | +{ | |
5306 | + op_index[op_ad] = op_ad; | |
5307 | + if (mode_64bit) | |
5308 | + { | |
5309 | + op_address[op_ad] = op; | |
5310 | + op_riprel[op_ad] = riprel; | |
5311 | + } | |
5312 | + else | |
5313 | + { | |
5314 | + /* Mask to get a 32-bit address. */ | |
5315 | + op_address[op_ad] = op & 0xffffffff; | |
5316 | + op_riprel[op_ad] = riprel & 0xffffffff; | |
5317 | + } | |
5318 | +} | |
5319 | + | |
5320 | +static void | |
5321 | +OP_REG (int code, int sizeflag) | |
5322 | +{ | |
5323 | + const char *s; | |
5324 | + int add = 0; | |
5325 | + USED_REX (REX_EXTZ); | |
5326 | + if (rex & REX_EXTZ) | |
5327 | + add = 8; | |
5328 | + | |
5329 | + switch (code) | |
5330 | + { | |
5331 | + case indir_dx_reg: | |
5332 | + if (intel_syntax) | |
5333 | + s = "[dx]"; | |
5334 | + else | |
5335 | + s = "(%dx)"; | |
5336 | + break; | |
5337 | + case ax_reg: case cx_reg: case dx_reg: case bx_reg: | |
5338 | + case sp_reg: case bp_reg: case si_reg: case di_reg: | |
5339 | + s = names16[code - ax_reg + add]; | |
5340 | + break; | |
5341 | + case es_reg: case ss_reg: case cs_reg: | |
5342 | + case ds_reg: case fs_reg: case gs_reg: | |
5343 | + s = names_seg[code - es_reg + add]; | |
5344 | + break; | |
5345 | + case al_reg: case ah_reg: case cl_reg: case ch_reg: | |
5346 | + case dl_reg: case dh_reg: case bl_reg: case bh_reg: | |
5347 | + USED_REX (0); | |
5348 | + if (rex) | |
5349 | + s = names8rex[code - al_reg + add]; | |
5350 | + else | |
5351 | + s = names8[code - al_reg]; | |
5352 | + break; | |
5353 | + case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg: | |
5354 | + case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg: | |
5355 | + if (mode_64bit) | |
5356 | + { | |
5357 | + s = names64[code - rAX_reg + add]; | |
5358 | + break; | |
5359 | + } | |
5360 | + code += eAX_reg - rAX_reg; | |
5361 | + /* Fall through. */ | |
5362 | + case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg: | |
5363 | + case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg: | |
5364 | + USED_REX (REX_MODE64); | |
5365 | + if (rex & REX_MODE64) | |
5366 | + s = names64[code - eAX_reg + add]; | |
5367 | + else if (sizeflag & DFLAG) | |
5368 | + s = names32[code - eAX_reg + add]; | |
5369 | + else | |
5370 | + s = names16[code - eAX_reg + add]; | |
5371 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
5372 | + break; | |
5373 | + default: | |
5374 | + s = INTERNAL_DISASSEMBLER_ERROR; | |
5375 | + break; | |
5376 | + } | |
5377 | + oappend (s); | |
5378 | +} | |
5379 | + | |
5380 | +static void | |
5381 | +OP_IMREG (int code, int sizeflag) | |
5382 | +{ | |
5383 | + const char *s; | |
5384 | + | |
5385 | + switch (code) | |
5386 | + { | |
5387 | + case indir_dx_reg: | |
5388 | + if (intel_syntax) | |
5389 | + s = "[dx]"; | |
5390 | + else | |
5391 | + s = "(%dx)"; | |
5392 | + break; | |
5393 | + case ax_reg: case cx_reg: case dx_reg: case bx_reg: | |
5394 | + case sp_reg: case bp_reg: case si_reg: case di_reg: | |
5395 | + s = names16[code - ax_reg]; | |
5396 | + break; | |
5397 | + case es_reg: case ss_reg: case cs_reg: | |
5398 | + case ds_reg: case fs_reg: case gs_reg: | |
5399 | + s = names_seg[code - es_reg]; | |
5400 | + break; | |
5401 | + case al_reg: case ah_reg: case cl_reg: case ch_reg: | |
5402 | + case dl_reg: case dh_reg: case bl_reg: case bh_reg: | |
5403 | + USED_REX (0); | |
5404 | + if (rex) | |
5405 | + s = names8rex[code - al_reg]; | |
5406 | + else | |
5407 | + s = names8[code - al_reg]; | |
5408 | + break; | |
5409 | + case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg: | |
5410 | + case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg: | |
5411 | + USED_REX (REX_MODE64); | |
5412 | + if (rex & REX_MODE64) | |
5413 | + s = names64[code - eAX_reg]; | |
5414 | + else if (sizeflag & DFLAG) | |
5415 | + s = names32[code - eAX_reg]; | |
5416 | + else | |
5417 | + s = names16[code - eAX_reg]; | |
5418 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
5419 | + break; | |
5420 | + default: | |
5421 | + s = INTERNAL_DISASSEMBLER_ERROR; | |
5422 | + break; | |
5423 | + } | |
5424 | + oappend (s); | |
5425 | +} | |
5426 | + | |
5427 | +static void | |
5428 | +OP_I (int bytemode, int sizeflag) | |
5429 | +{ | |
5430 | + bfd_signed_vma op; | |
5431 | + bfd_signed_vma mask = -1; | |
5432 | + | |
5433 | + switch (bytemode) | |
5434 | + { | |
5435 | + case b_mode: | |
5436 | + FETCH_DATA (the_info, codep + 1); | |
5437 | + op = *codep++; | |
5438 | + mask = 0xff; | |
5439 | + break; | |
5440 | + case q_mode: | |
5441 | + if (mode_64bit) | |
5442 | + { | |
5443 | + op = get32s (); | |
5444 | + break; | |
5445 | + } | |
5446 | + /* Fall through. */ | |
5447 | + case v_mode: | |
5448 | + USED_REX (REX_MODE64); | |
5449 | + if (rex & REX_MODE64) | |
5450 | + op = get32s (); | |
5451 | + else if (sizeflag & DFLAG) | |
5452 | + { | |
5453 | + op = get32 (); | |
5454 | + mask = 0xffffffff; | |
5455 | + } | |
5456 | + else | |
5457 | + { | |
5458 | + op = get16 (); | |
5459 | + mask = 0xfffff; | |
5460 | + } | |
5461 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
5462 | + break; | |
5463 | + case w_mode: | |
5464 | + mask = 0xfffff; | |
5465 | + op = get16 (); | |
5466 | + break; | |
5467 | + case const_1_mode: | |
5468 | + if (intel_syntax) | |
5469 | + oappend ("1"); | |
5470 | + return; | |
5471 | + default: | |
5472 | + oappend (INTERNAL_DISASSEMBLER_ERROR); | |
5473 | + return; | |
5474 | + } | |
5475 | + | |
5476 | + op &= mask; | |
5477 | + scratchbuf[0] = '$'; | |
5478 | + print_operand_value (scratchbuf + 1, 1, op); | |
5479 | + oappend (scratchbuf + intel_syntax); | |
5480 | + scratchbuf[0] = '\0'; | |
5481 | +} | |
5482 | + | |
5483 | +static void | |
5484 | +OP_I64 (int bytemode, int sizeflag) | |
5485 | +{ | |
5486 | + bfd_signed_vma op; | |
5487 | + bfd_signed_vma mask = -1; | |
5488 | + | |
5489 | + if (!mode_64bit) | |
5490 | + { | |
5491 | + OP_I (bytemode, sizeflag); | |
5492 | + return; | |
5493 | + } | |
5494 | + | |
5495 | + switch (bytemode) | |
5496 | + { | |
5497 | + case b_mode: | |
5498 | + FETCH_DATA (the_info, codep + 1); | |
5499 | + op = *codep++; | |
5500 | + mask = 0xff; | |
5501 | + break; | |
5502 | + case v_mode: | |
5503 | + USED_REX (REX_MODE64); | |
5504 | + if (rex & REX_MODE64) | |
5505 | + op = get64 (); | |
5506 | + else if (sizeflag & DFLAG) | |
5507 | + { | |
5508 | + op = get32 (); | |
5509 | + mask = 0xffffffff; | |
5510 | + } | |
5511 | + else | |
5512 | + { | |
5513 | + op = get16 (); | |
5514 | + mask = 0xfffff; | |
5515 | + } | |
5516 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
5517 | + break; | |
5518 | + case w_mode: | |
5519 | + mask = 0xfffff; | |
5520 | + op = get16 (); | |
5521 | + break; | |
5522 | + default: | |
5523 | + oappend (INTERNAL_DISASSEMBLER_ERROR); | |
5524 | + return; | |
5525 | + } | |
5526 | + | |
5527 | + op &= mask; | |
5528 | + scratchbuf[0] = '$'; | |
5529 | + print_operand_value (scratchbuf + 1, 1, op); | |
5530 | + oappend (scratchbuf + intel_syntax); | |
5531 | + scratchbuf[0] = '\0'; | |
5532 | +} | |
5533 | + | |
5534 | +static void | |
5535 | +OP_sI (int bytemode, int sizeflag) | |
5536 | +{ | |
5537 | + bfd_signed_vma op; | |
5538 | + bfd_signed_vma mask = -1; | |
5539 | + | |
5540 | + switch (bytemode) | |
5541 | + { | |
5542 | + case b_mode: | |
5543 | + FETCH_DATA (the_info, codep + 1); | |
5544 | + op = *codep++; | |
5545 | + if ((op & 0x80) != 0) | |
5546 | + op -= 0x100; | |
5547 | + mask = 0xffffffff; | |
5548 | + break; | |
5549 | + case v_mode: | |
5550 | + USED_REX (REX_MODE64); | |
5551 | + if (rex & REX_MODE64) | |
5552 | + op = get32s (); | |
5553 | + else if (sizeflag & DFLAG) | |
5554 | + { | |
5555 | + op = get32s (); | |
5556 | + mask = 0xffffffff; | |
5557 | + } | |
5558 | + else | |
5559 | + { | |
5560 | + mask = 0xffffffff; | |
5561 | + op = get16 (); | |
5562 | + if ((op & 0x8000) != 0) | |
5563 | + op -= 0x10000; | |
5564 | + } | |
5565 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
5566 | + break; | |
5567 | + case w_mode: | |
5568 | + op = get16 (); | |
5569 | + mask = 0xffffffff; | |
5570 | + if ((op & 0x8000) != 0) | |
5571 | + op -= 0x10000; | |
5572 | + break; | |
5573 | + default: | |
5574 | + oappend (INTERNAL_DISASSEMBLER_ERROR); | |
5575 | + return; | |
5576 | + } | |
5577 | + | |
5578 | + scratchbuf[0] = '$'; | |
5579 | + print_operand_value (scratchbuf + 1, 1, op); | |
5580 | + oappend (scratchbuf + intel_syntax); | |
5581 | +} | |
5582 | + | |
5583 | +static void | |
5584 | +OP_J (int bytemode, int sizeflag) | |
5585 | +{ | |
5586 | + bfd_vma disp; | |
5587 | + bfd_vma mask = -1; | |
5588 | + | |
5589 | + switch (bytemode) | |
5590 | + { | |
5591 | + case b_mode: | |
5592 | + FETCH_DATA (the_info, codep + 1); | |
5593 | + disp = *codep++; | |
5594 | + if ((disp & 0x80) != 0) | |
5595 | + disp -= 0x100; | |
5596 | + break; | |
5597 | + case v_mode: | |
5598 | + if (sizeflag & DFLAG) | |
5599 | + disp = get32s (); | |
5600 | + else | |
5601 | + { | |
5602 | + disp = get16 (); | |
5603 | + /* For some reason, a data16 prefix on a jump instruction | |
5604 | + means that the pc is masked to 16 bits after the | |
5605 | + displacement is added! */ | |
5606 | + mask = 0xffff; | |
5607 | + } | |
5608 | + break; | |
5609 | + default: | |
5610 | + oappend (INTERNAL_DISASSEMBLER_ERROR); | |
5611 | + return; | |
5612 | + } | |
5613 | + disp = (start_pc + codep - start_codep + disp) & mask; | |
5614 | + set_op (disp, 0); | |
5615 | + print_operand_value (scratchbuf, 1, disp); | |
5616 | + oappend (scratchbuf); | |
5617 | +} | |
5618 | + | |
5619 | +static void | |
5620 | +OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
5621 | +{ | |
5622 | + oappend (names_seg[reg]); | |
5623 | +} | |
5624 | + | |
5625 | +static void | |
5626 | +OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag) | |
5627 | +{ | |
5628 | + int seg, offset; | |
5629 | + | |
5630 | + if (sizeflag & DFLAG) | |
5631 | + { | |
5632 | + offset = get32 (); | |
5633 | + seg = get16 (); | |
5634 | + } | |
5635 | + else | |
5636 | + { | |
5637 | + offset = get16 (); | |
5638 | + seg = get16 (); | |
5639 | + } | |
5640 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
5641 | + if (intel_syntax) | |
5642 | + sprintf (scratchbuf, "0x%x,0x%x", seg, offset); | |
5643 | + else | |
5644 | + sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset); | |
5645 | + oappend (scratchbuf); | |
5646 | +} | |
5647 | + | |
5648 | +static void | |
5649 | +OP_OFF (int bytemode ATTRIBUTE_UNUSED, int sizeflag) | |
5650 | +{ | |
5651 | + bfd_vma off; | |
5652 | + | |
5653 | + append_seg (); | |
5654 | + | |
5655 | + if ((sizeflag & AFLAG) || mode_64bit) | |
5656 | + off = get32 (); | |
5657 | + else | |
5658 | + off = get16 (); | |
5659 | + | |
5660 | + if (intel_syntax) | |
5661 | + { | |
5662 | + if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS | |
5663 | + | PREFIX_ES | PREFIX_FS | PREFIX_GS))) | |
5664 | + { | |
5665 | + oappend (names_seg[ds_reg - es_reg]); | |
5666 | + oappend (":"); | |
5667 | + } | |
5668 | + } | |
5669 | + print_operand_value (scratchbuf, 1, off); | |
5670 | + oappend (scratchbuf); | |
5671 | +} | |
5672 | + | |
5673 | +static void | |
5674 | +OP_OFF64 (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
5675 | +{ | |
5676 | + bfd_vma off; | |
5677 | + | |
5678 | + if (!mode_64bit) | |
5679 | + { | |
5680 | + OP_OFF (bytemode, sizeflag); | |
5681 | + return; | |
5682 | + } | |
5683 | + | |
5684 | + append_seg (); | |
5685 | + | |
5686 | + off = get64 (); | |
5687 | + | |
5688 | + if (intel_syntax) | |
5689 | + { | |
5690 | + if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS | |
5691 | + | PREFIX_ES | PREFIX_FS | PREFIX_GS))) | |
5692 | + { | |
5693 | + oappend (names_seg[ds_reg - es_reg]); | |
5694 | + oappend (":"); | |
5695 | + } | |
5696 | + } | |
5697 | + print_operand_value (scratchbuf, 1, off); | |
5698 | + oappend (scratchbuf); | |
5699 | +} | |
5700 | + | |
5701 | +static void | |
5702 | +ptr_reg (int code, int sizeflag) | |
5703 | +{ | |
5704 | + const char *s; | |
5705 | + | |
5706 | + *obufp++ = open_char; | |
5707 | + used_prefixes |= (prefixes & PREFIX_ADDR); | |
5708 | + if (mode_64bit) | |
5709 | + { | |
5710 | + if (!(sizeflag & AFLAG)) | |
5711 | + s = names32[code - eAX_reg]; | |
5712 | + else | |
5713 | + s = names64[code - eAX_reg]; | |
5714 | + } | |
5715 | + else if (sizeflag & AFLAG) | |
5716 | + s = names32[code - eAX_reg]; | |
5717 | + else | |
5718 | + s = names16[code - eAX_reg]; | |
5719 | + oappend (s); | |
5720 | + *obufp++ = close_char; | |
5721 | + *obufp = 0; | |
5722 | +} | |
5723 | + | |
5724 | +static void | |
5725 | +OP_ESreg (int code, int sizeflag) | |
5726 | +{ | |
5727 | + if (intel_syntax) | |
5728 | + { | |
5729 | + if (codep[-1] & 1) | |
5730 | + { | |
5731 | + USED_REX (REX_MODE64); | |
5732 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
5733 | + if (rex & REX_MODE64) | |
5734 | + oappend ("QWORD PTR "); | |
5735 | + else if ((sizeflag & DFLAG)) | |
5736 | + oappend ("DWORD PTR "); | |
5737 | + else | |
5738 | + oappend ("WORD PTR "); | |
5739 | + } | |
5740 | + else | |
5741 | + oappend ("BYTE PTR "); | |
5742 | + } | |
5743 | + | |
5744 | + oappend ("%es:" + intel_syntax); | |
5745 | + ptr_reg (code, sizeflag); | |
5746 | +} | |
5747 | + | |
5748 | +static void | |
5749 | +OP_DSreg (int code, int sizeflag) | |
5750 | +{ | |
5751 | + if (intel_syntax) | |
5752 | + { | |
5753 | + if (codep[-1] != 0xd7 && (codep[-1] & 1)) | |
5754 | + { | |
5755 | + USED_REX (REX_MODE64); | |
5756 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
5757 | + if (rex & REX_MODE64) | |
5758 | + oappend ("QWORD PTR "); | |
5759 | + else if ((sizeflag & DFLAG)) | |
5760 | + oappend ("DWORD PTR "); | |
5761 | + else | |
5762 | + oappend ("WORD PTR "); | |
5763 | + } | |
5764 | + else | |
5765 | + oappend ("BYTE PTR "); | |
5766 | + } | |
5767 | + | |
5768 | + if ((prefixes | |
5769 | + & (PREFIX_CS | |
5770 | + | PREFIX_DS | |
5771 | + | PREFIX_SS | |
5772 | + | PREFIX_ES | |
5773 | + | PREFIX_FS | |
5774 | + | PREFIX_GS)) == 0) | |
5775 | + prefixes |= PREFIX_DS; | |
5776 | + append_seg (); | |
5777 | + ptr_reg (code, sizeflag); | |
5778 | +} | |
5779 | + | |
5780 | +static void | |
5781 | +OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
5782 | +{ | |
5783 | + int add = 0; | |
5784 | + if (rex & REX_EXTX) | |
5785 | + { | |
5786 | + USED_REX (REX_EXTX); | |
5787 | + add = 8; | |
5788 | + } | |
5789 | + else if (!mode_64bit && (prefixes & PREFIX_LOCK)) | |
5790 | + { | |
5791 | + used_prefixes |= PREFIX_LOCK; | |
5792 | + add = 8; | |
5793 | + } | |
5794 | + sprintf (scratchbuf, "%%cr%d", reg + add); | |
5795 | + oappend (scratchbuf + intel_syntax); | |
5796 | +} | |
5797 | + | |
5798 | +static void | |
5799 | +OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
5800 | +{ | |
5801 | + int add = 0; | |
5802 | + USED_REX (REX_EXTX); | |
5803 | + if (rex & REX_EXTX) | |
5804 | + add = 8; | |
5805 | + if (intel_syntax) | |
5806 | + sprintf (scratchbuf, "db%d", reg + add); | |
5807 | + else | |
5808 | + sprintf (scratchbuf, "%%db%d", reg + add); | |
5809 | + oappend (scratchbuf); | |
5810 | +} | |
5811 | + | |
5812 | +static void | |
5813 | +OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
5814 | +{ | |
5815 | + sprintf (scratchbuf, "%%tr%d", reg); | |
5816 | + oappend (scratchbuf + intel_syntax); | |
5817 | +} | |
5818 | + | |
5819 | +static void | |
5820 | +OP_Rd (int bytemode, int sizeflag) | |
5821 | +{ | |
5822 | + if (mod == 3) | |
5823 | + OP_E (bytemode, sizeflag); | |
5824 | + else | |
5825 | + BadOp (); | |
5826 | +} | |
5827 | + | |
5828 | +static void | |
5829 | +OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
5830 | +{ | |
5831 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
5832 | + if (prefixes & PREFIX_DATA) | |
5833 | + { | |
5834 | + int add = 0; | |
5835 | + USED_REX (REX_EXTX); | |
5836 | + if (rex & REX_EXTX) | |
5837 | + add = 8; | |
5838 | + sprintf (scratchbuf, "%%xmm%d", reg + add); | |
5839 | + } | |
5840 | + else | |
5841 | + sprintf (scratchbuf, "%%mm%d", reg); | |
5842 | + oappend (scratchbuf + intel_syntax); | |
5843 | +} | |
5844 | + | |
5845 | +static void | |
5846 | +OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
5847 | +{ | |
5848 | + int add = 0; | |
5849 | + USED_REX (REX_EXTX); | |
5850 | + if (rex & REX_EXTX) | |
5851 | + add = 8; | |
5852 | + sprintf (scratchbuf, "%%xmm%d", reg + add); | |
5853 | + oappend (scratchbuf + intel_syntax); | |
5854 | +} | |
5855 | + | |
5856 | +static void | |
5857 | +OP_EM (int bytemode, int sizeflag) | |
5858 | +{ | |
5859 | + if (mod != 3) | |
5860 | + { | |
5861 | + if (intel_syntax && bytemode == v_mode) | |
5862 | + { | |
5863 | + bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode; | |
5864 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
5865 | + } | |
5866 | + OP_E (bytemode, sizeflag); | |
5867 | + return; | |
5868 | + } | |
5869 | + | |
5870 | + /* Skip mod/rm byte. */ | |
5871 | + MODRM_CHECK; | |
5872 | + codep++; | |
5873 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
5874 | + if (prefixes & PREFIX_DATA) | |
5875 | + { | |
5876 | + int add = 0; | |
5877 | + | |
5878 | + USED_REX (REX_EXTZ); | |
5879 | + if (rex & REX_EXTZ) | |
5880 | + add = 8; | |
5881 | + sprintf (scratchbuf, "%%xmm%d", rm + add); | |
5882 | + } | |
5883 | + else | |
5884 | + sprintf (scratchbuf, "%%mm%d", rm); | |
5885 | + oappend (scratchbuf + intel_syntax); | |
5886 | +} | |
5887 | + | |
5888 | +static void | |
5889 | +OP_EX (int bytemode, int sizeflag) | |
5890 | +{ | |
5891 | + int add = 0; | |
5892 | + if (mod != 3) | |
5893 | + { | |
5894 | + if (intel_syntax && bytemode == v_mode) | |
5895 | + { | |
5896 | + switch (prefixes & (PREFIX_DATA|PREFIX_REPZ|PREFIX_REPNZ)) | |
5897 | + { | |
5898 | + case 0: bytemode = x_mode; break; | |
5899 | + case PREFIX_REPZ: bytemode = d_mode; used_prefixes |= PREFIX_REPZ; break; | |
5900 | + case PREFIX_DATA: bytemode = x_mode; used_prefixes |= PREFIX_DATA; break; | |
5901 | + case PREFIX_REPNZ: bytemode = q_mode; used_prefixes |= PREFIX_REPNZ; break; | |
5902 | + default: bytemode = 0; break; | |
5903 | + } | |
5904 | + } | |
5905 | + OP_E (bytemode, sizeflag); | |
5906 | + return; | |
5907 | + } | |
5908 | + USED_REX (REX_EXTZ); | |
5909 | + if (rex & REX_EXTZ) | |
5910 | + add = 8; | |
5911 | + | |
5912 | + /* Skip mod/rm byte. */ | |
5913 | + MODRM_CHECK; | |
5914 | + codep++; | |
5915 | + sprintf (scratchbuf, "%%xmm%d", rm + add); | |
5916 | + oappend (scratchbuf + intel_syntax); | |
5917 | +} | |
5918 | + | |
5919 | +static void | |
5920 | +OP_MS (int bytemode, int sizeflag) | |
5921 | +{ | |
5922 | + if (mod == 3) | |
5923 | + OP_EM (bytemode, sizeflag); | |
5924 | + else | |
5925 | + BadOp (); | |
5926 | +} | |
5927 | + | |
5928 | +static void | |
5929 | +OP_XS (int bytemode, int sizeflag) | |
5930 | +{ | |
5931 | + if (mod == 3) | |
5932 | + OP_EX (bytemode, sizeflag); | |
5933 | + else | |
5934 | + BadOp (); | |
5935 | +} | |
5936 | + | |
5937 | +static void | |
5938 | +OP_M (int bytemode, int sizeflag) | |
5939 | +{ | |
5940 | + if (mod == 3) | |
5941 | + BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */ | |
5942 | + else | |
5943 | + OP_E (bytemode, sizeflag); | |
5944 | +} | |
5945 | + | |
5946 | +static void | |
5947 | +OP_0f07 (int bytemode, int sizeflag) | |
5948 | +{ | |
5949 | + if (mod != 3 || rm != 0) | |
5950 | + BadOp (); | |
5951 | + else | |
5952 | + OP_E (bytemode, sizeflag); | |
5953 | +} | |
5954 | + | |
5955 | +static void | |
5956 | +OP_0fae (int bytemode, int sizeflag) | |
5957 | +{ | |
5958 | + if (mod == 3) | |
5959 | + { | |
5960 | + if (reg == 7) | |
5961 | + strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence"); | |
5962 | + | |
5963 | + if (reg < 5 || rm != 0) | |
5964 | + { | |
5965 | + BadOp (); /* bad sfence, mfence, or lfence */ | |
5966 | + return; | |
5967 | + } | |
5968 | + } | |
5969 | + else if (reg != 7) | |
5970 | + { | |
5971 | + BadOp (); /* bad clflush */ | |
5972 | + return; | |
5973 | + } | |
5974 | + | |
5975 | + OP_E (bytemode, sizeflag); | |
5976 | +} | |
5977 | + | |
5978 | +static void | |
5979 | +NOP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
5980 | +{ | |
5981 | + /* NOP with REPZ prefix is called PAUSE. */ | |
5982 | + if (prefixes == PREFIX_REPZ) | |
5983 | + strcpy (obuf, "pause"); | |
5984 | +} | |
5985 | + | |
5986 | +static const char *const Suffix3DNow[] = { | |
5987 | +/* 00 */ NULL, NULL, NULL, NULL, | |
5988 | +/* 04 */ NULL, NULL, NULL, NULL, | |
5989 | +/* 08 */ NULL, NULL, NULL, NULL, | |
5990 | +/* 0C */ "pi2fw", "pi2fd", NULL, NULL, | |
5991 | +/* 10 */ NULL, NULL, NULL, NULL, | |
5992 | +/* 14 */ NULL, NULL, NULL, NULL, | |
5993 | +/* 18 */ NULL, NULL, NULL, NULL, | |
5994 | +/* 1C */ "pf2iw", "pf2id", NULL, NULL, | |
5995 | +/* 20 */ NULL, NULL, NULL, NULL, | |
5996 | +/* 24 */ NULL, NULL, NULL, NULL, | |
5997 | +/* 28 */ NULL, NULL, NULL, NULL, | |
5998 | +/* 2C */ NULL, NULL, NULL, NULL, | |
5999 | +/* 30 */ NULL, NULL, NULL, NULL, | |
6000 | +/* 34 */ NULL, NULL, NULL, NULL, | |
6001 | +/* 38 */ NULL, NULL, NULL, NULL, | |
6002 | +/* 3C */ NULL, NULL, NULL, NULL, | |
6003 | +/* 40 */ NULL, NULL, NULL, NULL, | |
6004 | +/* 44 */ NULL, NULL, NULL, NULL, | |
6005 | +/* 48 */ NULL, NULL, NULL, NULL, | |
6006 | +/* 4C */ NULL, NULL, NULL, NULL, | |
6007 | +/* 50 */ NULL, NULL, NULL, NULL, | |
6008 | +/* 54 */ NULL, NULL, NULL, NULL, | |
6009 | +/* 58 */ NULL, NULL, NULL, NULL, | |
6010 | +/* 5C */ NULL, NULL, NULL, NULL, | |
6011 | +/* 60 */ NULL, NULL, NULL, NULL, | |
6012 | +/* 64 */ NULL, NULL, NULL, NULL, | |
6013 | +/* 68 */ NULL, NULL, NULL, NULL, | |
6014 | +/* 6C */ NULL, NULL, NULL, NULL, | |
6015 | +/* 70 */ NULL, NULL, NULL, NULL, | |
6016 | +/* 74 */ NULL, NULL, NULL, NULL, | |
6017 | +/* 78 */ NULL, NULL, NULL, NULL, | |
6018 | +/* 7C */ NULL, NULL, NULL, NULL, | |
6019 | +/* 80 */ NULL, NULL, NULL, NULL, | |
6020 | +/* 84 */ NULL, NULL, NULL, NULL, | |
6021 | +/* 88 */ NULL, NULL, "pfnacc", NULL, | |
6022 | +/* 8C */ NULL, NULL, "pfpnacc", NULL, | |
6023 | +/* 90 */ "pfcmpge", NULL, NULL, NULL, | |
6024 | +/* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt", | |
6025 | +/* 98 */ NULL, NULL, "pfsub", NULL, | |
6026 | +/* 9C */ NULL, NULL, "pfadd", NULL, | |
6027 | +/* A0 */ "pfcmpgt", NULL, NULL, NULL, | |
6028 | +/* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1", | |
6029 | +/* A8 */ NULL, NULL, "pfsubr", NULL, | |
6030 | +/* AC */ NULL, NULL, "pfacc", NULL, | |
6031 | +/* B0 */ "pfcmpeq", NULL, NULL, NULL, | |
6032 | +/* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw", | |
6033 | +/* B8 */ NULL, NULL, NULL, "pswapd", | |
6034 | +/* BC */ NULL, NULL, NULL, "pavgusb", | |
6035 | +/* C0 */ NULL, NULL, NULL, NULL, | |
6036 | +/* C4 */ NULL, NULL, NULL, NULL, | |
6037 | +/* C8 */ NULL, NULL, NULL, NULL, | |
6038 | +/* CC */ NULL, NULL, NULL, NULL, | |
6039 | +/* D0 */ NULL, NULL, NULL, NULL, | |
6040 | +/* D4 */ NULL, NULL, NULL, NULL, | |
6041 | +/* D8 */ NULL, NULL, NULL, NULL, | |
6042 | +/* DC */ NULL, NULL, NULL, NULL, | |
6043 | +/* E0 */ NULL, NULL, NULL, NULL, | |
6044 | +/* E4 */ NULL, NULL, NULL, NULL, | |
6045 | +/* E8 */ NULL, NULL, NULL, NULL, | |
6046 | +/* EC */ NULL, NULL, NULL, NULL, | |
6047 | +/* F0 */ NULL, NULL, NULL, NULL, | |
6048 | +/* F4 */ NULL, NULL, NULL, NULL, | |
6049 | +/* F8 */ NULL, NULL, NULL, NULL, | |
6050 | +/* FC */ NULL, NULL, NULL, NULL, | |
6051 | +}; | |
6052 | + | |
6053 | +static void | |
6054 | +OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
6055 | +{ | |
6056 | + const char *mnemonic; | |
6057 | + | |
6058 | + FETCH_DATA (the_info, codep + 1); | |
6059 | + /* AMD 3DNow! instructions are specified by an opcode suffix in the | |
6060 | + place where an 8-bit immediate would normally go. ie. the last | |
6061 | + byte of the instruction. */ | |
6062 | + obufp = obuf + strlen (obuf); | |
6063 | + mnemonic = Suffix3DNow[*codep++ & 0xff]; | |
6064 | + if (mnemonic) | |
6065 | + oappend (mnemonic); | |
6066 | + else | |
6067 | + { | |
6068 | + /* Since a variable sized modrm/sib chunk is between the start | |
6069 | + of the opcode (0x0f0f) and the opcode suffix, we need to do | |
6070 | + all the modrm processing first, and don't know until now that | |
6071 | + we have a bad opcode. This necessitates some cleaning up. */ | |
6072 | + op1out[0] = '\0'; | |
6073 | + op2out[0] = '\0'; | |
6074 | + BadOp (); | |
6075 | + } | |
6076 | +} | |
6077 | + | |
6078 | +static const char *simd_cmp_op[] = { | |
6079 | + "eq", | |
6080 | + "lt", | |
6081 | + "le", | |
6082 | + "unord", | |
6083 | + "neq", | |
6084 | + "nlt", | |
6085 | + "nle", | |
6086 | + "ord" | |
6087 | +}; | |
6088 | + | |
6089 | +static void | |
6090 | +OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
6091 | +{ | |
6092 | + unsigned int cmp_type; | |
6093 | + | |
6094 | + FETCH_DATA (the_info, codep + 1); | |
6095 | + obufp = obuf + strlen (obuf); | |
6096 | + cmp_type = *codep++ & 0xff; | |
6097 | + if (cmp_type < 8) | |
6098 | + { | |
6099 | + char suffix1 = 'p', suffix2 = 's'; | |
6100 | + used_prefixes |= (prefixes & PREFIX_REPZ); | |
6101 | + if (prefixes & PREFIX_REPZ) | |
6102 | + suffix1 = 's'; | |
6103 | + else | |
6104 | + { | |
6105 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
6106 | + if (prefixes & PREFIX_DATA) | |
6107 | + suffix2 = 'd'; | |
6108 | + else | |
6109 | + { | |
6110 | + used_prefixes |= (prefixes & PREFIX_REPNZ); | |
6111 | + if (prefixes & PREFIX_REPNZ) | |
6112 | + suffix1 = 's', suffix2 = 'd'; | |
6113 | + } | |
6114 | + } | |
6115 | + sprintf (scratchbuf, "cmp%s%c%c", | |
6116 | + simd_cmp_op[cmp_type], suffix1, suffix2); | |
6117 | + used_prefixes |= (prefixes & PREFIX_REPZ); | |
6118 | + oappend (scratchbuf); | |
6119 | + } | |
6120 | + else | |
6121 | + { | |
6122 | + /* We have a bad extension byte. Clean up. */ | |
6123 | + op1out[0] = '\0'; | |
6124 | + op2out[0] = '\0'; | |
6125 | + BadOp (); | |
6126 | + } | |
6127 | +} | |
6128 | + | |
6129 | +static void | |
6130 | +SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED) | |
6131 | +{ | |
6132 | + /* Change movlps/movhps to movhlps/movlhps for 2 register operand | |
6133 | + forms of these instructions. */ | |
6134 | + if (mod == 3) | |
6135 | + { | |
6136 | + char *p = obuf + strlen (obuf); | |
6137 | + *(p + 1) = '\0'; | |
6138 | + *p = *(p - 1); | |
6139 | + *(p - 1) = *(p - 2); | |
6140 | + *(p - 2) = *(p - 3); | |
6141 | + *(p - 3) = extrachar; | |
6142 | + } | |
6143 | +} | |
6144 | + | |
6145 | +static void | |
6146 | +PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag) | |
6147 | +{ | |
6148 | + if (mod == 3 && reg == 1 && rm <= 1) | |
6149 | + { | |
6150 | + /* Override "sidt". */ | |
6151 | + char *p = obuf + strlen (obuf) - 4; | |
6152 | + | |
6153 | + /* We might have a suffix when disassembling with -Msuffix. */ | |
6154 | + if (*p == 'i') | |
6155 | + --p; | |
6156 | + | |
6157 | + if (rm) | |
6158 | + { | |
6159 | + /* mwait %eax,%ecx */ | |
6160 | + strcpy (p, "mwait"); | |
6161 | + if (!intel_syntax) | |
6162 | + strcpy (op1out, names32[0]); | |
6163 | + } | |
6164 | + else | |
6165 | + { | |
6166 | + /* monitor %eax,%ecx,%edx" */ | |
6167 | + strcpy (p, "monitor"); | |
6168 | + if (!intel_syntax) | |
6169 | + { | |
6170 | + if (!mode_64bit) | |
6171 | + strcpy (op1out, names32[0]); | |
6172 | + else if (!(prefixes & PREFIX_ADDR)) | |
6173 | + strcpy (op1out, names64[0]); | |
6174 | + else | |
6175 | + { | |
6176 | + strcpy (op1out, names32[0]); | |
6177 | + used_prefixes |= PREFIX_ADDR; | |
6178 | + } | |
6179 | + strcpy (op3out, names32[2]); | |
6180 | + } | |
6181 | + } | |
6182 | + if (!intel_syntax) | |
6183 | + { | |
6184 | + strcpy (op2out, names32[1]); | |
6185 | + two_source_ops = 1; | |
6186 | + } | |
6187 | + | |
6188 | + codep++; | |
6189 | + } | |
6190 | + else | |
6191 | + OP_M (0, sizeflag); | |
6192 | +} | |
6193 | + | |
6194 | +static void | |
6195 | +SVME_Fixup (int bytemode, int sizeflag) | |
6196 | +{ | |
6197 | + const char *alt; | |
6198 | + char *p; | |
6199 | + | |
6200 | + switch (*codep) | |
6201 | + { | |
6202 | + case 0xd8: | |
6203 | + alt = "vmrun"; | |
6204 | + break; | |
6205 | + case 0xd9: | |
6206 | + alt = "vmmcall"; | |
6207 | + break; | |
6208 | + case 0xda: | |
6209 | + alt = "vmload"; | |
6210 | + break; | |
6211 | + case 0xdb: | |
6212 | + alt = "vmsave"; | |
6213 | + break; | |
6214 | + case 0xdc: | |
6215 | + alt = "stgi"; | |
6216 | + break; | |
6217 | + case 0xdd: | |
6218 | + alt = "clgi"; | |
6219 | + break; | |
6220 | + case 0xde: | |
6221 | + alt = "skinit"; | |
6222 | + break; | |
6223 | + case 0xdf: | |
6224 | + alt = "invlpga"; | |
6225 | + break; | |
6226 | + default: | |
6227 | + OP_M (bytemode, sizeflag); | |
6228 | + return; | |
6229 | + } | |
6230 | + /* Override "lidt". */ | |
6231 | + p = obuf + strlen (obuf) - 4; | |
6232 | + /* We might have a suffix. */ | |
6233 | + if (*p == 'i') | |
6234 | + --p; | |
6235 | + strcpy (p, alt); | |
6236 | + if (!(prefixes & PREFIX_ADDR)) | |
6237 | + { | |
6238 | + ++codep; | |
6239 | + return; | |
6240 | + } | |
6241 | + used_prefixes |= PREFIX_ADDR; | |
6242 | + switch (*codep++) | |
6243 | + { | |
6244 | + case 0xdf: | |
6245 | + strcpy (op2out, names32[1]); | |
6246 | + two_source_ops = 1; | |
6247 | + /* Fall through. */ | |
6248 | + case 0xd8: | |
6249 | + case 0xda: | |
6250 | + case 0xdb: | |
6251 | + *obufp++ = open_char; | |
6252 | + if (mode_64bit || (sizeflag & AFLAG)) | |
6253 | + alt = names32[0]; | |
6254 | + else | |
6255 | + alt = names16[0]; | |
6256 | + strcpy (obufp, alt); | |
6257 | + obufp += strlen (alt); | |
6258 | + *obufp++ = close_char; | |
6259 | + *obufp = '\0'; | |
6260 | + break; | |
6261 | + } | |
6262 | +} | |
6263 | + | |
6264 | +static void | |
6265 | +INVLPG_Fixup (int bytemode, int sizeflag) | |
6266 | +{ | |
6267 | + const char *alt; | |
6268 | + | |
6269 | + switch (*codep) | |
6270 | + { | |
6271 | + case 0xf8: | |
6272 | + alt = "swapgs"; | |
6273 | + break; | |
6274 | + case 0xf9: | |
6275 | + alt = "rdtscp"; | |
6276 | + break; | |
6277 | + default: | |
6278 | + OP_M (bytemode, sizeflag); | |
6279 | + return; | |
6280 | + } | |
6281 | + /* Override "invlpg". */ | |
6282 | + strcpy (obuf + strlen (obuf) - 6, alt); | |
6283 | + codep++; | |
6284 | +} | |
6285 | + | |
6286 | +static void | |
6287 | +BadOp (void) | |
6288 | +{ | |
6289 | + /* Throw away prefixes and 1st. opcode byte. */ | |
6290 | + codep = insn_codep + 1; | |
6291 | + oappend ("(bad)"); | |
6292 | +} | |
6293 | + | |
6294 | +static void | |
6295 | +SEG_Fixup (int extrachar, int sizeflag) | |
6296 | +{ | |
6297 | + if (mod == 3) | |
6298 | + { | |
6299 | + /* We need to add a proper suffix with | |
6300 | + | |
6301 | + movw %ds,%ax | |
6302 | + movl %ds,%eax | |
6303 | + movq %ds,%rax | |
6304 | + movw %ax,%ds | |
6305 | + movl %eax,%ds | |
6306 | + movq %rax,%ds | |
6307 | + */ | |
6308 | + const char *suffix; | |
6309 | + | |
6310 | + if (prefixes & PREFIX_DATA) | |
6311 | + suffix = "w"; | |
6312 | + else | |
6313 | + { | |
6314 | + USED_REX (REX_MODE64); | |
6315 | + if (rex & REX_MODE64) | |
6316 | + suffix = "q"; | |
6317 | + else | |
6318 | + suffix = "l"; | |
6319 | + } | |
6320 | + strcat (obuf, suffix); | |
6321 | + } | |
6322 | + else | |
6323 | + { | |
6324 | + /* We need to fix the suffix for | |
6325 | + | |
6326 | + movw %ds,(%eax) | |
6327 | + movw %ds,(%rax) | |
6328 | + movw (%eax),%ds | |
6329 | + movw (%rax),%ds | |
6330 | + | |
6331 | + Override "mov[l|q]". */ | |
6332 | + char *p = obuf + strlen (obuf) - 1; | |
6333 | + | |
6334 | + /* We might not have a suffix. */ | |
6335 | + if (*p == 'v') | |
6336 | + ++p; | |
6337 | + *p = 'w'; | |
6338 | + } | |
6339 | + | |
6340 | + OP_E (extrachar, sizeflag); | |
6341 | +} | |
6342 | + | |
6343 | +static void | |
6344 | +VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag) | |
6345 | +{ | |
6346 | + if (mod == 3 && reg == 0 && rm >=1 && rm <= 4) | |
6347 | + { | |
6348 | + /* Override "sgdt". */ | |
6349 | + char *p = obuf + strlen (obuf) - 4; | |
6350 | + | |
6351 | + /* We might have a suffix when disassembling with -Msuffix. */ | |
6352 | + if (*p == 'g') | |
6353 | + --p; | |
6354 | + | |
6355 | + switch (rm) | |
6356 | + { | |
6357 | + case 1: | |
6358 | + strcpy (p, "vmcall"); | |
6359 | + break; | |
6360 | + case 2: | |
6361 | + strcpy (p, "vmlaunch"); | |
6362 | + break; | |
6363 | + case 3: | |
6364 | + strcpy (p, "vmresume"); | |
6365 | + break; | |
6366 | + case 4: | |
6367 | + strcpy (p, "vmxoff"); | |
6368 | + break; | |
6369 | + } | |
6370 | + | |
6371 | + codep++; | |
6372 | + } | |
6373 | + else | |
6374 | + OP_E (0, sizeflag); | |
6375 | +} | |
6376 | + | |
6377 | +static void | |
6378 | +OP_VMX (int bytemode, int sizeflag) | |
6379 | +{ | |
6380 | + used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ)); | |
6381 | + if (prefixes & PREFIX_DATA) | |
6382 | + strcpy (obuf, "vmclear"); | |
6383 | + else if (prefixes & PREFIX_REPZ) | |
6384 | + strcpy (obuf, "vmxon"); | |
6385 | + else | |
6386 | + strcpy (obuf, "vmptrld"); | |
6387 | + OP_E (bytemode, sizeflag); | |
6388 | +} | |
6389 | --- /dev/null | |
6390 | +++ b/arch/x86/kdb/kdba_bp_32.c | |
6391 | @@ -0,0 +1,914 @@ | |
6392 | +/* | |
6393 | + * Kernel Debugger Architecture Dependent Breakpoint Handling | |
6394 | + * | |
6395 | + * This file is subject to the terms and conditions of the GNU General Public | |
6396 | + * License. See the file "COPYING" in the main directory of this archive | |
6397 | + * for more details. | |
6398 | + * | |
6399 | + * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved. | |
6400 | + */ | |
6401 | + | |
6402 | +#include <linux/string.h> | |
6403 | +#include <linux/kernel.h> | |
6404 | +#include <linux/sched.h> | |
6405 | +#include <linux/smp.h> | |
6406 | +#include <linux/ptrace.h> | |
6407 | +#include <linux/kdb.h> | |
6408 | +#include <linux/kdbprivate.h> | |
6409 | + | |
6410 | + | |
6411 | +static char *kdba_rwtypes[] = { "Instruction(Register)", "Data Write", | |
6412 | + "I/O", "Data Access"}; | |
6413 | + | |
6414 | +/* | |
6415 | + * Table describing processor architecture hardware | |
6416 | + * breakpoint registers for every CPU. | |
6417 | + */ | |
6418 | + | |
6419 | +static kdbhard_bp_t kdb_hardbreaks[NR_CPUS][KDB_MAXHARDBPT]; | |
6420 | + | |
6421 | +/* | |
6422 | + * kdba_db_trap | |
6423 | + * | |
6424 | + * Perform breakpoint processing upon entry to the | |
6425 | + * processor debugger fault. Determine and print | |
6426 | + * the active breakpoint. | |
6427 | + * | |
6428 | + * Parameters: | |
6429 | + * regs Exception frame containing machine register state | |
6430 | + * error Error number passed to kdb. | |
6431 | + * Outputs: | |
6432 | + * None. | |
6433 | + * Returns: | |
6434 | + * KDB_DB_BPT Standard instruction or data breakpoint encountered | |
6435 | + * KDB_DB_SS Single Step fault ('ss' command or end of 'ssb' command) | |
6436 | + * KDB_DB_SSB Single Step fault, caller should continue ('ssb' command) | |
6437 | + * KDB_DB_SSBPT Single step over breakpoint | |
6438 | + * KDB_DB_NOBPT No existing kdb breakpoint matches this debug exception | |
6439 | + * Locking: | |
6440 | + * None. | |
6441 | + * Remarks: | |
6442 | + * Yup, there be goto's here. | |
6443 | + * | |
6444 | + * If multiple processors receive debug exceptions simultaneously, | |
6445 | + * one may be waiting at the kdb fence in kdb() while the user | |
6446 | + * issues a 'bc' command to clear the breakpoint the processor | |
6447 | + * which is waiting has already encountered. If this is the case, | |
6448 | + * the debug registers will no longer match any entry in the | |
6449 | + * breakpoint table, and we'll return the value KDB_DB_NOBPT. | |
6450 | + * This can cause a panic in die_if_kernel(). It is safer to | |
6451 | + * disable the breakpoint (bd), go until all processors are past | |
6452 | + * the breakpoint then clear the breakpoint (bc). This code | |
6453 | + * recognises a breakpoint even when disabled but not when it has | |
6454 | + * been cleared. | |
6455 | + * | |
6456 | + * WARNING: This routine clears the debug state. It should be called | |
6457 | + * once per debug and the result cached. | |
6458 | + */ | |
6459 | + | |
6460 | +kdb_dbtrap_t | |
6461 | +kdba_db_trap(struct pt_regs *regs, int error_unused) | |
6462 | +{ | |
6463 | + kdb_machreg_t dr6; | |
6464 | + kdb_machreg_t dr7; | |
6465 | + int rw, reg; | |
6466 | + int i; | |
6467 | + kdb_dbtrap_t rv = KDB_DB_BPT; | |
6468 | + kdb_bp_t *bp; | |
6469 | + int cpu = smp_processor_id(); | |
6470 | + | |
6471 | + if (KDB_NULL_REGS(regs)) | |
6472 | + return KDB_DB_NOBPT; | |
6473 | + | |
6474 | + dr6 = kdba_getdr6(); | |
6475 | + dr7 = kdba_getdr7(); | |
6476 | + | |
6477 | + if (KDB_DEBUG(BP)) | |
6478 | + kdb_printf("kdb: dr6 0x%lx dr7 0x%lx\n", dr6, dr7); | |
6479 | + if (dr6 & DR6_BS) { | |
6480 | + if (KDB_STATE(SSBPT)) { | |
6481 | + if (KDB_DEBUG(BP)) | |
6482 | + kdb_printf("ssbpt\n"); | |
6483 | + KDB_STATE_CLEAR(SSBPT); | |
6484 | + for(i=0,bp=kdb_breakpoints; | |
6485 | + i < KDB_MAXBPT; | |
6486 | + i++, bp++) { | |
6487 | + if (KDB_DEBUG(BP)) | |
6488 | + kdb_printf("bp 0x%p enabled %d delayed %d global %d cpu %d\n", | |
6489 | + bp, bp->bp_enabled, bp->bp_delayed, bp->bp_global, bp->bp_cpu); | |
6490 | + if (!bp->bp_enabled) | |
6491 | + continue; | |
6492 | + if (!bp->bp_global && bp->bp_cpu != smp_processor_id()) | |
6493 | + continue; | |
6494 | + if (KDB_DEBUG(BP)) | |
6495 | + kdb_printf("bp for this cpu\n"); | |
6496 | + if (bp->bp_delayed) { | |
6497 | + bp->bp_delayed = 0; | |
6498 | + if (KDB_DEBUG(BP)){ | |
6499 | + /* Can't be hw breakpoint */ | |
6500 | + if (bp->bp_hardtype) | |
6501 | + kdb_printf("kdb: Error - hw bp delayed\n"); | |
6502 | + kdb_printf("kdba_installbp\n"); | |
6503 | + } | |
6504 | + kdba_installbp(regs, bp); | |
6505 | + if (!KDB_STATE(DOING_SS)) { | |
6506 | + regs->flags &= ~EF_TF; | |
6507 | + return(KDB_DB_SSBPT); | |
6508 | + } | |
6509 | + break; | |
6510 | + } | |
6511 | + } | |
6512 | + if (i == KDB_MAXBPT) { | |
6513 | + kdb_printf("kdb: Unable to find delayed breakpoint\n"); | |
6514 | + } | |
6515 | + if (!KDB_STATE(DOING_SS)) { | |
6516 | + regs->flags &= ~EF_TF; | |
6517 | + return(KDB_DB_NOBPT); | |
6518 | + } | |
6519 | + /* FALLTHROUGH */ | |
6520 | + } | |
6521 | + | |
6522 | + /* | |
6523 | + * KDB_STATE_DOING_SS is set when the kernel debugger is using | |
6524 | + * the processor trap flag to single-step a processor. If a | |
6525 | + * single step trap occurs and this flag is clear, the SS trap | |
6526 | + * will be ignored by KDB and the kernel will be allowed to deal | |
6527 | + * with it as necessary (e.g. for ptrace). | |
6528 | + */ | |
6529 | + if (!KDB_STATE(DOING_SS)) | |
6530 | + goto unknown; | |
6531 | + | |
6532 | + /* single step */ | |
6533 | + rv = KDB_DB_SS; /* Indicate single step */ | |
6534 | + if (KDB_STATE(DOING_SSB)) { | |
6535 | + unsigned char instruction[2]; | |
6536 | + | |
6537 | + kdb_id1(regs->ip); | |
6538 | + if (kdb_getarea(instruction, regs->ip) || | |
6539 | + (instruction[0]&0xf0) == 0xe0 || /* short disp jumps */ | |
6540 | + (instruction[0]&0xf0) == 0x70 || /* Misc. jumps */ | |
6541 | + instruction[0] == 0xc2 || /* ret */ | |
6542 | + instruction[0] == 0x9a || /* call */ | |
6543 | + (instruction[0]&0xf8) == 0xc8 || /* enter, leave, iret, int, */ | |
6544 | + ((instruction[0] == 0x0f) && | |
6545 | + ((instruction[1]&0xf0)== 0x80)) | |
6546 | + ) { | |
6547 | + /* | |
6548 | + * End the ssb command here. | |
6549 | + */ | |
6550 | + KDB_STATE_CLEAR(DOING_SSB); | |
6551 | + KDB_STATE_CLEAR(DOING_SS); | |
6552 | + } else { | |
6553 | + rv = KDB_DB_SSB; /* Indicate ssb - dismiss immediately */ | |
6554 | + } | |
6555 | + } else { | |
6556 | + /* | |
6557 | + * Print current insn | |
6558 | + */ | |
6559 | + kdb_printf("SS trap at "); | |
6560 | + kdb_symbol_print(regs->ip, NULL, KDB_SP_DEFAULT|KDB_SP_NEWLINE); | |
6561 | + kdb_id1(regs->ip); | |
6562 | + KDB_STATE_CLEAR(DOING_SS); | |
6563 | + } | |
6564 | + | |
6565 | + if (rv != KDB_DB_SSB) | |
6566 | + regs->flags &= ~EF_TF; | |
6567 | + } | |
6568 | + | |
6569 | + if (dr6 & DR6_B0) { | |
6570 | + rw = DR7_RW0(dr7); | |
6571 | + reg = 0; | |
6572 | + goto handle; | |
6573 | + } | |
6574 | + | |
6575 | + if (dr6 & DR6_B1) { | |
6576 | + rw = DR7_RW1(dr7); | |
6577 | + reg = 1; | |
6578 | + goto handle; | |
6579 | + } | |
6580 | + | |
6581 | + if (dr6 & DR6_B2) { | |
6582 | + rw = DR7_RW2(dr7); | |
6583 | + reg = 2; | |
6584 | + goto handle; | |
6585 | + } | |
6586 | + | |
6587 | + if (dr6 & DR6_B3) { | |
6588 | + rw = DR7_RW3(dr7); | |
6589 | + reg = 3; | |
6590 | + goto handle; | |
6591 | + } | |
6592 | + | |
6593 | + if (rv > 0) | |
6594 | + goto handled; | |
6595 | + | |
6596 | + goto unknown; /* dismiss */ | |
6597 | + | |
6598 | +handle: | |
6599 | + /* | |
6600 | + * Set Resume Flag | |
6601 | + */ | |
6602 | + regs->flags |= EF_RF; | |
6603 | + | |
6604 | + /* | |
6605 | + * Determine which breakpoint was encountered. | |
6606 | + */ | |
6607 | + for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) { | |
6608 | + if (!(bp->bp_free) | |
6609 | + && (bp->bp_global || bp->bp_cpu == smp_processor_id()) | |
6610 | + && (bp->bp_hard[cpu]) | |
6611 | + && (bp->bp_hard[cpu]->bph_reg == reg)) { | |
6612 | + /* | |
6613 | + * Hit this breakpoint. | |
6614 | + */ | |
6615 | + kdb_printf("%s breakpoint #%d at " kdb_bfd_vma_fmt "\n", | |
6616 | + kdba_rwtypes[rw], | |
6617 | + i, bp->bp_addr); | |
6618 | + | |
6619 | + /* | |
6620 | + * For an instruction breakpoint, disassemble | |
6621 | + * the current instruction. | |
6622 | + */ | |
6623 | + if (rw == 0) { | |
6624 | + kdb_id1(regs->ip); | |
6625 | + } | |
6626 | + | |
6627 | + goto handled; | |
6628 | + } | |
6629 | + } | |
6630 | + | |
6631 | +unknown: | |
6632 | + regs->flags |= EF_RF; /* Supress further faults */ | |
6633 | + rv = KDB_DB_NOBPT; /* Cause kdb() to return */ | |
6634 | + | |
6635 | +handled: | |
6636 | + | |
6637 | + /* | |
6638 | + * Clear the pending exceptions. | |
6639 | + */ | |
6640 | + kdba_putdr6(0); | |
6641 | + | |
6642 | + return rv; | |
6643 | +} | |
6644 | + | |
6645 | +/* | |
6646 | + * kdba_bp_trap | |
6647 | + * | |
6648 | + * Perform breakpoint processing upon entry to the | |
6649 | + * processor breakpoint instruction fault. Determine and print | |
6650 | + * the active breakpoint. | |
6651 | + * | |
6652 | + * Parameters: | |
6653 | + * regs Exception frame containing machine register state | |
6654 | + * error Error number passed to kdb. | |
6655 | + * Outputs: | |
6656 | + * None. | |
6657 | + * Returns: | |
6658 | + * 0 Standard instruction or data breakpoint encountered | |
6659 | + * 1 Single Step fault ('ss' command) | |
6660 | + * 2 Single Step fault, caller should continue ('ssb' command) | |
6661 | + * 3 No existing kdb breakpoint matches this debug exception | |
6662 | + * Locking: | |
6663 | + * None. | |
6664 | + * Remarks: | |
6665 | + * | |
6666 | + * If multiple processors receive debug exceptions simultaneously, | |
6667 | + * one may be waiting at the kdb fence in kdb() while the user | |
6668 | + * issues a 'bc' command to clear the breakpoint the processor which | |
6669 | + * is waiting has already encountered. If this is the case, the | |
6670 | + * debug registers will no longer match any entry in the breakpoint | |
6671 | + * table, and we'll return the value '3'. This can cause a panic | |
6672 | + * in die_if_kernel(). It is safer to disable the breakpoint (bd), | |
6673 | + * 'go' until all processors are past the breakpoint then clear the | |
6674 | + * breakpoint (bc). This code recognises a breakpoint even when | |
6675 | + * disabled but not when it has been cleared. | |
6676 | + * | |
6677 | + * WARNING: This routine resets the ip. It should be called | |
6678 | + * once per breakpoint and the result cached. | |
6679 | + */ | |
6680 | + | |
6681 | +kdb_dbtrap_t | |
6682 | +kdba_bp_trap(struct pt_regs *regs, int error_unused) | |
6683 | +{ | |
6684 | + int i; | |
6685 | + kdb_dbtrap_t rv; | |
6686 | + kdb_bp_t *bp; | |
6687 | + | |
6688 | + if (KDB_NULL_REGS(regs)) | |
6689 | + return KDB_DB_NOBPT; | |
6690 | + | |
6691 | + /* | |
6692 | + * Determine which breakpoint was encountered. | |
6693 | + */ | |
6694 | + if (KDB_DEBUG(BP)) | |
6695 | + kdb_printf("kdba_bp_trap: ip=0x%lx (not adjusted) " | |
6696 | + "flags=0x%lx regs=0x%p sp=0x%lx\n", | |
6697 | + regs->ip, regs->flags, regs, regs->sp); | |
6698 | + | |
6699 | + rv = KDB_DB_NOBPT; /* Cause kdb() to return */ | |
6700 | + | |
6701 | + for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) { | |
6702 | + if (bp->bp_free) | |
6703 | + continue; | |
6704 | + if (!bp->bp_global && bp->bp_cpu != smp_processor_id()) | |
6705 | + continue; | |
6706 | + if ((void *)bp->bp_addr == (void *)(regs->ip - bp->bp_adjust)) { | |
6707 | + /* Hit this breakpoint. */ | |
6708 | + regs->ip -= bp->bp_adjust; | |
6709 | + kdb_printf("Instruction(i) breakpoint #%d at 0x%lx (adjusted)\n", | |
6710 | + i, regs->ip); | |
6711 | + kdb_id1(regs->ip); | |
6712 | + rv = KDB_DB_BPT; | |
6713 | + bp->bp_delay = 1; | |
6714 | + /* SSBPT is set when the kernel debugger must single | |
6715 | + * step a task in order to re-establish an instruction | |
6716 | + * breakpoint which uses the instruction replacement | |
6717 | + * mechanism. It is cleared by any action that removes | |
6718 | + * the need to single-step the breakpoint. | |
6719 | + */ | |
6720 | + KDB_STATE_SET(SSBPT); | |
6721 | + break; | |
6722 | + } | |
6723 | + } | |
6724 | + | |
6725 | + return rv; | |
6726 | +} | |
6727 | + | |
6728 | +/* | |
6729 | + * kdba_handle_bp | |
6730 | + * | |
6731 | + * Handle an instruction-breakpoint trap. Called when re-installing | |
6732 | + * an enabled breakpoint which has has the bp_delay bit set. | |
6733 | + * | |
6734 | + * Parameters: | |
6735 | + * Returns: | |
6736 | + * Locking: | |
6737 | + * Remarks: | |
6738 | + * | |
6739 | + * Ok, we really need to: | |
6740 | + * 1) Restore the original instruction byte | |
6741 | + * 2) Single Step | |
6742 | + * 3) Restore breakpoint instruction | |
6743 | + * 4) Continue. | |
6744 | + * | |
6745 | + * | |
6746 | + */ | |
6747 | + | |
6748 | +static void | |
6749 | +kdba_handle_bp(struct pt_regs *regs, kdb_bp_t *bp) | |
6750 | +{ | |
6751 | + if (KDB_NULL_REGS(regs)) | |
6752 | + return; | |
6753 | + | |
6754 | + if (KDB_DEBUG(BP)) | |
6755 | + kdb_printf("regs->ip = 0x%lx\n", regs->ip); | |
6756 | + | |
6757 | + /* | |
6758 | + * Setup single step | |
6759 | + */ | |
6760 | + kdba_setsinglestep(regs); | |
6761 | + | |
6762 | + /* | |
6763 | + * Reset delay attribute | |
6764 | + */ | |
6765 | + bp->bp_delay = 0; | |
6766 | + bp->bp_delayed = 1; | |
6767 | +} | |
6768 | + | |
6769 | + | |
6770 | +/* | |
6771 | + * kdba_bptype | |
6772 | + * | |
6773 | + * Return a string describing type of breakpoint. | |
6774 | + * | |
6775 | + * Parameters: | |
6776 | + * bph Pointer to hardware breakpoint description | |
6777 | + * Outputs: | |
6778 | + * None. | |
6779 | + * Returns: | |
6780 | + * Character string. | |
6781 | + * Locking: | |
6782 | + * None. | |
6783 | + * Remarks: | |
6784 | + */ | |
6785 | + | |
6786 | +char * | |
6787 | +kdba_bptype(kdbhard_bp_t *bph) | |
6788 | +{ | |
6789 | + char *mode; | |
6790 | + | |
6791 | + mode = kdba_rwtypes[bph->bph_mode]; | |
6792 | + | |
6793 | + return mode; | |
6794 | +} | |
6795 | + | |
6796 | +/* | |
6797 | + * kdba_printbpreg | |
6798 | + * | |
6799 | + * Print register name assigned to breakpoint | |
6800 | + * | |
6801 | + * Parameters: | |
6802 | + * bph Pointer hardware breakpoint structure | |
6803 | + * Outputs: | |
6804 | + * None. | |
6805 | + * Returns: | |
6806 | + * None. | |
6807 | + * Locking: | |
6808 | + * None. | |
6809 | + * Remarks: | |
6810 | + */ | |
6811 | + | |
6812 | +static void | |
6813 | +kdba_printbpreg(kdbhard_bp_t *bph) | |
6814 | +{ | |
6815 | + kdb_printf(" in dr%ld", bph->bph_reg); | |
6816 | +} | |
6817 | + | |
6818 | +/* | |
6819 | + * kdba_printbp | |
6820 | + * | |
6821 | + * Print string describing hardware breakpoint. | |
6822 | + * | |
6823 | + * Parameters: | |
6824 | + * bph Pointer to hardware breakpoint description | |
6825 | + * Outputs: | |
6826 | + * None. | |
6827 | + * Returns: | |
6828 | + * None. | |
6829 | + * Locking: | |
6830 | + * None. | |
6831 | + * Remarks: | |
6832 | + */ | |
6833 | + | |
6834 | +void | |
6835 | +kdba_printbp(kdb_bp_t *bp) | |
6836 | +{ | |
6837 | + int cpu; | |
6838 | + | |
6839 | + kdb_printf("\n is enabled"); | |
6840 | + if (bp->bp_hardtype) { | |
6841 | + if (bp->bp_global) | |
6842 | + cpu = smp_processor_id(); | |
6843 | + else | |
6844 | + cpu = bp->bp_cpu; | |
6845 | + kdba_printbpreg(bp->bp_hard[cpu]); | |
6846 | + if (bp->bp_hard[cpu]->bph_mode != 0) { | |
6847 | + kdb_printf(" for %d bytes", | |
6848 | + bp->bp_hard[cpu]->bph_length+1); | |
6849 | + } | |
6850 | + } | |
6851 | +} | |
6852 | + | |
6853 | +/* | |
6854 | + * kdba_parsebp | |
6855 | + * | |
6856 | + * Parse architecture dependent portion of the | |
6857 | + * breakpoint command. | |
6858 | + * | |
6859 | + * Parameters: | |
6860 | + * None. | |
6861 | + * Outputs: | |
6862 | + * None. | |
6863 | + * Returns: | |
6864 | + * Zero for success, a kdb diagnostic for failure | |
6865 | + * Locking: | |
6866 | + * None. | |
6867 | + * Remarks: | |
6868 | + * for Ia32 architure, data access, data write and | |
6869 | + * I/O breakpoints are supported in addition to instruction | |
6870 | + * breakpoints. | |
6871 | + * | |
6872 | + * {datar|dataw|io|inst} [length] | |
6873 | + */ | |
6874 | + | |
6875 | +int | |
6876 | +kdba_parsebp(int argc, const char **argv, int *nextargp, kdb_bp_t *bp) | |
6877 | +{ | |
6878 | + int nextarg = *nextargp; | |
6879 | + int diag; | |
6880 | + kdbhard_bp_t *bph = &bp->bp_template; | |
6881 | + | |
6882 | + bph->bph_mode = 0; /* Default to instruction breakpoint */ | |
6883 | + bph->bph_length = 0; /* Length must be zero for insn bp */ | |
6884 | + if ((argc + 1) != nextarg) { | |
6885 | + if (strnicmp(argv[nextarg], "datar", sizeof("datar")) == 0) { | |
6886 | + bph->bph_mode = 3; | |
6887 | + } else if (strnicmp(argv[nextarg], "dataw", sizeof("dataw")) == 0) { | |
6888 | + bph->bph_mode = 1; | |
6889 | + } else if (strnicmp(argv[nextarg], "io", sizeof("io")) == 0) { | |
6890 | + bph->bph_mode = 2; | |
6891 | + } else if (strnicmp(argv[nextarg], "inst", sizeof("inst")) == 0) { | |
6892 | + bph->bph_mode = 0; | |
6893 | + } else { | |
6894 | + return KDB_ARGCOUNT; | |
6895 | + } | |
6896 | + | |
6897 | + bph->bph_length = 3; /* Default to 4 byte */ | |
6898 | + | |
6899 | + nextarg++; | |
6900 | + | |
6901 | + if ((argc + 1) != nextarg) { | |
6902 | + unsigned long len; | |
6903 | + | |
6904 | + diag = kdbgetularg((char *)argv[nextarg], | |
6905 | + &len); | |
6906 | + if (diag) | |
6907 | + return diag; | |
6908 | + | |
6909 | + | |
6910 | + if ((len > 4) || (len == 3)) | |
6911 | + return KDB_BADLENGTH; | |
6912 | + | |
6913 | + bph->bph_length = len; | |
6914 | + bph->bph_length--; /* Normalize for debug register */ | |
6915 | + nextarg++; | |
6916 | + } | |
6917 | + | |
6918 | + if ((argc + 1) != nextarg) | |
6919 | + return KDB_ARGCOUNT; | |
6920 | + | |
6921 | + /* | |
6922 | + * Indicate to architecture independent level that | |
6923 | + * a hardware register assignment is required to enable | |
6924 | + * this breakpoint. | |
6925 | + */ | |
6926 | + | |
6927 | + bph->bph_free = 0; | |
6928 | + } else { | |
6929 | + if (KDB_DEBUG(BP)) | |
6930 | + kdb_printf("kdba_bp: no args, forcehw is %d\n", bp->bp_forcehw); | |
6931 | + if (bp->bp_forcehw) { | |
6932 | + /* | |
6933 | + * We are forced to use a hardware register for this | |
6934 | + * breakpoint because either the bph or bpha | |
6935 | + * commands were used to establish this breakpoint. | |
6936 | + */ | |
6937 | + bph->bph_free = 0; | |
6938 | + } else { | |
6939 | + /* | |
6940 | + * Indicate to architecture dependent level that | |
6941 | + * the instruction replacement breakpoint technique | |
6942 | + * should be used for this breakpoint. | |
6943 | + */ | |
6944 | + bph->bph_free = 1; | |
6945 | + bp->bp_adjust = 1; /* software, int 3 is one byte */ | |
6946 | + } | |
6947 | + } | |
6948 | + | |
6949 | + if (bph->bph_mode != 2 && kdba_verify_rw(bp->bp_addr, bph->bph_length+1)) { | |
6950 | + kdb_printf("Invalid address for breakpoint, ignoring bp command\n"); | |
6951 | + return KDB_BADADDR; | |
6952 | + } | |
6953 | + | |
6954 | + *nextargp = nextarg; | |
6955 | + return 0; | |
6956 | +} | |
6957 | + | |
6958 | +/* | |
6959 | + * kdba_allocbp | |
6960 | + * | |
6961 | + * Allocate hw register for bp on specific CPU | |
6962 | + * | |
6963 | + * Parameters: | |
6964 | + * None. | |
6965 | + * Outputs: | |
6966 | + * None. | |
6967 | + * Returns: | |
6968 | + * A pointer to the allocated register kdbhard_bp_t structure for | |
6969 | + * success, Null and a non-zero diagnostic for failure. | |
6970 | + * Locking: | |
6971 | + * None. | |
6972 | + * Remarks: | |
6973 | + */ | |
6974 | + | |
6975 | +static kdbhard_bp_t * | |
6976 | +kdba_allocbp(kdbhard_bp_t *bph, int *diagp, unsigned int cpu) | |
6977 | +{ | |
6978 | + int i; | |
6979 | + kdbhard_bp_t *newbph; | |
6980 | + | |
6981 | + for(i=0; i < KDB_MAXHARDBPT; i++) { | |
6982 | + newbph=&(kdb_hardbreaks[cpu][i]); | |
6983 | + if (newbph->bph_free) { | |
6984 | + break; | |
6985 | + } | |
6986 | + } | |
6987 | + | |
6988 | + if (i == KDB_MAXHARDBPT) { | |
6989 | + *diagp = KDB_TOOMANYDBREGS; | |
6990 | + return NULL; | |
6991 | + } | |
6992 | + | |
6993 | + *diagp = 0; | |
6994 | + | |
6995 | + /* | |
6996 | + * Copy data from template. Can't just copy the entire template | |
6997 | + * here because the register number in kdb_hardbreaks must be | |
6998 | + * preserved. | |
6999 | + */ | |
7000 | + newbph->bph_data = bph->bph_data; | |
7001 | + newbph->bph_write = bph->bph_write; | |
7002 | + newbph->bph_mode = bph->bph_mode; | |
7003 | + newbph->bph_length = bph->bph_length; | |
7004 | + | |
7005 | + /* | |
7006 | + * Mark entry allocated. | |
7007 | + */ | |
7008 | + newbph->bph_free = 0; | |
7009 | + | |
7010 | + return newbph; | |
7011 | +} | |
7012 | + | |
7013 | +/* | |
7014 | + * kdba_alloc_hwbp | |
7015 | + * | |
7016 | + * Associate a hardware registers with a breakpoint. | |
7017 | + * If hw bp is global hw registers descriptor will be allocated | |
7018 | + * on every CPU. | |
7019 | + * | |
7020 | + * Parameters: | |
7021 | + * bp - hardware bp | |
7022 | + * diagp - pointer to variable that will store error when | |
7023 | + * function complete | |
7024 | + * Outputs: | |
7025 | + * None. | |
7026 | + * Returns: | |
7027 | + * None | |
7028 | + * Locking: | |
7029 | + * None. | |
7030 | + * Remarks: | |
7031 | + * Should be called with correct bp->bp_template | |
7032 | + */ | |
7033 | + | |
7034 | +void | |
7035 | +kdba_alloc_hwbp(kdb_bp_t *bp, int *diagp) | |
7036 | +{ | |
7037 | + int i; | |
7038 | + | |
7039 | + if (bp->bp_global){ | |
7040 | + for (i = 0; i < NR_CPUS; ++i) { | |
7041 | + if (!cpu_online(i)) | |
7042 | + continue; | |
7043 | + bp->bp_hard[i] = kdba_allocbp(&bp->bp_template, diagp, i); | |
7044 | + if (*diagp) | |
7045 | + break; | |
7046 | + } | |
7047 | + } else { | |
7048 | + bp->bp_hard[bp->bp_cpu] = kdba_allocbp(&bp->bp_template, diagp, bp->bp_cpu); | |
7049 | + } | |
7050 | + bp->bp_hardtype = 1; | |
7051 | +} | |
7052 | + | |
7053 | +/* | |
7054 | + * kdba_freebp | |
7055 | + * | |
7056 | + * Deallocate hw registers descriptor for bp on specific CPU | |
7057 | + * | |
7058 | + * Parameters: | |
7059 | + * None. | |
7060 | + * Outputs: | |
7061 | + * None. | |
7062 | + * Returns: | |
7063 | + * Zero for success, a kdb diagnostic for failure | |
7064 | + * Locking: | |
7065 | + * None. | |
7066 | + * Remarks: | |
7067 | + */ | |
7068 | + | |
7069 | +static void | |
7070 | +kdba_freebp(kdbhard_bp_t *bph) | |
7071 | +{ | |
7072 | + bph->bph_free = 1; | |
7073 | +} | |
7074 | + | |
7075 | +/* | |
7076 | + * kdba_free_hwbp | |
7077 | + * | |
7078 | + * Frees allocated hw registers descriptors for bp. | |
7079 | + * If hw bp is global, hw registers descriptors will be freed | |
7080 | + * on every CPU. | |
7081 | + * | |
7082 | + * Parameters: | |
7083 | + * bp - hardware bp | |
7084 | + * Outputs: | |
7085 | + * None. | |
7086 | + * Returns: | |
7087 | + * None | |
7088 | + * Locking: | |
7089 | + * None. | |
7090 | + * Remarks: | |
7091 | + * Should be called with correct bp->bp_template | |
7092 | + */ | |
7093 | + | |
7094 | +void | |
7095 | +kdba_free_hwbp(kdb_bp_t *bp) | |
7096 | +{ | |
7097 | + int i; | |
7098 | + | |
7099 | + /* When kernel enters KDB, first, all local bps | |
7100 | + * are removed, so here we don't need to clear | |
7101 | + * debug registers. | |
7102 | + */ | |
7103 | + | |
7104 | + if (bp->bp_global){ | |
7105 | + for (i = 0; i < NR_CPUS; ++i) { | |
7106 | + if (!cpu_online(i)) | |
7107 | + continue; | |
7108 | + if (bp->bp_hard[i]) | |
7109 | + kdba_freebp(bp->bp_hard[i]); | |
7110 | + bp->bp_hard[i] = 0; | |
7111 | + } | |
7112 | + } else { | |
7113 | + kdba_freebp(bp->bp_hard[bp->bp_cpu]); | |
7114 | + bp->bp_hard[bp->bp_cpu] = NULL; | |
7115 | + } | |
7116 | + bp->bp_hardtype = 0; | |
7117 | +} | |
7118 | + | |
7119 | +/* | |
7120 | + * kdba_initbp | |
7121 | + * | |
7122 | + * Initialize the breakpoint table for the hardware breakpoint | |
7123 | + * register. | |
7124 | + * | |
7125 | + * Parameters: | |
7126 | + * None. | |
7127 | + * Outputs: | |
7128 | + * None. | |
7129 | + * Returns: | |
7130 | + * Zero for success, a kdb diagnostic for failure | |
7131 | + * Locking: | |
7132 | + * None. | |
7133 | + * Remarks: | |
7134 | + * | |
7135 | + * There is one entry per register. On the ia32 architecture | |
7136 | + * all the registers are interchangeable, so no special allocation | |
7137 | + * criteria are required. | |
7138 | + */ | |
7139 | + | |
7140 | +void | |
7141 | +kdba_initbp(void) | |
7142 | +{ | |
7143 | + int i,j; | |
7144 | + kdbhard_bp_t *bph; | |
7145 | + | |
7146 | + /* | |
7147 | + * Clear the hardware breakpoint table | |
7148 | + */ | |
7149 | + | |
7150 | + memset(kdb_hardbreaks, '\0', sizeof(kdb_hardbreaks)); | |
7151 | + | |
7152 | + for (i = 0; i < NR_CPUS; ++i) { | |
7153 | + /* Called early so we don't know actual | |
7154 | + * ammount of CPUs | |
7155 | + */ | |
7156 | + for(j=0; j < KDB_MAXHARDBPT; j++) { | |
7157 | + bph=&(kdb_hardbreaks[i][j]); | |
7158 | + bph->bph_reg = j; | |
7159 | + bph->bph_free = 1; | |
7160 | + } | |
7161 | + } | |
7162 | +} | |
7163 | + | |
7164 | +/* | |
7165 | + * kdba_installbp | |
7166 | + * | |
7167 | + * Install a breakpoint | |
7168 | + * | |
7169 | + * Parameters: | |
7170 | + * regs Exception frame | |
7171 | + * bp Breakpoint structure for the breakpoint to be installed | |
7172 | + * Outputs: | |
7173 | + * None. | |
7174 | + * Returns: | |
7175 | + * 0 if breakpoint installed. | |
7176 | + * Locking: | |
7177 | + * None. | |
7178 | + * Remarks: | |
7179 | + * For hardware breakpoints, a debug register is allocated | |
7180 | + * and assigned to the breakpoint. If no debug register is | |
7181 | + * available, a warning message is printed and the breakpoint | |
7182 | + * is disabled. | |
7183 | + * | |
7184 | + * For instruction replacement breakpoints, we must single-step | |
7185 | + * over the replaced instruction at this point so we can re-install | |
7186 | + * the breakpoint instruction after the single-step. SSBPT is set | |
7187 | + * when the breakpoint is initially hit and is cleared by any action | |
7188 | + * that removes the need for single-step over the breakpoint. | |
7189 | + */ | |
7190 | + | |
7191 | +int | |
7192 | +kdba_installbp(struct pt_regs *regs, kdb_bp_t *bp) | |
7193 | +{ | |
7194 | + int cpu = smp_processor_id(); | |
7195 | + | |
7196 | + /* | |
7197 | + * Install the breakpoint, if it is not already installed. | |
7198 | + */ | |
7199 | + | |
7200 | + if (KDB_DEBUG(BP)) { | |
7201 | + kdb_printf("kdba_installbp bp_installed %d\n", bp->bp_installed); | |
7202 | + } | |
7203 | + if (!KDB_STATE(SSBPT)) | |
7204 | + bp->bp_delay = 0; | |
7205 | + | |
7206 | + if (bp->bp_hardtype) { | |
7207 | + if (KDB_DEBUG(BP) && !bp->bp_global && cpu != bp->bp_cpu){ | |
7208 | + kdb_printf("kdba_installbp: cpu != bp->bp_cpu for local hw bp\n"); | |
7209 | + } | |
7210 | + | |
7211 | + if (KDB_DEBUG(BP) && !bp->bp_hard[cpu]){ | |
7212 | + kdb_printf("kdba_installbp: Error - bp_hard[smp_processor_id()] is emply\n"); | |
7213 | + return 1; | |
7214 | + } | |
7215 | + | |
7216 | + if (!bp->bp_hard[cpu]->bph_installed){ | |
7217 | + kdba_installdbreg(bp); | |
7218 | + bp->bp_hard[cpu]->bph_installed = 1; | |
7219 | + if (KDB_DEBUG(BP)) { | |
7220 | + kdb_printf("kdba_installbp hardware reg %ld at " kdb_bfd_vma_fmt "\n", | |
7221 | + bp->bp_hard[cpu]->bph_reg, bp->bp_addr); | |
7222 | + } | |
7223 | + } | |
7224 | + } else if (!bp->bp_installed) { | |
7225 | + if (bp->bp_delay) { | |
7226 | + if (KDB_DEBUG(BP)) | |
7227 | + kdb_printf("kdba_installbp delayed bp\n"); | |
7228 | + kdba_handle_bp(regs, bp); | |
7229 | + } else { | |
7230 | + if (kdb_getarea_size(&(bp->bp_inst), bp->bp_addr, 1) || | |
7231 | + kdb_putword(bp->bp_addr, IA32_BREAKPOINT_INSTRUCTION, 1)) { | |
7232 | + kdb_printf("kdba_installbp failed to set software breakpoint at 0x%lx\n", bp->bp_addr); | |
7233 | + return(1); | |
7234 | + } | |
7235 | + bp->bp_installed = 1; | |
7236 | + if (KDB_DEBUG(BP)) | |
7237 | + kdb_printf("kdba_installbp instruction 0x%x at " kdb_bfd_vma_fmt "\n", | |
7238 | + IA32_BREAKPOINT_INSTRUCTION, bp->bp_addr); | |
7239 | + } | |
7240 | + } | |
7241 | + return(0); | |
7242 | +} | |
7243 | + | |
7244 | +/* | |
7245 | + * kdba_removebp | |
7246 | + * | |
7247 | + * Make a breakpoint ineffective. | |
7248 | + * | |
7249 | + * Parameters: | |
7250 | + * None. | |
7251 | + * Outputs: | |
7252 | + * None. | |
7253 | + * Returns: | |
7254 | + * None. | |
7255 | + * Locking: | |
7256 | + * None. | |
7257 | + * Remarks: | |
7258 | + */ | |
7259 | + | |
7260 | +int | |
7261 | +kdba_removebp(kdb_bp_t *bp) | |
7262 | +{ | |
7263 | + int cpu = smp_processor_id(); | |
7264 | + | |
7265 | + /* | |
7266 | + * For hardware breakpoints, remove it from the active register, | |
7267 | + * for software breakpoints, restore the instruction stream. | |
7268 | + */ | |
7269 | + if (KDB_DEBUG(BP)) { | |
7270 | + kdb_printf("kdba_removebp bp_installed %d\n", bp->bp_installed); | |
7271 | + } | |
7272 | + | |
7273 | + if (bp->bp_hardtype) { | |
7274 | + if (KDB_DEBUG(BP) && !bp->bp_global && cpu != bp->bp_cpu){ | |
7275 | + kdb_printf("kdba_removebp: cpu != bp->bp_cpu for local hw bp\n"); | |
7276 | + } | |
7277 | + | |
7278 | + if (KDB_DEBUG(BP) && !bp->bp_hard[cpu]){ | |
7279 | + kdb_printf("kdba_removebp: Error - bp_hard[smp_processor_id()] is emply\n"); | |
7280 | + return 1; | |
7281 | + } | |
7282 | + | |
7283 | + if (KDB_DEBUG(BP)) { | |
7284 | + kdb_printf("kdb: removing hardware reg %ld at " kdb_bfd_vma_fmt "\n", | |
7285 | + bp->bp_hard[cpu]->bph_reg, bp->bp_addr); | |
7286 | + } | |
7287 | + | |
7288 | + if (bp->bp_hard[cpu]->bph_installed){ | |
7289 | + if (KDB_DEBUG(BP)) { | |
7290 | + kdb_printf("kdba_installbp hardware reg %ld at " kdb_bfd_vma_fmt "\n", | |
7291 | + bp->bp_hard[cpu]->bph_reg, bp->bp_addr); | |
7292 | + } | |
7293 | + kdba_removedbreg(bp); | |
7294 | + bp->bp_hard[cpu]->bph_installed = 0; | |
7295 | + } | |
7296 | + } else if (bp->bp_installed) { | |
7297 | + if (KDB_DEBUG(BP)) | |
7298 | + kdb_printf("kdb: restoring instruction 0x%x at " kdb_bfd_vma_fmt "\n", | |
7299 | + bp->bp_inst, bp->bp_addr); | |
7300 | + if (kdb_putword(bp->bp_addr, bp->bp_inst, 1)) | |
7301 | + return(1); | |
7302 | + bp->bp_installed = 0; | |
7303 | + } | |
7304 | + return(0); | |
7305 | +} | |
7306 | --- /dev/null | |
7307 | +++ b/arch/x86/kdb/kdba_bp_64.c | |
7308 | @@ -0,0 +1,912 @@ | |
7309 | +/* | |
7310 | + * Kernel Debugger Architecture Dependent Breakpoint Handling | |
7311 | + * | |
7312 | + * This file is subject to the terms and conditions of the GNU General Public | |
7313 | + * License. See the file "COPYING" in the main directory of this archive | |
7314 | + * for more details. | |
7315 | + * | |
7316 | + * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved. | |
7317 | + */ | |
7318 | + | |
7319 | +#include <linux/string.h> | |
7320 | +#include <linux/kernel.h> | |
7321 | +#include <linux/sched.h> | |
7322 | +#include <linux/smp.h> | |
7323 | +#include <linux/ptrace.h> | |
7324 | +#include <linux/kdb.h> | |
7325 | +#include <linux/kdbprivate.h> | |
7326 | + | |
7327 | + | |
7328 | +static char *kdba_rwtypes[] = { "Instruction(Register)", "Data Write", | |
7329 | + "I/O", "Data Access"}; | |
7330 | + | |
7331 | +/* | |
7332 | + * Table describing processor architecture hardware | |
7333 | + * breakpoint registers for every CPU. | |
7334 | + */ | |
7335 | + | |
7336 | +static kdbhard_bp_t kdb_hardbreaks[NR_CPUS][KDB_MAXHARDBPT]; | |
7337 | + | |
7338 | +/* | |
7339 | + * kdba_db_trap | |
7340 | + * | |
7341 | + * Perform breakpoint processing upon entry to the | |
7342 | + * processor debugger fault. Determine and print | |
7343 | + * the active breakpoint. | |
7344 | + * | |
7345 | + * Parameters: | |
7346 | + * regs Exception frame containing machine register state | |
7347 | + * error Error number passed to kdb. | |
7348 | + * Outputs: | |
7349 | + * None. | |
7350 | + * Returns: | |
7351 | + * KDB_DB_BPT Standard instruction or data breakpoint encountered | |
7352 | + * KDB_DB_SS Single Step fault ('ss' command or end of 'ssb' command) | |
7353 | + * KDB_DB_SSB Single Step fault, caller should continue ('ssb' command) | |
7354 | + * KDB_DB_SSBPT Single step over breakpoint | |
7355 | + * KDB_DB_NOBPT No existing kdb breakpoint matches this debug exception | |
7356 | + * Locking: | |
7357 | + * None. | |
7358 | + * Remarks: | |
7359 | + * Yup, there be goto's here. | |
7360 | + * | |
7361 | + * If multiple processors receive debug exceptions simultaneously, | |
7362 | + * one may be waiting at the kdb fence in kdb() while the user | |
7363 | + * issues a 'bc' command to clear the breakpoint the processor | |
7364 | + * which is waiting has already encountered. If this is the case, | |
7365 | + * the debug registers will no longer match any entry in the | |
7366 | + * breakpoint table, and we'll return the value KDB_DB_NOBPT. | |
7367 | + * This can cause a panic in die_if_kernel(). It is safer to | |
7368 | + * disable the breakpoint (bd), go until all processors are past | |
7369 | + * the breakpoint then clear the breakpoint (bc). This code | |
7370 | + * recognises a breakpoint even when disabled but not when it has | |
7371 | + * been cleared. | |
7372 | + * | |
7373 | + * WARNING: This routine clears the debug state. It should be called | |
7374 | + * once per debug and the result cached. | |
7375 | + */ | |
7376 | + | |
7377 | +kdb_dbtrap_t | |
7378 | +kdba_db_trap(struct pt_regs *regs, int error_unused) | |
7379 | +{ | |
7380 | + kdb_machreg_t dr6; | |
7381 | + kdb_machreg_t dr7; | |
7382 | + int rw, reg; | |
7383 | + int i; | |
7384 | + kdb_dbtrap_t rv = KDB_DB_BPT; | |
7385 | + kdb_bp_t *bp; | |
7386 | + int cpu = smp_processor_id(); | |
7387 | + | |
7388 | + if (KDB_NULL_REGS(regs)) | |
7389 | + return KDB_DB_NOBPT; | |
7390 | + | |
7391 | + dr6 = kdba_getdr6(); | |
7392 | + dr7 = kdba_getdr7(); | |
7393 | + | |
7394 | + if (KDB_DEBUG(BP)) | |
7395 | + kdb_printf("kdb: dr6 0x%lx dr7 0x%lx\n", dr6, dr7); | |
7396 | + if (dr6 & DR6_BS) { | |
7397 | + if (KDB_STATE(SSBPT)) { | |
7398 | + if (KDB_DEBUG(BP)) | |
7399 | + kdb_printf("ssbpt\n"); | |
7400 | + KDB_STATE_CLEAR(SSBPT); | |
7401 | + for(i=0,bp=kdb_breakpoints; | |
7402 | + i < KDB_MAXBPT; | |
7403 | + i++, bp++) { | |
7404 | + if (KDB_DEBUG(BP)) | |
7405 | + kdb_printf("bp 0x%p enabled %d delayed %d global %d cpu %d\n", | |
7406 | + bp, bp->bp_enabled, bp->bp_delayed, bp->bp_global, bp->bp_cpu); | |
7407 | + if (!bp->bp_enabled) | |
7408 | + continue; | |
7409 | + if (!bp->bp_global && bp->bp_cpu != smp_processor_id()) | |
7410 | + continue; | |
7411 | + if (KDB_DEBUG(BP)) | |
7412 | + kdb_printf("bp for this cpu\n"); | |
7413 | + if (bp->bp_delayed) { | |
7414 | + bp->bp_delayed = 0; | |
7415 | + if (KDB_DEBUG(BP)){ | |
7416 | + /* Can't be hw breakpoint */ | |
7417 | + if (bp->bp_hardtype) | |
7418 | + kdb_printf("kdb: Error - hw bp delayed\n"); | |
7419 | + kdb_printf("kdba_installbp\n"); | |
7420 | + } | |
7421 | + kdba_installbp(regs, bp); | |
7422 | + if (!KDB_STATE(DOING_SS)) { | |
7423 | + regs->flags &= ~X86_EFLAGS_TF; | |
7424 | + return(KDB_DB_SSBPT); | |
7425 | + } | |
7426 | + break; | |
7427 | + } | |
7428 | + } | |
7429 | + if (i == KDB_MAXBPT) { | |
7430 | + kdb_printf("kdb: Unable to find delayed breakpoint\n"); | |
7431 | + } | |
7432 | + if (!KDB_STATE(DOING_SS)) { | |
7433 | + regs->flags &= ~X86_EFLAGS_TF; | |
7434 | + return(KDB_DB_NOBPT); | |
7435 | + } | |
7436 | + /* FALLTHROUGH */ | |
7437 | + } | |
7438 | + | |
7439 | + /* | |
7440 | + * KDB_STATE_DOING_SS is set when the kernel debugger is using | |
7441 | + * the processor trap flag to single-step a processor. If a | |
7442 | + * single step trap occurs and this flag is clear, the SS trap | |
7443 | + * will be ignored by KDB and the kernel will be allowed to deal | |
7444 | + * with it as necessary (e.g. for ptrace). | |
7445 | + */ | |
7446 | + if (!KDB_STATE(DOING_SS)) | |
7447 | + goto unknown; | |
7448 | + | |
7449 | + /* single step */ | |
7450 | + rv = KDB_DB_SS; /* Indicate single step */ | |
7451 | + if (KDB_STATE(DOING_SSB)) { | |
7452 | + unsigned char instruction[2]; | |
7453 | + | |
7454 | + kdb_id1(regs->ip); | |
7455 | + if (kdb_getarea(instruction, regs->ip) || | |
7456 | + (instruction[0]&0xf0) == 0xe0 || /* short disp jumps */ | |
7457 | + (instruction[0]&0xf0) == 0x70 || /* Misc. jumps */ | |
7458 | + instruction[0] == 0xc2 || /* ret */ | |
7459 | + instruction[0] == 0x9a || /* call */ | |
7460 | + (instruction[0]&0xf8) == 0xc8 || /* enter, leave, iret, int, */ | |
7461 | + ((instruction[0] == 0x0f) && | |
7462 | + ((instruction[1]&0xf0)== 0x80)) | |
7463 | + ) { | |
7464 | + /* | |
7465 | + * End the ssb command here. | |
7466 | + */ | |
7467 | + KDB_STATE_CLEAR(DOING_SSB); | |
7468 | + KDB_STATE_CLEAR(DOING_SS); | |
7469 | + } else { | |
7470 | + rv = KDB_DB_SSB; /* Indicate ssb - dismiss immediately */ | |
7471 | + } | |
7472 | + } else { | |
7473 | + /* | |
7474 | + * Print current insn | |
7475 | + */ | |
7476 | + kdb_printf("SS trap at "); | |
7477 | + kdb_symbol_print(regs->ip, NULL, KDB_SP_DEFAULT|KDB_SP_NEWLINE); | |
7478 | + kdb_id1(regs->ip); | |
7479 | + KDB_STATE_CLEAR(DOING_SS); | |
7480 | + } | |
7481 | + | |
7482 | + if (rv != KDB_DB_SSB) | |
7483 | + regs->flags &= ~X86_EFLAGS_TF; | |
7484 | + } | |
7485 | + | |
7486 | + if (dr6 & DR6_B0) { | |
7487 | + rw = DR7_RW0(dr7); | |
7488 | + reg = 0; | |
7489 | + goto handle; | |
7490 | + } | |
7491 | + | |
7492 | + if (dr6 & DR6_B1) { | |
7493 | + rw = DR7_RW1(dr7); | |
7494 | + reg = 1; | |
7495 | + goto handle; | |
7496 | + } | |
7497 | + | |
7498 | + if (dr6 & DR6_B2) { | |
7499 | + rw = DR7_RW2(dr7); | |
7500 | + reg = 2; | |
7501 | + goto handle; | |
7502 | + } | |
7503 | + | |
7504 | + if (dr6 & DR6_B3) { | |
7505 | + rw = DR7_RW3(dr7); | |
7506 | + reg = 3; | |
7507 | + goto handle; | |
7508 | + } | |
7509 | + | |
7510 | + if (rv > 0) | |
7511 | + goto handled; | |
7512 | + | |
7513 | + goto unknown; /* dismiss */ | |
7514 | + | |
7515 | +handle: | |
7516 | + /* | |
7517 | + * Set Resume Flag | |
7518 | + */ | |
7519 | + regs->flags |= X86_EFLAGS_RF; | |
7520 | + | |
7521 | + /* | |
7522 | + * Determine which breakpoint was encountered. | |
7523 | + */ | |
7524 | + for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) { | |
7525 | + if (!(bp->bp_free) | |
7526 | + && (bp->bp_global || bp->bp_cpu == smp_processor_id()) | |
7527 | + && (bp->bp_hard[cpu]) | |
7528 | + && (bp->bp_hard[cpu]->bph_reg == reg)) { | |
7529 | + /* | |
7530 | + * Hit this breakpoint. | |
7531 | + */ | |
7532 | + kdb_printf("%s breakpoint #%d at " kdb_bfd_vma_fmt "\n", | |
7533 | + kdba_rwtypes[rw], | |
7534 | + i, bp->bp_addr); | |
7535 | + | |
7536 | + /* | |
7537 | + * For an instruction breakpoint, disassemble | |
7538 | + * the current instruction. | |
7539 | + */ | |
7540 | + if (rw == 0) { | |
7541 | + kdb_id1(regs->ip); | |
7542 | + } | |
7543 | + | |
7544 | + goto handled; | |
7545 | + } | |
7546 | + } | |
7547 | + | |
7548 | +unknown: | |
7549 | + regs->flags |= X86_EFLAGS_RF; /* Supress further faults */ | |
7550 | + rv = KDB_DB_NOBPT; /* Cause kdb() to return */ | |
7551 | + | |
7552 | +handled: | |
7553 | + | |
7554 | + /* | |
7555 | + * Clear the pending exceptions. | |
7556 | + */ | |
7557 | + kdba_putdr6(0); | |
7558 | + | |
7559 | + return rv; | |
7560 | +} | |
7561 | + | |
7562 | +/* | |
7563 | + * kdba_bp_trap | |
7564 | + * | |
7565 | + * Perform breakpoint processing upon entry to the | |
7566 | + * processor breakpoint instruction fault. Determine and print | |
7567 | + * the active breakpoint. | |
7568 | + * | |
7569 | + * Parameters: | |
7570 | + * regs Exception frame containing machine register state | |
7571 | + * error Error number passed to kdb. | |
7572 | + * Outputs: | |
7573 | + * None. | |
7574 | + * Returns: | |
7575 | + * 0 Standard instruction or data breakpoint encountered | |
7576 | + * 1 Single Step fault ('ss' command) | |
7577 | + * 2 Single Step fault, caller should continue ('ssb' command) | |
7578 | + * 3 No existing kdb breakpoint matches this debug exception | |
7579 | + * Locking: | |
7580 | + * None. | |
7581 | + * Remarks: | |
7582 | + * | |
7583 | + * If multiple processors receive debug exceptions simultaneously, | |
7584 | + * one may be waiting at the kdb fence in kdb() while the user | |
7585 | + * issues a 'bc' command to clear the breakpoint the processor which | |
7586 | + * is waiting has already encountered. If this is the case, the | |
7587 | + * debug registers will no longer match any entry in the breakpoint | |
7588 | + * table, and we'll return the value '3'. This can cause a panic | |
7589 | + * in die_if_kernel(). It is safer to disable the breakpoint (bd), | |
7590 | + * 'go' until all processors are past the breakpoint then clear the | |
7591 | + * breakpoint (bc). This code recognises a breakpoint even when | |
7592 | + * disabled but not when it has been cleared. | |
7593 | + * | |
7594 | + * WARNING: This routine resets the ip. It should be called | |
7595 | + * once per breakpoint and the result cached. | |
7596 | + */ | |
7597 | + | |
7598 | +kdb_dbtrap_t | |
7599 | +kdba_bp_trap(struct pt_regs *regs, int error_unused) | |
7600 | +{ | |
7601 | + int i; | |
7602 | + kdb_dbtrap_t rv; | |
7603 | + kdb_bp_t *bp; | |
7604 | + | |
7605 | + if (KDB_NULL_REGS(regs)) | |
7606 | + return KDB_DB_NOBPT; | |
7607 | + | |
7608 | + /* | |
7609 | + * Determine which breakpoint was encountered. | |
7610 | + */ | |
7611 | + if (KDB_DEBUG(BP)) | |
7612 | + kdb_printf("kdba_bp_trap: ip=0x%lx (not adjusted) " | |
7613 | + "flags=0x%lx ef=0x%p sp=0x%lx\n", | |
7614 | + regs->ip, regs->flags, regs, regs->sp); | |
7615 | + | |
7616 | + rv = KDB_DB_NOBPT; /* Cause kdb() to return */ | |
7617 | + | |
7618 | + for(i=0, bp=kdb_breakpoints; i<KDB_MAXBPT; i++, bp++) { | |
7619 | + if (bp->bp_free) | |
7620 | + continue; | |
7621 | + if (!bp->bp_global && bp->bp_cpu != smp_processor_id()) | |
7622 | + continue; | |
7623 | + if ((void *)bp->bp_addr == (void *)(regs->ip - bp->bp_adjust)) { | |
7624 | + /* Hit this breakpoint. */ | |
7625 | + regs->ip -= bp->bp_adjust; | |
7626 | + kdb_printf("Instruction(i) breakpoint #%d at 0x%lx (adjusted)\n", | |
7627 | + i, regs->ip); | |
7628 | + kdb_id1(regs->ip); | |
7629 | + rv = KDB_DB_BPT; | |
7630 | + bp->bp_delay = 1; | |
7631 | + /* SSBPT is set when the kernel debugger must single | |
7632 | + * step a task in order to re-establish an instruction | |
7633 | + * breakpoint which uses the instruction replacement | |
7634 | + * mechanism. It is cleared by any action that removes | |
7635 | + * the need to single-step the breakpoint. | |
7636 | + */ | |
7637 | + KDB_STATE_SET(SSBPT); | |
7638 | + break; | |
7639 | + } | |
7640 | + } | |
7641 | + | |
7642 | + return rv; | |
7643 | +} | |
7644 | + | |
7645 | +/* | |
7646 | + * kdba_handle_bp | |
7647 | + * | |
7648 | + * Handle an instruction-breakpoint trap. Called when re-installing | |
7649 | + * an enabled breakpoint which has has the bp_delay bit set. | |
7650 | + * | |
7651 | + * Parameters: | |
7652 | + * Returns: | |
7653 | + * Locking: | |
7654 | + * Remarks: | |
7655 | + * | |
7656 | + * Ok, we really need to: | |
7657 | + * 1) Restore the original instruction byte | |
7658 | + * 2) Single Step | |
7659 | + * 3) Restore breakpoint instruction | |
7660 | + * 4) Continue. | |
7661 | + * | |
7662 | + * | |
7663 | + */ | |
7664 | + | |
7665 | +static void | |
7666 | +kdba_handle_bp(struct pt_regs *regs, kdb_bp_t *bp) | |
7667 | +{ | |
7668 | + if (KDB_NULL_REGS(regs)) | |
7669 | + return; | |
7670 | + | |
7671 | + if (KDB_DEBUG(BP)) | |
7672 | + kdb_printf("regs->ip = 0x%lx\n", regs->ip); | |
7673 | + | |
7674 | + /* | |
7675 | + * Setup single step | |
7676 | + */ | |
7677 | + kdba_setsinglestep(regs); | |
7678 | + | |
7679 | + /* | |
7680 | + * Reset delay attribute | |
7681 | + */ | |
7682 | + bp->bp_delay = 0; | |
7683 | + bp->bp_delayed = 1; | |
7684 | +} | |
7685 | + | |
7686 | + | |
7687 | +/* | |
7688 | + * kdba_bptype | |
7689 | + * | |
7690 | + * Return a string describing type of breakpoint. | |
7691 | + * | |
7692 | + * Parameters: | |
7693 | + * bph Pointer to hardware breakpoint description | |
7694 | + * Outputs: | |
7695 | + * None. | |
7696 | + * Returns: | |
7697 | + * Character string. | |
7698 | + * Locking: | |
7699 | + * None. | |
7700 | + * Remarks: | |
7701 | + */ | |
7702 | + | |
7703 | +char * | |
7704 | +kdba_bptype(kdbhard_bp_t *bph) | |
7705 | +{ | |
7706 | + char *mode; | |
7707 | + | |
7708 | + mode = kdba_rwtypes[bph->bph_mode]; | |
7709 | + | |
7710 | + return mode; | |
7711 | +} | |
7712 | + | |
7713 | +/* | |
7714 | + * kdba_printbpreg | |
7715 | + * | |
7716 | + * Print register name assigned to breakpoint | |
7717 | + * | |
7718 | + * Parameters: | |
7719 | + * bph Pointer hardware breakpoint structure | |
7720 | + * Outputs: | |
7721 | + * None. | |
7722 | + * Returns: | |
7723 | + * None. | |
7724 | + * Locking: | |
7725 | + * None. | |
7726 | + * Remarks: | |
7727 | + */ | |
7728 | + | |
7729 | +static void | |
7730 | +kdba_printbpreg(kdbhard_bp_t *bph) | |
7731 | +{ | |
7732 | + kdb_printf(" in dr%ld", bph->bph_reg); | |
7733 | +} | |
7734 | + | |
7735 | +/* | |
7736 | + * kdba_printbp | |
7737 | + * | |
7738 | + * Print string describing hardware breakpoint. | |
7739 | + * | |
7740 | + * Parameters: | |
7741 | + * bph Pointer to hardware breakpoint description | |
7742 | + * Outputs: | |
7743 | + * None. | |
7744 | + * Returns: | |
7745 | + * None. | |
7746 | + * Locking: | |
7747 | + * None. | |
7748 | + * Remarks: | |
7749 | + */ | |
7750 | + | |
7751 | +void | |
7752 | +kdba_printbp(kdb_bp_t *bp) | |
7753 | +{ | |
7754 | + int cpu; | |
7755 | + | |
7756 | + kdb_printf("\n is enabled"); | |
7757 | + if (bp->bp_hardtype) { | |
7758 | + if (bp->bp_global) | |
7759 | + cpu = smp_processor_id(); | |
7760 | + else | |
7761 | + cpu = bp->bp_cpu; | |
7762 | + kdba_printbpreg(bp->bp_hard[cpu]); | |
7763 | + if (bp->bp_hard[cpu]->bph_mode != 0) { | |
7764 | + kdb_printf(" for %d bytes", | |
7765 | + bp->bp_hard[cpu]->bph_length+1); | |
7766 | + } | |
7767 | + } | |
7768 | +} | |
7769 | + | |
7770 | +/* | |
7771 | + * kdba_parsebp | |
7772 | + * | |
7773 | + * Parse architecture dependent portion of the | |
7774 | + * breakpoint command. | |
7775 | + * | |
7776 | + * Parameters: | |
7777 | + * None. | |
7778 | + * Outputs: | |
7779 | + * None. | |
7780 | + * Returns: | |
7781 | + * Zero for success, a kdb diagnostic for failure | |
7782 | + * Locking: | |
7783 | + * None. | |
7784 | + * Remarks: | |
7785 | + * for Ia32 architure, data access, data write and | |
7786 | + * I/O breakpoints are supported in addition to instruction | |
7787 | + * breakpoints. | |
7788 | + * | |
7789 | + * {datar|dataw|io|inst} [length] | |
7790 | + */ | |
7791 | + | |
7792 | +int | |
7793 | +kdba_parsebp(int argc, const char **argv, int *nextargp, kdb_bp_t *bp) | |
7794 | +{ | |
7795 | + int nextarg = *nextargp; | |
7796 | + int diag; | |
7797 | + kdbhard_bp_t *bph = &bp->bp_template; | |
7798 | + | |
7799 | + bph->bph_mode = 0; /* Default to instruction breakpoint */ | |
7800 | + bph->bph_length = 0; /* Length must be zero for insn bp */ | |
7801 | + if ((argc + 1) != nextarg) { | |
7802 | + if (strnicmp(argv[nextarg], "datar", sizeof("datar")) == 0) { | |
7803 | + bph->bph_mode = 3; | |
7804 | + } else if (strnicmp(argv[nextarg], "dataw", sizeof("dataw")) == 0) { | |
7805 | + bph->bph_mode = 1; | |
7806 | + } else if (strnicmp(argv[nextarg], "io", sizeof("io")) == 0) { | |
7807 | + bph->bph_mode = 2; | |
7808 | + } else if (strnicmp(argv[nextarg], "inst", sizeof("inst")) == 0) { | |
7809 | + bph->bph_mode = 0; | |
7810 | + } else { | |
7811 | + return KDB_ARGCOUNT; | |
7812 | + } | |
7813 | + | |
7814 | + bph->bph_length = 3; /* Default to 4 byte */ | |
7815 | + | |
7816 | + nextarg++; | |
7817 | + | |
7818 | + if ((argc + 1) != nextarg) { | |
7819 | + unsigned long len; | |
7820 | + | |
7821 | + diag = kdbgetularg((char *)argv[nextarg], | |
7822 | + &len); | |
7823 | + if (diag) | |
7824 | + return diag; | |
7825 | + | |
7826 | + | |
7827 | + if ((len > 4) || (len == 3)) | |
7828 | + return KDB_BADLENGTH; | |
7829 | + | |
7830 | + bph->bph_length = len; | |
7831 | + bph->bph_length--; /* Normalize for debug register */ | |
7832 | + nextarg++; | |
7833 | + } | |
7834 | + | |
7835 | + if ((argc + 1) != nextarg) | |
7836 | + return KDB_ARGCOUNT; | |
7837 | + | |
7838 | + /* | |
7839 | + * Indicate to architecture independent level that | |
7840 | + * a hardware register assignment is required to enable | |
7841 | + * this breakpoint. | |
7842 | + */ | |
7843 | + | |
7844 | + bph->bph_free = 0; | |
7845 | + } else { | |
7846 | + if (KDB_DEBUG(BP)) | |
7847 | + kdb_printf("kdba_bp: no args, forcehw is %d\n", bp->bp_forcehw); | |
7848 | + if (bp->bp_forcehw) { | |
7849 | + /* | |
7850 | + * We are forced to use a hardware register for this | |
7851 | + * breakpoint because either the bph or bpha | |
7852 | + * commands were used to establish this breakpoint. | |
7853 | + */ | |
7854 | + bph->bph_free = 0; | |
7855 | + } else { | |
7856 | + /* | |
7857 | + * Indicate to architecture dependent level that | |
7858 | + * the instruction replacement breakpoint technique | |
7859 | + * should be used for this breakpoint. | |
7860 | + */ | |
7861 | + bph->bph_free = 1; | |
7862 | + bp->bp_adjust = 1; /* software, int 3 is one byte */ | |
7863 | + } | |
7864 | + } | |
7865 | + | |
7866 | + if (bph->bph_mode != 2 && kdba_verify_rw(bp->bp_addr, bph->bph_length+1)) { | |
7867 | + kdb_printf("Invalid address for breakpoint, ignoring bp command\n"); | |
7868 | + return KDB_BADADDR; | |
7869 | + } | |
7870 | + | |
7871 | + *nextargp = nextarg; | |
7872 | + return 0; | |
7873 | +} | |
7874 | + | |
7875 | +/* | |
7876 | + * kdba_allocbp | |
7877 | + * | |
7878 | + * Allocate hw register for bp on specific CPU | |
7879 | + * | |
7880 | + * Parameters: | |
7881 | + * None. | |
7882 | + * Outputs: | |
7883 | + * None. | |
7884 | + * Returns: | |
7885 | + * A pointer to the allocated register kdbhard_bp_t structure for | |
7886 | + * success, Null and a non-zero diagnostic for failure. | |
7887 | + * Locking: | |
7888 | + * None. | |
7889 | + * Remarks: | |
7890 | + */ | |
7891 | + | |
7892 | +static kdbhard_bp_t * | |
7893 | +kdba_allocbp(kdbhard_bp_t *bph, int *diagp, unsigned int cpu) | |
7894 | +{ | |
7895 | + int i; | |
7896 | + kdbhard_bp_t *newbph; | |
7897 | + | |
7898 | + for(i=0; i < KDB_MAXHARDBPT; i++) { | |
7899 | + newbph=&(kdb_hardbreaks[cpu][i]); | |
7900 | + if (newbph->bph_free) { | |
7901 | + break; | |
7902 | + } | |
7903 | + } | |
7904 | + | |
7905 | + if (i == KDB_MAXHARDBPT) { | |
7906 | + *diagp = KDB_TOOMANYDBREGS; | |
7907 | + return NULL; | |
7908 | + } | |
7909 | + | |
7910 | + *diagp = 0; | |
7911 | + | |
7912 | + /* | |
7913 | + * Copy data from template. Can't just copy the entire template | |
7914 | + * here because the register number in kdb_hardbreaks must be | |
7915 | + * preserved. | |
7916 | + */ | |
7917 | + newbph->bph_data = bph->bph_data; | |
7918 | + newbph->bph_write = bph->bph_write; | |
7919 | + newbph->bph_mode = bph->bph_mode; | |
7920 | + newbph->bph_length = bph->bph_length; | |
7921 | + | |
7922 | + /* | |
7923 | + * Mark entry allocated. | |
7924 | + */ | |
7925 | + newbph->bph_free = 0; | |
7926 | + | |
7927 | + return newbph; | |
7928 | +} | |
7929 | + | |
7930 | +/* | |
7931 | + * kdba_alloc_hwbp | |
7932 | + * | |
7933 | + * Associate a hardware registers with a breakpoint. | |
7934 | + * If hw bp is global hw registers descriptor will be allocated | |
7935 | + * on every CPU. | |
7936 | + * | |
7937 | + * Parameters: | |
7938 | + * bp - hardware bp | |
7939 | + * diagp - pointer to variable that will store error when | |
7940 | + * function complete | |
7941 | + * Outputs: | |
7942 | + * None. | |
7943 | + * Returns: | |
7944 | + * None | |
7945 | + * Locking: | |
7946 | + * None. | |
7947 | + * Remarks: | |
7948 | + * Should be called with correct bp->bp_template | |
7949 | + */ | |
7950 | + | |
7951 | +void | |
7952 | +kdba_alloc_hwbp(kdb_bp_t *bp, int *diagp) | |
7953 | +{ | |
7954 | + int i; | |
7955 | + | |
7956 | + if (bp->bp_global){ | |
7957 | + for (i = 0; i < NR_CPUS; ++i) { | |
7958 | + if (!cpu_online(i)) | |
7959 | + continue; | |
7960 | + bp->bp_hard[i] = kdba_allocbp(&bp->bp_template, diagp, i); | |
7961 | + if (*diagp) | |
7962 | + break; | |
7963 | + } | |
7964 | + } else { | |
7965 | + bp->bp_hard[bp->bp_cpu] = kdba_allocbp(&bp->bp_template, diagp, bp->bp_cpu); | |
7966 | + } | |
7967 | + bp->bp_hardtype = 1; | |
7968 | +} | |
7969 | + | |
7970 | +/* | |
7971 | + * kdba_freebp | |
7972 | + * | |
7973 | + * Deallocate hw registers descriptor for bp on specific CPU | |
7974 | + * | |
7975 | + * Parameters: | |
7976 | + * None. | |
7977 | + * Outputs: | |
7978 | + * None. | |
7979 | + * Returns: | |
7980 | + * Zero for success, a kdb diagnostic for failure | |
7981 | + * Locking: | |
7982 | + * None. | |
7983 | + * Remarks: | |
7984 | + */ | |
7985 | + | |
7986 | +static void | |
7987 | +kdba_freebp(kdbhard_bp_t *bph) | |
7988 | +{ | |
7989 | + bph->bph_free = 1; | |
7990 | +} | |
7991 | + | |
7992 | +/* | |
7993 | + * kdba_free_hwbp | |
7994 | + * | |
7995 | + * Frees allocated hw registers descriptors for bp. | |
7996 | + * If hw bp is global, hw registers descriptors will be freed | |
7997 | + * on every CPU. | |
7998 | + * | |
7999 | + * Parameters: | |
8000 | + * bp - hardware bp | |
8001 | + * Outputs: | |
8002 | + * None. | |
8003 | + * Returns: | |
8004 | + * None | |
8005 | + * Locking: | |
8006 | + * None. | |
8007 | + * Remarks: | |
8008 | + * Should be called with correct bp->bp_template | |
8009 | + */ | |
8010 | + | |
8011 | +void | |
8012 | +kdba_free_hwbp(kdb_bp_t *bp) | |
8013 | +{ | |
8014 | + int i; | |
8015 | + | |
8016 | + /* When kernel enters KDB, first, all local bps | |
8017 | + * are removed, so here we don't need to clear | |
8018 | + * debug registers. | |
8019 | + */ | |
8020 | + | |
8021 | + if (bp->bp_global){ | |
8022 | + for (i = 0; i < NR_CPUS; ++i) { | |
8023 | + if (!cpu_online(i)) | |
8024 | + continue; | |
8025 | + if (bp->bp_hard[i]) | |
8026 | + kdba_freebp(bp->bp_hard[i]); | |
8027 | + bp->bp_hard[i] = 0; | |
8028 | + } | |
8029 | + } else { | |
8030 | + kdba_freebp(bp->bp_hard[bp->bp_cpu]); | |
8031 | + bp->bp_hard[bp->bp_cpu] = NULL; | |
8032 | + } | |
8033 | + bp->bp_hardtype = 0; | |
8034 | +} | |
8035 | + | |
8036 | +/* | |
8037 | + * kdba_initbp | |
8038 | + * | |
8039 | + * Initialize the breakpoint table for the hardware breakpoint | |
8040 | + * register. | |
8041 | + * | |
8042 | + * Parameters: | |
8043 | + * None. | |
8044 | + * Outputs: | |
8045 | + * None. | |
8046 | + * Returns: | |
8047 | + * Zero for success, a kdb diagnostic for failure | |
8048 | + * Locking: | |
8049 | + * None. | |
8050 | + * Remarks: | |
8051 | + * | |
8052 | + * There is one entry per register. On the ia32 architecture | |
8053 | + * all the registers are interchangeable, so no special allocation | |
8054 | + * criteria are required. | |
8055 | + */ | |
8056 | + | |
8057 | +void | |
8058 | +kdba_initbp(void) | |
8059 | +{ | |
8060 | + int i,j; | |
8061 | + kdbhard_bp_t *bph; | |
8062 | + | |
8063 | + /* | |
8064 | + * Clear the hardware breakpoint table | |
8065 | + */ | |
8066 | + | |
8067 | + memset(kdb_hardbreaks, '\0', sizeof(kdb_hardbreaks)); | |
8068 | + | |
8069 | + for (i = 0; i < NR_CPUS; ++i) { | |
8070 | + /* Called early so we don't know actual | |
8071 | + * ammount of CPUs | |
8072 | + */ | |
8073 | + for(j=0; j < KDB_MAXHARDBPT; j++) { | |
8074 | + bph=&(kdb_hardbreaks[i][j]); | |
8075 | + bph->bph_reg = j; | |
8076 | + bph->bph_free = 1; | |
8077 | + } | |
8078 | + } | |
8079 | +} | |
8080 | + | |
8081 | +/* | |
8082 | + * kdba_installbp | |
8083 | + * | |
8084 | + * Install a breakpoint | |
8085 | + * | |
8086 | + * Parameters: | |
8087 | + * regs Exception frame | |
8088 | + * bp Breakpoint structure for the breakpoint to be installed | |
8089 | + * Outputs: | |
8090 | + * None. | |
8091 | + * Returns: | |
8092 | + * 0 if breakpoint installed. | |
8093 | + * Locking: | |
8094 | + * None. | |
8095 | + * Remarks: | |
8096 | + * For hardware breakpoints, a debug register is allocated | |
8097 | + * and assigned to the breakpoint. If no debug register is | |
8098 | + * available, a warning message is printed and the breakpoint | |
8099 | + * is disabled. | |
8100 | + * | |
8101 | + * For instruction replacement breakpoints, we must single-step | |
8102 | + * over the replaced instruction at this point so we can re-install | |
8103 | + * the breakpoint instruction after the single-step. | |
8104 | + */ | |
8105 | + | |
8106 | +int | |
8107 | +kdba_installbp(struct pt_regs *regs, kdb_bp_t *bp) | |
8108 | +{ | |
8109 | + int cpu = smp_processor_id(); | |
8110 | + | |
8111 | + /* | |
8112 | + * Install the breakpoint, if it is not already installed. | |
8113 | + */ | |
8114 | + | |
8115 | + if (KDB_DEBUG(BP)) { | |
8116 | + kdb_printf("kdba_installbp bp_installed %d\n", bp->bp_installed); | |
8117 | + } | |
8118 | + if (!KDB_STATE(SSBPT)) | |
8119 | + bp->bp_delay = 0; | |
8120 | + | |
8121 | + if (bp->bp_hardtype) { | |
8122 | + if (KDB_DEBUG(BP) && !bp->bp_global && cpu != bp->bp_cpu){ | |
8123 | + kdb_printf("kdba_removebp: cpu != bp->bp_cpu for local hw bp\n"); | |
8124 | + } | |
8125 | + | |
8126 | + if (KDB_DEBUG(BP) && !bp->bp_hard[cpu]){ | |
8127 | + kdb_printf("kdba_removebp: Error - bp_hard[smp_processor_id()] is emply\n"); | |
8128 | + return 1; | |
8129 | + } | |
8130 | + | |
8131 | + if (!bp->bp_hard[cpu]->bph_installed){ | |
8132 | + kdba_installdbreg(bp); | |
8133 | + bp->bp_hard[cpu]->bph_installed = 1; | |
8134 | + if (KDB_DEBUG(BP)) { | |
8135 | + kdb_printf("kdba_installbp hardware reg %ld at " kdb_bfd_vma_fmt "\n", | |
8136 | + bp->bp_hard[cpu]->bph_reg, bp->bp_addr); | |
8137 | + } | |
8138 | + } | |
8139 | + } else if (!bp->bp_installed) { | |
8140 | + if (bp->bp_delay) { | |
8141 | + if (KDB_DEBUG(BP)) | |
8142 | + kdb_printf("kdba_installbp delayed bp\n"); | |
8143 | + kdba_handle_bp(regs, bp); | |
8144 | + } else { | |
8145 | + if (kdb_getarea_size(&(bp->bp_inst), bp->bp_addr, 1) || | |
8146 | + kdb_putword(bp->bp_addr, IA32_BREAKPOINT_INSTRUCTION, 1)) { | |
8147 | + kdb_printf("kdba_installbp failed to set software breakpoint at " kdb_bfd_vma_fmt "\n", bp->bp_addr); | |
8148 | + return(1); | |
8149 | + } | |
8150 | + bp->bp_installed = 1; | |
8151 | + if (KDB_DEBUG(BP)) | |
8152 | + kdb_printf("kdba_installbp instruction 0x%x at " kdb_bfd_vma_fmt "\n", | |
8153 | + IA32_BREAKPOINT_INSTRUCTION, bp->bp_addr); | |
8154 | + } | |
8155 | + } | |
8156 | + return(0); | |
8157 | +} | |
8158 | + | |
8159 | +/* | |
8160 | + * kdba_removebp | |
8161 | + * | |
8162 | + * Make a breakpoint ineffective. | |
8163 | + * | |
8164 | + * Parameters: | |
8165 | + * None. | |
8166 | + * Outputs: | |
8167 | + * None. | |
8168 | + * Returns: | |
8169 | + * None. | |
8170 | + * Locking: | |
8171 | + * None. | |
8172 | + * Remarks: | |
8173 | + */ | |
8174 | + | |
8175 | +int | |
8176 | +kdba_removebp(kdb_bp_t *bp) | |
8177 | +{ | |
8178 | + int cpu = smp_processor_id(); | |
8179 | + | |
8180 | + /* | |
8181 | + * For hardware breakpoints, remove it from the active register, | |
8182 | + * for software breakpoints, restore the instruction stream. | |
8183 | + */ | |
8184 | + if (KDB_DEBUG(BP)) { | |
8185 | + kdb_printf("kdba_removebp bp_installed %d\n", bp->bp_installed); | |
8186 | + } | |
8187 | + | |
8188 | + if (bp->bp_hardtype) { | |
8189 | + if (KDB_DEBUG(BP) && !bp->bp_global && cpu != bp->bp_cpu){ | |
8190 | + kdb_printf("kdba_removebp: cpu != bp->bp_cpu for local hw bp\n"); | |
8191 | + } | |
8192 | + | |
8193 | + if (KDB_DEBUG(BP) && !bp->bp_hard[cpu]){ | |
8194 | + kdb_printf("kdba_removebp: Error - bp_hard[smp_processor_id()] is emply\n"); | |
8195 | + return 1; | |
8196 | + } | |
8197 | + | |
8198 | + if (KDB_DEBUG(BP)) { | |
8199 | + kdb_printf("kdb: removing hardware reg %ld at " kdb_bfd_vma_fmt "\n", | |
8200 | + bp->bp_hard[cpu]->bph_reg, bp->bp_addr); | |
8201 | + } | |
8202 | + | |
8203 | + if (bp->bp_hard[cpu]->bph_installed){ | |
8204 | + if (KDB_DEBUG(BP)) { | |
8205 | + kdb_printf("kdba_installbp hardware reg %ld at " kdb_bfd_vma_fmt "\n", | |
8206 | + bp->bp_hard[cpu]->bph_reg, bp->bp_addr); | |
8207 | + } | |
8208 | + kdba_removedbreg(bp); | |
8209 | + bp->bp_hard[cpu]->bph_installed = 0; | |
8210 | + } | |
8211 | + } else if (bp->bp_installed) { | |
8212 | + if (KDB_DEBUG(BP)) | |
8213 | + kdb_printf("kdb: restoring instruction 0x%x at " kdb_bfd_vma_fmt "\n", | |
8214 | + bp->bp_inst, bp->bp_addr); | |
8215 | + if (kdb_putword(bp->bp_addr, bp->bp_inst, 1)) | |
8216 | + return(1); | |
8217 | + bp->bp_installed = 0; | |
8218 | + } | |
8219 | + return(0); | |
8220 | +} | |
8221 | --- /dev/null | |
8222 | +++ b/arch/x86/kdb/kdba_bt.c | |
8223 | @@ -0,0 +1,5597 @@ | |
8224 | +/* | |
8225 | + * This file is subject to the terms and conditions of the GNU General Public | |
8226 | + * License. See the file "COPYING" in the main directory of this archive | |
8227 | + * for more details. | |
8228 | + * | |
8229 | + * Copyright (c) 2006, 2007-2008 Silicon Graphics, Inc. All Rights Reserved. | |
8230 | + * | |
8231 | + * Common code for doing accurate backtraces on i386 and x86_64, including | |
8232 | + * printing the values of arguments. | |
8233 | + */ | |
8234 | + | |
8235 | +#include <linux/init.h> | |
8236 | +#include <linux/kallsyms.h> | |
8237 | +#include <linux/kdb.h> | |
8238 | +#include <linux/kdbprivate.h> | |
8239 | +#include <linux/ctype.h> | |
8240 | +#include <linux/string.h> | |
8241 | +#include <linux/stringify.h> | |
8242 | +#include <linux/kernel.h> | |
8243 | +#include <linux/sched.h> | |
8244 | +#include <linux/nmi.h> | |
8245 | +#include <asm/asm-offsets.h> | |
8246 | +#include <asm/system.h> | |
8247 | + | |
8248 | +#define KDB_DEBUG_BB(fmt, ...) \ | |
8249 | + {if (KDB_DEBUG(BB)) kdb_printf(fmt, ## __VA_ARGS__);} | |
8250 | +#define KDB_DEBUG_BB_OFFSET_PRINTF(offset, prefix, suffix) \ | |
8251 | + kdb_printf(prefix "%c0x%x" suffix, \ | |
8252 | + offset >= 0 ? '+' : '-', \ | |
8253 | + offset >= 0 ? offset : -offset) | |
8254 | +#define KDB_DEBUG_BB_OFFSET(offset, prefix, suffix) \ | |
8255 | + {if (KDB_DEBUG(BB)) KDB_DEBUG_BB_OFFSET_PRINTF(offset, prefix, suffix);} | |
8256 | + | |
8257 | +#define BB_CHECK(expr, val, ret) \ | |
8258 | +({ \ | |
8259 | + if (unlikely(expr)) { \ | |
8260 | + kdb_printf("%s, line %d: BB_CHECK(" #expr ") failed " \ | |
8261 | + #val "=%lx\n", \ | |
8262 | + __FUNCTION__, __LINE__, (long)val); \ | |
8263 | + bb_giveup = 1; \ | |
8264 | + return ret; \ | |
8265 | + } \ | |
8266 | +}) | |
8267 | + | |
8268 | +static int bb_giveup; | |
8269 | + | |
8270 | +/* Use BBRG_Rxx for both i386 and x86_64. RAX through R15 must be at the end, | |
8271 | + * starting with RAX. Some of these codes do not reflect actual registers, | |
8272 | + * such codes are special cases when parsing the record of register changes. | |
8273 | + * When updating BBRG_ entries, update bbrg_name as well. | |
8274 | + */ | |
8275 | + | |
8276 | +enum bb_reg_code | |
8277 | +{ | |
8278 | + BBRG_UNDEFINED = 0, /* Register contents are undefined */ | |
8279 | + BBRG_OSP, /* original stack pointer on entry to function */ | |
8280 | + BBRG_RAX, | |
8281 | + BBRG_RBX, | |
8282 | + BBRG_RCX, | |
8283 | + BBRG_RDX, | |
8284 | + BBRG_RDI, | |
8285 | + BBRG_RSI, | |
8286 | + BBRG_RBP, | |
8287 | + BBRG_RSP, | |
8288 | + BBRG_R8, | |
8289 | + BBRG_R9, | |
8290 | + BBRG_R10, | |
8291 | + BBRG_R11, | |
8292 | + BBRG_R12, | |
8293 | + BBRG_R13, | |
8294 | + BBRG_R14, | |
8295 | + BBRG_R15, | |
8296 | +}; | |
8297 | + | |
8298 | +const static char *bbrg_name[] = { | |
8299 | + [BBRG_UNDEFINED] = "undefined", | |
8300 | + [BBRG_OSP] = "osp", | |
8301 | + [BBRG_RAX] = "rax", | |
8302 | + [BBRG_RBX] = "rbx", | |
8303 | + [BBRG_RCX] = "rcx", | |
8304 | + [BBRG_RDX] = "rdx", | |
8305 | + [BBRG_RDI] = "rdi", | |
8306 | + [BBRG_RSI] = "rsi", | |
8307 | + [BBRG_RBP] = "rbp", | |
8308 | + [BBRG_RSP] = "rsp", | |
8309 | + [BBRG_R8] = "r8", | |
8310 | + [BBRG_R9] = "r9", | |
8311 | + [BBRG_R10] = "r10", | |
8312 | + [BBRG_R11] = "r11", | |
8313 | + [BBRG_R12] = "r12", | |
8314 | + [BBRG_R13] = "r13", | |
8315 | + [BBRG_R14] = "r14", | |
8316 | + [BBRG_R15] = "r15", | |
8317 | +}; | |
8318 | + | |
8319 | +/* Map a register name to its register code. This includes the sub-register | |
8320 | + * addressable fields, e.g. parts of rax can be addressed as ax, al, ah, eax. | |
8321 | + * The list is sorted so it can be binary chopped, sort command is: | |
8322 | + * LANG=C sort -t '"' -k2 | |
8323 | + */ | |
8324 | + | |
8325 | +struct bb_reg_code_map { | |
8326 | + enum bb_reg_code reg; | |
8327 | + const char *name; | |
8328 | +}; | |
8329 | + | |
8330 | +const static struct bb_reg_code_map | |
8331 | +bb_reg_code_map[] = { | |
8332 | + { BBRG_RAX, "ah" }, | |
8333 | + { BBRG_RAX, "al" }, | |
8334 | + { BBRG_RAX, "ax" }, | |
8335 | + { BBRG_RBX, "bh" }, | |
8336 | + { BBRG_RBX, "bl" }, | |
8337 | + { BBRG_RBP, "bp" }, | |
8338 | + { BBRG_RBP, "bpl" }, | |
8339 | + { BBRG_RBX, "bx" }, | |
8340 | + { BBRG_RCX, "ch" }, | |
8341 | + { BBRG_RCX, "cl" }, | |
8342 | + { BBRG_RCX, "cx" }, | |
8343 | + { BBRG_RDX, "dh" }, | |
8344 | + { BBRG_RDI, "di" }, | |
8345 | + { BBRG_RDI, "dil" }, | |
8346 | + { BBRG_RDX, "dl" }, | |
8347 | + { BBRG_RDX, "dx" }, | |
8348 | + { BBRG_RAX, "eax" }, | |
8349 | + { BBRG_RBP, "ebp" }, | |
8350 | + { BBRG_RBX, "ebx" }, | |
8351 | + { BBRG_RCX, "ecx" }, | |
8352 | + { BBRG_RDI, "edi" }, | |
8353 | + { BBRG_RDX, "edx" }, | |
8354 | + { BBRG_RSI, "esi" }, | |
8355 | + { BBRG_RSP, "esp" }, | |
8356 | + { BBRG_R10, "r10" }, | |
8357 | + { BBRG_R10, "r10d" }, | |
8358 | + { BBRG_R10, "r10l" }, | |
8359 | + { BBRG_R10, "r10w" }, | |
8360 | + { BBRG_R11, "r11" }, | |
8361 | + { BBRG_R11, "r11d" }, | |
8362 | + { BBRG_R11, "r11l" }, | |
8363 | + { BBRG_R11, "r11w" }, | |
8364 | + { BBRG_R12, "r12" }, | |
8365 | + { BBRG_R12, "r12d" }, | |
8366 | + { BBRG_R12, "r12l" }, | |
8367 | + { BBRG_R12, "r12w" }, | |
8368 | + { BBRG_R13, "r13" }, | |
8369 | + { BBRG_R13, "r13d" }, | |
8370 | + { BBRG_R13, "r13l" }, | |
8371 | + { BBRG_R13, "r13w" }, | |
8372 | + { BBRG_R14, "r14" }, | |
8373 | + { BBRG_R14, "r14d" }, | |
8374 | + { BBRG_R14, "r14l" }, | |
8375 | + { BBRG_R14, "r14w" }, | |
8376 | + { BBRG_R15, "r15" }, | |
8377 | + { BBRG_R15, "r15d" }, | |
8378 | + { BBRG_R15, "r15l" }, | |
8379 | + { BBRG_R15, "r15w" }, | |
8380 | + { BBRG_R8, "r8" }, | |
8381 | + { BBRG_R8, "r8d" }, | |
8382 | + { BBRG_R8, "r8l" }, | |
8383 | + { BBRG_R8, "r8w" }, | |
8384 | + { BBRG_R9, "r9" }, | |
8385 | + { BBRG_R9, "r9d" }, | |
8386 | + { BBRG_R9, "r9l" }, | |
8387 | + { BBRG_R9, "r9w" }, | |
8388 | + { BBRG_RAX, "rax" }, | |
8389 | + { BBRG_RBP, "rbp" }, | |
8390 | + { BBRG_RBX, "rbx" }, | |
8391 | + { BBRG_RCX, "rcx" }, | |
8392 | + { BBRG_RDI, "rdi" }, | |
8393 | + { BBRG_RDX, "rdx" }, | |
8394 | + { BBRG_RSI, "rsi" }, | |
8395 | + { BBRG_RSP, "rsp" }, | |
8396 | + { BBRG_RSI, "si" }, | |
8397 | + { BBRG_RSI, "sil" }, | |
8398 | + { BBRG_RSP, "sp" }, | |
8399 | + { BBRG_RSP, "spl" }, | |
8400 | +}; | |
8401 | + | |
8402 | +/* Record register contents in terms of the values that were passed to this | |
8403 | + * function, IOW track which registers contain an input value. A register's | |
8404 | + * contents can be undefined, it can contain an input register value or it can | |
8405 | + * contain an offset from the original stack pointer. | |
8406 | + * | |
8407 | + * This structure is used to represent the current contents of the integer | |
8408 | + * registers, it is held in an array that is indexed by BBRG_xxx. The element | |
8409 | + * for BBRG_xxx indicates what input value is currently in BBRG_xxx. When | |
8410 | + * 'value' is BBRG_OSP then register BBRG_xxx contains a stack pointer, | |
8411 | + * pointing at 'offset' from the original stack pointer on entry to the | |
8412 | + * function. When 'value' is not BBRG_OSP then element BBRG_xxx contains the | |
8413 | + * original contents of an input register and offset is ignored. | |
8414 | + * | |
8415 | + * An input register 'value' can be stored in more than one register and/or in | |
8416 | + * more than one memory location. | |
8417 | + */ | |
8418 | + | |
8419 | +struct bb_reg_contains | |
8420 | +{ | |
8421 | + enum bb_reg_code value: 8; | |
8422 | + short offset; | |
8423 | +}; | |
8424 | + | |
8425 | +/* Note: the offsets in struct bb_mem_contains in this code are _NOT_ offsets | |
8426 | + * from OSP, they are offsets from current RSP. It fits better with the way | |
8427 | + * that struct pt_regs is built, some code pushes extra data before pt_regs so | |
8428 | + * working with OSP relative offsets gets messy. struct bb_mem_contains | |
8429 | + * entries must be in descending order of RSP offset. | |
8430 | + */ | |
8431 | + | |
8432 | +typedef struct { DECLARE_BITMAP(bits, BBRG_R15+1); } bbrgmask_t; | |
8433 | +#define BB_SKIP(reg) (1 << (BBRG_ ## reg)) | |
8434 | +struct bb_mem_contains { | |
8435 | + short offset_address; | |
8436 | + enum bb_reg_code value: 8; | |
8437 | +}; | |
8438 | + | |
8439 | +/* Transfer of control to a label outside the current function. If the | |
8440 | + * transfer is to a known common restore path that expects known registers | |
8441 | + * and/or a known memory state (e.g. struct pt_regs) then do a sanity check on | |
8442 | + * the state at this point. | |
8443 | + */ | |
8444 | + | |
8445 | +struct bb_name_state { | |
8446 | + const char *name; /* target function */ | |
8447 | + bfd_vma address; /* Address of target function */ | |
8448 | + const char *fname; /* optional from function name */ | |
8449 | + const struct bb_mem_contains *mem; /* expected memory state */ | |
8450 | + const struct bb_reg_contains *regs; /* expected register state */ | |
8451 | + const unsigned short mem_size; /* ARRAY_SIZE(mem) */ | |
8452 | + const unsigned short regs_size; /* ARRAY_SIZE(regs) */ | |
8453 | + const short osp_offset; /* RSP in regs == OSP+osp_offset */ | |
8454 | + const bbrgmask_t skip_mem; /* Some slots in mem may be undefined */ | |
8455 | + const bbrgmask_t skip_regs; /* Some slots in regs may be undefined */ | |
8456 | +}; | |
8457 | + | |
8458 | +/* NS (NAME_STATE) macros define the register and memory state when we transfer | |
8459 | + * control to or start decoding a special case name. Use NS when the target | |
8460 | + * label always has the same state. Use NS_FROM and specify the source label | |
8461 | + * if the target state is slightly different depending on where it is branched | |
8462 | + * from. This gives better state checking, by isolating the special cases. | |
8463 | + * | |
8464 | + * Note: for the same target label, NS_FROM entries must be followed by a | |
8465 | + * single NS entry. | |
8466 | + */ | |
8467 | + | |
8468 | +#define NS_FROM(iname, ifname, imem, iregs, iskip_mem, iskip_regs, iosp_offset) \ | |
8469 | + { \ | |
8470 | + .name = iname, \ | |
8471 | + .fname = ifname, \ | |
8472 | + .mem = imem, \ | |
8473 | + .regs = iregs, \ | |
8474 | + .mem_size = ARRAY_SIZE(imem), \ | |
8475 | + .regs_size = ARRAY_SIZE(iregs), \ | |
8476 | + .skip_mem.bits[0] = iskip_mem, \ | |
8477 | + .skip_regs.bits[0] = iskip_regs, \ | |
8478 | + .osp_offset = iosp_offset, \ | |
8479 | + .address = 0 \ | |
8480 | + } | |
8481 | + | |
8482 | +/* Shorter forms for the common cases */ | |
8483 | +#define NS(iname, imem, iregs, iskip_mem, iskip_regs, iosp_offset) \ | |
8484 | + NS_FROM(iname, NULL, imem, iregs, iskip_mem, iskip_regs, iosp_offset) | |
8485 | +#define NS_MEM(iname, imem, iskip_mem) \ | |
8486 | + NS_FROM(iname, NULL, imem, no_regs, iskip_mem, 0, 0) | |
8487 | +#define NS_MEM_FROM(iname, ifname, imem, iskip_mem) \ | |
8488 | + NS_FROM(iname, ifname, imem, no_regs, iskip_mem, 0, 0) | |
8489 | +#define NS_REG(iname, iregs, iskip_regs) \ | |
8490 | + NS_FROM(iname, NULL, no_memory, iregs, 0, iskip_regs, 0) | |
8491 | +#define NS_REG_FROM(iname, ifname, iregs, iskip_regs) \ | |
8492 | + NS_FROM(iname, ifname, no_memory, iregs, 0, iskip_regs, 0) | |
8493 | + | |
8494 | +static void | |
8495 | +bb_reg_code_set_value(enum bb_reg_code dst, enum bb_reg_code src); | |
8496 | + | |
8497 | +static const char *bb_mod_name, *bb_func_name; | |
8498 | + | |
8499 | +static int | |
8500 | +bb_noret(const char *name) | |
8501 | +{ | |
8502 | + if (strcmp(name, "panic") == 0 || | |
8503 | + strcmp(name, "do_exit") == 0 || | |
8504 | + strcmp(name, "do_group_exit") == 0 || | |
8505 | + strcmp(name, "complete_and_exit") == 0) | |
8506 | + return 1; | |
8507 | + return 0; | |
8508 | +} | |
8509 | + | |
8510 | +/*============================================================================*/ | |
8511 | +/* */ | |
8512 | +/* Most of the basic block code and data is common to x86_64 and i386. This */ | |
8513 | +/* large ifdef contains almost all of the differences between the two */ | |
8514 | +/* architectures. */ | |
8515 | +/* */ | |
8516 | +/* Make sure you update the correct section of this ifdef. */ | |
8517 | +/* */ | |
8518 | +/*============================================================================*/ | |
8519 | + | |
8520 | +#ifdef CONFIG_X86_64 | |
8521 | + | |
8522 | +/* Registers that can be used to pass parameters, in the order that parameters | |
8523 | + * are passed. | |
8524 | + */ | |
8525 | + | |
8526 | +const static enum bb_reg_code | |
8527 | +bb_param_reg[] = { | |
8528 | + BBRG_RDI, | |
8529 | + BBRG_RSI, | |
8530 | + BBRG_RDX, | |
8531 | + BBRG_RCX, | |
8532 | + BBRG_R8, | |
8533 | + BBRG_R9, | |
8534 | +}; | |
8535 | + | |
8536 | +const static enum bb_reg_code | |
8537 | +bb_preserved_reg[] = { | |
8538 | + BBRG_RBX, | |
8539 | + BBRG_RBP, | |
8540 | + BBRG_RSP, | |
8541 | + BBRG_R12, | |
8542 | + BBRG_R13, | |
8543 | + BBRG_R14, | |
8544 | + BBRG_R15, | |
8545 | +}; | |
8546 | + | |
8547 | +static const struct bb_mem_contains full_pt_regs[] = { | |
8548 | + { 0x70, BBRG_RDI }, | |
8549 | + { 0x68, BBRG_RSI }, | |
8550 | + { 0x60, BBRG_RDX }, | |
8551 | + { 0x58, BBRG_RCX }, | |
8552 | + { 0x50, BBRG_RAX }, | |
8553 | + { 0x48, BBRG_R8 }, | |
8554 | + { 0x40, BBRG_R9 }, | |
8555 | + { 0x38, BBRG_R10 }, | |
8556 | + { 0x30, BBRG_R11 }, | |
8557 | + { 0x28, BBRG_RBX }, | |
8558 | + { 0x20, BBRG_RBP }, | |
8559 | + { 0x18, BBRG_R12 }, | |
8560 | + { 0x10, BBRG_R13 }, | |
8561 | + { 0x08, BBRG_R14 }, | |
8562 | + { 0x00, BBRG_R15 }, | |
8563 | +}; | |
8564 | +static const struct bb_mem_contains partial_pt_regs[] = { | |
8565 | + { 0x40, BBRG_RDI }, | |
8566 | + { 0x38, BBRG_RSI }, | |
8567 | + { 0x30, BBRG_RDX }, | |
8568 | + { 0x28, BBRG_RCX }, | |
8569 | + { 0x20, BBRG_RAX }, | |
8570 | + { 0x18, BBRG_R8 }, | |
8571 | + { 0x10, BBRG_R9 }, | |
8572 | + { 0x08, BBRG_R10 }, | |
8573 | + { 0x00, BBRG_R11 }, | |
8574 | +}; | |
8575 | +static const struct bb_mem_contains partial_pt_regs_plus_1[] = { | |
8576 | + { 0x48, BBRG_RDI }, | |
8577 | + { 0x40, BBRG_RSI }, | |
8578 | + { 0x38, BBRG_RDX }, | |
8579 | + { 0x30, BBRG_RCX }, | |
8580 | + { 0x28, BBRG_RAX }, | |
8581 | + { 0x20, BBRG_R8 }, | |
8582 | + { 0x18, BBRG_R9 }, | |
8583 | + { 0x10, BBRG_R10 }, | |
8584 | + { 0x08, BBRG_R11 }, | |
8585 | +}; | |
8586 | +static const struct bb_mem_contains partial_pt_regs_plus_2[] = { | |
8587 | + { 0x50, BBRG_RDI }, | |
8588 | + { 0x48, BBRG_RSI }, | |
8589 | + { 0x40, BBRG_RDX }, | |
8590 | + { 0x38, BBRG_RCX }, | |
8591 | + { 0x30, BBRG_RAX }, | |
8592 | + { 0x28, BBRG_R8 }, | |
8593 | + { 0x20, BBRG_R9 }, | |
8594 | + { 0x18, BBRG_R10 }, | |
8595 | + { 0x10, BBRG_R11 }, | |
8596 | +}; | |
8597 | +static const struct bb_mem_contains no_memory[] = { | |
8598 | +}; | |
8599 | +/* Hardware has already pushed an error_code on the stack. Use undefined just | |
8600 | + * to set the initial stack offset. | |
8601 | + */ | |
8602 | +static const struct bb_mem_contains error_code[] = { | |
8603 | + { 0x0, BBRG_UNDEFINED }, | |
8604 | +}; | |
8605 | +/* error_code plus original rax */ | |
8606 | +static const struct bb_mem_contains error_code_rax[] = { | |
8607 | + { 0x8, BBRG_UNDEFINED }, | |
8608 | + { 0x0, BBRG_RAX }, | |
8609 | +}; | |
8610 | + | |
8611 | +static const struct bb_reg_contains all_regs[] = { | |
8612 | + [BBRG_RAX] = { BBRG_RAX, 0 }, | |
8613 | + [BBRG_RBX] = { BBRG_RBX, 0 }, | |
8614 | + [BBRG_RCX] = { BBRG_RCX, 0 }, | |
8615 | + [BBRG_RDX] = { BBRG_RDX, 0 }, | |
8616 | + [BBRG_RDI] = { BBRG_RDI, 0 }, | |
8617 | + [BBRG_RSI] = { BBRG_RSI, 0 }, | |
8618 | + [BBRG_RBP] = { BBRG_RBP, 0 }, | |
8619 | + [BBRG_RSP] = { BBRG_OSP, 0 }, | |
8620 | + [BBRG_R8 ] = { BBRG_R8, 0 }, | |
8621 | + [BBRG_R9 ] = { BBRG_R9, 0 }, | |
8622 | + [BBRG_R10] = { BBRG_R10, 0 }, | |
8623 | + [BBRG_R11] = { BBRG_R11, 0 }, | |
8624 | + [BBRG_R12] = { BBRG_R12, 0 }, | |
8625 | + [BBRG_R13] = { BBRG_R13, 0 }, | |
8626 | + [BBRG_R14] = { BBRG_R14, 0 }, | |
8627 | + [BBRG_R15] = { BBRG_R15, 0 }, | |
8628 | +}; | |
8629 | +static const struct bb_reg_contains no_regs[] = { | |
8630 | +}; | |
8631 | + | |
8632 | +static struct bb_name_state bb_special_cases[] = { | |
8633 | + | |
8634 | + /* First the cases that pass data only in memory. We do not check any | |
8635 | + * register state for these cases. | |
8636 | + */ | |
8637 | + | |
8638 | + /* Simple cases, no exceptions */ | |
8639 | + NS_MEM("ia32_ptregs_common", partial_pt_regs_plus_1, 0), | |
8640 | + NS_MEM("ia32_sysret", partial_pt_regs, 0), | |
8641 | + NS_MEM("int_careful", partial_pt_regs, 0), | |
8642 | + NS_MEM("int_restore_rest", full_pt_regs, 0), | |
8643 | + NS_MEM("int_signal", full_pt_regs, 0), | |
8644 | + NS_MEM("int_very_careful", partial_pt_regs, 0), | |
8645 | + NS_MEM("int_with_check", partial_pt_regs, 0), | |
8646 | +#ifdef CONFIG_TRACE_IRQFLAGS | |
8647 | + NS_MEM("paranoid_exit0", full_pt_regs, 0), | |
8648 | +#endif /* CONFIG_TRACE_IRQFLAGS */ | |
8649 | + NS_MEM("paranoid_exit1", full_pt_regs, 0), | |
8650 | + NS_MEM("ptregscall_common", partial_pt_regs_plus_1, 0), | |
8651 | + NS_MEM("restore_norax", partial_pt_regs, 0), | |
8652 | + NS_MEM("restore", partial_pt_regs, 0), | |
8653 | + NS_MEM("ret_from_intr", partial_pt_regs_plus_2, 0), | |
8654 | + NS_MEM("stub32_clone", partial_pt_regs_plus_1, 0), | |
8655 | + NS_MEM("stub32_execve", partial_pt_regs_plus_1, 0), | |
8656 | + NS_MEM("stub32_fork", partial_pt_regs_plus_1, 0), | |
8657 | + NS_MEM("stub32_iopl", partial_pt_regs_plus_1, 0), | |
8658 | + NS_MEM("stub32_rt_sigreturn", partial_pt_regs_plus_1, 0), | |
8659 | + NS_MEM("stub32_rt_sigsuspend", partial_pt_regs_plus_1, 0), | |
8660 | + NS_MEM("stub32_sigaltstack", partial_pt_regs_plus_1, 0), | |
8661 | + NS_MEM("stub32_sigreturn", partial_pt_regs_plus_1, 0), | |
8662 | + NS_MEM("stub32_sigsuspend", partial_pt_regs_plus_1, 0), | |
8663 | + NS_MEM("stub32_vfork", partial_pt_regs_plus_1, 0), | |
8664 | + NS_MEM("stub_clone", partial_pt_regs_plus_1, 0), | |
8665 | + NS_MEM("stub_execve", partial_pt_regs_plus_1, 0), | |
8666 | + NS_MEM("stub_fork", partial_pt_regs_plus_1, 0), | |
8667 | + NS_MEM("stub_iopl", partial_pt_regs_plus_1, 0), | |
8668 | + NS_MEM("stub_rt_sigreturn", partial_pt_regs_plus_1, 0), | |
8669 | + NS_MEM("stub_rt_sigsuspend", partial_pt_regs_plus_1, 0), | |
8670 | + NS_MEM("stub_sigaltstack", partial_pt_regs_plus_1, 0), | |
8671 | + NS_MEM("stub_vfork", partial_pt_regs_plus_1, 0), | |
8672 | + | |
8673 | + NS_MEM_FROM("ia32_badsys", "ia32_sysenter_target", | |
8674 | + partial_pt_regs, | |
8675 | + /* ia32_sysenter_target uses CLEAR_RREGS to clear R8-R11 on | |
8676 | + * some paths. It also stomps on RAX. | |
8677 | + */ | |
8678 | + BB_SKIP(R8) | BB_SKIP(R9) | BB_SKIP(R10) | BB_SKIP(R11) | | |
8679 | + BB_SKIP(RAX)), | |
8680 | + NS_MEM_FROM("ia32_badsys", "ia32_cstar_target", | |
8681 | + partial_pt_regs, | |
8682 | + /* ia32_cstar_target uses CLEAR_RREGS to clear R8-R11 on some | |
8683 | + * paths. It also stomps on RAX. Even more confusing, instead | |
8684 | + * of storing RCX it stores RBP. WTF? | |
8685 | + */ | |
8686 | + BB_SKIP(R8) | BB_SKIP(R9) | BB_SKIP(R10) | BB_SKIP(R11) | | |
8687 | + BB_SKIP(RAX) | BB_SKIP(RCX)), | |
8688 | + NS_MEM("ia32_badsys", partial_pt_regs, 0), | |
8689 | + | |
8690 | + /* Various bits of code branch to int_ret_from_sys_call, with slightly | |
8691 | + * different missing values in pt_regs. | |
8692 | + */ | |
8693 | + NS_MEM_FROM("int_ret_from_sys_call", "ret_from_fork", | |
8694 | + partial_pt_regs, | |
8695 | + BB_SKIP(R11)), | |
8696 | + NS_MEM_FROM("int_ret_from_sys_call", "stub_execve", | |
8697 | + partial_pt_regs, | |
8698 | + BB_SKIP(RAX) | BB_SKIP(RCX)), | |
8699 | + NS_MEM_FROM("int_ret_from_sys_call", "stub_rt_sigreturn", | |
8700 | + partial_pt_regs, | |
8701 | + BB_SKIP(RAX) | BB_SKIP(RCX)), | |
8702 | + NS_MEM_FROM("int_ret_from_sys_call", "kernel_execve", | |
8703 | + partial_pt_regs, | |
8704 | + BB_SKIP(RAX)), | |
8705 | + NS_MEM_FROM("int_ret_from_sys_call", "ia32_syscall", | |
8706 | + partial_pt_regs, | |
8707 | + /* ia32_syscall only saves RDI through RCX. */ | |
8708 | + BB_SKIP(R8) | BB_SKIP(R9) | BB_SKIP(R10) | BB_SKIP(R11) | | |
8709 | + BB_SKIP(RAX)), | |
8710 | + NS_MEM_FROM("int_ret_from_sys_call", "ia32_sysenter_target", | |
8711 | + partial_pt_regs, | |
8712 | + /* ia32_sysenter_target uses CLEAR_RREGS to clear R8-R11 on | |
8713 | + * some paths. It also stomps on RAX. | |
8714 | + */ | |
8715 | + BB_SKIP(R8) | BB_SKIP(R9) | BB_SKIP(R10) | BB_SKIP(R11) | | |
8716 | + BB_SKIP(RAX)), | |
8717 | + NS_MEM_FROM("int_ret_from_sys_call", "ia32_cstar_target", | |
8718 | + partial_pt_regs, | |
8719 | + /* ia32_cstar_target uses CLEAR_RREGS to clear R8-R11 on some | |
8720 | + * paths. It also stomps on RAX. Even more confusing, instead | |
8721 | + * of storing RCX it stores RBP. WTF? | |
8722 | + */ | |
8723 | + BB_SKIP(R8) | BB_SKIP(R9) | BB_SKIP(R10) | BB_SKIP(R11) | | |
8724 | + BB_SKIP(RAX) | BB_SKIP(RCX)), | |
8725 | + NS_MEM("int_ret_from_sys_call", partial_pt_regs, 0), | |
8726 | + | |
8727 | +#ifdef CONFIG_PREEMPT | |
8728 | + NS_MEM("retint_kernel", partial_pt_regs, BB_SKIP(RAX)), | |
8729 | +#endif /* CONFIG_PREEMPT */ | |
8730 | + | |
8731 | + NS_MEM("retint_careful", partial_pt_regs, BB_SKIP(RAX)), | |
8732 | + | |
8733 | + /* Horrible hack: For a brand new x86_64 task, switch_to() branches to | |
8734 | + * ret_from_fork with a totally different stack state from all the | |
8735 | + * other tasks that come out of switch_to(). This non-standard state | |
8736 | + * cannot be represented so just ignore the branch from switch_to() to | |
8737 | + * ret_from_fork. Due to inlining and linker labels, switch_to() can | |
8738 | + * appear as several different function labels, including schedule, | |
8739 | + * context_switch and __sched_text_start. | |
8740 | + */ | |
8741 | + NS_MEM_FROM("ret_from_fork", "schedule", no_memory, 0), | |
8742 | + NS_MEM_FROM("ret_from_fork", "__sched_text_start", no_memory, 0), | |
8743 | + NS_MEM_FROM("ret_from_fork", "context_switch", no_memory, 0), | |
8744 | + NS_MEM("ret_from_fork", full_pt_regs, 0), | |
8745 | + | |
8746 | + | |
8747 | + NS_MEM_FROM("ret_from_sys_call", "ret_from_fork", | |
8748 | + partial_pt_regs, | |
8749 | + BB_SKIP(R11)), | |
8750 | + NS_MEM("ret_from_sys_call", partial_pt_regs, 0), | |
8751 | + | |
8752 | + NS_MEM("retint_restore_args", | |
8753 | + partial_pt_regs, | |
8754 | + BB_SKIP(RAX) | BB_SKIP(RCX)), | |
8755 | + | |
8756 | + NS_MEM("retint_swapgs", | |
8757 | + partial_pt_regs, | |
8758 | + BB_SKIP(RAX) | BB_SKIP(RCX)), | |
8759 | + | |
8760 | + /* Now the cases that pass data in registers. We do not check any | |
8761 | + * memory state for these cases. | |
8762 | + */ | |
8763 | + | |
8764 | + NS_REG("bad_put_user", | |
8765 | + all_regs, | |
8766 | + BB_SKIP(RAX) | BB_SKIP(RCX) | BB_SKIP(R8)), | |
8767 | + | |
8768 | + NS_REG("bad_get_user", | |
8769 | + all_regs, | |
8770 | + BB_SKIP(RAX) | BB_SKIP(RCX) | BB_SKIP(R8)), | |
8771 | + | |
8772 | + NS_REG("bad_to_user", | |
8773 | + all_regs, | |
8774 | + BB_SKIP(RAX) | BB_SKIP(RCX)), | |
8775 | + | |
8776 | + NS_REG("ia32_ptregs_common", | |
8777 | + all_regs, | |
8778 | + 0), | |
8779 | + | |
8780 | + NS_REG("copy_user_generic_unrolled", | |
8781 | + all_regs, | |
8782 | + BB_SKIP(RAX) | BB_SKIP(RCX)), | |
8783 | + | |
8784 | + NS_REG("copy_user_generic_string", | |
8785 | + all_regs, | |
8786 | + BB_SKIP(RAX) | BB_SKIP(RCX)), | |
8787 | + | |
8788 | + NS_REG("irq_return", | |
8789 | + all_regs, | |
8790 | + 0), | |
8791 | + | |
8792 | + /* Finally the cases that pass data in both registers and memory. | |
8793 | + */ | |
8794 | + | |
8795 | + NS("invalid_TSS", error_code, all_regs, 0, 0, 0), | |
8796 | + NS("segment_not_present", error_code, all_regs, 0, 0, 0), | |
8797 | + NS("alignment_check", error_code, all_regs, 0, 0, 0), | |
8798 | + NS("page_fault", error_code, all_regs, 0, 0, 0), | |
8799 | + NS("general_protection", error_code, all_regs, 0, 0, 0), | |
8800 | + NS("error_entry", error_code_rax, all_regs, 0, BB_SKIP(RAX), -0x10), | |
8801 | + NS("common_interrupt", error_code, all_regs, 0, 0, -0x8), | |
8802 | +}; | |
8803 | + | |
8804 | +static const char *bb_spurious[] = { | |
8805 | + /* schedule */ | |
8806 | + "thread_return", | |
8807 | + /* ret_from_fork */ | |
8808 | + "rff_action", | |
8809 | + "rff_trace", | |
8810 | + /* system_call */ | |
8811 | + "ret_from_sys_call", | |
8812 | + "sysret_check", | |
8813 | + "sysret_careful", | |
8814 | + "sysret_signal", | |
8815 | + "badsys", | |
8816 | + "tracesys", | |
8817 | + "int_ret_from_sys_call", | |
8818 | + "int_with_check", | |
8819 | + "int_careful", | |
8820 | + "int_very_careful", | |
8821 | + "int_signal", | |
8822 | + "int_restore_rest", | |
8823 | + /* common_interrupt */ | |
8824 | + "ret_from_intr", | |
8825 | + "exit_intr", | |
8826 | + "retint_with_reschedule", | |
8827 | + "retint_check", | |
8828 | + "retint_swapgs", | |
8829 | + "retint_restore_args", | |
8830 | + "restore_args", | |
8831 | + "irq_return", | |
8832 | + "bad_iret", | |
8833 | + "retint_careful", | |
8834 | + "retint_signal", | |
8835 | +#ifdef CONFIG_PREEMPT | |
8836 | + "retint_kernel", | |
8837 | +#endif /* CONFIG_PREEMPT */ | |
8838 | + /* .macro paranoidexit */ | |
8839 | +#ifdef CONFIG_TRACE_IRQFLAGS | |
8840 | + "paranoid_exit0", | |
8841 | + "paranoid_userspace0", | |
8842 | + "paranoid_restore0", | |
8843 | + "paranoid_swapgs0", | |
8844 | + "paranoid_schedule0", | |
8845 | +#endif /* CONFIG_TRACE_IRQFLAGS */ | |
8846 | + "paranoid_exit1", | |
8847 | + "paranoid_swapgs1", | |
8848 | + "paranoid_restore1", | |
8849 | + "paranoid_userspace1", | |
8850 | + "paranoid_schedule1", | |
8851 | + /* error_entry */ | |
8852 | + "error_swapgs", | |
8853 | + "error_sti", | |
8854 | + "error_exit", | |
8855 | + "error_kernelspace", | |
8856 | + /* load_gs_index */ | |
8857 | + "gs_change", | |
8858 | + "bad_gs", | |
8859 | + /* ia32_sysenter_target */ | |
8860 | + "sysenter_do_call", | |
8861 | + "sysenter_tracesys", | |
8862 | + /* ia32_cstar_target */ | |
8863 | + "cstar_do_call", | |
8864 | + "cstar_tracesys", | |
8865 | + "ia32_badarg", | |
8866 | + /* ia32_syscall */ | |
8867 | + "ia32_do_syscall", | |
8868 | + "ia32_sysret", | |
8869 | + "ia32_tracesys", | |
8870 | + "ia32_badsys", | |
8871 | +#ifdef CONFIG_HIBERNATION | |
8872 | + /* restore_image */ | |
8873 | + "loop", | |
8874 | + "done", | |
8875 | +#endif /* CONFIG_HIBERNATION */ | |
8876 | +#ifdef CONFIG_KPROBES | |
8877 | + /* jprobe_return */ | |
8878 | + "jprobe_return_end", | |
8879 | + /* kretprobe_trampoline_holder */ | |
8880 | + "kretprobe_trampoline", | |
8881 | +#endif /* CONFIG_KPROBES */ | |
8882 | +#ifdef CONFIG_KEXEC | |
8883 | + /* relocate_kernel */ | |
8884 | + "relocate_new_kernel", | |
8885 | +#endif /* CONFIG_KEXEC */ | |
8886 | +#ifdef CONFIG_XEN | |
8887 | + /* arch/i386/xen/xen-asm.S */ | |
8888 | + "xen_irq_enable_direct_end", | |
8889 | + "xen_irq_disable_direct_end", | |
8890 | + "xen_save_fl_direct_end", | |
8891 | + "xen_restore_fl_direct_end", | |
8892 | + "xen_iret_start_crit", | |
8893 | + "iret_restore_end", | |
8894 | + "xen_iret_end_crit", | |
8895 | + "hyper_iret", | |
8896 | +#endif /* CONFIG_XEN */ | |
8897 | +}; | |
8898 | + | |
8899 | +static const char *bb_hardware_handlers[] = { | |
8900 | + "system_call", | |
8901 | + "common_interrupt", | |
8902 | + "error_entry", | |
8903 | + "debug", | |
8904 | + "nmi", | |
8905 | + "int3", | |
8906 | + "double_fault", | |
8907 | + "stack_segment", | |
8908 | + "machine_check", | |
8909 | + "kdb_call", | |
8910 | +}; | |
8911 | + | |
8912 | +static int | |
8913 | +bb_hardware_pushed_arch(kdb_machreg_t rsp, | |
8914 | + const struct kdb_activation_record *ar) | |
8915 | +{ | |
8916 | + /* x86_64 interrupt stacks are 16 byte aligned and you must get the | |
8917 | + * next rsp from stack, it cannot be statically calculated. Do not | |
8918 | + * include the word at rsp, it is pushed by hardware but is treated as | |
8919 | + * a normal software return value. | |
8920 | + * | |
8921 | + * When an IST switch occurs (e.g. NMI) then the saved rsp points to | |
8922 | + * another stack entirely. Assume that the IST stack is 16 byte | |
8923 | + * aligned and just return the size of the hardware data on this stack. | |
8924 | + * The stack unwind code will take care of the stack switch. | |
8925 | + */ | |
8926 | + kdb_machreg_t saved_rsp = *((kdb_machreg_t *)rsp + 3); | |
8927 | + int hardware_pushed = saved_rsp - rsp - KDB_WORD_SIZE; | |
8928 | + if (hardware_pushed < 4 * KDB_WORD_SIZE || | |
8929 | + saved_rsp < ar->stack.logical_start || | |
8930 | + saved_rsp >= ar->stack.logical_end) | |
8931 | + return 4 * KDB_WORD_SIZE; | |
8932 | + else | |
8933 | + return hardware_pushed; | |
8934 | +} | |
8935 | + | |
8936 | +static void | |
8937 | +bb_start_block0(void) | |
8938 | +{ | |
8939 | + bb_reg_code_set_value(BBRG_RAX, BBRG_RAX); | |
8940 | + bb_reg_code_set_value(BBRG_RBX, BBRG_RBX); | |
8941 | + bb_reg_code_set_value(BBRG_RCX, BBRG_RCX); | |
8942 | + bb_reg_code_set_value(BBRG_RDX, BBRG_RDX); | |
8943 | + bb_reg_code_set_value(BBRG_RDI, BBRG_RDI); | |
8944 | + bb_reg_code_set_value(BBRG_RSI, BBRG_RSI); | |
8945 | + bb_reg_code_set_value(BBRG_RBP, BBRG_RBP); | |
8946 | + bb_reg_code_set_value(BBRG_RSP, BBRG_OSP); | |
8947 | + bb_reg_code_set_value(BBRG_R8, BBRG_R8); | |
8948 | + bb_reg_code_set_value(BBRG_R9, BBRG_R9); | |
8949 | + bb_reg_code_set_value(BBRG_R10, BBRG_R10); | |
8950 | + bb_reg_code_set_value(BBRG_R11, BBRG_R11); | |
8951 | + bb_reg_code_set_value(BBRG_R12, BBRG_R12); | |
8952 | + bb_reg_code_set_value(BBRG_R13, BBRG_R13); | |
8953 | + bb_reg_code_set_value(BBRG_R14, BBRG_R14); | |
8954 | + bb_reg_code_set_value(BBRG_R15, BBRG_R15); | |
8955 | +} | |
8956 | + | |
8957 | +/* x86_64 does not have a special case for __switch_to */ | |
8958 | + | |
8959 | +static void | |
8960 | +bb_fixup_switch_to(char *p) | |
8961 | +{ | |
8962 | +} | |
8963 | + | |
8964 | +static int | |
8965 | +bb_asmlinkage_arch(void) | |
8966 | +{ | |
8967 | + return strncmp(bb_func_name, "__down", 6) == 0 || | |
8968 | + strncmp(bb_func_name, "__up", 4) == 0 || | |
8969 | + strncmp(bb_func_name, "stub_", 5) == 0 || | |
8970 | + strcmp(bb_func_name, "ret_from_fork") == 0 || | |
8971 | + strcmp(bb_func_name, "ptregscall_common") == 0; | |
8972 | +} | |
8973 | + | |
8974 | +#else /* !CONFIG_X86_64 */ | |
8975 | + | |
8976 | +/* Registers that can be used to pass parameters, in the order that parameters | |
8977 | + * are passed. | |
8978 | + */ | |
8979 | + | |
8980 | +const static enum bb_reg_code | |
8981 | +bb_param_reg[] = { | |
8982 | + BBRG_RAX, | |
8983 | + BBRG_RDX, | |
8984 | + BBRG_RCX, | |
8985 | +}; | |
8986 | + | |
8987 | +const static enum bb_reg_code | |
8988 | +bb_preserved_reg[] = { | |
8989 | + BBRG_RBX, | |
8990 | + BBRG_RBP, | |
8991 | + BBRG_RSP, | |
8992 | + BBRG_RSI, | |
8993 | + BBRG_RDI, | |
8994 | +}; | |
8995 | + | |
8996 | +static const struct bb_mem_contains full_pt_regs[] = { | |
8997 | + { 0x18, BBRG_RAX }, | |
8998 | + { 0x14, BBRG_RBP }, | |
8999 | + { 0x10, BBRG_RDI }, | |
9000 | + { 0x0c, BBRG_RSI }, | |
9001 | + { 0x08, BBRG_RDX }, | |
9002 | + { 0x04, BBRG_RCX }, | |
9003 | + { 0x00, BBRG_RBX }, | |
9004 | +}; | |
9005 | +static const struct bb_mem_contains no_memory[] = { | |
9006 | +}; | |
9007 | +/* Hardware has already pushed an error_code on the stack. Use undefined just | |
9008 | + * to set the initial stack offset. | |
9009 | + */ | |
9010 | +static const struct bb_mem_contains error_code[] = { | |
9011 | + { 0x0, BBRG_UNDEFINED }, | |
9012 | +}; | |
9013 | +/* rbx already pushed */ | |
9014 | +static const struct bb_mem_contains rbx_pushed[] = { | |
9015 | + { 0x0, BBRG_RBX }, | |
9016 | +}; | |
9017 | +#ifdef CONFIG_MATH_EMULATION | |
9018 | +static const struct bb_mem_contains mem_fpu_reg_round[] = { | |
9019 | + { 0xc, BBRG_RBP }, | |
9020 | + { 0x8, BBRG_RSI }, | |
9021 | + { 0x4, BBRG_RDI }, | |
9022 | + { 0x0, BBRG_RBX }, | |
9023 | +}; | |
9024 | +#endif /* CONFIG_MATH_EMULATION */ | |
9025 | + | |
9026 | +static const struct bb_reg_contains all_regs[] = { | |
9027 | + [BBRG_RAX] = { BBRG_RAX, 0 }, | |
9028 | + [BBRG_RBX] = { BBRG_RBX, 0 }, | |
9029 | + [BBRG_RCX] = { BBRG_RCX, 0 }, | |
9030 | + [BBRG_RDX] = { BBRG_RDX, 0 }, | |
9031 | + [BBRG_RDI] = { BBRG_RDI, 0 }, | |
9032 | + [BBRG_RSI] = { BBRG_RSI, 0 }, | |
9033 | + [BBRG_RBP] = { BBRG_RBP, 0 }, | |
9034 | + [BBRG_RSP] = { BBRG_OSP, 0 }, | |
9035 | +}; | |
9036 | +static const struct bb_reg_contains no_regs[] = { | |
9037 | +}; | |
9038 | +#ifdef CONFIG_MATH_EMULATION | |
9039 | +static const struct bb_reg_contains reg_fpu_reg_round[] = { | |
9040 | + [BBRG_RBP] = { BBRG_OSP, -0x4 }, | |
9041 | + [BBRG_RSP] = { BBRG_OSP, -0x10 }, | |
9042 | +}; | |
9043 | +#endif /* CONFIG_MATH_EMULATION */ | |
9044 | + | |
9045 | +static struct bb_name_state bb_special_cases[] = { | |
9046 | + | |
9047 | + /* First the cases that pass data only in memory. We do not check any | |
9048 | + * register state for these cases. | |
9049 | + */ | |
9050 | + | |
9051 | + /* Simple cases, no exceptions */ | |
9052 | + NS_MEM("check_userspace", full_pt_regs, 0), | |
9053 | + NS_MEM("device_not_available_emulate", full_pt_regs, 0), | |
9054 | + NS_MEM("ldt_ss", full_pt_regs, 0), | |
9055 | + NS_MEM("no_singlestep", full_pt_regs, 0), | |
9056 | + NS_MEM("restore_all", full_pt_regs, 0), | |
9057 | + NS_MEM("restore_nocheck", full_pt_regs, 0), | |
9058 | + NS_MEM("restore_nocheck_notrace", full_pt_regs, 0), | |
9059 | + NS_MEM("ret_from_exception", full_pt_regs, 0), | |
9060 | + NS_MEM("ret_from_fork", full_pt_regs, 0), | |
9061 | + NS_MEM("ret_from_intr", full_pt_regs, 0), | |
9062 | + NS_MEM("work_notifysig", full_pt_regs, 0), | |
9063 | + NS_MEM("work_pending", full_pt_regs, 0), | |
9064 | + | |
9065 | +#ifdef CONFIG_PREEMPT | |
9066 | + NS_MEM("resume_kernel", full_pt_regs, 0), | |
9067 | +#endif /* CONFIG_PREEMPT */ | |
9068 | + | |
9069 | + NS_MEM("common_interrupt", error_code, 0), | |
9070 | + NS_MEM("error_code", error_code, 0), | |
9071 | + | |
9072 | + NS_MEM("bad_put_user", rbx_pushed, 0), | |
9073 | + | |
9074 | + NS_MEM_FROM("resume_userspace", "syscall_badsys", | |
9075 | + full_pt_regs, BB_SKIP(RAX)), | |
9076 | + NS_MEM_FROM("resume_userspace", "syscall_fault", | |
9077 | + full_pt_regs, BB_SKIP(RAX)), | |
9078 | + NS_MEM_FROM("resume_userspace", "syscall_trace_entry", | |
9079 | + full_pt_regs, BB_SKIP(RAX)), | |
9080 | + /* Too difficult to trace through the various vm86 functions for now. | |
9081 | + * They are C functions that start off with some memory state, fiddle | |
9082 | + * the registers then jmp directly to resume_userspace. For the | |
9083 | + * moment, just assume that they are valid and do no checks. | |
9084 | + */ | |
9085 | + NS_FROM("resume_userspace", "do_int", | |
9086 | + no_memory, no_regs, 0, 0, 0), | |
9087 | + NS_FROM("resume_userspace", "do_sys_vm86", | |
9088 | + no_memory, no_regs, 0, 0, 0), | |
9089 | + NS_FROM("resume_userspace", "handle_vm86_fault", | |
9090 | + no_memory, no_regs, 0, 0, 0), | |
9091 | + NS_FROM("resume_userspace", "handle_vm86_trap", | |
9092 | + no_memory, no_regs, 0, 0, 0), | |
9093 | + NS_MEM("resume_userspace", full_pt_regs, 0), | |
9094 | + | |
9095 | + NS_MEM_FROM("syscall_badsys", "ia32_sysenter_target", | |
9096 | + full_pt_regs, BB_SKIP(RBP)), | |
9097 | + NS_MEM("syscall_badsys", full_pt_regs, 0), | |
9098 | + | |
9099 | + NS_MEM_FROM("syscall_call", "syscall_trace_entry", | |
9100 | + full_pt_regs, BB_SKIP(RAX)), | |
9101 | + NS_MEM("syscall_call", full_pt_regs, 0), | |
9102 | + | |
9103 | + NS_MEM_FROM("syscall_exit", "syscall_trace_entry", | |
9104 | + full_pt_regs, BB_SKIP(RAX)), | |
9105 | + NS_MEM("syscall_exit", full_pt_regs, 0), | |
9106 | + | |
9107 | + NS_MEM_FROM("syscall_exit_work", "ia32_sysenter_target", | |
9108 | + full_pt_regs, BB_SKIP(RAX) | BB_SKIP(RBP)), | |
9109 | + NS_MEM_FROM("syscall_exit_work", "system_call", | |
9110 | + full_pt_regs, BB_SKIP(RAX)), | |
9111 | + NS_MEM("syscall_exit_work", full_pt_regs, 0), | |
9112 | + | |
9113 | + NS_MEM_FROM("syscall_trace_entry", "ia32_sysenter_target", | |
9114 | + full_pt_regs, BB_SKIP(RBP)), | |
9115 | + NS_MEM_FROM("syscall_trace_entry", "system_call", | |
9116 | + full_pt_regs, BB_SKIP(RAX)), | |
9117 | + NS_MEM("syscall_trace_entry", full_pt_regs, 0), | |
9118 | + | |
9119 | + /* Now the cases that pass data in registers. We do not check any | |
9120 | + * memory state for these cases. | |
9121 | + */ | |
9122 | + | |
9123 | + NS_REG("syscall_fault", all_regs, 0), | |
9124 | + | |
9125 | + NS_REG("bad_get_user", all_regs, | |
9126 | + BB_SKIP(RAX) | BB_SKIP(RDX)), | |
9127 | + | |
9128 | + /* Finally the cases that pass data in both registers and memory. | |
9129 | + */ | |
9130 | + | |
9131 | + /* This entry is redundant now because bb_fixup_switch_to() hides the | |
9132 | + * jmp __switch_to case, however the entry is left here as | |
9133 | + * documentation. | |
9134 | + * | |
9135 | + * NS("__switch_to", no_memory, no_regs, 0, 0, 0), | |
9136 | + */ | |
9137 | + | |
9138 | + NS("iret_exc", no_memory, all_regs, 0, 0, 0x20), | |
9139 | + | |
9140 | +#ifdef CONFIG_MATH_EMULATION | |
9141 | + NS("fpu_reg_round", mem_fpu_reg_round, reg_fpu_reg_round, 0, 0, 0), | |
9142 | +#endif /* CONFIG_MATH_EMULATION */ | |
9143 | +}; | |
9144 | + | |
9145 | +static const char *bb_spurious[] = { | |
9146 | + /* ret_from_exception */ | |
9147 | + "ret_from_intr", | |
9148 | + "check_userspace", | |
9149 | + "resume_userspace", | |
9150 | + /* resume_kernel */ | |
9151 | +#ifdef CONFIG_PREEMPT | |
9152 | + "need_resched", | |
9153 | +#endif /* CONFIG_PREEMPT */ | |
9154 | + /* ia32_sysenter_target */ | |
9155 | + "sysenter_past_esp", | |
9156 | + /* system_call */ | |
9157 | + "no_singlestep", | |
9158 | + "syscall_call", | |
9159 | + "syscall_exit", | |
9160 | + "restore_all", | |
9161 | + "restore_nocheck", | |
9162 | + "restore_nocheck_notrace", | |
9163 | + "ldt_ss", | |
9164 | + /* do not include iret_exc, it is in a .fixup section */ | |
9165 | + /* work_pending */ | |
9166 | + "work_resched", | |
9167 | + "work_notifysig", | |
9168 | +#ifdef CONFIG_VM86 | |
9169 | + "work_notifysig_v86", | |
9170 | +#endif /* CONFIG_VM86 */ | |
9171 | + /* page_fault */ | |
9172 | + "error_code", | |
9173 | + /* device_not_available */ | |
9174 | + "device_not_available_emulate", | |
9175 | + /* debug */ | |
9176 | + "debug_esp_fix_insn", | |
9177 | + "debug_stack_correct", | |
9178 | + /* nmi */ | |
9179 | + "nmi_stack_correct", | |
9180 | + "nmi_stack_fixup", | |
9181 | + "nmi_debug_stack_check", | |
9182 | + "nmi_espfix_stack", | |
9183 | +#ifdef CONFIG_HIBERNATION | |
9184 | + /* restore_image */ | |
9185 | + "copy_loop", | |
9186 | + "done", | |
9187 | +#endif /* CONFIG_HIBERNATION */ | |
9188 | +#ifdef CONFIG_KPROBES | |
9189 | + /* jprobe_return */ | |
9190 | + "jprobe_return_end", | |
9191 | +#endif /* CONFIG_KPROBES */ | |
9192 | +#ifdef CONFIG_KEXEC | |
9193 | + /* relocate_kernel */ | |
9194 | + "relocate_new_kernel", | |
9195 | +#endif /* CONFIG_KEXEC */ | |
9196 | +#ifdef CONFIG_MATH_EMULATION | |
9197 | + /* assorted *.S files in arch/i386/math_emu */ | |
9198 | + "Denorm_done", | |
9199 | + "Denorm_shift_more_than_32", | |
9200 | + "Denorm_shift_more_than_63", | |
9201 | + "Denorm_shift_more_than_64", | |
9202 | + "Do_unmasked_underflow", | |
9203 | + "Exp_not_underflow", | |
9204 | + "fpu_Arith_exit", | |
9205 | + "fpu_reg_round", | |
9206 | + "fpu_reg_round_signed_special_exit", | |
9207 | + "fpu_reg_round_special_exit", | |
9208 | + "L_accum_done", | |
9209 | + "L_accum_loaded", | |
9210 | + "L_accum_loop", | |
9211 | + "L_arg1_larger", | |
9212 | + "L_bugged", | |
9213 | + "L_bugged_1", | |
9214 | + "L_bugged_2", | |
9215 | + "L_bugged_3", | |
9216 | + "L_bugged_4", | |
9217 | + "L_bugged_denorm_486", | |
9218 | + "L_bugged_round24", | |
9219 | + "L_bugged_round53", | |
9220 | + "L_bugged_round64", | |
9221 | + "LCheck_24_round_up", | |
9222 | + "LCheck_53_round_up", | |
9223 | + "LCheck_Round_Overflow", | |
9224 | + "LCheck_truncate_24", | |
9225 | + "LCheck_truncate_53", | |
9226 | + "LCheck_truncate_64", | |
9227 | + "LDenormal_adj_exponent", | |
9228 | + "L_deNormalised", | |
9229 | + "LDo_24_round_up", | |
9230 | + "LDo_2nd_32_bits", | |
9231 | + "LDo_2nd_div", | |
9232 | + "LDo_3rd_32_bits", | |
9233 | + "LDo_3rd_div", | |
9234 | + "LDo_53_round_up", | |
9235 | + "LDo_64_round_up", | |
9236 | + "L_done", | |
9237 | + "LDo_truncate_24", | |
9238 | + "LDown_24", | |
9239 | + "LDown_53", | |
9240 | + "LDown_64", | |
9241 | + "L_entry_bugged", | |
9242 | + "L_error_exit", | |
9243 | + "L_exactly_32", | |
9244 | + "L_exception_exit", | |
9245 | + "L_exit", | |
9246 | + "L_exit_nuo_valid", | |
9247 | + "L_exit_nuo_zero", | |
9248 | + "L_exit_valid", | |
9249 | + "L_extent_zero", | |
9250 | + "LFirst_div_done", | |
9251 | + "LFirst_div_not_1", | |
9252 | + "L_Full_Division", | |
9253 | + "LGreater_Half_24", | |
9254 | + "LGreater_Half_53", | |
9255 | + "LGreater_than_1", | |
9256 | + "LLess_than_1", | |
9257 | + "L_Make_denorm", | |
9258 | + "L_more_31_no_low", | |
9259 | + "L_more_63_no_low", | |
9260 | + "L_more_than_31", | |
9261 | + "L_more_than_63", | |
9262 | + "L_more_than_64", | |
9263 | + "L_more_than_65", | |
9264 | + "L_more_than_95", | |
9265 | + "L_must_be_zero", | |
9266 | + "L_n_exit", | |
9267 | + "L_no_adjust", | |
9268 | + "L_no_bit_lost", | |
9269 | + "L_no_overflow", | |
9270 | + "L_no_precision_loss", | |
9271 | + "L_Normalised", | |
9272 | + "L_norm_bugged", | |
9273 | + "L_n_shift_1", | |
9274 | + "L_nuo_shift_1", | |
9275 | + "L_overflow", | |
9276 | + "L_precision_lost_down", | |
9277 | + "L_precision_lost_up", | |
9278 | + "LPrevent_2nd_overflow", | |
9279 | + "LPrevent_3rd_overflow", | |
9280 | + "LPseudoDenormal", | |
9281 | + "L_Re_normalise", | |
9282 | + "LResult_Normalised", | |
9283 | + "L_round", | |
9284 | + "LRound_large", | |
9285 | + "LRound_nearest_24", | |
9286 | + "LRound_nearest_53", | |
9287 | + "LRound_nearest_64", | |
9288 | + "LRound_not_small", | |
9289 | + "LRound_ovfl", | |
9290 | + "LRound_precision", | |
9291 | + "LRound_prep", | |
9292 | + "L_round_the_result", | |
9293 | + "LRound_To_24", | |
9294 | + "LRound_To_53", | |
9295 | + "LRound_To_64", | |
9296 | + "LSecond_div_done", | |
9297 | + "LSecond_div_not_1", | |
9298 | + "L_shift_1", | |
9299 | + "L_shift_32", | |
9300 | + "L_shift_65_nc", | |
9301 | + "L_shift_done", | |
9302 | + "Ls_less_than_32", | |
9303 | + "Ls_more_than_63", | |
9304 | + "Ls_more_than_95", | |
9305 | + "L_Store_significand", | |
9306 | + "L_subtr", | |
9307 | + "LTest_over", | |
9308 | + "LTruncate_53", | |
9309 | + "LTruncate_64", | |
9310 | + "L_underflow", | |
9311 | + "L_underflow_to_zero", | |
9312 | + "LUp_24", | |
9313 | + "LUp_53", | |
9314 | + "LUp_64", | |
9315 | + "L_zero", | |
9316 | + "Normalise_result", | |
9317 | + "Signal_underflow", | |
9318 | + "sqrt_arg_ge_2", | |
9319 | + "sqrt_get_more_precision", | |
9320 | + "sqrt_more_prec_large", | |
9321 | + "sqrt_more_prec_ok", | |
9322 | + "sqrt_more_prec_small", | |
9323 | + "sqrt_near_exact", | |
9324 | + "sqrt_near_exact_large", | |
9325 | + "sqrt_near_exact_ok", | |
9326 | + "sqrt_near_exact_small", | |
9327 | + "sqrt_near_exact_x", | |
9328 | + "sqrt_prelim_no_adjust", | |
9329 | + "sqrt_round_result", | |
9330 | + "sqrt_stage_2_done", | |
9331 | + "sqrt_stage_2_error", | |
9332 | + "sqrt_stage_2_finish", | |
9333 | + "sqrt_stage_2_positive", | |
9334 | + "sqrt_stage_3_error", | |
9335 | + "sqrt_stage_3_finished", | |
9336 | + "sqrt_stage_3_no_error", | |
9337 | + "sqrt_stage_3_positive", | |
9338 | + "Unmasked_underflow", | |
9339 | + "xExp_not_underflow", | |
9340 | +#endif /* CONFIG_MATH_EMULATION */ | |
9341 | +}; | |
9342 | + | |
9343 | +static const char *bb_hardware_handlers[] = { | |
9344 | + "ret_from_exception", | |
9345 | + "system_call", | |
9346 | + "work_pending", | |
9347 | + "syscall_fault", | |
9348 | + "page_fault", | |
9349 | + "coprocessor_error", | |
9350 | + "simd_coprocessor_error", | |
9351 | + "device_not_available", | |
9352 | + "debug", | |
9353 | + "nmi", | |
9354 | + "int3", | |
9355 | + "overflow", | |
9356 | + "bounds", | |
9357 | + "invalid_op", | |
9358 | + "coprocessor_segment_overrun", | |
9359 | + "invalid_TSS", | |
9360 | + "segment_not_present", | |
9361 | + "stack_segment", | |
9362 | + "general_protection", | |
9363 | + "alignment_check", | |
9364 | + "kdb_call", | |
9365 | + "divide_error", | |
9366 | + "machine_check", | |
9367 | + "spurious_interrupt_bug", | |
9368 | +}; | |
9369 | + | |
9370 | +static int | |
9371 | +bb_hardware_pushed_arch(kdb_machreg_t rsp, | |
9372 | + const struct kdb_activation_record *ar) | |
9373 | +{ | |
9374 | + return (2 * KDB_WORD_SIZE); | |
9375 | +} | |
9376 | + | |
9377 | +static void | |
9378 | +bb_start_block0(void) | |
9379 | +{ | |
9380 | + bb_reg_code_set_value(BBRG_RAX, BBRG_RAX); | |
9381 | + bb_reg_code_set_value(BBRG_RBX, BBRG_RBX); | |
9382 | + bb_reg_code_set_value(BBRG_RCX, BBRG_RCX); | |
9383 | + bb_reg_code_set_value(BBRG_RDX, BBRG_RDX); | |
9384 | + bb_reg_code_set_value(BBRG_RDI, BBRG_RDI); | |
9385 | + bb_reg_code_set_value(BBRG_RSI, BBRG_RSI); | |
9386 | + bb_reg_code_set_value(BBRG_RBP, BBRG_RBP); | |
9387 | + bb_reg_code_set_value(BBRG_RSP, BBRG_OSP); | |
9388 | +} | |
9389 | + | |
9390 | +/* The i386 code that switches stack in a context switch is an extremely | |
9391 | + * special case. It saves the rip pointing to a label that is not otherwise | |
9392 | + * referenced, saves the current rsp then pushes a word. The magic code that | |
9393 | + * resumes the new task picks up the saved rip and rsp, effectively referencing | |
9394 | + * a label that otherwise is not used and ignoring the pushed word. | |
9395 | + * | |
9396 | + * The simplest way to handle this very strange case is to recognise jmp | |
9397 | + * address <__switch_to> and treat it as a popfl instruction. This avoids | |
9398 | + * terminating the block on this jmp and removes one word from the stack state, | |
9399 | + * which is the end effect of all the magic code. | |
9400 | + * | |
9401 | + * Called with the instruction line, starting after the first ':'. | |
9402 | + */ | |
9403 | + | |
9404 | +static void | |
9405 | +bb_fixup_switch_to(char *p) | |
9406 | +{ | |
9407 | + char *p1 = p; | |
9408 | + p += strspn(p, " \t"); /* start of instruction */ | |
9409 | + if (strncmp(p, "jmp", 3)) | |
9410 | + return; | |
9411 | + p += strcspn(p, " \t"); /* end of instruction */ | |
9412 | + p += strspn(p, " \t"); /* start of address */ | |
9413 | + p += strcspn(p, " \t"); /* end of address */ | |
9414 | + p += strspn(p, " \t"); /* start of comment */ | |
9415 | + if (strcmp(p, "<__switch_to>") == 0) | |
9416 | + strcpy(p1, "popfl"); | |
9417 | +} | |
9418 | + | |
9419 | +static int | |
9420 | +bb_asmlinkage_arch(void) | |
9421 | +{ | |
9422 | + return strcmp(bb_func_name, "ret_from_exception") == 0 || | |
9423 | + strcmp(bb_func_name, "syscall_trace_entry") == 0; | |
9424 | +} | |
9425 | + | |
9426 | +#endif /* CONFIG_X86_64 */ | |
9427 | + | |
9428 | + | |
9429 | +/*============================================================================*/ | |
9430 | +/* */ | |
9431 | +/* Common code and data. */ | |
9432 | +/* */ | |
9433 | +/*============================================================================*/ | |
9434 | + | |
9435 | + | |
9436 | +/* Tracking registers by decoding the instructions is quite a bit harder than | |
9437 | + * doing the same tracking using compiler generated information. Register | |
9438 | + * contents can remain in the same register, they can be copied to other | |
9439 | + * registers, they can be stored on stack or they can be modified/overwritten. | |
9440 | + * At any one time, there are 0 or more copies of the original value that was | |
9441 | + * supplied in each register on input to the current function. If a register | |
9442 | + * exists in multiple places, one copy of that register is the master version, | |
9443 | + * the others are temporary copies which may or may not be destroyed before the | |
9444 | + * end of the function. | |
9445 | + * | |
9446 | + * The compiler knows which copy of a register is the master and which are | |
9447 | + * temporary copies, which makes it relatively easy to track register contents | |
9448 | + * as they are saved and restored. Without that compiler based knowledge, this | |
9449 | + * code has to track _every_ possible copy of each register, simply because we | |
9450 | + * do not know which is the master copy and which are temporary copies which | |
9451 | + * may be destroyed later. | |
9452 | + * | |
9453 | + * It gets worse: registers that contain parameters can be copied to other | |
9454 | + * registers which are then saved on stack in a lower level function. Also the | |
9455 | + * stack pointer may be held in multiple registers (typically RSP and RBP) | |
9456 | + * which contain different offsets from the base of the stack on entry to this | |
9457 | + * function. All of which means that we have to track _all_ register | |
9458 | + * movements, or at least as much as possible. | |
9459 | + * | |
9460 | + * Start with the basic block that contains the start of the function, by | |
9461 | + * definition all registers contain their initial value. Track each | |
9462 | + * instruction's effect on register contents, this includes reading from a | |
9463 | + * parameter register before any write to that register, IOW the register | |
9464 | + * really does contain a parameter. The register state is represented by a | |
9465 | + * dynamically sized array with each entry containing :- | |
9466 | + * | |
9467 | + * Register name | |
9468 | + * Location it is copied to (another register or stack + offset) | |
9469 | + * | |
9470 | + * Besides the register tracking array, we track which parameter registers are | |
9471 | + * read before being written, to determine how many parameters are passed in | |
9472 | + * registers. We also track which registers contain stack pointers, including | |
9473 | + * their offset from the original stack pointer on entry to the function. | |
9474 | + * | |
9475 | + * At each exit from the current basic block (via JMP instruction or drop | |
9476 | + * through), the register state is cloned to form the state on input to the | |
9477 | + * target basic block and the target is marked for processing using this state. | |
9478 | + * When there are multiple ways to enter a basic block (e.g. several JMP | |
9479 | + * instructions referencing the same target) then there will be multiple sets | |
9480 | + * of register state to form the "input" for that basic block, there is no | |
9481 | + * guarantee that all paths to that block will have the same register state. | |
9482 | + * | |
9483 | + * As each target block is processed, all the known sets of register state are | |
9484 | + * merged to form a suitable subset of the state which agrees with all the | |
9485 | + * inputs. The most common case is where one path to this block copies a | |
9486 | + * register to another register but another path does not, therefore the copy | |
9487 | + * is only a temporary and should not be propogated into this block. | |
9488 | + * | |
9489 | + * If the target block already has an input state from the current transfer | |
9490 | + * point and the new input state is identical to the previous input state then | |
9491 | + * we have reached a steady state for the arc from the current location to the | |
9492 | + * target block. Therefore there is no need to process the target block again. | |
9493 | + * | |
9494 | + * The steps of "process a block, create state for target block(s), pick a new | |
9495 | + * target block, merge state for target block, process target block" will | |
9496 | + * continue until all the state changes have propogated all the way down the | |
9497 | + * basic block tree, including round any cycles in the tree. The merge step | |
9498 | + * only deletes tracking entries from the input state(s), it never adds a | |
9499 | + * tracking entry. Therefore the overall algorithm is guaranteed to converge | |
9500 | + * to a steady state, the worst possible case is that every tracking entry into | |
9501 | + * a block is deleted, which will result in an empty output state. | |
9502 | + * | |
9503 | + * As each instruction is decoded, it is checked to see if this is the point at | |
9504 | + * which execution left this function. This can be a call to another function | |
9505 | + * (actually the return address to this function) or is the instruction which | |
9506 | + * was about to be executed when an interrupt occurred (including an oops). | |
9507 | + * Save the register state at this point. | |
9508 | + * | |
9509 | + * We always know what the registers contain when execution left this function. | |
9510 | + * For an interrupt, the registers are in struct pt_regs. For a call to | |
9511 | + * another function, we have already deduced the register state on entry to the | |
9512 | + * other function by unwinding to the start of that function. Given the | |
9513 | + * register state on exit from this function plus the known register contents | |
9514 | + * on entry to the next function, we can determine the stack pointer value on | |
9515 | + * input to this function. That in turn lets us calculate the address of input | |
9516 | + * registers that have been stored on stack, giving us the input parameters. | |
9517 | + * Finally the stack pointer gives us the return address which is the exit | |
9518 | + * point from the calling function, repeat the unwind process on that function. | |
9519 | + * | |
9520 | + * The data that tracks which registers contain input parameters is function | |
9521 | + * global, not local to any basic block. To determine which input registers | |
9522 | + * contain parameters, we have to decode the entire function. Otherwise an | |
9523 | + * exit early in the function might not have read any parameters yet. | |
9524 | + */ | |
9525 | + | |
9526 | +/* Record memory contents in terms of the values that were passed to this | |
9527 | + * function, IOW track which memory locations contain an input value. A memory | |
9528 | + * location's contents can be undefined, it can contain an input register value | |
9529 | + * or it can contain an offset from the original stack pointer. | |
9530 | + * | |
9531 | + * This structure is used to record register contents that have been stored in | |
9532 | + * memory. Location (BBRG_OSP + 'offset_address') contains the input value | |
9533 | + * from register 'value'. When 'value' is BBRG_OSP then offset_value contains | |
9534 | + * the offset from the original stack pointer that was stored in this memory | |
9535 | + * location. When 'value' is not BBRG_OSP then the memory location contains | |
9536 | + * the original contents of an input register and offset_value is ignored. | |
9537 | + * | |
9538 | + * An input register 'value' can be stored in more than one register and/or in | |
9539 | + * more than one memory location. | |
9540 | + */ | |
9541 | + | |
9542 | +struct bb_memory_contains | |
9543 | +{ | |
9544 | + short offset_address; | |
9545 | + enum bb_reg_code value: 8; | |
9546 | + short offset_value; | |
9547 | +}; | |
9548 | + | |
9549 | +/* Track the register state in each basic block. */ | |
9550 | + | |
9551 | +struct bb_reg_state | |
9552 | +{ | |
9553 | + /* Indexed by register value 'reg - BBRG_RAX' */ | |
9554 | + struct bb_reg_contains contains[KDB_INT_REGISTERS]; | |
9555 | + int ref_count; | |
9556 | + int mem_count; | |
9557 | + /* dynamic size for memory locations, see mem_count */ | |
9558 | + struct bb_memory_contains memory[0]; | |
9559 | +}; | |
9560 | + | |
9561 | +static struct bb_reg_state *bb_reg_state, *bb_exit_state; | |
9562 | +static int bb_reg_state_max, bb_reg_params, bb_memory_params; | |
9563 | + | |
9564 | +struct bb_actual | |
9565 | +{ | |
9566 | + bfd_vma value; | |
9567 | + int valid; | |
9568 | +}; | |
9569 | + | |
9570 | +/* Contains the actual hex value of a register, plus a valid bit. Indexed by | |
9571 | + * register value 'reg - BBRG_RAX' | |
9572 | + */ | |
9573 | +static struct bb_actual bb_actual[KDB_INT_REGISTERS]; | |
9574 | + | |
9575 | +static bfd_vma bb_func_start, bb_func_end; | |
9576 | +static bfd_vma bb_common_interrupt, bb_error_entry, bb_ret_from_intr, | |
9577 | + bb_thread_return, bb_sync_regs, bb_save_v86_state, | |
9578 | + bb__sched_text_start, bb__sched_text_end; | |
9579 | + | |
9580 | +/* Record jmp instructions, both conditional and unconditional. These form the | |
9581 | + * arcs between the basic blocks. This is also used to record the state when | |
9582 | + * one block drops through into the next. | |
9583 | + * | |
9584 | + * A bb can have multiple associated bb_jmp entries, one for each jcc | |
9585 | + * instruction plus at most one bb_jmp for the drop through case. If a bb | |
9586 | + * drops through to the next bb then the drop through bb_jmp entry will be the | |
9587 | + * last entry in the set of bb_jmp's that are associated with the bb. This is | |
9588 | + * enforced by the fact that jcc entries are added during the disassembly phase | |
9589 | + * of pass 1, the drop through entries are added near the end of pass 1. | |
9590 | + * | |
9591 | + * At address 'from' in this block, we have a jump to address 'to'. The | |
9592 | + * register state at 'from' is copied to the target block. | |
9593 | + */ | |
9594 | + | |
9595 | +struct bb_jmp | |
9596 | +{ | |
9597 | + bfd_vma from; | |
9598 | + bfd_vma to; | |
9599 | + struct bb_reg_state *state; | |
9600 | + unsigned int drop_through: 1; | |
9601 | +}; | |
9602 | + | |
9603 | +struct bb | |
9604 | +{ | |
9605 | + bfd_vma start; | |
9606 | + /* The end address of a basic block is sloppy. It can be the first | |
9607 | + * byte of the last instruction in the block or it can be the last byte | |
9608 | + * of the block. | |
9609 | + */ | |
9610 | + bfd_vma end; | |
9611 | + unsigned int changed: 1; | |
9612 | + unsigned int drop_through: 1; | |
9613 | +}; | |
9614 | + | |
9615 | +static struct bb **bb_list, *bb_curr; | |
9616 | +static int bb_max, bb_count; | |
9617 | + | |
9618 | +static struct bb_jmp *bb_jmp_list; | |
9619 | +static int bb_jmp_max, bb_jmp_count; | |
9620 | + | |
9621 | +/* Add a new bb entry to the list. This does an insert sort. */ | |
9622 | + | |
9623 | +static struct bb * | |
9624 | +bb_new(bfd_vma order) | |
9625 | +{ | |
9626 | + int i, j; | |
9627 | + struct bb *bb, *p; | |
9628 | + if (bb_giveup) | |
9629 | + return NULL; | |
9630 | + if (bb_count == bb_max) { | |
9631 | + struct bb **bb_list_new; | |
9632 | + bb_max += 10; | |
9633 | + bb_list_new = debug_kmalloc(bb_max*sizeof(*bb_list_new), | |
9634 | + GFP_ATOMIC); | |
9635 | + if (!bb_list_new) { | |
9636 | + kdb_printf("\n\n%s: out of debug_kmalloc\n", __FUNCTION__); | |
9637 | + bb_giveup = 1; | |
9638 | + return NULL; | |
9639 | + } | |
9640 | + memcpy(bb_list_new, bb_list, bb_count*sizeof(*bb_list)); | |
9641 | + debug_kfree(bb_list); | |
9642 | + bb_list = bb_list_new; | |
9643 | + } | |
9644 | + bb = debug_kmalloc(sizeof(*bb), GFP_ATOMIC); | |
9645 | + if (!bb) { | |
9646 | + kdb_printf("\n\n%s: out of debug_kmalloc\n", __FUNCTION__); | |
9647 | + bb_giveup = 1; | |
9648 | + return NULL; | |
9649 | + } | |
9650 | + memset(bb, 0, sizeof(*bb)); | |
9651 | + for (i = 0; i < bb_count; ++i) { | |
9652 | + p = bb_list[i]; | |
9653 | + if ((p->start && p->start > order) || | |
9654 | + (p->end && p->end > order)) | |
9655 | + break; | |
9656 | + } | |
9657 | + for (j = bb_count-1; j >= i; --j) | |
9658 | + bb_list[j+1] = bb_list[j]; | |
9659 | + bb_list[i] = bb; | |
9660 | + ++bb_count; | |
9661 | + return bb; | |
9662 | +} | |
9663 | + | |
9664 | +/* Add a new bb_jmp entry to the list. This list is not sorted. */ | |
9665 | + | |
9666 | +static struct bb_jmp * | |
9667 | +bb_jmp_new(bfd_vma from, bfd_vma to, unsigned int drop_through) | |
9668 | +{ | |
9669 | + struct bb_jmp *bb_jmp; | |
9670 | + if (bb_giveup) | |
9671 | + return NULL; | |
9672 | + if (bb_jmp_count == bb_jmp_max) { | |
9673 | + struct bb_jmp *bb_jmp_list_new; | |
9674 | + bb_jmp_max += 10; | |
9675 | + bb_jmp_list_new = | |
9676 | + debug_kmalloc(bb_jmp_max*sizeof(*bb_jmp_list_new), | |
9677 | + GFP_ATOMIC); | |
9678 | + if (!bb_jmp_list_new) { | |
9679 | + kdb_printf("\n\n%s: out of debug_kmalloc\n", | |
9680 | + __FUNCTION__); | |
9681 | + bb_giveup = 1; | |
9682 | + return NULL; | |
9683 | + } | |
9684 | + memcpy(bb_jmp_list_new, bb_jmp_list, | |
9685 | + bb_jmp_count*sizeof(*bb_jmp_list)); | |
9686 | + debug_kfree(bb_jmp_list); | |
9687 | + bb_jmp_list = bb_jmp_list_new; | |
9688 | + } | |
9689 | + bb_jmp = bb_jmp_list + bb_jmp_count++; | |
9690 | + bb_jmp->from = from; | |
9691 | + bb_jmp->to = to; | |
9692 | + bb_jmp->drop_through = drop_through; | |
9693 | + bb_jmp->state = NULL; | |
9694 | + return bb_jmp; | |
9695 | +} | |
9696 | + | |
9697 | +static void | |
9698 | +bb_delete(int i) | |
9699 | +{ | |
9700 | + struct bb *bb = bb_list[i]; | |
9701 | + memcpy(bb_list+i, bb_list+i+1, (bb_count-i-1)*sizeof(*bb_list)); | |
9702 | + bb_list[--bb_count] = NULL; | |
9703 | + debug_kfree(bb); | |
9704 | +} | |
9705 | + | |
9706 | +static struct bb * | |
9707 | +bb_add(bfd_vma start, bfd_vma end) | |
9708 | +{ | |
9709 | + int i; | |
9710 | + struct bb *bb; | |
9711 | + /* Ignore basic blocks whose start address is outside the current | |
9712 | + * function. These occur for call instructions and for tail recursion. | |
9713 | + */ | |
9714 | + if (start && | |
9715 | + (start < bb_func_start || start >= bb_func_end)) | |
9716 | + return NULL; | |
9717 | + for (i = 0; i < bb_count; ++i) { | |
9718 | + bb = bb_list[i]; | |
9719 | + if ((start && bb->start == start) || | |
9720 | + (end && bb->end == end)) | |
9721 | + return bb; | |
9722 | + } | |
9723 | + bb = bb_new(start ? start : end); | |
9724 | + if (bb) { | |
9725 | + bb->start = start; | |
9726 | + bb->end = end; | |
9727 | + } | |
9728 | + return bb; | |
9729 | +} | |
9730 | + | |
9731 | +static struct bb_jmp * | |
9732 | +bb_jmp_add(bfd_vma from, bfd_vma to, unsigned int drop_through) | |
9733 | +{ | |
9734 | + int i; | |
9735 | + struct bb_jmp *bb_jmp; | |
9736 | + for (i = 0, bb_jmp = bb_jmp_list; i < bb_jmp_count; ++i, ++bb_jmp) { | |
9737 | + if (bb_jmp->from == from && | |
9738 | + bb_jmp->to == to && | |
9739 | + bb_jmp->drop_through == drop_through) | |
9740 | + return bb_jmp; | |
9741 | + } | |
9742 | + bb_jmp = bb_jmp_new(from, to, drop_through); | |
9743 | + return bb_jmp; | |
9744 | +} | |
9745 | + | |
9746 | +static unsigned long bb_curr_addr, bb_exit_addr; | |
9747 | +static char bb_buffer[256]; /* A bit too big to go on stack */ | |
9748 | + | |
9749 | +/* Computed jmp uses 'jmp *addr(,%reg,[48])' where 'addr' is the start of a | |
9750 | + * table of addresses that point into the current function. Run the table and | |
9751 | + * generate bb starts for each target address plus a bb_jmp from this address | |
9752 | + * to the target address. | |
9753 | + * | |
9754 | + * Only called for 'jmp' instructions, with the pointer starting at 'jmp'. | |
9755 | + */ | |
9756 | + | |
9757 | +static void | |
9758 | +bb_pass1_computed_jmp(char *p) | |
9759 | +{ | |
9760 | + unsigned long table, scale; | |
9761 | + kdb_machreg_t addr; | |
9762 | + struct bb* bb; | |
9763 | + p += strcspn(p, " \t"); /* end of instruction */ | |
9764 | + p += strspn(p, " \t"); /* start of address */ | |
9765 | + if (*p++ != '*') | |
9766 | + return; | |
9767 | + table = simple_strtoul(p, &p, 0); | |
9768 | + if (strncmp(p, "(,%", 3) != 0) | |
9769 | + return; | |
9770 | + p += 3; | |
9771 | + p += strcspn(p, ","); /* end of reg */ | |
9772 | + if (*p++ != ',') | |
9773 | + return; | |
9774 | + scale = simple_strtoul(p, &p, 0); | |
9775 | + if (scale != KDB_WORD_SIZE || strcmp(p, ")")) | |
9776 | + return; | |
9777 | + while (!bb_giveup) { | |
9778 | + if (kdb_getword(&addr, table, sizeof(addr))) | |
9779 | + return; | |
9780 | + if (addr < bb_func_start || addr >= bb_func_end) | |
9781 | + return; | |
9782 | + bb = bb_add(addr, 0); | |
9783 | + if (bb) | |
9784 | + bb_jmp_add(bb_curr_addr, addr, 0); | |
9785 | + table += KDB_WORD_SIZE; | |
9786 | + } | |
9787 | +} | |
9788 | + | |
9789 | +/* Pass 1, identify the start and end of each basic block */ | |
9790 | + | |
9791 | +static int | |
9792 | +bb_dis_pass1(PTR file, const char *fmt, ...) | |
9793 | +{ | |
9794 | + int l = strlen(bb_buffer); | |
9795 | + char *p; | |
9796 | + va_list ap; | |
9797 | + va_start(ap, fmt); | |
9798 | + vsnprintf(bb_buffer + l, sizeof(bb_buffer) - l, fmt, ap); | |
9799 | + va_end(ap); | |
9800 | + if ((p = strchr(bb_buffer, '\n'))) { | |
9801 | + *p = '\0'; | |
9802 | + /* ret[q], iret[q], sysexit, sysret, ud2a or jmp[q] end a | |
9803 | + * block. As does a call to a function marked noret. | |
9804 | + */ | |
9805 | + p = bb_buffer; | |
9806 | + p += strcspn(p, ":"); | |
9807 | + if (*p++ == ':') { | |
9808 | + bb_fixup_switch_to(p); | |
9809 | + p += strspn(p, " \t"); /* start of instruction */ | |
9810 | + if (strncmp(p, "ret", 3) == 0 || | |
9811 | + strncmp(p, "iret", 4) == 0 || | |
9812 | + strncmp(p, "sysexit", 7) == 0 || | |
9813 | + strncmp(p, "sysret", 6) == 0 || | |
9814 | + strncmp(p, "ud2a", 4) == 0 || | |
9815 | + strncmp(p, "jmp", 3) == 0) { | |
9816 | + if (strncmp(p, "jmp", 3) == 0) | |
9817 | + bb_pass1_computed_jmp(p); | |
9818 | + bb_add(0, bb_curr_addr); | |
9819 | + }; | |
9820 | + if (strncmp(p, "call", 4) == 0) { | |
9821 | + strsep(&p, " \t"); /* end of opcode */ | |
9822 | + if (p) | |
9823 | + p += strspn(p, " \t"); /* operand(s) */ | |
9824 | + if (p && strchr(p, '<')) { | |
9825 | + p = strchr(p, '<') + 1; | |
9826 | + *strchr(p, '>') = '\0'; | |
9827 | + if (bb_noret(p)) | |
9828 | + bb_add(0, bb_curr_addr); | |
9829 | + } | |
9830 | + }; | |
9831 | + } | |
9832 | + bb_buffer[0] = '\0'; | |
9833 | + } | |
9834 | + return 0; | |
9835 | +} | |
9836 | + | |
9837 | +static void | |
9838 | +bb_printaddr_pass1(bfd_vma addr, disassemble_info *dip) | |
9839 | +{ | |
9840 | + kdb_symtab_t symtab; | |
9841 | + unsigned int offset; | |
9842 | + struct bb* bb; | |
9843 | + /* disasm only calls the printaddr routine for the target of jmp, loop | |
9844 | + * or call instructions, i.e. the start of a basic block. call is | |
9845 | + * ignored by bb_add because the target address is outside the current | |
9846 | + * function. | |
9847 | + */ | |
9848 | + dip->fprintf_func(dip->stream, "0x%lx", addr); | |
9849 | + kdbnearsym(addr, &symtab); | |
9850 | + if (symtab.sym_name) { | |
9851 | + dip->fprintf_func(dip->stream, " <%s", symtab.sym_name); | |
9852 | + if ((offset = addr - symtab.sym_start)) | |
9853 | + dip->fprintf_func(dip->stream, "+0x%x", offset); | |
9854 | + dip->fprintf_func(dip->stream, ">"); | |
9855 | + } | |
9856 | + bb = bb_add(addr, 0); | |
9857 | + if (bb) | |
9858 | + bb_jmp_add(bb_curr_addr, addr, 0); | |
9859 | +} | |
9860 | + | |
9861 | +static void | |
9862 | +bb_pass1(void) | |
9863 | +{ | |
9864 | + int i; | |
9865 | + unsigned long addr; | |
9866 | + struct bb *bb; | |
9867 | + struct bb_jmp *bb_jmp; | |
9868 | + | |
9869 | + if (KDB_DEBUG(BB) | KDB_DEBUG(BB_SUMM)) | |
9870 | + kdb_printf("%s: func_name %s func_start " kdb_bfd_vma_fmt0 | |
9871 | + " func_end " kdb_bfd_vma_fmt0 "\n", | |
9872 | + __FUNCTION__, | |
9873 | + bb_func_name, | |
9874 | + bb_func_start, | |
9875 | + bb_func_end); | |
9876 | + kdb_di.fprintf_func = bb_dis_pass1; | |
9877 | + kdb_di.print_address_func = bb_printaddr_pass1; | |
9878 | + | |
9879 | + bb_add(bb_func_start, 0); | |
9880 | + for (bb_curr_addr = bb_func_start; | |
9881 | + bb_curr_addr < bb_func_end; | |
9882 | + ++bb_curr_addr) { | |
9883 | + unsigned char c; | |
9884 | + if (kdb_getarea(c, bb_curr_addr)) { | |
9885 | + kdb_printf("%s: unreadable function code at ", | |
9886 | + __FUNCTION__); | |
9887 | + kdb_symbol_print(bb_curr_addr, NULL, KDB_SP_DEFAULT); | |
9888 | + kdb_printf(", giving up\n"); | |
9889 | + bb_giveup = 1; | |
9890 | + return; | |
9891 | + } | |
9892 | + } | |
9893 | + for (addr = bb_func_start; addr < bb_func_end; ) { | |
9894 | + bb_curr_addr = addr; | |
9895 | + addr += kdba_id_printinsn(addr, &kdb_di); | |
9896 | + kdb_di.fprintf_func(NULL, "\n"); | |
9897 | + } | |
9898 | + if (bb_giveup) | |
9899 | + goto out; | |
9900 | + | |
9901 | + /* Special case: a block consisting of a single instruction which is | |
9902 | + * both the target of a jmp and is also an ending instruction, so we | |
9903 | + * add two blocks using the same address, one as a start and one as an | |
9904 | + * end, in no guaranteed order. The end must be ordered after the | |
9905 | + * start. | |
9906 | + */ | |
9907 | + for (i = 0; i < bb_count-1; ++i) { | |
9908 | + struct bb *bb1 = bb_list[i], *bb2 = bb_list[i+1]; | |
9909 | + if (bb1->end && bb1->end == bb2->start) { | |
9910 | + bb = bb_list[i+1]; | |
9911 | + bb_list[i+1] = bb_list[i]; | |
9912 | + bb_list[i] = bb; | |
9913 | + } | |
9914 | + } | |
9915 | + | |
9916 | + /* Some bb have a start address, some have an end address. Collapse | |
9917 | + * them into entries that have both start and end addresses. The first | |
9918 | + * entry is guaranteed to have a start address. | |
9919 | + */ | |
9920 | + for (i = 0; i < bb_count-1; ++i) { | |
9921 | + struct bb *bb1 = bb_list[i], *bb2 = bb_list[i+1]; | |
9922 | + if (bb1->end) | |
9923 | + continue; | |
9924 | + if (bb2->start) { | |
9925 | + bb1->end = bb2->start - 1; | |
9926 | + bb1->drop_through = 1; | |
9927 | + bb_jmp_add(bb1->end, bb2->start, 1); | |
9928 | + } else { | |
9929 | + bb1->end = bb2->end; | |
9930 | + bb_delete(i+1); | |
9931 | + } | |
9932 | + } | |
9933 | + bb = bb_list[bb_count-1]; | |
9934 | + if (!bb->end) | |
9935 | + bb->end = bb_func_end - 1; | |
9936 | + | |
9937 | + /* It would be nice to check that all bb have a valid start and end | |
9938 | + * address but there is just too much garbage code in the kernel to do | |
9939 | + * that check. Aligned functions in assembler code mean that there is | |
9940 | + * space between the end of one function and the start of the next and | |
9941 | + * that space contains previous code from the assembler's buffers. It | |
9942 | + * looks like dead code with nothing that branches to it, so no start | |
9943 | + * address. do_sys_vm86() ends with 'jmp resume_userspace' which the C | |
9944 | + * compiler does not know about so gcc appends the normal exit code, | |
9945 | + * again nothing branches to this dangling code. | |
9946 | + * | |
9947 | + * The best we can do is delete bb entries with no start address. | |
9948 | + */ | |
9949 | + for (i = 0; i < bb_count; ++i) { | |
9950 | + struct bb *bb = bb_list[i]; | |
9951 | + if (!bb->start) | |
9952 | + bb_delete(i--); | |
9953 | + } | |
9954 | + for (i = 0; i < bb_count; ++i) { | |
9955 | + struct bb *bb = bb_list[i]; | |
9956 | + if (!bb->end) { | |
9957 | + kdb_printf("%s: incomplete bb state\n", __FUNCTION__); | |
9958 | + bb_giveup = 1; | |
9959 | + goto debug; | |
9960 | + } | |
9961 | + } | |
9962 | + | |
9963 | +out: | |
9964 | + if (!KDB_DEBUG(BB)) | |
9965 | + return; | |
9966 | +debug: | |
9967 | + kdb_printf("%s: end\n", __FUNCTION__); | |
9968 | + for (i = 0; i < bb_count; ++i) { | |
9969 | + bb = bb_list[i]; | |
9970 | + kdb_printf(" bb[%d] start " | |
9971 | + kdb_bfd_vma_fmt0 | |
9972 | + " end " kdb_bfd_vma_fmt0 | |
9973 | + " drop_through %d", | |
9974 | + i, bb->start, bb->end, bb->drop_through); | |
9975 | + kdb_printf("\n"); | |
9976 | + } | |
9977 | + for (i = 0; i < bb_jmp_count; ++i) { | |
9978 | + bb_jmp = bb_jmp_list + i; | |
9979 | + kdb_printf(" bb_jmp[%d] from " | |
9980 | + kdb_bfd_vma_fmt0 | |
9981 | + " to " kdb_bfd_vma_fmt0 | |
9982 | + " drop_through %d\n", | |
9983 | + i, bb_jmp->from, bb_jmp->to, bb_jmp->drop_through); | |
9984 | + } | |
9985 | +} | |
9986 | + | |
9987 | +/* Pass 2, record register changes in each basic block */ | |
9988 | + | |
9989 | +/* For each opcode that we care about, indicate how it uses its operands. Most | |
9990 | + * opcodes can be handled generically because they completely specify their | |
9991 | + * operands in the instruction, however many opcodes have side effects such as | |
9992 | + * reading or writing rax or updating rsp. Instructions that change registers | |
9993 | + * that are not listed in the operands must be handled as special cases. In | |
9994 | + * addition, instructions that copy registers while preserving their contents | |
9995 | + * (push, pop, mov) or change the contents in a well defined way (add with an | |
9996 | + * immediate, lea) must be handled as special cases in order to track the | |
9997 | + * register contents. | |
9998 | + * | |
9999 | + * The tables below only list opcodes that are actually used in the Linux | |
10000 | + * kernel, so they omit most of the floating point and all of the SSE type | |
10001 | + * instructions. The operand usage entries only cater for accesses to memory | |
10002 | + * and to the integer registers, accesses to floating point registers and flags | |
10003 | + * are not relevant for kernel backtraces. | |
10004 | + */ | |
10005 | + | |
10006 | +enum bb_operand_usage { | |
10007 | + BBOU_UNKNOWN = 0, | |
10008 | + /* generic entries. because xchg can do any combinations of | |
10009 | + * read src, write src, read dst and write dst we need to | |
10010 | + * define all 16 possibilities. These are ordered by rs = 1, | |
10011 | + * rd = 2, ws = 4, wd = 8, bb_usage_x*() functions rely on this | |
10012 | + * order. | |
10013 | + */ | |
10014 | + BBOU_RS = 1, /* read src */ /* 1 */ | |
10015 | + BBOU_RD, /* read dst */ /* 2 */ | |
10016 | + BBOU_RSRD, /* 3 */ | |
10017 | + BBOU_WS, /* write src */ /* 4 */ | |
10018 | + BBOU_RSWS, /* 5 */ | |
10019 | + BBOU_RDWS, /* 6 */ | |
10020 | + BBOU_RSRDWS, /* 7 */ | |
10021 | + BBOU_WD, /* write dst */ /* 8 */ | |
10022 | + BBOU_RSWD, /* 9 */ | |
10023 | + BBOU_RDWD, /* 10 */ | |
10024 | + BBOU_RSRDWD, /* 11 */ | |
10025 | + BBOU_WSWD, /* 12 */ | |
10026 | + BBOU_RSWSWD, /* 13 */ | |
10027 | + BBOU_RDWSWD, /* 14 */ | |
10028 | + BBOU_RSRDWSWD, /* 15 */ | |
10029 | + /* opcode specific entries */ | |
10030 | + BBOU_ADD, | |
10031 | + BBOU_CALL, | |
10032 | + BBOU_CBW, | |
10033 | + BBOU_CMOV, | |
10034 | + BBOU_CMPXCHG, | |
10035 | + BBOU_CMPXCHGD, | |
10036 | + BBOU_CPUID, | |
10037 | + BBOU_CWD, | |
10038 | + BBOU_DIV, | |
10039 | + BBOU_IDIV, | |
10040 | + BBOU_IMUL, | |
10041 | + BBOU_IRET, | |
10042 | + BBOU_JMP, | |
10043 | + BBOU_LAHF, | |
10044 | + BBOU_LEA, | |
10045 | + BBOU_LEAVE, | |
10046 | + BBOU_LODS, | |
10047 | + BBOU_LOOP, | |
10048 | + BBOU_LSS, | |
10049 | + BBOU_MONITOR, | |
10050 | + BBOU_MOV, | |
10051 | + BBOU_MOVS, | |
10052 | + BBOU_MUL, | |
10053 | + BBOU_MWAIT, | |
10054 | + BBOU_NOP, | |
10055 | + BBOU_OUTS, | |
10056 | + BBOU_POP, | |
10057 | + BBOU_POPF, | |
10058 | + BBOU_PUSH, | |
10059 | + BBOU_PUSHF, | |
10060 | + BBOU_RDMSR, | |
10061 | + BBOU_RDTSC, | |
10062 | + BBOU_RET, | |
10063 | + BBOU_SAHF, | |
10064 | + BBOU_SCAS, | |
10065 | + BBOU_SUB, | |
10066 | + BBOU_SYSEXIT, | |
10067 | + BBOU_SYSRET, | |
10068 | + BBOU_WRMSR, | |
10069 | + BBOU_XADD, | |
10070 | + BBOU_XCHG, | |
10071 | + BBOU_XOR, | |
10072 | +}; | |
10073 | + | |
10074 | +struct bb_opcode_usage { | |
10075 | + int length; | |
10076 | + enum bb_operand_usage usage; | |
10077 | + const char *opcode; | |
10078 | +}; | |
10079 | + | |
10080 | +/* This table is sorted in alphabetical order of opcode, except that the | |
10081 | + * trailing '"' is treated as a high value. For example, 'in' sorts after | |
10082 | + * 'inc', 'bt' after 'btc'. This modified sort order ensures that shorter | |
10083 | + * opcodes come after long ones. A normal sort would put 'in' first, so 'in' | |
10084 | + * would match both 'inc' and 'in'. When adding any new entries to this table, | |
10085 | + * be careful to put shorter entries last in their group. | |
10086 | + * | |
10087 | + * To automatically sort the table (in vi) | |
10088 | + * Mark the first and last opcode line with 'a and 'b | |
10089 | + * 'a | |
10090 | + * !'bsed -e 's/"}/}}/' | LANG=C sort -t '"' -k2 | sed -e 's/}}/"}/' | |
10091 | + * | |
10092 | + * If a new instruction has to be added, first consider if it affects registers | |
10093 | + * other than those listed in the operands. Also consider if you want to track | |
10094 | + * the results of issuing the instruction, IOW can you extract useful | |
10095 | + * information by looking in detail at the modified registers or memory. If | |
10096 | + * either test is true then you need a special case to handle the instruction. | |
10097 | + * | |
10098 | + * The generic entries at the start of enum bb_operand_usage all have one thing | |
10099 | + * in common, if a register or memory location is updated then that location | |
10100 | + * becomes undefined, i.e. we lose track of anything that was previously saved | |
10101 | + * in that location. So only use a generic BBOU_* value when the result of the | |
10102 | + * instruction cannot be calculated exactly _and_ when all the affected | |
10103 | + * registers are listed in the operands. | |
10104 | + * | |
10105 | + * Examples: | |
10106 | + * | |
10107 | + * 'call' does not generate a known result, but as a side effect of call, | |
10108 | + * several scratch registers become undefined, so it needs a special BBOU_CALL | |
10109 | + * entry. | |
10110 | + * | |
10111 | + * 'adc' generates a variable result, it depends on the carry flag, so 'adc' | |
10112 | + * gets a generic entry. 'add' can generate an exact result (add with | |
10113 | + * immediate on a register that points to the stack) or it can generate an | |
10114 | + * unknown result (add a variable, or add immediate to a register that does not | |
10115 | + * contain a stack pointer) so 'add' has its own BBOU_ADD entry. | |
10116 | + */ | |
10117 | + | |
10118 | +static const struct bb_opcode_usage | |
10119 | +bb_opcode_usage_all[] = { | |
10120 | + {3, BBOU_RSRDWD, "adc"}, | |
10121 | + {3, BBOU_ADD, "add"}, | |
10122 | + {3, BBOU_RSRDWD, "and"}, | |
10123 | + {3, BBOU_RSWD, "bsf"}, | |
10124 | + {3, BBOU_RSWD, "bsr"}, | |
10125 | + {5, BBOU_RSWS, "bswap"}, | |
10126 | + {3, BBOU_RSRDWD, "btc"}, | |
10127 | + {3, BBOU_RSRDWD, "btr"}, | |
10128 | + {3, BBOU_RSRDWD, "bts"}, | |
10129 | + {2, BBOU_RSRD, "bt"}, | |
10130 | + {4, BBOU_CALL, "call"}, | |
10131 | + {4, BBOU_CBW, "cbtw"}, /* Intel cbw */ | |
10132 | + {3, BBOU_NOP, "clc"}, | |
10133 | + {3, BBOU_NOP, "cld"}, | |
10134 | + {7, BBOU_RS, "clflush"}, | |
10135 | + {4, BBOU_NOP, "clgi"}, | |
10136 | + {3, BBOU_NOP, "cli"}, | |
10137 | + {4, BBOU_CWD, "cltd"}, /* Intel cdq */ | |
10138 | + {4, BBOU_CBW, "cltq"}, /* Intel cdqe */ | |
10139 | + {4, BBOU_NOP, "clts"}, | |
10140 | + {4, BBOU_CMOV, "cmov"}, | |
10141 | + {9, BBOU_CMPXCHGD,"cmpxchg16"}, | |
10142 | + {8, BBOU_CMPXCHGD,"cmpxchg8"}, | |
10143 | + {7, BBOU_CMPXCHG, "cmpxchg"}, | |
10144 | + {3, BBOU_RSRD, "cmp"}, | |
10145 | + {5, BBOU_CPUID, "cpuid"}, | |
10146 | + {4, BBOU_CWD, "cqto"}, /* Intel cdo */ | |
10147 | + {4, BBOU_CWD, "cwtd"}, /* Intel cwd */ | |
10148 | + {4, BBOU_CBW, "cwtl"}, /* Intel cwde */ | |
10149 | + {4, BBOU_NOP, "data"}, /* alternative ASM_NOP<n> generates data16 on x86_64 */ | |
10150 | + {3, BBOU_RSWS, "dec"}, | |
10151 | + {3, BBOU_DIV, "div"}, | |
10152 | + {5, BBOU_RS, "fdivl"}, | |
10153 | + {5, BBOU_NOP, "finit"}, | |
10154 | + {6, BBOU_RS, "fistpl"}, | |
10155 | + {4, BBOU_RS, "fldl"}, | |
10156 | + {4, BBOU_RS, "fmul"}, | |
10157 | + {6, BBOU_NOP, "fnclex"}, | |
10158 | + {6, BBOU_NOP, "fninit"}, | |
10159 | + {6, BBOU_RS, "fnsave"}, | |
10160 | + {7, BBOU_NOP, "fnsetpm"}, | |
10161 | + {6, BBOU_RS, "frstor"}, | |
10162 | + {5, BBOU_WS, "fstsw"}, | |
10163 | + {5, BBOU_RS, "fsubp"}, | |
10164 | + {5, BBOU_NOP, "fwait"}, | |
10165 | + {7, BBOU_RS, "fxrstor"}, | |
10166 | + {6, BBOU_RS, "fxsave"}, | |
10167 | + {3, BBOU_NOP, "hlt"}, | |
10168 | + {4, BBOU_IDIV, "idiv"}, | |
10169 | + {4, BBOU_IMUL, "imul"}, | |
10170 | + {3, BBOU_RSWS, "inc"}, | |
10171 | + {3, BBOU_NOP, "int"}, | |
10172 | + {7, BBOU_RSRD, "invlpga"}, | |
10173 | + {6, BBOU_RS, "invlpg"}, | |
10174 | + {2, BBOU_RSWD, "in"}, | |
10175 | + {4, BBOU_IRET, "iret"}, | |
10176 | + {1, BBOU_JMP, "j"}, | |
10177 | + {4, BBOU_LAHF, "lahf"}, | |
10178 | + {3, BBOU_RSWD, "lar"}, | |
10179 | + {5, BBOU_RS, "lcall"}, | |
10180 | + {5, BBOU_LEAVE, "leave"}, | |
10181 | + {3, BBOU_LEA, "lea"}, | |
10182 | + {6, BBOU_NOP, "lfence"}, | |
10183 | + {4, BBOU_RS, "lgdt"}, | |
10184 | + {4, BBOU_RS, "lidt"}, | |
10185 | + {4, BBOU_RS, "ljmp"}, | |
10186 | + {4, BBOU_RS, "lldt"}, | |
10187 | + {4, BBOU_RS, "lmsw"}, | |
10188 | + {4, BBOU_LODS, "lods"}, | |
10189 | + {4, BBOU_LOOP, "loop"}, | |
10190 | + {4, BBOU_NOP, "lret"}, | |
10191 | + {3, BBOU_RSWD, "lsl"}, | |
10192 | + {3, BBOU_LSS, "lss"}, | |
10193 | + {3, BBOU_RS, "ltr"}, | |
10194 | + {6, BBOU_NOP, "mfence"}, | |
10195 | + {7, BBOU_MONITOR, "monitor"}, | |
10196 | + {4, BBOU_MOVS, "movs"}, | |
10197 | + {3, BBOU_MOV, "mov"}, | |
10198 | + {3, BBOU_MUL, "mul"}, | |
10199 | + {5, BBOU_MWAIT, "mwait"}, | |
10200 | + {3, BBOU_RSWS, "neg"}, | |
10201 | + {3, BBOU_NOP, "nop"}, | |
10202 | + {3, BBOU_RSWS, "not"}, | |
10203 | + {2, BBOU_RSRDWD, "or"}, | |
10204 | + {4, BBOU_OUTS, "outs"}, | |
10205 | + {3, BBOU_RSRD, "out"}, | |
10206 | + {5, BBOU_NOP, "pause"}, | |
10207 | + {4, BBOU_POPF, "popf"}, | |
10208 | + {3, BBOU_POP, "pop"}, | |
10209 | + {8, BBOU_RS, "prefetch"}, | |
10210 | + {5, BBOU_PUSHF, "pushf"}, | |
10211 | + {4, BBOU_PUSH, "push"}, | |
10212 | + {3, BBOU_RSRDWD, "rcl"}, | |
10213 | + {3, BBOU_RSRDWD, "rcr"}, | |
10214 | + {5, BBOU_RDMSR, "rdmsr"}, | |
10215 | + {5, BBOU_RDMSR, "rdpmc"}, /* same side effects as rdmsr */ | |
10216 | + {5, BBOU_RDTSC, "rdtsc"}, | |
10217 | + {3, BBOU_RET, "ret"}, | |
10218 | + {3, BBOU_RSRDWD, "rol"}, | |
10219 | + {3, BBOU_RSRDWD, "ror"}, | |
10220 | + {4, BBOU_SAHF, "sahf"}, | |
10221 | + {3, BBOU_RSRDWD, "sar"}, | |
10222 | + {3, BBOU_RSRDWD, "sbb"}, | |
10223 | + {4, BBOU_SCAS, "scas"}, | |
10224 | + {3, BBOU_WS, "set"}, | |
10225 | + {6, BBOU_NOP, "sfence"}, | |
10226 | + {4, BBOU_WS, "sgdt"}, | |
10227 | + {3, BBOU_RSRDWD, "shl"}, | |
10228 | + {3, BBOU_RSRDWD, "shr"}, | |
10229 | + {4, BBOU_WS, "sidt"}, | |
10230 | + {4, BBOU_WS, "sldt"}, | |
10231 | + {3, BBOU_NOP, "stc"}, | |
10232 | + {3, BBOU_NOP, "std"}, | |
10233 | + {4, BBOU_NOP, "stgi"}, | |
10234 | + {3, BBOU_NOP, "sti"}, | |
10235 | + {4, BBOU_SCAS, "stos"}, | |
10236 | + {4, BBOU_WS, "strl"}, | |
10237 | + {3, BBOU_WS, "str"}, | |
10238 | + {3, BBOU_SUB, "sub"}, | |
10239 | + {6, BBOU_NOP, "swapgs"}, | |
10240 | + {7, BBOU_SYSEXIT, "sysexit"}, | |
10241 | + {6, BBOU_SYSRET, "sysret"}, | |
10242 | + {4, BBOU_NOP, "test"}, | |
10243 | + {4, BBOU_NOP, "ud2a"}, | |
10244 | + {7, BBOU_RS, "vmclear"}, | |
10245 | + {8, BBOU_NOP, "vmlaunch"}, | |
10246 | + {6, BBOU_RS, "vmload"}, | |
10247 | + {7, BBOU_RS, "vmptrld"}, | |
10248 | + {6, BBOU_WD, "vmread"}, /* vmread src is an encoding, not a register */ | |
10249 | + {8, BBOU_NOP, "vmresume"}, | |
10250 | + {5, BBOU_RS, "vmrun"}, | |
10251 | + {6, BBOU_RS, "vmsave"}, | |
10252 | + {7, BBOU_WD, "vmwrite"}, /* vmwrite src is an encoding, not a register */ | |
10253 | + {6, BBOU_NOP, "wbinvd"}, | |
10254 | + {5, BBOU_WRMSR, "wrmsr"}, | |
10255 | + {4, BBOU_XADD, "xadd"}, | |
10256 | + {4, BBOU_XCHG, "xchg"}, | |
10257 | + {3, BBOU_XOR, "xor"}, | |
10258 | + {10, BBOU_WS, "xstore-rng"}, | |
10259 | +}; | |
10260 | + | |
10261 | +/* To speed up searching, index bb_opcode_usage_all by the first letter of each | |
10262 | + * opcode. | |
10263 | + */ | |
10264 | +static struct { | |
10265 | + const struct bb_opcode_usage *opcode; | |
10266 | + int size; | |
10267 | +} bb_opcode_usage[26]; | |
10268 | + | |
10269 | +struct bb_operand { | |
10270 | + char *base; | |
10271 | + char *index; | |
10272 | + char *segment; | |
10273 | + long disp; | |
10274 | + unsigned int scale; | |
10275 | + enum bb_reg_code base_rc; /* UNDEFINED or RAX through R15 */ | |
10276 | + enum bb_reg_code index_rc; /* UNDEFINED or RAX through R15 */ | |
10277 | + unsigned int present :1; | |
10278 | + unsigned int disp_present :1; | |
10279 | + unsigned int indirect :1; /* must be combined with reg or memory */ | |
10280 | + unsigned int immediate :1; /* exactly one of these 3 must be set */ | |
10281 | + unsigned int reg :1; | |
10282 | + unsigned int memory :1; | |
10283 | +}; | |
10284 | + | |
10285 | +struct bb_decode { | |
10286 | + char *prefix; | |
10287 | + char *opcode; | |
10288 | + const struct bb_opcode_usage *match; | |
10289 | + struct bb_operand src; | |
10290 | + struct bb_operand dst; | |
10291 | + struct bb_operand dst2; | |
10292 | +}; | |
10293 | + | |
10294 | +static struct bb_decode bb_decode; | |
10295 | + | |
10296 | +static enum bb_reg_code | |
10297 | +bb_reg_map(const char *reg) | |
10298 | +{ | |
10299 | + int lo, hi, c; | |
10300 | + const struct bb_reg_code_map *p; | |
10301 | + lo = 0; | |
10302 | + hi = ARRAY_SIZE(bb_reg_code_map) - 1; | |
10303 | + while (lo <= hi) { | |
10304 | + int mid = (hi + lo) / 2; | |
10305 | + p = bb_reg_code_map + mid; | |
10306 | + c = strcmp(p->name, reg+1); | |
10307 | + if (c == 0) | |
10308 | + return p->reg; | |
10309 | + else if (c > 0) | |
10310 | + hi = mid - 1; | |
10311 | + else | |
10312 | + lo = mid + 1; | |
10313 | + } | |
10314 | + return BBRG_UNDEFINED; | |
10315 | +} | |
10316 | + | |
10317 | +static void | |
10318 | +bb_parse_operand(char *str, struct bb_operand *operand) | |
10319 | +{ | |
10320 | + char *p = str; | |
10321 | + int sign = 1; | |
10322 | + operand->present = 1; | |
10323 | + /* extract any segment prefix */ | |
10324 | + if (p[0] == '%' && p[1] && p[2] == 's' && p[3] == ':') { | |
10325 | + operand->memory = 1; | |
10326 | + operand->segment = p; | |
10327 | + p[3] = '\0'; | |
10328 | + p += 4; | |
10329 | + } | |
10330 | + /* extract displacement, base, index, scale */ | |
10331 | + if (*p == '*') { | |
10332 | + /* jmp/call *disp(%reg), *%reg or *0xnnn */ | |
10333 | + operand->indirect = 1; | |
10334 | + ++p; | |
10335 | + } | |
10336 | + if (*p == '-') { | |
10337 | + sign = -1; | |
10338 | + ++p; | |
10339 | + } | |
10340 | + if (*p == '$') { | |
10341 | + operand->immediate = 1; | |
10342 | + operand->disp_present = 1; | |
10343 | + operand->disp = simple_strtoul(p+1, &p, 0); | |
10344 | + } else if (isdigit(*p)) { | |
10345 | + operand->memory = 1; | |
10346 | + operand->disp_present = 1; | |
10347 | + operand->disp = simple_strtoul(p, &p, 0) * sign; | |
10348 | + } | |
10349 | + if (*p == '%') { | |
10350 | + operand->reg = 1; | |
10351 | + operand->base = p; | |
10352 | + } else if (*p == '(') { | |
10353 | + operand->memory = 1; | |
10354 | + operand->base = ++p; | |
10355 | + p += strcspn(p, ",)"); | |
10356 | + if (p == operand->base) | |
10357 | + operand->base = NULL; | |
10358 | + if (*p == ',') { | |
10359 | + *p = '\0'; | |
10360 | + operand->index = ++p; | |
10361 | + p += strcspn(p, ",)"); | |
10362 | + if (p == operand->index) | |
10363 | + operand->index = NULL; | |
10364 | + } | |
10365 | + if (*p == ',') { | |
10366 | + *p = '\0'; | |
10367 | + operand->scale = simple_strtoul(p+1, &p, 0); | |
10368 | + } | |
10369 | + *p = '\0'; | |
10370 | + } else if (*p) { | |
10371 | + kdb_printf("%s: unexpected token '%c' after disp '%s'\n", | |
10372 | + __FUNCTION__, *p, str); | |
10373 | + bb_giveup = 1; | |
10374 | + } | |
10375 | + if ((operand->immediate + operand->reg + operand->memory != 1) || | |
10376 | + (operand->indirect && operand->immediate)) { | |
10377 | + kdb_printf("%s: incorrect decode '%s' N %d I %d R %d M %d\n", | |
10378 | + __FUNCTION__, str, | |
10379 | + operand->indirect, operand->immediate, operand->reg, | |
10380 | + operand->memory); | |
10381 | + bb_giveup = 1; | |
10382 | + } | |
10383 | + if (operand->base) | |
10384 | + operand->base_rc = bb_reg_map(operand->base); | |
10385 | + if (operand->index) | |
10386 | + operand->index_rc = bb_reg_map(operand->index); | |
10387 | +} | |
10388 | + | |
10389 | +static void | |
10390 | +bb_print_operand(const char *type, const struct bb_operand *operand) | |
10391 | +{ | |
10392 | + if (!operand->present) | |
10393 | + return; | |
10394 | + kdb_printf(" %s %c%c: ", | |
10395 | + type, | |
10396 | + operand->indirect ? 'N' : ' ', | |
10397 | + operand->immediate ? 'I' : | |
10398 | + operand->reg ? 'R' : | |
10399 | + operand->memory ? 'M' : | |
10400 | + '?' | |
10401 | + ); | |
10402 | + if (operand->segment) | |
10403 | + kdb_printf("%s:", operand->segment); | |
10404 | + if (operand->immediate) { | |
10405 | + kdb_printf("$0x%lx", operand->disp); | |
10406 | + } else if (operand->reg) { | |
10407 | + if (operand->indirect) | |
10408 | + kdb_printf("*"); | |
10409 | + kdb_printf("%s", operand->base); | |
10410 | + } else if (operand->memory) { | |
10411 | + if (operand->indirect && (operand->base || operand->index)) | |
10412 | + kdb_printf("*"); | |
10413 | + if (operand->disp_present) { | |
10414 | + kdb_printf("0x%lx", operand->disp); | |
10415 | + } | |
10416 | + if (operand->base || operand->index || operand->scale) { | |
10417 | + kdb_printf("("); | |
10418 | + if (operand->base) | |
10419 | + kdb_printf("%s", operand->base); | |
10420 | + if (operand->index || operand->scale) | |
10421 | + kdb_printf(","); | |
10422 | + if (operand->index) | |
10423 | + kdb_printf("%s", operand->index); | |
10424 | + if (operand->scale) | |
10425 | + kdb_printf(",%d", operand->scale); | |
10426 | + kdb_printf(")"); | |
10427 | + } | |
10428 | + } | |
10429 | + if (operand->base_rc) | |
10430 | + kdb_printf(" base_rc %d (%s)", | |
10431 | + operand->base_rc, bbrg_name[operand->base_rc]); | |
10432 | + if (operand->index_rc) | |
10433 | + kdb_printf(" index_rc %d (%s)", | |
10434 | + operand->index_rc, | |
10435 | + bbrg_name[operand->index_rc]); | |
10436 | + kdb_printf("\n"); | |
10437 | +} | |
10438 | + | |
10439 | +static void | |
10440 | +bb_print_opcode(void) | |
10441 | +{ | |
10442 | + const struct bb_opcode_usage *o = bb_decode.match; | |
10443 | + kdb_printf(" "); | |
10444 | + if (bb_decode.prefix) | |
10445 | + kdb_printf("%s ", bb_decode.prefix); | |
10446 | + kdb_printf("opcode '%s' matched by '%s', usage %d\n", | |
10447 | + bb_decode.opcode, o->opcode, o->usage); | |
10448 | +} | |
10449 | + | |
10450 | +static int | |
10451 | +bb_parse_opcode(void) | |
10452 | +{ | |
10453 | + int c, i; | |
10454 | + const struct bb_opcode_usage *o; | |
10455 | + static int bb_parse_opcode_error_limit = 5; | |
10456 | + c = bb_decode.opcode[0] - 'a'; | |
10457 | + if (c < 0 || c >= ARRAY_SIZE(bb_opcode_usage)) | |
10458 | + goto nomatch; | |
10459 | + o = bb_opcode_usage[c].opcode; | |
10460 | + if (!o) | |
10461 | + goto nomatch; | |
10462 | + for (i = 0; i < bb_opcode_usage[c].size; ++i, ++o) { | |
10463 | + if (strncmp(bb_decode.opcode, o->opcode, o->length) == 0) { | |
10464 | + bb_decode.match = o; | |
10465 | + if (KDB_DEBUG(BB)) | |
10466 | + bb_print_opcode(); | |
10467 | + return 0; | |
10468 | + } | |
10469 | + } | |
10470 | +nomatch: | |
10471 | + if (!bb_parse_opcode_error_limit) | |
10472 | + return 1; | |
10473 | + --bb_parse_opcode_error_limit; | |
10474 | + kdb_printf("%s: no match at [%s]%s " kdb_bfd_vma_fmt0 " - '%s'\n", | |
10475 | + __FUNCTION__, | |
10476 | + bb_mod_name, bb_func_name, bb_curr_addr, | |
10477 | + bb_decode.opcode); | |
10478 | + return 1; | |
10479 | +} | |
10480 | + | |
10481 | +static bool | |
10482 | +bb_is_int_reg(enum bb_reg_code reg) | |
10483 | +{ | |
10484 | + return reg >= BBRG_RAX && reg < (BBRG_RAX + KDB_INT_REGISTERS); | |
10485 | +} | |
10486 | + | |
10487 | +static bool | |
10488 | +bb_is_simple_memory(const struct bb_operand *operand) | |
10489 | +{ | |
10490 | + return operand->memory && | |
10491 | + bb_is_int_reg(operand->base_rc) && | |
10492 | + !operand->index_rc && | |
10493 | + operand->scale == 0 && | |
10494 | + !operand->segment; | |
10495 | +} | |
10496 | + | |
10497 | +static bool | |
10498 | +bb_is_static_disp(const struct bb_operand *operand) | |
10499 | +{ | |
10500 | + return operand->memory && | |
10501 | + !operand->base_rc && | |
10502 | + !operand->index_rc && | |
10503 | + operand->scale == 0 && | |
10504 | + !operand->segment && | |
10505 | + !operand->indirect; | |
10506 | +} | |
10507 | + | |
10508 | +static enum bb_reg_code | |
10509 | +bb_reg_code_value(enum bb_reg_code reg) | |
10510 | +{ | |
10511 | + BB_CHECK(!bb_is_int_reg(reg), reg, 0); | |
10512 | + return bb_reg_state->contains[reg - BBRG_RAX].value; | |
10513 | +} | |
10514 | + | |
10515 | +static short | |
10516 | +bb_reg_code_offset(enum bb_reg_code reg) | |
10517 | +{ | |
10518 | + BB_CHECK(!bb_is_int_reg(reg), reg, 0); | |
10519 | + return bb_reg_state->contains[reg - BBRG_RAX].offset; | |
10520 | +} | |
10521 | + | |
10522 | +static void | |
10523 | +bb_reg_code_set_value(enum bb_reg_code dst, enum bb_reg_code src) | |
10524 | +{ | |
10525 | + BB_CHECK(!bb_is_int_reg(dst), dst, ); | |
10526 | + bb_reg_state->contains[dst - BBRG_RAX].value = src; | |
10527 | +} | |
10528 | + | |
10529 | +static void | |
10530 | +bb_reg_code_set_offset(enum bb_reg_code dst, short offset) | |
10531 | +{ | |
10532 | + BB_CHECK(!bb_is_int_reg(dst), dst, ); | |
10533 | + bb_reg_state->contains[dst - BBRG_RAX].offset = offset; | |
10534 | +} | |
10535 | + | |
10536 | +static bool | |
10537 | +bb_is_osp_defined(enum bb_reg_code reg) | |
10538 | +{ | |
10539 | + if (bb_is_int_reg(reg)) | |
10540 | + return bb_reg_code_value(reg) == BBRG_OSP; | |
10541 | + else | |
10542 | + return 0; | |
10543 | +} | |
10544 | + | |
10545 | +static bfd_vma | |
10546 | +bb_actual_value(enum bb_reg_code reg) | |
10547 | +{ | |
10548 | + BB_CHECK(!bb_is_int_reg(reg), reg, 0); | |
10549 | + return bb_actual[reg - BBRG_RAX].value; | |
10550 | +} | |
10551 | + | |
10552 | +static int | |
10553 | +bb_actual_valid(enum bb_reg_code reg) | |
10554 | +{ | |
10555 | + BB_CHECK(!bb_is_int_reg(reg), reg, 0); | |
10556 | + return bb_actual[reg - BBRG_RAX].valid; | |
10557 | +} | |
10558 | + | |
10559 | +static void | |
10560 | +bb_actual_set_value(enum bb_reg_code reg, bfd_vma value) | |
10561 | +{ | |
10562 | + BB_CHECK(!bb_is_int_reg(reg), reg, ); | |
10563 | + bb_actual[reg - BBRG_RAX].value = value; | |
10564 | +} | |
10565 | + | |
10566 | +static void | |
10567 | +bb_actual_set_valid(enum bb_reg_code reg, int valid) | |
10568 | +{ | |
10569 | + BB_CHECK(!bb_is_int_reg(reg), reg, ); | |
10570 | + bb_actual[reg - BBRG_RAX].valid = valid; | |
10571 | +} | |
10572 | + | |
10573 | +/* The scheduler code switches RSP then does PUSH, it is not an error for RSP | |
10574 | + * to be undefined in this area of the code. | |
10575 | + */ | |
10576 | +static bool | |
10577 | +bb_is_scheduler_address(void) | |
10578 | +{ | |
10579 | + return bb_curr_addr >= bb__sched_text_start && | |
10580 | + bb_curr_addr < bb__sched_text_end; | |
10581 | +} | |
10582 | + | |
10583 | +static void | |
10584 | +bb_reg_read(enum bb_reg_code reg) | |
10585 | +{ | |
10586 | + int i, r = 0; | |
10587 | + if (!bb_is_int_reg(reg) || | |
10588 | + bb_reg_code_value(reg) != reg) | |
10589 | + return; | |
10590 | + for (i = 0; | |
10591 | + i < min_t(unsigned int, REGPARM, ARRAY_SIZE(bb_param_reg)); | |
10592 | + ++i) { | |
10593 | + if (reg == bb_param_reg[i]) { | |
10594 | + r = i + 1; | |
10595 | + break; | |
10596 | + } | |
10597 | + } | |
10598 | + bb_reg_params = max(bb_reg_params, r); | |
10599 | +} | |
10600 | + | |
10601 | +static void | |
10602 | +bb_do_reg_state_print(const struct bb_reg_state *s) | |
10603 | +{ | |
10604 | + int i, offset_address, offset_value; | |
10605 | + const struct bb_memory_contains *c; | |
10606 | + enum bb_reg_code value; | |
10607 | + kdb_printf(" bb_reg_state %p\n", s); | |
10608 | + for (i = 0; i < ARRAY_SIZE(s->contains); ++i) { | |
10609 | + value = s->contains[i].value; | |
10610 | + offset_value = s->contains[i].offset; | |
10611 | + kdb_printf(" %s = %s", | |
10612 | + bbrg_name[i + BBRG_RAX], bbrg_name[value]); | |
10613 | + if (value == BBRG_OSP) | |
10614 | + KDB_DEBUG_BB_OFFSET_PRINTF(offset_value, "", ""); | |
10615 | + kdb_printf("\n"); | |
10616 | + } | |
10617 | + for (i = 0, c = s->memory; i < s->mem_count; ++i, ++c) { | |
10618 | + offset_address = c->offset_address; | |
10619 | + value = c->value; | |
10620 | + offset_value = c->offset_value; | |
10621 | + kdb_printf(" slot %d offset_address %c0x%x %s", | |
10622 | + i, | |
10623 | + offset_address >= 0 ? '+' : '-', | |
10624 | + offset_address >= 0 ? offset_address : -offset_address, | |
10625 | + bbrg_name[value]); | |
10626 | + if (value == BBRG_OSP) | |
10627 | + KDB_DEBUG_BB_OFFSET_PRINTF(offset_value, "", ""); | |
10628 | + kdb_printf("\n"); | |
10629 | + } | |
10630 | +} | |
10631 | + | |
10632 | +static void | |
10633 | +bb_reg_state_print(const struct bb_reg_state *s) | |
10634 | +{ | |
10635 | + if (KDB_DEBUG(BB)) | |
10636 | + bb_do_reg_state_print(s); | |
10637 | +} | |
10638 | + | |
10639 | +/* Set register 'dst' to contain the value from 'src'. This includes reading | |
10640 | + * from 'src' and writing to 'dst'. The offset value is copied iff 'src' | |
10641 | + * contains a stack pointer. | |
10642 | + * | |
10643 | + * Be very careful about the context here. 'dst' and 'src' reflect integer | |
10644 | + * registers by name, _not_ by the value of their contents. "mov %rax,%rsi" | |
10645 | + * will call this function as bb_reg_set_reg(BBRG_RSI, BBRG_RAX), which | |
10646 | + * reflects what the assembler code is doing. However we need to track the | |
10647 | + * _values_ in the registers, not their names. IOW, we really care about "what | |
10648 | + * value does rax contain when it is copied into rsi?", so we can record the | |
10649 | + * fact that we now have two copies of that value, one in rax and one in rsi. | |
10650 | + */ | |
10651 | + | |
10652 | +static void | |
10653 | +bb_reg_set_reg(enum bb_reg_code dst, enum bb_reg_code src) | |
10654 | +{ | |
10655 | + enum bb_reg_code src_value = BBRG_UNDEFINED; | |
10656 | + short offset_value = 0; | |
10657 | + KDB_DEBUG_BB(" %s = %s", bbrg_name[dst], bbrg_name[src]); | |
10658 | + if (bb_is_int_reg(src)) { | |
10659 | + bb_reg_read(src); | |
10660 | + src_value = bb_reg_code_value(src); | |
10661 | + KDB_DEBUG_BB(" (%s", bbrg_name[src_value]); | |
10662 | + if (bb_is_osp_defined(src)) { | |
10663 | + offset_value = bb_reg_code_offset(src); | |
10664 | + KDB_DEBUG_BB_OFFSET(offset_value, "", ""); | |
10665 | + } | |
10666 | + KDB_DEBUG_BB(")"); | |
10667 | + } | |
10668 | + if (bb_is_int_reg(dst)) { | |
10669 | + bb_reg_code_set_value(dst, src_value); | |
10670 | + bb_reg_code_set_offset(dst, offset_value); | |
10671 | + } | |
10672 | + KDB_DEBUG_BB("\n"); | |
10673 | +} | |
10674 | + | |
10675 | +static void | |
10676 | +bb_reg_set_undef(enum bb_reg_code dst) | |
10677 | +{ | |
10678 | + bb_reg_set_reg(dst, BBRG_UNDEFINED); | |
10679 | +} | |
10680 | + | |
10681 | +/* Delete any record of a stored register held in osp + 'offset' */ | |
10682 | + | |
10683 | +static void | |
10684 | +bb_delete_memory(short offset) | |
10685 | +{ | |
10686 | + int i; | |
10687 | + struct bb_memory_contains *c; | |
10688 | + for (i = 0, c = bb_reg_state->memory; | |
10689 | + i < bb_reg_state->mem_count; | |
10690 | + ++i, ++c) { | |
10691 | + if (c->offset_address == offset && | |
10692 | + c->value != BBRG_UNDEFINED) { | |
10693 | + KDB_DEBUG_BB(" delete %s from ", | |
10694 | + bbrg_name[c->value]); | |
10695 | + KDB_DEBUG_BB_OFFSET(offset, "osp", ""); | |
10696 | + KDB_DEBUG_BB(" slot %d\n", | |
10697 | + (int)(c - bb_reg_state->memory)); | |
10698 | + memset(c, BBRG_UNDEFINED, sizeof(*c)); | |
10699 | + if (i == bb_reg_state->mem_count - 1) | |
10700 | + --bb_reg_state->mem_count; | |
10701 | + } | |
10702 | + } | |
10703 | +} | |
10704 | + | |
10705 | +/* Set memory location *('dst' + 'offset_address') to contain the supplied | |
10706 | + * value and offset. 'dst' is assumed to be a register that contains a stack | |
10707 | + * pointer. | |
10708 | + */ | |
10709 | + | |
10710 | +static void | |
10711 | +bb_memory_set_reg_value(enum bb_reg_code dst, short offset_address, | |
10712 | + enum bb_reg_code value, short offset_value) | |
10713 | +{ | |
10714 | + int i; | |
10715 | + struct bb_memory_contains *c, *free = NULL; | |
10716 | + BB_CHECK(!bb_is_osp_defined(dst), dst, ); | |
10717 | + KDB_DEBUG_BB(" *(%s", bbrg_name[dst]); | |
10718 | + KDB_DEBUG_BB_OFFSET(offset_address, "", ""); | |
10719 | + offset_address += bb_reg_code_offset(dst); | |
10720 | + KDB_DEBUG_BB_OFFSET(offset_address, " osp", ") = "); | |
10721 | + KDB_DEBUG_BB("%s", bbrg_name[value]); | |
10722 | + if (value == BBRG_OSP) | |
10723 | + KDB_DEBUG_BB_OFFSET(offset_value, "", ""); | |
10724 | + for (i = 0, c = bb_reg_state->memory; | |
10725 | + i < bb_reg_state_max; | |
10726 | + ++i, ++c) { | |
10727 | + if (c->offset_address == offset_address) | |
10728 | + free = c; | |
10729 | + else if (c->value == BBRG_UNDEFINED && !free) | |
10730 | + free = c; | |
10731 | + } | |
10732 | + if (!free) { | |
10733 | + struct bb_reg_state *new, *old = bb_reg_state; | |
10734 | + size_t old_size, new_size; | |
10735 | + int slot; | |
10736 | + old_size = sizeof(*old) + bb_reg_state_max * | |
10737 | + sizeof(old->memory[0]); | |
10738 | + slot = bb_reg_state_max; | |
10739 | + bb_reg_state_max += 5; | |
10740 | + new_size = sizeof(*new) + bb_reg_state_max * | |
10741 | + sizeof(new->memory[0]); | |
10742 | + new = debug_kmalloc(new_size, GFP_ATOMIC); | |
10743 | + if (!new) { | |
10744 | + kdb_printf("\n\n%s: out of debug_kmalloc\n", __FUNCTION__); | |
10745 | + bb_giveup = 1; | |
10746 | + } else { | |
10747 | + memcpy(new, old, old_size); | |
10748 | + memset((char *)new + old_size, BBRG_UNDEFINED, | |
10749 | + new_size - old_size); | |
10750 | + bb_reg_state = new; | |
10751 | + debug_kfree(old); | |
10752 | + free = bb_reg_state->memory + slot; | |
10753 | + } | |
10754 | + } | |
10755 | + if (free) { | |
10756 | + int slot = free - bb_reg_state->memory; | |
10757 | + free->offset_address = offset_address; | |
10758 | + free->value = value; | |
10759 | + free->offset_value = offset_value; | |
10760 | + KDB_DEBUG_BB(" slot %d", slot); | |
10761 | + bb_reg_state->mem_count = max(bb_reg_state->mem_count, slot+1); | |
10762 | + } | |
10763 | + KDB_DEBUG_BB("\n"); | |
10764 | +} | |
10765 | + | |
10766 | +/* Set memory location *('dst' + 'offset') to contain the value from register | |
10767 | + * 'src'. 'dst' is assumed to be a register that contains a stack pointer. | |
10768 | + * This differs from bb_memory_set_reg_value because it takes a src register | |
10769 | + * which contains a value and possibly an offset, bb_memory_set_reg_value is | |
10770 | + * passed the value and offset directly. | |
10771 | + */ | |
10772 | + | |
10773 | +static void | |
10774 | +bb_memory_set_reg(enum bb_reg_code dst, enum bb_reg_code src, | |
10775 | + short offset_address) | |
10776 | +{ | |
10777 | + int offset_value; | |
10778 | + enum bb_reg_code value; | |
10779 | + BB_CHECK(!bb_is_osp_defined(dst), dst, ); | |
10780 | + if (!bb_is_int_reg(src)) | |
10781 | + return; | |
10782 | + value = bb_reg_code_value(src); | |
10783 | + if (value == BBRG_UNDEFINED) { | |
10784 | + bb_delete_memory(offset_address + bb_reg_code_offset(dst)); | |
10785 | + return; | |
10786 | + } | |
10787 | + offset_value = bb_reg_code_offset(src); | |
10788 | + bb_reg_read(src); | |
10789 | + bb_memory_set_reg_value(dst, offset_address, value, offset_value); | |
10790 | +} | |
10791 | + | |
10792 | +/* Set register 'dst' to contain the value from memory *('src' + offset_address). | |
10793 | + * 'src' is assumed to be a register that contains a stack pointer. | |
10794 | + */ | |
10795 | + | |
10796 | +static void | |
10797 | +bb_reg_set_memory(enum bb_reg_code dst, enum bb_reg_code src, short offset_address) | |
10798 | +{ | |
10799 | + int i, defined = 0; | |
10800 | + struct bb_memory_contains *s; | |
10801 | + BB_CHECK(!bb_is_osp_defined(src), src, ); | |
10802 | + KDB_DEBUG_BB(" %s = *(%s", | |
10803 | + bbrg_name[dst], bbrg_name[src]); | |
10804 | + KDB_DEBUG_BB_OFFSET(offset_address, "", ")"); | |
10805 | + offset_address += bb_reg_code_offset(src); | |
10806 | + KDB_DEBUG_BB_OFFSET(offset_address, " (osp", ")"); | |
10807 | + for (i = 0, s = bb_reg_state->memory; | |
10808 | + i < bb_reg_state->mem_count; | |
10809 | + ++i, ++s) { | |
10810 | + if (s->offset_address == offset_address && bb_is_int_reg(dst)) { | |
10811 | + bb_reg_code_set_value(dst, s->value); | |
10812 | + KDB_DEBUG_BB(" value %s", bbrg_name[s->value]); | |
10813 | + if (s->value == BBRG_OSP) { | |
10814 | + bb_reg_code_set_offset(dst, s->offset_value); | |
10815 | + KDB_DEBUG_BB_OFFSET(s->offset_value, "", ""); | |
10816 | + } else { | |
10817 | + bb_reg_code_set_offset(dst, 0); | |
10818 | + } | |
10819 | + defined = 1; | |
10820 | + } | |
10821 | + } | |
10822 | + if (!defined) | |
10823 | + bb_reg_set_reg(dst, BBRG_UNDEFINED); | |
10824 | + else | |
10825 | + KDB_DEBUG_BB("\n"); | |
10826 | +} | |
10827 | + | |
10828 | +/* A generic read from an operand. */ | |
10829 | + | |
10830 | +static void | |
10831 | +bb_read_operand(const struct bb_operand *operand) | |
10832 | +{ | |
10833 | + int m = 0; | |
10834 | + if (operand->base_rc) | |
10835 | + bb_reg_read(operand->base_rc); | |
10836 | + if (operand->index_rc) | |
10837 | + bb_reg_read(operand->index_rc); | |
10838 | + if (bb_is_simple_memory(operand) && | |
10839 | + bb_is_osp_defined(operand->base_rc) && | |
10840 | + bb_decode.match->usage != BBOU_LEA) { | |
10841 | + m = (bb_reg_code_offset(operand->base_rc) + operand->disp + | |
10842 | + KDB_WORD_SIZE - 1) / KDB_WORD_SIZE; | |
10843 | + bb_memory_params = max(bb_memory_params, m); | |
10844 | + } | |
10845 | +} | |
10846 | + | |
10847 | +/* A generic write to an operand, resulting in an undefined value in that | |
10848 | + * location. All well defined operands are handled separately, this function | |
10849 | + * only handles the opcodes where the result is undefined. | |
10850 | + */ | |
10851 | + | |
10852 | +static void | |
10853 | +bb_write_operand(const struct bb_operand *operand) | |
10854 | +{ | |
10855 | + enum bb_reg_code base_rc = operand->base_rc; | |
10856 | + if (operand->memory) { | |
10857 | + if (base_rc) | |
10858 | + bb_reg_read(base_rc); | |
10859 | + if (operand->index_rc) | |
10860 | + bb_reg_read(operand->index_rc); | |
10861 | + } else if (operand->reg && base_rc) { | |
10862 | + bb_reg_set_undef(base_rc); | |
10863 | + } | |
10864 | + if (bb_is_simple_memory(operand) && bb_is_osp_defined(base_rc)) { | |
10865 | + int offset; | |
10866 | + offset = bb_reg_code_offset(base_rc) + operand->disp; | |
10867 | + offset = ALIGN(offset - KDB_WORD_SIZE + 1, KDB_WORD_SIZE); | |
10868 | + bb_delete_memory(offset); | |
10869 | + } | |
10870 | +} | |
10871 | + | |
10872 | +/* Adjust a register that contains a stack pointer */ | |
10873 | + | |
10874 | +static void | |
10875 | +bb_adjust_osp(enum bb_reg_code reg, int adjust) | |
10876 | +{ | |
10877 | + int offset = bb_reg_code_offset(reg), old_offset = offset; | |
10878 | + KDB_DEBUG_BB(" %s osp offset ", bbrg_name[reg]); | |
10879 | + KDB_DEBUG_BB_OFFSET(bb_reg_code_offset(reg), "", " -> "); | |
10880 | + offset += adjust; | |
10881 | + bb_reg_code_set_offset(reg, offset); | |
10882 | + KDB_DEBUG_BB_OFFSET(bb_reg_code_offset(reg), "", "\n"); | |
10883 | + /* When RSP is adjusted upwards, it invalidates any memory | |
10884 | + * stored between the old and current stack offsets. | |
10885 | + */ | |
10886 | + if (reg == BBRG_RSP) { | |
10887 | + while (old_offset < bb_reg_code_offset(reg)) { | |
10888 | + bb_delete_memory(old_offset); | |
10889 | + old_offset += KDB_WORD_SIZE; | |
10890 | + } | |
10891 | + } | |
10892 | +} | |
10893 | + | |
10894 | +/* The current instruction adjusts a register that contains a stack pointer. | |
10895 | + * Direction is 1 or -1, depending on whether the instruction is add/lea or | |
10896 | + * sub. | |
10897 | + */ | |
10898 | + | |
10899 | +static void | |
10900 | +bb_adjust_osp_instruction(int direction) | |
10901 | +{ | |
10902 | + enum bb_reg_code dst_reg = bb_decode.dst.base_rc; | |
10903 | + if (bb_decode.src.immediate || | |
10904 | + bb_decode.match->usage == BBOU_LEA /* lea has its own checks */) { | |
10905 | + int adjust = direction * bb_decode.src.disp; | |
10906 | + bb_adjust_osp(dst_reg, adjust); | |
10907 | + } else { | |
10908 | + /* variable stack adjustment, osp offset is not well defined */ | |
10909 | + KDB_DEBUG_BB(" %s osp offset ", bbrg_name[dst_reg]); | |
10910 | + KDB_DEBUG_BB_OFFSET(bb_reg_code_offset(dst_reg), "", " -> undefined\n"); | |
10911 | + bb_reg_code_set_value(dst_reg, BBRG_UNDEFINED); | |
10912 | + bb_reg_code_set_offset(dst_reg, 0); | |
10913 | + } | |
10914 | +} | |
10915 | + | |
10916 | +/* Some instructions using memory have an explicit length suffix (b, w, l, q). | |
10917 | + * The equivalent instructions using a register imply the length from the | |
10918 | + * register name. Deduce the operand length. | |
10919 | + */ | |
10920 | + | |
10921 | +static int | |
10922 | +bb_operand_length(const struct bb_operand *operand, char opcode_suffix) | |
10923 | +{ | |
10924 | + int l = 0; | |
10925 | + switch (opcode_suffix) { | |
10926 | + case 'b': | |
10927 | + l = 8; | |
10928 | + break; | |
10929 | + case 'w': | |
10930 | + l = 16; | |
10931 | + break; | |
10932 | + case 'l': | |
10933 | + l = 32; | |
10934 | + break; | |
10935 | + case 'q': | |
10936 | + l = 64; | |
10937 | + break; | |
10938 | + } | |
10939 | + if (l == 0 && operand->reg) { | |
10940 | + switch (strlen(operand->base)) { | |
10941 | + case 3: | |
10942 | + switch (operand->base[2]) { | |
10943 | + case 'h': | |
10944 | + case 'l': | |
10945 | + l = 8; | |
10946 | + break; | |
10947 | + default: | |
10948 | + l = 16; | |
10949 | + break; | |
10950 | + } | |
10951 | + case 4: | |
10952 | + if (operand->base[1] == 'r') | |
10953 | + l = 64; | |
10954 | + else | |
10955 | + l = 32; | |
10956 | + break; | |
10957 | + } | |
10958 | + } | |
10959 | + return l; | |
10960 | +} | |
10961 | + | |
10962 | +static int | |
10963 | +bb_reg_state_size(const struct bb_reg_state *state) | |
10964 | +{ | |
10965 | + return sizeof(*state) + | |
10966 | + state->mem_count * sizeof(state->memory[0]); | |
10967 | +} | |
10968 | + | |
10969 | +/* Canonicalize the current bb_reg_state so it can be compared against | |
10970 | + * previously created states. Sort the memory entries in descending order of | |
10971 | + * offset_address (stack grows down). Empty slots are moved to the end of the | |
10972 | + * list and trimmed. | |
10973 | + */ | |
10974 | + | |
10975 | +static void | |
10976 | +bb_reg_state_canonicalize(void) | |
10977 | +{ | |
10978 | + int i, order, changed; | |
10979 | + struct bb_memory_contains *p1, *p2, temp; | |
10980 | + do { | |
10981 | + changed = 0; | |
10982 | + for (i = 0, p1 = bb_reg_state->memory; | |
10983 | + i < bb_reg_state->mem_count-1; | |
10984 | + ++i, ++p1) { | |
10985 | + p2 = p1 + 1; | |
10986 | + if (p2->value == BBRG_UNDEFINED) { | |
10987 | + order = 0; | |
10988 | + } else if (p1->value == BBRG_UNDEFINED) { | |
10989 | + order = 1; | |
10990 | + } else if (p1->offset_address < p2->offset_address) { | |
10991 | + order = 1; | |
10992 | + } else if (p1->offset_address > p2->offset_address) { | |
10993 | + order = -1; | |
10994 | + } else { | |
10995 | + order = 0; | |
10996 | + } | |
10997 | + if (order > 0) { | |
10998 | + temp = *p2; | |
10999 | + *p2 = *p1; | |
11000 | + *p1 = temp; | |
11001 | + changed = 1; | |
11002 | + } | |
11003 | + } | |
11004 | + } while(changed); | |
11005 | + for (i = 0, p1 = bb_reg_state->memory; | |
11006 | + i < bb_reg_state_max; | |
11007 | + ++i, ++p1) { | |
11008 | + if (p1->value != BBRG_UNDEFINED) | |
11009 | + bb_reg_state->mem_count = i + 1; | |
11010 | + } | |
11011 | + bb_reg_state_print(bb_reg_state); | |
11012 | +} | |
11013 | + | |
11014 | +static int | |
11015 | +bb_special_case(bfd_vma to) | |
11016 | +{ | |
11017 | + int i, j, rsp_offset, expect_offset, offset, errors = 0, max_errors = 40; | |
11018 | + enum bb_reg_code reg, expect_value, value; | |
11019 | + struct bb_name_state *r; | |
11020 | + | |
11021 | + for (i = 0, r = bb_special_cases; | |
11022 | + i < ARRAY_SIZE(bb_special_cases); | |
11023 | + ++i, ++r) { | |
11024 | + if (to == r->address && | |
11025 | + (r->fname == NULL || strcmp(bb_func_name, r->fname) == 0)) | |
11026 | + goto match; | |
11027 | + } | |
11028 | + /* Some inline assembler code has jumps to .fixup sections which result | |
11029 | + * in out of line transfers with undefined state, ignore them. | |
11030 | + */ | |
11031 | + if (strcmp(bb_func_name, "strnlen_user") == 0 || | |
11032 | + strcmp(bb_func_name, "copy_from_user") == 0) | |
11033 | + return 1; | |
11034 | + return 0; | |
11035 | + | |
11036 | +match: | |
11037 | + /* Check the running registers match */ | |
11038 | + for (reg = BBRG_RAX; reg < r->regs_size; ++reg) { | |
11039 | + expect_value = r->regs[reg].value; | |
11040 | + if (test_bit(expect_value, r->skip_regs.bits)) { | |
11041 | + /* this regs entry is not defined for this label */ | |
11042 | + continue; | |
11043 | + } | |
11044 | + if (expect_value == BBRG_UNDEFINED) | |
11045 | + continue; | |
11046 | + expect_offset = r->regs[reg].offset; | |
11047 | + value = bb_reg_code_value(reg); | |
11048 | + offset = bb_reg_code_offset(reg); | |
11049 | + if (expect_value == value && | |
11050 | + (value != BBRG_OSP || r->osp_offset == offset)) | |
11051 | + continue; | |
11052 | + kdb_printf("%s: Expected %s to contain %s", | |
11053 | + __FUNCTION__, | |
11054 | + bbrg_name[reg], | |
11055 | + bbrg_name[expect_value]); | |
11056 | + if (r->osp_offset) | |
11057 | + KDB_DEBUG_BB_OFFSET_PRINTF(r->osp_offset, "", ""); | |
11058 | + kdb_printf(". It actually contains %s", bbrg_name[value]); | |
11059 | + if (offset) | |
11060 | + KDB_DEBUG_BB_OFFSET_PRINTF(offset, "", ""); | |
11061 | + kdb_printf("\n"); | |
11062 | + ++errors; | |
11063 | + if (max_errors-- == 0) | |
11064 | + goto fail; | |
11065 | + } | |
11066 | + /* Check that any memory data on stack matches */ | |
11067 | + i = j = 0; | |
11068 | + while (i < bb_reg_state->mem_count && | |
11069 | + j < r->mem_size) { | |
11070 | + expect_value = r->mem[j].value; | |
11071 | + if (test_bit(expect_value, r->skip_mem.bits) || | |
11072 | + expect_value == BBRG_UNDEFINED) { | |
11073 | + /* this memory slot is not defined for this label */ | |
11074 | + ++j; | |
11075 | + continue; | |
11076 | + } | |
11077 | + rsp_offset = bb_reg_state->memory[i].offset_address - | |
11078 | + bb_reg_code_offset(BBRG_RSP); | |
11079 | + if (rsp_offset > | |
11080 | + r->mem[j].offset_address) { | |
11081 | + /* extra slots in memory are OK */ | |
11082 | + ++i; | |
11083 | + } else if (rsp_offset < | |
11084 | + r->mem[j].offset_address) { | |
11085 | + /* Required memory slot is missing */ | |
11086 | + kdb_printf("%s: Invalid bb_reg_state.memory, " | |
11087 | + "missing memory entry[%d] %s\n", | |
11088 | + __FUNCTION__, j, bbrg_name[expect_value]); | |
11089 | + ++errors; | |
11090 | + if (max_errors-- == 0) | |
11091 | + goto fail; | |
11092 | + ++j; | |
11093 | + } else { | |
11094 | + if (bb_reg_state->memory[i].offset_value || | |
11095 | + bb_reg_state->memory[i].value != expect_value) { | |
11096 | + /* memory slot is present but contains wrong | |
11097 | + * value. | |
11098 | + */ | |
11099 | + kdb_printf("%s: Invalid bb_reg_state.memory, " | |
11100 | + "wrong value in slot %d, " | |
11101 | + "should be %s, it is %s\n", | |
11102 | + __FUNCTION__, i, | |
11103 | + bbrg_name[expect_value], | |
11104 | + bbrg_name[bb_reg_state->memory[i].value]); | |
11105 | + ++errors; | |
11106 | + if (max_errors-- == 0) | |
11107 | + goto fail; | |
11108 | + } | |
11109 | + ++i; | |
11110 | + ++j; | |
11111 | + } | |
11112 | + } | |
11113 | + while (j < r->mem_size) { | |
11114 | + expect_value = r->mem[j].value; | |
11115 | + if (test_bit(expect_value, r->skip_mem.bits) || | |
11116 | + expect_value == BBRG_UNDEFINED) | |
11117 | + ++j; | |
11118 | + else | |
11119 | + break; | |
11120 | + } | |
11121 | + if (j != r->mem_size) { | |
11122 | + /* Hit end of memory before testing all the pt_reg slots */ | |
11123 | + kdb_printf("%s: Invalid bb_reg_state.memory, " | |
11124 | + "missing trailing entries\n", | |
11125 | + __FUNCTION__); | |
11126 | + ++errors; | |
11127 | + if (max_errors-- == 0) | |
11128 | + goto fail; | |
11129 | + } | |
11130 | + if (errors) | |
11131 | + goto fail; | |
11132 | + return 1; | |
11133 | +fail: | |
11134 | + kdb_printf("%s: on transfer to %s\n", __FUNCTION__, r->name); | |
11135 | + bb_giveup = 1; | |
11136 | + return 1; | |
11137 | +} | |
11138 | + | |
11139 | +/* Transfer of control to a label outside the current function. If the | |
11140 | + * transfer is to a known common code path then do a sanity check on the state | |
11141 | + * at this point. | |
11142 | + */ | |
11143 | + | |
11144 | +static void | |
11145 | +bb_sanity_check(int type) | |
11146 | +{ | |
11147 | + enum bb_reg_code expect, actual; | |
11148 | + int i, offset, error = 0; | |
11149 | + | |
11150 | + for (i = 0; i < ARRAY_SIZE(bb_preserved_reg); ++i) { | |
11151 | + expect = bb_preserved_reg[i]; | |
11152 | + actual = bb_reg_code_value(expect); | |
11153 | + offset = bb_reg_code_offset(expect); | |
11154 | + if (expect == actual) | |
11155 | + continue; | |
11156 | + /* type == 1 is sysret/sysexit, ignore RSP */ | |
11157 | + if (type && expect == BBRG_RSP) | |
11158 | + continue; | |
11159 | + /* type == 1 is sysret/sysexit, ignore RBP for i386 */ | |
11160 | + /* We used to have "#ifndef CONFIG_X86_64" for the type=1 RBP | |
11161 | + * test; however, x86_64 can run ia32 compatible mode and | |
11162 | + * hit this problem. Perform the following test anyway! | |
11163 | + */ | |
11164 | + if (type && expect == BBRG_RBP) | |
11165 | + continue; | |
11166 | + /* RSP should contain OSP+0. Except for ptregscall_common and | |
11167 | + * ia32_ptregs_common, they get a partial pt_regs, fudge the | |
11168 | + * stack to make it a full pt_regs then reverse the effect on | |
11169 | + * exit, so the offset is -0x50 on exit. | |
11170 | + */ | |
11171 | + if (expect == BBRG_RSP && | |
11172 | + bb_is_osp_defined(expect) && | |
11173 | + (offset == 0 || | |
11174 | + (offset == -0x50 && | |
11175 | + (strcmp(bb_func_name, "ptregscall_common") == 0 || | |
11176 | + strcmp(bb_func_name, "ia32_ptregs_common") == 0)))) | |
11177 | + continue; | |
11178 | + kdb_printf("%s: Expected %s, got %s", | |
11179 | + __FUNCTION__, | |
11180 | + bbrg_name[expect], bbrg_name[actual]); | |
11181 | + if (offset) | |
11182 | + KDB_DEBUG_BB_OFFSET_PRINTF(offset, "", ""); | |
11183 | + kdb_printf("\n"); | |
11184 | + error = 1; | |
11185 | + } | |
11186 | + BB_CHECK(error, error, ); | |
11187 | +} | |
11188 | + | |
11189 | +/* Transfer of control. Follow the arc and save the current state as input to | |
11190 | + * another basic block. | |
11191 | + */ | |
11192 | + | |
11193 | +static void | |
11194 | +bb_transfer(bfd_vma from, bfd_vma to, unsigned int drop_through) | |
11195 | +{ | |
11196 | + int i, found; | |
11197 | + size_t size; | |
11198 | + struct bb* bb = NULL; /*stupid gcc */ | |
11199 | + struct bb_jmp *bb_jmp; | |
11200 | + struct bb_reg_state *state; | |
11201 | + bb_reg_state_canonicalize(); | |
11202 | + found = 0; | |
11203 | + for (i = 0; i < bb_jmp_count; ++i) { | |
11204 | + bb_jmp = bb_jmp_list + i; | |
11205 | + if (bb_jmp->from == from && | |
11206 | + bb_jmp->to == to && | |
11207 | + bb_jmp->drop_through == drop_through) { | |
11208 | + found = 1; | |
11209 | + break; | |
11210 | + } | |
11211 | + } | |
11212 | + if (!found) { | |
11213 | + /* Transfer outside the current function. Check the special | |
11214 | + * cases (mainly in entry.S) first. If it is not a known | |
11215 | + * special case then check if the target address is the start | |
11216 | + * of a function or not. If it is the start of a function then | |
11217 | + * assume tail recursion and require that the state be the same | |
11218 | + * as on entry. Otherwise assume out of line code (e.g. | |
11219 | + * spinlock contention path) and ignore it, the state can be | |
11220 | + * anything. | |
11221 | + */ | |
11222 | + kdb_symtab_t symtab; | |
11223 | + if (bb_special_case(to)) | |
11224 | + return; | |
11225 | + kdbnearsym(to, &symtab); | |
11226 | + if (symtab.sym_start != to) | |
11227 | + return; | |
11228 | + bb_sanity_check(0); | |
11229 | + if (bb_giveup) | |
11230 | + return; | |
11231 | +#ifdef NO_SIBLINGS | |
11232 | + /* Only print this message when the kernel is compiled with | |
11233 | + * -fno-optimize-sibling-calls. Otherwise it would print a | |
11234 | + * message for every tail recursion call. If you see the | |
11235 | + * message below then you probably have an assembler label that | |
11236 | + * is not listed in the special cases. | |
11237 | + */ | |
11238 | + kdb_printf(" not matched: from " | |
11239 | + kdb_bfd_vma_fmt0 | |
11240 | + " to " kdb_bfd_vma_fmt0 | |
11241 | + " drop_through %d bb_jmp[%d]\n", | |
11242 | + from, to, drop_through, i); | |
11243 | +#endif /* NO_SIBLINGS */ | |
11244 | + return; | |
11245 | + } | |
11246 | + KDB_DEBUG_BB(" matched: from " kdb_bfd_vma_fmt0 | |
11247 | + " to " kdb_bfd_vma_fmt0 | |
11248 | + " drop_through %d bb_jmp[%d]\n", | |
11249 | + from, to, drop_through, i); | |
11250 | + found = 0; | |
11251 | + for (i = 0; i < bb_count; ++i) { | |
11252 | + bb = bb_list[i]; | |
11253 | + if (bb->start == to) { | |
11254 | + found = 1; | |
11255 | + break; | |
11256 | + } | |
11257 | + } | |
11258 | + BB_CHECK(!found, to, ); | |
11259 | + /* If the register state for this arc has already been set (we are | |
11260 | + * rescanning the block that originates the arc) and the state is the | |
11261 | + * same as the previous state for this arc then this input to the | |
11262 | + * target block is the same as last time, so there is no need to rescan | |
11263 | + * the target block. | |
11264 | + */ | |
11265 | + state = bb_jmp->state; | |
11266 | + size = bb_reg_state_size(bb_reg_state); | |
11267 | + if (state) { | |
11268 | + bb_reg_state->ref_count = state->ref_count; | |
11269 | + if (memcmp(state, bb_reg_state, size) == 0) { | |
11270 | + KDB_DEBUG_BB(" no state change\n"); | |
11271 | + return; | |
11272 | + } | |
11273 | + if (--state->ref_count == 0) | |
11274 | + debug_kfree(state); | |
11275 | + bb_jmp->state = NULL; | |
11276 | + } | |
11277 | + /* New input state is required. To save space, check if any other arcs | |
11278 | + * have the same state and reuse them where possible. The overall set | |
11279 | + * of inputs to the target block is now different so the target block | |
11280 | + * must be rescanned. | |
11281 | + */ | |
11282 | + bb->changed = 1; | |
11283 | + for (i = 0; i < bb_jmp_count; ++i) { | |
11284 | + state = bb_jmp_list[i].state; | |
11285 | + if (!state) | |
11286 | + continue; | |
11287 | + bb_reg_state->ref_count = state->ref_count; | |
11288 | + if (memcmp(state, bb_reg_state, size) == 0) { | |
11289 | + KDB_DEBUG_BB(" reuse bb_jmp[%d]\n", i); | |
11290 | + bb_jmp->state = state; | |
11291 | + ++state->ref_count; | |
11292 | + return; | |
11293 | + } | |
11294 | + } | |
11295 | + state = debug_kmalloc(size, GFP_ATOMIC); | |
11296 | + if (!state) { | |
11297 | + kdb_printf("\n\n%s: out of debug_kmalloc\n", __FUNCTION__); | |
11298 | + bb_giveup = 1; | |
11299 | + return; | |
11300 | + } | |
11301 | + memcpy(state, bb_reg_state, size); | |
11302 | + state->ref_count = 1; | |
11303 | + bb_jmp->state = state; | |
11304 | + KDB_DEBUG_BB(" new state %p\n", state); | |
11305 | +} | |
11306 | + | |
11307 | +/* Isolate the processing for 'mov' so it can be used for 'xadd'/'xchg' as | |
11308 | + * well. | |
11309 | + * | |
11310 | + * xadd/xchg expect this function to return BBOU_NOP for special cases, | |
11311 | + * otherwise it returns BBOU_RSWD. All special cases must be handled entirely | |
11312 | + * within this function, including doing bb_read_operand or bb_write_operand | |
11313 | + * where necessary. | |
11314 | + */ | |
11315 | + | |
11316 | +static enum bb_operand_usage | |
11317 | +bb_usage_mov(const struct bb_operand *src, const struct bb_operand *dst, int l) | |
11318 | +{ | |
11319 | + int full_register_src, full_register_dst; | |
11320 | + full_register_src = bb_operand_length(src, bb_decode.opcode[l]) | |
11321 | + == KDB_WORD_SIZE * 8; | |
11322 | + full_register_dst = bb_operand_length(dst, bb_decode.opcode[l]) | |
11323 | + == KDB_WORD_SIZE * 8; | |
11324 | + /* If both src and dst are full integer registers then record the | |
11325 | + * register change. | |
11326 | + */ | |
11327 | + if (src->reg && | |
11328 | + bb_is_int_reg(src->base_rc) && | |
11329 | + dst->reg && | |
11330 | + bb_is_int_reg(dst->base_rc) && | |
11331 | + full_register_src && | |
11332 | + full_register_dst) { | |
11333 | + /* Special case for the code that switches stacks in | |
11334 | + * jprobe_return. That code must modify RSP but it does it in | |
11335 | + * a well defined manner. Do not invalidate RSP. | |
11336 | + */ | |
11337 | + if (src->base_rc == BBRG_RBX && | |
11338 | + dst->base_rc == BBRG_RSP && | |
11339 | + strcmp(bb_func_name, "jprobe_return") == 0) { | |
11340 | + bb_read_operand(src); | |
11341 | + return BBOU_NOP; | |
11342 | + } | |
11343 | + /* math_abort takes the equivalent of a longjmp structure and | |
11344 | + * resets the stack. Ignore this, it leaves RSP well defined. | |
11345 | + */ | |
11346 | + if (dst->base_rc == BBRG_RSP && | |
11347 | + strcmp(bb_func_name, "math_abort") == 0) { | |
11348 | + bb_read_operand(src); | |
11349 | + return BBOU_NOP; | |
11350 | + } | |
11351 | + bb_reg_set_reg(dst->base_rc, src->base_rc); | |
11352 | + return BBOU_NOP; | |
11353 | + } | |
11354 | + /* If the move is from a full integer register to stack then record it. | |
11355 | + */ | |
11356 | + if (src->reg && | |
11357 | + bb_is_simple_memory(dst) && | |
11358 | + bb_is_osp_defined(dst->base_rc) && | |
11359 | + full_register_src) { | |
11360 | + /* Ugly special case. Initializing list heads on stack causes | |
11361 | + * false references to stack variables when the list head is | |
11362 | + * used. Static code analysis cannot detect that the list head | |
11363 | + * has been changed by a previous execution loop and that a | |
11364 | + * basic block is only executed after the list head has been | |
11365 | + * changed. | |
11366 | + * | |
11367 | + * These false references can result in valid stack variables | |
11368 | + * being incorrectly cleared on some logic paths. Ignore | |
11369 | + * stores to stack variables which point to themselves or to | |
11370 | + * the previous word so the list head initialization is not | |
11371 | + * recorded. | |
11372 | + */ | |
11373 | + if (bb_is_osp_defined(src->base_rc)) { | |
11374 | + int stack1 = bb_reg_code_offset(src->base_rc); | |
11375 | + int stack2 = bb_reg_code_offset(dst->base_rc) + | |
11376 | + dst->disp; | |
11377 | + if (stack1 == stack2 || | |
11378 | + stack1 == stack2 - KDB_WORD_SIZE) | |
11379 | + return BBOU_NOP; | |
11380 | + } | |
11381 | + bb_memory_set_reg(dst->base_rc, src->base_rc, dst->disp); | |
11382 | + return BBOU_NOP; | |
11383 | + } | |
11384 | + /* If the move is from stack to a full integer register then record it. | |
11385 | + */ | |
11386 | + if (bb_is_simple_memory(src) && | |
11387 | + bb_is_osp_defined(src->base_rc) && | |
11388 | + dst->reg && | |
11389 | + bb_is_int_reg(dst->base_rc) && | |
11390 | + full_register_dst) { | |
11391 | +#ifdef CONFIG_X86_32 | |
11392 | + /* mov from TSS_sysenter_sp0+offset to esp to fix up the | |
11393 | + * sysenter stack, it leaves esp well defined. mov | |
11394 | + * TSS_ysenter_sp0+offset(%esp),%esp is followed by up to 5 | |
11395 | + * push instructions to mimic the hardware stack push. If | |
11396 | + * TSS_sysenter_sp0 is offset then only 3 words will be | |
11397 | + * pushed. | |
11398 | + */ | |
11399 | + if (dst->base_rc == BBRG_RSP && | |
11400 | + src->disp >= TSS_sysenter_sp0 && | |
11401 | + bb_is_osp_defined(BBRG_RSP)) { | |
11402 | + int pushes; | |
11403 | + pushes = src->disp == TSS_sysenter_sp0 ? 5 : 3; | |
11404 | + bb_reg_code_set_offset(BBRG_RSP, | |
11405 | + bb_reg_code_offset(BBRG_RSP) + | |
11406 | + pushes * KDB_WORD_SIZE); | |
11407 | + KDB_DEBUG_BB_OFFSET( | |
11408 | + bb_reg_code_offset(BBRG_RSP), | |
11409 | + " sysenter fixup, RSP", | |
11410 | + "\n"); | |
11411 | + return BBOU_NOP; | |
11412 | + } | |
11413 | +#endif /* CONFIG_X86_32 */ | |
11414 | + bb_read_operand(src); | |
11415 | + bb_reg_set_memory(dst->base_rc, src->base_rc, src->disp); | |
11416 | + return BBOU_NOP; | |
11417 | + } | |
11418 | + /* move %gs:0x<nn>,%rsp is used to unconditionally switch to another | |
11419 | + * stack. Ignore this special case, it is handled by the stack | |
11420 | + * unwinding code. | |
11421 | + */ | |
11422 | + if (src->segment && | |
11423 | + strcmp(src->segment, "%gs") == 0 && | |
11424 | + dst->reg && | |
11425 | + dst->base_rc == BBRG_RSP) | |
11426 | + return BBOU_NOP; | |
11427 | + /* move %reg,%reg is a nop */ | |
11428 | + if (src->reg && | |
11429 | + dst->reg && | |
11430 | + !src->segment && | |
11431 | + !dst->segment && | |
11432 | + strcmp(src->base, dst->base) == 0) | |
11433 | + return BBOU_NOP; | |
11434 | + /* Special case for the code that switches stacks in the scheduler | |
11435 | + * (switch_to()). That code must modify RSP but it does it in a well | |
11436 | + * defined manner. Do not invalidate RSP. | |
11437 | + */ | |
11438 | + if (dst->reg && | |
11439 | + dst->base_rc == BBRG_RSP && | |
11440 | + full_register_dst && | |
11441 | + bb_is_scheduler_address()) { | |
11442 | + bb_read_operand(src); | |
11443 | + return BBOU_NOP; | |
11444 | + } | |
11445 | + /* Special case for the code that switches stacks in resume from | |
11446 | + * hibernation code. That code must modify RSP but it does it in a | |
11447 | + * well defined manner. Do not invalidate RSP. | |
11448 | + */ | |
11449 | + if (src->memory && | |
11450 | + dst->reg && | |
11451 | + dst->base_rc == BBRG_RSP && | |
11452 | + full_register_dst && | |
11453 | + strcmp(bb_func_name, "restore_image") == 0) { | |
11454 | + bb_read_operand(src); | |
11455 | + return BBOU_NOP; | |
11456 | + } | |
11457 | + return BBOU_RSWD; | |
11458 | +} | |
11459 | + | |
11460 | +static enum bb_operand_usage | |
11461 | +bb_usage_xadd(const struct bb_operand *src, const struct bb_operand *dst) | |
11462 | +{ | |
11463 | + /* Simulate xadd as a series of instructions including mov, that way we | |
11464 | + * get the benefit of all the special cases already handled by | |
11465 | + * BBOU_MOV. | |
11466 | + * | |
11467 | + * tmp = src + dst, src = dst, dst = tmp. | |
11468 | + * | |
11469 | + * For tmp, pick a register that is undefined. If all registers are | |
11470 | + * defined then pick one that is not being used by xadd. | |
11471 | + */ | |
11472 | + enum bb_reg_code reg = BBRG_UNDEFINED; | |
11473 | + struct bb_operand tmp; | |
11474 | + struct bb_reg_contains save_tmp; | |
11475 | + enum bb_operand_usage usage; | |
11476 | + int undefined = 0; | |
11477 | + for (reg = BBRG_RAX; reg < BBRG_RAX + KDB_INT_REGISTERS; ++reg) { | |
11478 | + if (bb_reg_code_value(reg) == BBRG_UNDEFINED) { | |
11479 | + undefined = 1; | |
11480 | + break; | |
11481 | + } | |
11482 | + } | |
11483 | + if (!undefined) { | |
11484 | + for (reg = BBRG_RAX; reg < BBRG_RAX + KDB_INT_REGISTERS; ++reg) { | |
11485 | + if (reg != src->base_rc && | |
11486 | + reg != src->index_rc && | |
11487 | + reg != dst->base_rc && | |
11488 | + reg != dst->index_rc && | |
11489 | + reg != BBRG_RSP) | |
11490 | + break; | |
11491 | + } | |
11492 | + } | |
11493 | + KDB_DEBUG_BB(" %s saving tmp %s\n", __FUNCTION__, bbrg_name[reg]); | |
11494 | + save_tmp = bb_reg_state->contains[reg - BBRG_RAX]; | |
11495 | + bb_reg_set_undef(reg); | |
11496 | + memset(&tmp, 0, sizeof(tmp)); | |
11497 | + tmp.present = 1; | |
11498 | + tmp.reg = 1; | |
11499 | + tmp.base = debug_kmalloc(strlen(bbrg_name[reg]) + 2, GFP_ATOMIC); | |
11500 | + if (tmp.base) { | |
11501 | + tmp.base[0] = '%'; | |
11502 | + strcpy(tmp.base + 1, bbrg_name[reg]); | |
11503 | + } | |
11504 | + tmp.base_rc = reg; | |
11505 | + bb_read_operand(src); | |
11506 | + bb_read_operand(dst); | |
11507 | + if (bb_usage_mov(src, dst, sizeof("xadd")-1) == BBOU_NOP) | |
11508 | + usage = BBOU_RSRD; | |
11509 | + else | |
11510 | + usage = BBOU_RSRDWS; | |
11511 | + bb_usage_mov(&tmp, dst, sizeof("xadd")-1); | |
11512 | + KDB_DEBUG_BB(" %s restoring tmp %s\n", __FUNCTION__, bbrg_name[reg]); | |
11513 | + bb_reg_state->contains[reg - BBRG_RAX] = save_tmp; | |
11514 | + debug_kfree(tmp.base); | |
11515 | + return usage; | |
11516 | +} | |
11517 | + | |
11518 | +static enum bb_operand_usage | |
11519 | +bb_usage_xchg(const struct bb_operand *src, const struct bb_operand *dst) | |
11520 | +{ | |
11521 | + /* Simulate xchg as a series of mov instructions, that way we get the | |
11522 | + * benefit of all the special cases already handled by BBOU_MOV. | |
11523 | + * | |
11524 | + * mov dst,tmp; mov src,dst; mov tmp,src; | |
11525 | + * | |
11526 | + * For tmp, pick a register that is undefined. If all registers are | |
11527 | + * defined then pick one that is not being used by xchg. | |
11528 | + */ | |
11529 | + enum bb_reg_code reg = BBRG_UNDEFINED; | |
11530 | + int rs = BBOU_RS, rd = BBOU_RD, ws = BBOU_WS, wd = BBOU_WD; | |
11531 | + struct bb_operand tmp; | |
11532 | + struct bb_reg_contains save_tmp; | |
11533 | + int undefined = 0; | |
11534 | + for (reg = BBRG_RAX; reg < BBRG_RAX + KDB_INT_REGISTERS; ++reg) { | |
11535 | + if (bb_reg_code_value(reg) == BBRG_UNDEFINED) { | |
11536 | + undefined = 1; | |
11537 | + break; | |
11538 | + } | |
11539 | + } | |
11540 | + if (!undefined) { | |
11541 | + for (reg = BBRG_RAX; reg < BBRG_RAX + KDB_INT_REGISTERS; ++reg) { | |
11542 | + if (reg != src->base_rc && | |
11543 | + reg != src->index_rc && | |
11544 | + reg != dst->base_rc && | |
11545 | + reg != dst->index_rc && | |
11546 | + reg != BBRG_RSP) | |
11547 | + break; | |
11548 | + } | |
11549 | + } | |
11550 | + KDB_DEBUG_BB(" %s saving tmp %s\n", __FUNCTION__, bbrg_name[reg]); | |
11551 | + save_tmp = bb_reg_state->contains[reg - BBRG_RAX]; | |
11552 | + memset(&tmp, 0, sizeof(tmp)); | |
11553 | + tmp.present = 1; | |
11554 | + tmp.reg = 1; | |
11555 | + tmp.base = debug_kmalloc(strlen(bbrg_name[reg]) + 2, GFP_ATOMIC); | |
11556 | + if (tmp.base) { | |
11557 | + tmp.base[0] = '%'; | |
11558 | + strcpy(tmp.base + 1, bbrg_name[reg]); | |
11559 | + } | |
11560 | + tmp.base_rc = reg; | |
11561 | + if (bb_usage_mov(dst, &tmp, sizeof("xchg")-1) == BBOU_NOP) | |
11562 | + rd = 0; | |
11563 | + if (bb_usage_mov(src, dst, sizeof("xchg")-1) == BBOU_NOP) { | |
11564 | + rs = 0; | |
11565 | + wd = 0; | |
11566 | + } | |
11567 | + if (bb_usage_mov(&tmp, src, sizeof("xchg")-1) == BBOU_NOP) | |
11568 | + ws = 0; | |
11569 | + KDB_DEBUG_BB(" %s restoring tmp %s\n", __FUNCTION__, bbrg_name[reg]); | |
11570 | + bb_reg_state->contains[reg - BBRG_RAX] = save_tmp; | |
11571 | + debug_kfree(tmp.base); | |
11572 | + return rs | rd | ws | wd; | |
11573 | +} | |
11574 | + | |
11575 | +/* Invalidate all the scratch registers */ | |
11576 | + | |
11577 | +static void | |
11578 | +bb_invalidate_scratch_reg(void) | |
11579 | +{ | |
11580 | + int i, j; | |
11581 | + for (i = BBRG_RAX; i < BBRG_RAX + KDB_INT_REGISTERS; ++i) { | |
11582 | + for (j = 0; j < ARRAY_SIZE(bb_preserved_reg); ++j) { | |
11583 | + if (i == bb_preserved_reg[j]) | |
11584 | + goto preserved; | |
11585 | + } | |
11586 | + bb_reg_set_undef(i); | |
11587 | +preserved: | |
11588 | + continue; | |
11589 | + } | |
11590 | +} | |
11591 | + | |
11592 | +static void | |
11593 | +bb_pass2_computed_jmp(const struct bb_operand *src) | |
11594 | +{ | |
11595 | + unsigned long table = src->disp; | |
11596 | + kdb_machreg_t addr; | |
11597 | + while (!bb_giveup) { | |
11598 | + if (kdb_getword(&addr, table, sizeof(addr))) | |
11599 | + return; | |
11600 | + if (addr < bb_func_start || addr >= bb_func_end) | |
11601 | + return; | |
11602 | + bb_transfer(bb_curr_addr, addr, 0); | |
11603 | + table += KDB_WORD_SIZE; | |
11604 | + } | |
11605 | +} | |
11606 | + | |
11607 | +/* The current instruction has been decoded and all the information is in | |
11608 | + * bb_decode. Based on the opcode, track any operand usage that we care about. | |
11609 | + */ | |
11610 | + | |
11611 | +static void | |
11612 | +bb_usage(void) | |
11613 | +{ | |
11614 | + enum bb_operand_usage usage = bb_decode.match->usage; | |
11615 | + struct bb_operand *src = &bb_decode.src; | |
11616 | + struct bb_operand *dst = &bb_decode.dst; | |
11617 | + struct bb_operand *dst2 = &bb_decode.dst2; | |
11618 | + int opcode_suffix, operand_length; | |
11619 | + | |
11620 | + /* First handle all the special usage cases, and map them to a generic | |
11621 | + * case after catering for the side effects. | |
11622 | + */ | |
11623 | + | |
11624 | + if (usage == BBOU_IMUL && | |
11625 | + src->present && !dst->present && !dst2->present) { | |
11626 | + /* single operand imul, same effects as mul */ | |
11627 | + usage = BBOU_MUL; | |
11628 | + } | |
11629 | + | |
11630 | + /* AT&T syntax uses movs<l1><l2> for move with sign extension, instead | |
11631 | + * of the Intel movsx. The AT&T syntax causes problems for the opcode | |
11632 | + * mapping; movs with sign extension needs to be treated as a generic | |
11633 | + * read src, write dst, but instead it falls under the movs I/O | |
11634 | + * instruction. Fix it. | |
11635 | + */ | |
11636 | + if (usage == BBOU_MOVS && strlen(bb_decode.opcode) > 5) | |
11637 | + usage = BBOU_RSWD; | |
11638 | + | |
11639 | + /* This switch statement deliberately does not use 'default' at the top | |
11640 | + * level. That way the compiler will complain if a new BBOU_ enum is | |
11641 | + * added above and not explicitly handled here. | |
11642 | + */ | |
11643 | + switch (usage) { | |
11644 | + case BBOU_UNKNOWN: /* drop through */ | |
11645 | + case BBOU_RS: /* drop through */ | |
11646 | + case BBOU_RD: /* drop through */ | |
11647 | + case BBOU_RSRD: /* drop through */ | |
11648 | + case BBOU_WS: /* drop through */ | |
11649 | + case BBOU_RSWS: /* drop through */ | |
11650 | + case BBOU_RDWS: /* drop through */ | |
11651 | + case BBOU_RSRDWS: /* drop through */ | |
11652 | + case BBOU_WD: /* drop through */ | |
11653 | + case BBOU_RSWD: /* drop through */ | |
11654 | + case BBOU_RDWD: /* drop through */ | |
11655 | + case BBOU_RSRDWD: /* drop through */ | |
11656 | + case BBOU_WSWD: /* drop through */ | |
11657 | + case BBOU_RSWSWD: /* drop through */ | |
11658 | + case BBOU_RDWSWD: /* drop through */ | |
11659 | + case BBOU_RSRDWSWD: | |
11660 | + break; /* ignore generic usage for now */ | |
11661 | + case BBOU_ADD: | |
11662 | + /* Special case for add instructions that adjust registers | |
11663 | + * which are mapping the stack. | |
11664 | + */ | |
11665 | + if (dst->reg && bb_is_osp_defined(dst->base_rc)) { | |
11666 | + bb_adjust_osp_instruction(1); | |
11667 | + usage = BBOU_RS; | |
11668 | + } else { | |
11669 | + usage = BBOU_RSRDWD; | |
11670 | + } | |
11671 | + break; | |
11672 | + case BBOU_CALL: | |
11673 | + /* Invalidate the scratch registers. Functions sync_regs and | |
11674 | + * save_v86_state are special, their return value is the new | |
11675 | + * stack pointer. | |
11676 | + */ | |
11677 | + bb_reg_state_print(bb_reg_state); | |
11678 | + bb_invalidate_scratch_reg(); | |
11679 | + if (bb_is_static_disp(src)) { | |
11680 | + if (src->disp == bb_sync_regs) { | |
11681 | + bb_reg_set_reg(BBRG_RAX, BBRG_RSP); | |
11682 | + } else if (src->disp == bb_save_v86_state) { | |
11683 | + bb_reg_set_reg(BBRG_RAX, BBRG_RSP); | |
11684 | + bb_adjust_osp(BBRG_RAX, +KDB_WORD_SIZE); | |
11685 | + } | |
11686 | + } | |
11687 | + usage = BBOU_NOP; | |
11688 | + break; | |
11689 | + case BBOU_CBW: | |
11690 | + /* Convert word in RAX. Read RAX, write RAX */ | |
11691 | + bb_reg_read(BBRG_RAX); | |
11692 | + bb_reg_set_undef(BBRG_RAX); | |
11693 | + usage = BBOU_NOP; | |
11694 | + break; | |
11695 | + case BBOU_CMOV: | |
11696 | + /* cmove %gs:0x<nn>,%rsp is used to conditionally switch to | |
11697 | + * another stack. Ignore this special case, it is handled by | |
11698 | + * the stack unwinding code. | |
11699 | + */ | |
11700 | + if (src->segment && | |
11701 | + strcmp(src->segment, "%gs") == 0 && | |
11702 | + dst->reg && | |
11703 | + dst->base_rc == BBRG_RSP) | |
11704 | + usage = BBOU_NOP; | |
11705 | + else | |
11706 | + usage = BBOU_RSWD; | |
11707 | + break; | |
11708 | + case BBOU_CMPXCHG: | |
11709 | + /* Read RAX, write RAX plus src read, dst write */ | |
11710 | + bb_reg_read(BBRG_RAX); | |
11711 | + bb_reg_set_undef(BBRG_RAX); | |
11712 | + usage = BBOU_RSWD; | |
11713 | + break; | |
11714 | + case BBOU_CMPXCHGD: | |
11715 | + /* Read RAX, RBX, RCX, RDX, write RAX, RDX plus src read/write */ | |
11716 | + bb_reg_read(BBRG_RAX); | |
11717 | + bb_reg_read(BBRG_RBX); | |
11718 | + bb_reg_read(BBRG_RCX); | |
11719 | + bb_reg_read(BBRG_RDX); | |
11720 | + bb_reg_set_undef(BBRG_RAX); | |
11721 | + bb_reg_set_undef(BBRG_RDX); | |
11722 | + usage = BBOU_RSWS; | |
11723 | + break; | |
11724 | + case BBOU_CPUID: | |
11725 | + /* Read RAX, write RAX, RBX, RCX, RDX */ | |
11726 | + bb_reg_read(BBRG_RAX); | |
11727 | + bb_reg_set_undef(BBRG_RAX); | |
11728 | + bb_reg_set_undef(BBRG_RBX); | |
11729 | + bb_reg_set_undef(BBRG_RCX); | |
11730 | + bb_reg_set_undef(BBRG_RDX); | |
11731 | + usage = BBOU_NOP; | |
11732 | + break; | |
11733 | + case BBOU_CWD: | |
11734 | + /* Convert word in RAX, RDX. Read RAX, write RDX */ | |
11735 | + bb_reg_read(BBRG_RAX); | |
11736 | + bb_reg_set_undef(BBRG_RDX); | |
11737 | + usage = BBOU_NOP; | |
11738 | + break; | |
11739 | + case BBOU_DIV: /* drop through */ | |
11740 | + case BBOU_IDIV: | |
11741 | + /* The 8 bit variants only affect RAX, the 16, 32 and 64 bit | |
11742 | + * variants affect RDX as well. | |
11743 | + */ | |
11744 | + switch (usage) { | |
11745 | + case BBOU_DIV: | |
11746 | + opcode_suffix = bb_decode.opcode[3]; | |
11747 | + break; | |
11748 | + case BBOU_IDIV: | |
11749 | + opcode_suffix = bb_decode.opcode[4]; | |
11750 | + break; | |
11751 | + default: | |
11752 | + opcode_suffix = 'q'; | |
11753 | + break; | |
11754 | + } | |
11755 | + operand_length = bb_operand_length(src, opcode_suffix); | |
11756 | + bb_reg_read(BBRG_RAX); | |
11757 | + bb_reg_set_undef(BBRG_RAX); | |
11758 | + if (operand_length != 8) { | |
11759 | + bb_reg_read(BBRG_RDX); | |
11760 | + bb_reg_set_undef(BBRG_RDX); | |
11761 | + } | |
11762 | + usage = BBOU_RS; | |
11763 | + break; | |
11764 | + case BBOU_IMUL: | |
11765 | + /* Only the two and three operand forms get here. The one | |
11766 | + * operand form is treated as mul. | |
11767 | + */ | |
11768 | + if (dst2->present) { | |
11769 | + /* The three operand form is a special case, read the first two | |
11770 | + * operands, write the third. | |
11771 | + */ | |
11772 | + bb_read_operand(src); | |
11773 | + bb_read_operand(dst); | |
11774 | + bb_write_operand(dst2); | |
11775 | + usage = BBOU_NOP; | |
11776 | + } else { | |
11777 | + usage = BBOU_RSRDWD; | |
11778 | + } | |
11779 | + break; | |
11780 | + case BBOU_IRET: | |
11781 | + bb_sanity_check(0); | |
11782 | + usage = BBOU_NOP; | |
11783 | + break; | |
11784 | + case BBOU_JMP: | |
11785 | + if (bb_is_static_disp(src)) | |
11786 | + bb_transfer(bb_curr_addr, src->disp, 0); | |
11787 | + else if (src->indirect && | |
11788 | + src->disp && | |
11789 | + src->base == NULL && | |
11790 | + src->index && | |
11791 | + src->scale == KDB_WORD_SIZE) | |
11792 | + bb_pass2_computed_jmp(src); | |
11793 | + usage = BBOU_RS; | |
11794 | + break; | |
11795 | + case BBOU_LAHF: | |
11796 | + /* Write RAX */ | |
11797 | + bb_reg_set_undef(BBRG_RAX); | |
11798 | + usage = BBOU_NOP; | |
11799 | + break; | |
11800 | + case BBOU_LEA: | |
11801 | + /* dst = src + disp. Often used to calculate offsets into the | |
11802 | + * stack, so check if it uses a stack pointer. | |
11803 | + */ | |
11804 | + usage = BBOU_RSWD; | |
11805 | + if (bb_is_simple_memory(src)) { | |
11806 | + if (bb_is_osp_defined(src->base_rc)) { | |
11807 | + bb_reg_set_reg(dst->base_rc, src->base_rc); | |
11808 | + bb_adjust_osp_instruction(1); | |
11809 | + usage = BBOU_RS; | |
11810 | + } else if (src->disp == 0 && | |
11811 | + src->base_rc == dst->base_rc) { | |
11812 | + /* lea 0(%reg),%reg is generated by i386 | |
11813 | + * GENERIC_NOP7. | |
11814 | + */ | |
11815 | + usage = BBOU_NOP; | |
11816 | + } else if (src->disp == 4096 && | |
11817 | + (src->base_rc == BBRG_R8 || | |
11818 | + src->base_rc == BBRG_RDI) && | |
11819 | + strcmp(bb_func_name, "relocate_kernel") == 0) { | |
11820 | + /* relocate_kernel: setup a new stack at the | |
11821 | + * end of the physical control page, using | |
11822 | + * (x86_64) lea 4096(%r8),%rsp or (i386) lea | |
11823 | + * 4096(%edi),%esp | |
11824 | + */ | |
11825 | + usage = BBOU_NOP; | |
11826 | + } | |
11827 | + } | |
11828 | + break; | |
11829 | + case BBOU_LEAVE: | |
11830 | + /* RSP = RBP; RBP = *(RSP); RSP += KDB_WORD_SIZE; */ | |
11831 | + bb_reg_set_reg(BBRG_RSP, BBRG_RBP); | |
11832 | + if (bb_is_osp_defined(BBRG_RSP)) | |
11833 | + bb_reg_set_memory(BBRG_RBP, BBRG_RSP, 0); | |
11834 | + else | |
11835 | + bb_reg_set_undef(BBRG_RBP); | |
11836 | + if (bb_is_osp_defined(BBRG_RSP)) | |
11837 | + bb_adjust_osp(BBRG_RSP, KDB_WORD_SIZE); | |
11838 | + /* common_interrupt uses leave in a non-standard manner */ | |
11839 | + if (strcmp(bb_func_name, "common_interrupt") != 0) | |
11840 | + bb_sanity_check(0); | |
11841 | + usage = BBOU_NOP; | |
11842 | + break; | |
11843 | + case BBOU_LODS: | |
11844 | + /* Read RSI, write RAX, RSI */ | |
11845 | + bb_reg_read(BBRG_RSI); | |
11846 | + bb_reg_set_undef(BBRG_RAX); | |
11847 | + bb_reg_set_undef(BBRG_RSI); | |
11848 | + usage = BBOU_NOP; | |
11849 | + break; | |
11850 | + case BBOU_LOOP: | |
11851 | + /* Read and write RCX */ | |
11852 | + bb_reg_read(BBRG_RCX); | |
11853 | + bb_reg_set_undef(BBRG_RCX); | |
11854 | + if (bb_is_static_disp(src)) | |
11855 | + bb_transfer(bb_curr_addr, src->disp, 0); | |
11856 | + usage = BBOU_NOP; | |
11857 | + break; | |
11858 | + case BBOU_LSS: | |
11859 | + /* lss offset(%esp),%esp leaves esp well defined */ | |
11860 | + if (dst->reg && | |
11861 | + dst->base_rc == BBRG_RSP && | |
11862 | + bb_is_simple_memory(src) && | |
11863 | + src->base_rc == BBRG_RSP) { | |
11864 | + bb_adjust_osp(BBRG_RSP, 2*KDB_WORD_SIZE + src->disp); | |
11865 | + usage = BBOU_NOP; | |
11866 | + } else { | |
11867 | + usage = BBOU_RSWD; | |
11868 | + } | |
11869 | + break; | |
11870 | + case BBOU_MONITOR: | |
11871 | + /* Read RAX, RCX, RDX */ | |
11872 | + bb_reg_set_undef(BBRG_RAX); | |
11873 | + bb_reg_set_undef(BBRG_RCX); | |
11874 | + bb_reg_set_undef(BBRG_RDX); | |
11875 | + usage = BBOU_NOP; | |
11876 | + break; | |
11877 | + case BBOU_MOV: | |
11878 | + usage = bb_usage_mov(src, dst, sizeof("mov")-1); | |
11879 | + break; | |
11880 | + case BBOU_MOVS: | |
11881 | + /* Read RSI, RDI, write RSI, RDI */ | |
11882 | + bb_reg_read(BBRG_RSI); | |
11883 | + bb_reg_read(BBRG_RDI); | |
11884 | + bb_reg_set_undef(BBRG_RSI); | |
11885 | + bb_reg_set_undef(BBRG_RDI); | |
11886 | + usage = BBOU_NOP; | |
11887 | + break; | |
11888 | + case BBOU_MUL: | |
11889 | + /* imul (one operand form only) or mul. Read RAX. If the | |
11890 | + * operand length is not 8 then write RDX. | |
11891 | + */ | |
11892 | + if (bb_decode.opcode[0] == 'i') | |
11893 | + opcode_suffix = bb_decode.opcode[4]; | |
11894 | + else | |
11895 | + opcode_suffix = bb_decode.opcode[3]; | |
11896 | + operand_length = bb_operand_length(src, opcode_suffix); | |
11897 | + bb_reg_read(BBRG_RAX); | |
11898 | + if (operand_length != 8) | |
11899 | + bb_reg_set_undef(BBRG_RDX); | |
11900 | + usage = BBOU_NOP; | |
11901 | + break; | |
11902 | + case BBOU_MWAIT: | |
11903 | + /* Read RAX, RCX */ | |
11904 | + bb_reg_read(BBRG_RAX); | |
11905 | + bb_reg_read(BBRG_RCX); | |
11906 | + usage = BBOU_NOP; | |
11907 | + break; | |
11908 | + case BBOU_NOP: | |
11909 | + break; | |
11910 | + case BBOU_OUTS: | |
11911 | + /* Read RSI, RDX, write RSI */ | |
11912 | + bb_reg_read(BBRG_RSI); | |
11913 | + bb_reg_read(BBRG_RDX); | |
11914 | + bb_reg_set_undef(BBRG_RSI); | |
11915 | + usage = BBOU_NOP; | |
11916 | + break; | |
11917 | + case BBOU_POP: | |
11918 | + /* Complicated by the fact that you can pop from top of stack | |
11919 | + * to a stack location, for this case the destination location | |
11920 | + * is calculated after adjusting RSP. Analysis of the kernel | |
11921 | + * code shows that gcc only uses this strange format to get the | |
11922 | + * flags into a local variable, e.g. pushf; popl 0x10(%esp); so | |
11923 | + * I am going to ignore this special case. | |
11924 | + */ | |
11925 | + usage = BBOU_WS; | |
11926 | + if (!bb_is_osp_defined(BBRG_RSP)) { | |
11927 | + if (!bb_is_scheduler_address()) { | |
11928 | + kdb_printf("pop when BBRG_RSP is undefined?\n"); | |
11929 | + bb_giveup = 1; | |
11930 | + } | |
11931 | + } else { | |
11932 | + if (src->reg) { | |
11933 | + bb_reg_set_memory(src->base_rc, BBRG_RSP, 0); | |
11934 | + usage = BBOU_NOP; | |
11935 | + } | |
11936 | + /* pop %rsp does not adjust rsp */ | |
11937 | + if (!src->reg || | |
11938 | + src->base_rc != BBRG_RSP) | |
11939 | + bb_adjust_osp(BBRG_RSP, KDB_WORD_SIZE); | |
11940 | + } | |
11941 | + break; | |
11942 | + case BBOU_POPF: | |
11943 | + /* Do not care about flags, just adjust RSP */ | |
11944 | + if (!bb_is_osp_defined(BBRG_RSP)) { | |
11945 | + if (!bb_is_scheduler_address()) { | |
11946 | + kdb_printf("popf when BBRG_RSP is undefined?\n"); | |
11947 | + bb_giveup = 1; | |
11948 | + } | |
11949 | + } else { | |
11950 | + bb_adjust_osp(BBRG_RSP, KDB_WORD_SIZE); | |
11951 | + } | |
11952 | + usage = BBOU_WS; | |
11953 | + break; | |
11954 | + case BBOU_PUSH: | |
11955 | + /* Complicated by the fact that you can push from a stack | |
11956 | + * location to top of stack, the source location is calculated | |
11957 | + * before adjusting RSP. Analysis of the kernel code shows | |
11958 | + * that gcc only uses this strange format to restore the flags | |
11959 | + * from a local variable, e.g. pushl 0x10(%esp); popf; so I am | |
11960 | + * going to ignore this special case. | |
11961 | + */ | |
11962 | + usage = BBOU_RS; | |
11963 | + if (!bb_is_osp_defined(BBRG_RSP)) { | |
11964 | + if (!bb_is_scheduler_address()) { | |
11965 | + kdb_printf("push when BBRG_RSP is undefined?\n"); | |
11966 | + bb_giveup = 1; | |
11967 | + } | |
11968 | + } else { | |
11969 | + bb_adjust_osp(BBRG_RSP, -KDB_WORD_SIZE); | |
11970 | + if (src->reg && | |
11971 | + bb_reg_code_offset(BBRG_RSP) <= 0) | |
11972 | + bb_memory_set_reg(BBRG_RSP, src->base_rc, 0); | |
11973 | + } | |
11974 | + break; | |
11975 | + case BBOU_PUSHF: | |
11976 | + /* Do not care about flags, just adjust RSP */ | |
11977 | + if (!bb_is_osp_defined(BBRG_RSP)) { | |
11978 | + if (!bb_is_scheduler_address()) { | |
11979 | + kdb_printf("pushf when BBRG_RSP is undefined?\n"); | |
11980 | + bb_giveup = 1; | |
11981 | + } | |
11982 | + } else { | |
11983 | + bb_adjust_osp(BBRG_RSP, -KDB_WORD_SIZE); | |
11984 | + } | |
11985 | + usage = BBOU_WS; | |
11986 | + break; | |
11987 | + case BBOU_RDMSR: | |
11988 | + /* Read RCX, write RAX, RDX */ | |
11989 | + bb_reg_read(BBRG_RCX); | |
11990 | + bb_reg_set_undef(BBRG_RAX); | |
11991 | + bb_reg_set_undef(BBRG_RDX); | |
11992 | + usage = BBOU_NOP; | |
11993 | + break; | |
11994 | + case BBOU_RDTSC: | |
11995 | + /* Write RAX, RDX */ | |
11996 | + bb_reg_set_undef(BBRG_RAX); | |
11997 | + bb_reg_set_undef(BBRG_RDX); | |
11998 | + usage = BBOU_NOP; | |
11999 | + break; | |
12000 | + case BBOU_RET: | |
12001 | + usage = BBOU_NOP; | |
12002 | + /* Functions that restore state which was saved by another | |
12003 | + * function or build new kernel stacks. We cannot verify what | |
12004 | + * is being restored so skip the sanity check. | |
12005 | + */ | |
12006 | + if (strcmp(bb_func_name, "restore_image") == 0 || | |
12007 | + strcmp(bb_func_name, "relocate_kernel") == 0 || | |
12008 | + strcmp(bb_func_name, "identity_mapped") == 0 || | |
12009 | + strcmp(bb_func_name, "xen_iret_crit_fixup") == 0 || | |
12010 | + strcmp(bb_func_name, "math_abort") == 0) | |
12011 | + break; | |
12012 | + bb_sanity_check(0); | |
12013 | + break; | |
12014 | + case BBOU_SAHF: | |
12015 | + /* Read RAX */ | |
12016 | + bb_reg_read(BBRG_RAX); | |
12017 | + usage = BBOU_NOP; | |
12018 | + break; | |
12019 | + case BBOU_SCAS: | |
12020 | + /* Read RAX, RDI, write RDI */ | |
12021 | + bb_reg_read(BBRG_RAX); | |
12022 | + bb_reg_read(BBRG_RDI); | |
12023 | + bb_reg_set_undef(BBRG_RDI); | |
12024 | + usage = BBOU_NOP; | |
12025 | + break; | |
12026 | + case BBOU_SUB: | |
12027 | + /* Special case for sub instructions that adjust registers | |
12028 | + * which are mapping the stack. | |
12029 | + */ | |
12030 | + if (dst->reg && bb_is_osp_defined(dst->base_rc)) { | |
12031 | + bb_adjust_osp_instruction(-1); | |
12032 | + usage = BBOU_RS; | |
12033 | + } else { | |
12034 | + usage = BBOU_RSRDWD; | |
12035 | + } | |
12036 | + break; | |
12037 | + case BBOU_SYSEXIT: | |
12038 | + bb_sanity_check(1); | |
12039 | + usage = BBOU_NOP; | |
12040 | + break; | |
12041 | + case BBOU_SYSRET: | |
12042 | + bb_sanity_check(1); | |
12043 | + usage = BBOU_NOP; | |
12044 | + break; | |
12045 | + case BBOU_WRMSR: | |
12046 | + /* Read RCX, RAX, RDX */ | |
12047 | + bb_reg_read(BBRG_RCX); | |
12048 | + bb_reg_read(BBRG_RAX); | |
12049 | + bb_reg_read(BBRG_RDX); | |
12050 | + usage = BBOU_NOP; | |
12051 | + break; | |
12052 | + case BBOU_XADD: | |
12053 | + usage = bb_usage_xadd(src, dst); | |
12054 | + break; | |
12055 | + case BBOU_XCHG: | |
12056 | + /* i386 do_IRQ with 4K stacks does xchg %ebx,%esp; call | |
12057 | + * irq_handler; mov %ebx,%esp; to switch stacks. Ignore this | |
12058 | + * stack switch when tracking registers, it is handled by | |
12059 | + * higher level backtrace code. Convert xchg %ebx,%esp to mov | |
12060 | + * %esp,%ebx so the later mov %ebx,%esp becomes a NOP and the | |
12061 | + * stack remains defined so we can backtrace through do_IRQ's | |
12062 | + * stack switch. | |
12063 | + * | |
12064 | + * Ditto for do_softirq. | |
12065 | + */ | |
12066 | + if (src->reg && | |
12067 | + dst->reg && | |
12068 | + src->base_rc == BBRG_RBX && | |
12069 | + dst->base_rc == BBRG_RSP && | |
12070 | + (strcmp(bb_func_name, "do_IRQ") == 0 || | |
12071 | + strcmp(bb_func_name, "do_softirq") == 0)) { | |
12072 | + strcpy(bb_decode.opcode, "mov"); | |
12073 | + usage = bb_usage_mov(dst, src, sizeof("mov")-1); | |
12074 | + } else { | |
12075 | + usage = bb_usage_xchg(src, dst); | |
12076 | + } | |
12077 | + break; | |
12078 | + case BBOU_XOR: | |
12079 | + /* xor %reg,%reg only counts as a register write, the original | |
12080 | + * contents of reg are irrelevant. | |
12081 | + */ | |
12082 | + if (src->reg && dst->reg && src->base_rc == dst->base_rc) | |
12083 | + usage = BBOU_WS; | |
12084 | + else | |
12085 | + usage = BBOU_RSRDWD; | |
12086 | + break; | |
12087 | + } | |
12088 | + | |
12089 | + /* The switch statement above handled all the special cases. Every | |
12090 | + * opcode should now have a usage of NOP or one of the generic cases. | |
12091 | + */ | |
12092 | + if (usage == BBOU_UNKNOWN || usage == BBOU_NOP) { | |
12093 | + /* nothing to do */ | |
12094 | + } else if (usage >= BBOU_RS && usage <= BBOU_RSRDWSWD) { | |
12095 | + if (usage & BBOU_RS) | |
12096 | + bb_read_operand(src); | |
12097 | + if (usage & BBOU_RD) | |
12098 | + bb_read_operand(dst); | |
12099 | + if (usage & BBOU_WS) | |
12100 | + bb_write_operand(src); | |
12101 | + if (usage & BBOU_WD) | |
12102 | + bb_write_operand(dst); | |
12103 | + } else { | |
12104 | + kdb_printf("%s: opcode not fully handled\n", __FUNCTION__); | |
12105 | + if (!KDB_DEBUG(BB)) { | |
12106 | + bb_print_opcode(); | |
12107 | + if (bb_decode.src.present) | |
12108 | + bb_print_operand("src", &bb_decode.src); | |
12109 | + if (bb_decode.dst.present) | |
12110 | + bb_print_operand("dst", &bb_decode.dst); | |
12111 | + if (bb_decode.dst2.present) | |
12112 | + bb_print_operand("dst2", &bb_decode.dst2); | |
12113 | + } | |
12114 | + bb_giveup = 1; | |
12115 | + } | |
12116 | +} | |
12117 | + | |
12118 | +static void | |
12119 | +bb_parse_buffer(void) | |
12120 | +{ | |
12121 | + char *p, *src, *dst = NULL, *dst2 = NULL; | |
12122 | + int paren = 0; | |
12123 | + p = bb_buffer; | |
12124 | + memset(&bb_decode, 0, sizeof(bb_decode)); | |
12125 | + KDB_DEBUG_BB(" '%s'\n", p); | |
12126 | + p += strcspn(p, ":"); /* skip address and function name+offset: */ | |
12127 | + if (*p++ != ':') { | |
12128 | + kdb_printf("%s: cannot find ':' in buffer '%s'\n", | |
12129 | + __FUNCTION__, bb_buffer); | |
12130 | + bb_giveup = 1; | |
12131 | + return; | |
12132 | + } | |
12133 | + p += strspn(p, " \t"); /* step to opcode */ | |
12134 | + if (strncmp(p, "(bad)", 5) == 0) | |
12135 | + strcpy(p, "nop"); | |
12136 | + /* separate any opcode prefix */ | |
12137 | + if (strncmp(p, "lock", 4) == 0 || | |
12138 | + strncmp(p, "rep", 3) == 0 || | |
12139 | + strncmp(p, "rex", 3) == 0 || | |
12140 | + strncmp(p, "addr", 4) == 0) { | |
12141 | + bb_decode.prefix = p; | |
12142 | + p += strcspn(p, " \t"); | |
12143 | + *p++ = '\0'; | |
12144 | + p += strspn(p, " \t"); | |
12145 | + } | |
12146 | + bb_decode.opcode = p; | |
12147 | + strsep(&p, " \t"); /* step to end of opcode */ | |
12148 | + if (bb_parse_opcode()) | |
12149 | + return; | |
12150 | + if (!p) | |
12151 | + goto no_operands; | |
12152 | + p += strspn(p, " \t"); /* step to operand(s) */ | |
12153 | + if (!*p) | |
12154 | + goto no_operands; | |
12155 | + src = p; | |
12156 | + p = strsep(&p, " \t"); /* strip comments after operands */ | |
12157 | + /* split 'src','dst' but ignore ',' inside '(' ')' */ | |
12158 | + while (*p) { | |
12159 | + if (*p == '(') { | |
12160 | + ++paren; | |
12161 | + } else if (*p == ')') { | |
12162 | + --paren; | |
12163 | + } else if (*p == ',' && paren == 0) { | |
12164 | + *p = '\0'; | |
12165 | + if (dst) | |
12166 | + dst2 = p+1; | |
12167 | + else | |
12168 | + dst = p+1; | |
12169 | + } | |
12170 | + ++p; | |
12171 | + } | |
12172 | + bb_parse_operand(src, &bb_decode.src); | |
12173 | + if (KDB_DEBUG(BB)) | |
12174 | + bb_print_operand("src", &bb_decode.src); | |
12175 | + if (dst && !bb_giveup) { | |
12176 | + bb_parse_operand(dst, &bb_decode.dst); | |
12177 | + if (KDB_DEBUG(BB)) | |
12178 | + bb_print_operand("dst", &bb_decode.dst); | |
12179 | + } | |
12180 | + if (dst2 && !bb_giveup) { | |
12181 | + bb_parse_operand(dst2, &bb_decode.dst2); | |
12182 | + if (KDB_DEBUG(BB)) | |
12183 | + bb_print_operand("dst2", &bb_decode.dst2); | |
12184 | + } | |
12185 | +no_operands: | |
12186 | + if (!bb_giveup) | |
12187 | + bb_usage(); | |
12188 | +} | |
12189 | + | |
12190 | +static int | |
12191 | +bb_dis_pass2(PTR file, const char *fmt, ...) | |
12192 | +{ | |
12193 | + char *p; | |
12194 | + int l = strlen(bb_buffer); | |
12195 | + va_list ap; | |
12196 | + va_start(ap, fmt); | |
12197 | + vsnprintf(bb_buffer + l, sizeof(bb_buffer) - l, fmt, ap); | |
12198 | + va_end(ap); | |
12199 | + if ((p = strchr(bb_buffer, '\n'))) { | |
12200 | + *p = '\0'; | |
12201 | + p = bb_buffer; | |
12202 | + p += strcspn(p, ":"); | |
12203 | + if (*p++ == ':') | |
12204 | + bb_fixup_switch_to(p); | |
12205 | + bb_parse_buffer(); | |
12206 | + bb_buffer[0] = '\0'; | |
12207 | + } | |
12208 | + return 0; | |
12209 | +} | |
12210 | + | |
12211 | +static void | |
12212 | +bb_printaddr_pass2(bfd_vma addr, disassemble_info *dip) | |
12213 | +{ | |
12214 | + kdb_symtab_t symtab; | |
12215 | + unsigned int offset; | |
12216 | + dip->fprintf_func(dip->stream, "0x%lx", addr); | |
12217 | + kdbnearsym(addr, &symtab); | |
12218 | + if (symtab.sym_name) { | |
12219 | + dip->fprintf_func(dip->stream, " <%s", symtab.sym_name); | |
12220 | + if ((offset = addr - symtab.sym_start)) | |
12221 | + dip->fprintf_func(dip->stream, "+0x%x", offset); | |
12222 | + dip->fprintf_func(dip->stream, ">"); | |
12223 | + } | |
12224 | +} | |
12225 | + | |
12226 | +/* Set the starting register and memory state for the current bb */ | |
12227 | + | |
12228 | +static void | |
12229 | +bb_start_block0_special(void) | |
12230 | +{ | |
12231 | + int i; | |
12232 | + short offset_address; | |
12233 | + enum bb_reg_code reg, value; | |
12234 | + struct bb_name_state *r; | |
12235 | + for (i = 0, r = bb_special_cases; | |
12236 | + i < ARRAY_SIZE(bb_special_cases); | |
12237 | + ++i, ++r) { | |
12238 | + if (bb_func_start == r->address && r->fname == NULL) | |
12239 | + goto match; | |
12240 | + } | |
12241 | + return; | |
12242 | +match: | |
12243 | + /* Set the running registers */ | |
12244 | + for (reg = BBRG_RAX; reg < r->regs_size; ++reg) { | |
12245 | + value = r->regs[reg].value; | |
12246 | + if (test_bit(value, r->skip_regs.bits)) { | |
12247 | + /* this regs entry is not defined for this label */ | |
12248 | + continue; | |
12249 | + } | |
12250 | + bb_reg_code_set_value(reg, value); | |
12251 | + bb_reg_code_set_offset(reg, r->regs[reg].offset); | |
12252 | + } | |
12253 | + /* Set any memory contents, e.g. pt_regs. Adjust RSP as required. */ | |
12254 | + offset_address = 0; | |
12255 | + for (i = 0; i < r->mem_size; ++i) { | |
12256 | + offset_address = max_t(int, | |
12257 | + r->mem[i].offset_address + KDB_WORD_SIZE, | |
12258 | + offset_address); | |
12259 | + } | |
12260 | + if (bb_reg_code_offset(BBRG_RSP) > -offset_address) | |
12261 | + bb_adjust_osp(BBRG_RSP, -offset_address - bb_reg_code_offset(BBRG_RSP)); | |
12262 | + for (i = 0; i < r->mem_size; ++i) { | |
12263 | + value = r->mem[i].value; | |
12264 | + if (test_bit(value, r->skip_mem.bits)) { | |
12265 | + /* this memory entry is not defined for this label */ | |
12266 | + continue; | |
12267 | + } | |
12268 | + bb_memory_set_reg_value(BBRG_RSP, r->mem[i].offset_address, | |
12269 | + value, 0); | |
12270 | + bb_reg_set_undef(value); | |
12271 | + } | |
12272 | + return; | |
12273 | +} | |
12274 | + | |
12275 | +static void | |
12276 | +bb_pass2_start_block(int number) | |
12277 | +{ | |
12278 | + int i, j, k, first, changed; | |
12279 | + size_t size; | |
12280 | + struct bb_jmp *bb_jmp; | |
12281 | + struct bb_reg_state *state; | |
12282 | + struct bb_memory_contains *c1, *c2; | |
12283 | + bb_reg_state->mem_count = bb_reg_state_max; | |
12284 | + size = bb_reg_state_size(bb_reg_state); | |
12285 | + memset(bb_reg_state, 0, size); | |
12286 | + | |
12287 | + if (number == 0) { | |
12288 | + /* The first block is assumed to have well defined inputs */ | |
12289 | + bb_start_block0(); | |
12290 | + /* Some assembler labels have non-standard entry | |
12291 | + * states. | |
12292 | + */ | |
12293 | + bb_start_block0_special(); | |
12294 | + bb_reg_state_print(bb_reg_state); | |
12295 | + return; | |
12296 | + } | |
12297 | + | |
12298 | + /* Merge all the input states for the current bb together */ | |
12299 | + first = 1; | |
12300 | + changed = 0; | |
12301 | + for (i = 0; i < bb_jmp_count; ++i) { | |
12302 | + bb_jmp = bb_jmp_list + i; | |
12303 | + if (bb_jmp->to != bb_curr->start) | |
12304 | + continue; | |
12305 | + state = bb_jmp->state; | |
12306 | + if (!state) | |
12307 | + continue; | |
12308 | + if (first) { | |
12309 | + size = bb_reg_state_size(state); | |
12310 | + memcpy(bb_reg_state, state, size); | |
12311 | + KDB_DEBUG_BB(" first state %p\n", state); | |
12312 | + bb_reg_state_print(bb_reg_state); | |
12313 | + first = 0; | |
12314 | + continue; | |
12315 | + } | |
12316 | + | |
12317 | + KDB_DEBUG_BB(" merging state %p\n", state); | |
12318 | + /* Merge the register states */ | |
12319 | + for (j = 0; j < ARRAY_SIZE(state->contains); ++j) { | |
12320 | + if (memcmp(bb_reg_state->contains + j, | |
12321 | + state->contains + j, | |
12322 | + sizeof(bb_reg_state->contains[0]))) { | |
12323 | + /* Different states for this register from two | |
12324 | + * or more inputs, make it undefined. | |
12325 | + */ | |
12326 | + if (bb_reg_state->contains[j].value == | |
12327 | + BBRG_UNDEFINED) { | |
12328 | + KDB_DEBUG_BB(" ignoring %s\n", | |
12329 | + bbrg_name[j + BBRG_RAX]); | |
12330 | + } else { | |
12331 | + bb_reg_set_undef(BBRG_RAX + j); | |
12332 | + changed = 1; | |
12333 | + } | |
12334 | + } | |
12335 | + } | |
12336 | + | |
12337 | + /* Merge the memory states. This relies on both | |
12338 | + * bb_reg_state->memory and state->memory being sorted in | |
12339 | + * descending order, with undefined entries at the end. | |
12340 | + */ | |
12341 | + c1 = bb_reg_state->memory; | |
12342 | + c2 = state->memory; | |
12343 | + j = k = 0; | |
12344 | + while (j < bb_reg_state->mem_count && | |
12345 | + k < state->mem_count) { | |
12346 | + if (c1->offset_address < c2->offset_address) { | |
12347 | + KDB_DEBUG_BB_OFFSET(c2->offset_address, | |
12348 | + " ignoring c2->offset_address ", | |
12349 | + "\n"); | |
12350 | + ++c2; | |
12351 | + ++k; | |
12352 | + continue; | |
12353 | + } | |
12354 | + if (c1->offset_address > c2->offset_address) { | |
12355 | + /* Memory location is not in all input states, | |
12356 | + * delete the memory location. | |
12357 | + */ | |
12358 | + bb_delete_memory(c1->offset_address); | |
12359 | + changed = 1; | |
12360 | + ++c1; | |
12361 | + ++j; | |
12362 | + continue; | |
12363 | + } | |
12364 | + if (memcmp(c1, c2, sizeof(*c1))) { | |
12365 | + /* Same location, different contents, delete | |
12366 | + * the memory location. | |
12367 | + */ | |
12368 | + bb_delete_memory(c1->offset_address); | |
12369 | + KDB_DEBUG_BB_OFFSET(c2->offset_address, | |
12370 | + " ignoring c2->offset_address ", | |
12371 | + "\n"); | |
12372 | + changed = 1; | |
12373 | + } | |
12374 | + ++c1; | |
12375 | + ++c2; | |
12376 | + ++j; | |
12377 | + ++k; | |
12378 | + } | |
12379 | + while (j < bb_reg_state->mem_count) { | |
12380 | + bb_delete_memory(c1->offset_address); | |
12381 | + changed = 1; | |
12382 | + ++c1; | |
12383 | + ++j; | |
12384 | + } | |
12385 | + } | |
12386 | + if (changed) { | |
12387 | + KDB_DEBUG_BB(" final state\n"); | |
12388 | + bb_reg_state_print(bb_reg_state); | |
12389 | + } | |
12390 | +} | |
12391 | + | |
12392 | +/* We have reached the exit point from the current function, either a call to | |
12393 | + * the next function or the instruction that was about to executed when an | |
12394 | + * interrupt occurred. Save the current register state in bb_exit_state. | |
12395 | + */ | |
12396 | + | |
12397 | +static void | |
12398 | +bb_save_exit_state(void) | |
12399 | +{ | |
12400 | + size_t size; | |
12401 | + debug_kfree(bb_exit_state); | |
12402 | + bb_exit_state = NULL; | |
12403 | + bb_reg_state_canonicalize(); | |
12404 | + size = bb_reg_state_size(bb_reg_state); | |
12405 | + bb_exit_state = debug_kmalloc(size, GFP_ATOMIC); | |
12406 | + if (!bb_exit_state) { | |
12407 | + kdb_printf("\n\n%s: out of debug_kmalloc\n", __FUNCTION__); | |
12408 | + bb_giveup = 1; | |
12409 | + return; | |
12410 | + } | |
12411 | + memcpy(bb_exit_state, bb_reg_state, size); | |
12412 | +} | |
12413 | + | |
12414 | +static int | |
12415 | +bb_pass2_do_changed_blocks(int allow_missing) | |
12416 | +{ | |
12417 | + int i, j, missing, changed, maxloops; | |
12418 | + unsigned long addr; | |
12419 | + struct bb_jmp *bb_jmp; | |
12420 | + KDB_DEBUG_BB("\n %s: allow_missing %d\n", __FUNCTION__, allow_missing); | |
12421 | + /* Absolute worst case is we have to iterate over all the basic blocks | |
12422 | + * in an "out of order" state, each iteration losing one register or | |
12423 | + * memory state. Any more loops than that is a bug. "out of order" | |
12424 | + * means that the layout of blocks in memory does not match the logic | |
12425 | + * flow through those blocks so (for example) block 27 comes before | |
12426 | + * block 2. To allow for out of order blocks, multiply maxloops by the | |
12427 | + * number of blocks. | |
12428 | + */ | |
12429 | + maxloops = (KDB_INT_REGISTERS + bb_reg_state_max) * bb_count; | |
12430 | + changed = 1; | |
12431 | + do { | |
12432 | + changed = 0; | |
12433 | + for (i = 0; i < bb_count; ++i) { | |
12434 | + bb_curr = bb_list[i]; | |
12435 | + if (!bb_curr->changed) | |
12436 | + continue; | |
12437 | + missing = 0; | |
12438 | + for (j = 0, bb_jmp = bb_jmp_list; | |
12439 | + j < bb_jmp_count; | |
12440 | + ++j, ++bb_jmp) { | |
12441 | + if (bb_jmp->to == bb_curr->start && | |
12442 | + !bb_jmp->state) | |
12443 | + ++missing; | |
12444 | + } | |
12445 | + if (missing > allow_missing) | |
12446 | + continue; | |
12447 | + bb_curr->changed = 0; | |
12448 | + changed = 1; | |
12449 | + KDB_DEBUG_BB("\n bb[%d]\n", i); | |
12450 | + bb_pass2_start_block(i); | |
12451 | + for (addr = bb_curr->start; | |
12452 | + addr <= bb_curr->end; ) { | |
12453 | + bb_curr_addr = addr; | |
12454 | + if (addr == bb_exit_addr) | |
12455 | + bb_save_exit_state(); | |
12456 | + addr += kdba_id_printinsn(addr, &kdb_di); | |
12457 | + kdb_di.fprintf_func(NULL, "\n"); | |
12458 | + if (bb_giveup) | |
12459 | + goto done; | |
12460 | + } | |
12461 | + if (!bb_exit_state) { | |
12462 | + /* ATTRIB_NORET functions are a problem with | |
12463 | + * the current gcc. Allow the trailing address | |
12464 | + * a bit of leaway. | |
12465 | + */ | |
12466 | + if (addr == bb_exit_addr || | |
12467 | + addr == bb_exit_addr + 1) | |
12468 | + bb_save_exit_state(); | |
12469 | + } | |
12470 | + if (bb_curr->drop_through) | |
12471 | + bb_transfer(bb_curr->end, | |
12472 | + bb_list[i+1]->start, 1); | |
12473 | + } | |
12474 | + if (maxloops-- == 0) { | |
12475 | + kdb_printf("\n\n%s maxloops reached\n", | |
12476 | + __FUNCTION__); | |
12477 | + bb_giveup = 1; | |
12478 | + goto done; | |
12479 | + } | |
12480 | + } while(changed); | |
12481 | +done: | |
12482 | + for (i = 0; i < bb_count; ++i) { | |
12483 | + bb_curr = bb_list[i]; | |
12484 | + if (bb_curr->changed) | |
12485 | + return 1; /* more to do, increase allow_missing */ | |
12486 | + } | |
12487 | + return 0; /* all blocks done */ | |
12488 | +} | |
12489 | + | |
12490 | +/* Assume that the current function is a pass through function that does not | |
12491 | + * refer to its register parameters. Exclude known asmlinkage functions and | |
12492 | + * assume the other functions actually use their registers. | |
12493 | + */ | |
12494 | + | |
12495 | +static void | |
12496 | +bb_assume_pass_through(void) | |
12497 | +{ | |
12498 | + static int first_time = 1; | |
12499 | + if (strncmp(bb_func_name, "sys_", 4) == 0 || | |
12500 | + strncmp(bb_func_name, "compat_sys_", 11) == 0 || | |
12501 | + strcmp(bb_func_name, "schedule") == 0 || | |
12502 | + strcmp(bb_func_name, "do_softirq") == 0 || | |
12503 | + strcmp(bb_func_name, "printk") == 0 || | |
12504 | + strcmp(bb_func_name, "vprintk") == 0 || | |
12505 | + strcmp(bb_func_name, "preempt_schedule") == 0 || | |
12506 | + strcmp(bb_func_name, "start_kernel") == 0 || | |
12507 | + strcmp(bb_func_name, "csum_partial") == 0 || | |
12508 | + strcmp(bb_func_name, "csum_partial_copy_generic") == 0 || | |
12509 | + strcmp(bb_func_name, "math_state_restore") == 0 || | |
12510 | + strcmp(bb_func_name, "panic") == 0 || | |
12511 | + strcmp(bb_func_name, "kdb_printf") == 0 || | |
12512 | + strcmp(bb_func_name, "kdb_interrupt") == 0) | |
12513 | + return; | |
12514 | + if (bb_asmlinkage_arch()) | |
12515 | + return; | |
12516 | + bb_reg_params = REGPARM; | |
12517 | + if (first_time) { | |
12518 | + kdb_printf(" %s has memory parameters but no register " | |
12519 | + "parameters.\n Assuming it is a 'pass " | |
12520 | + "through' function that does not refer to " | |
12521 | + "its register\n parameters and setting %d " | |
12522 | + "register parameters\n", | |
12523 | + bb_func_name, REGPARM); | |
12524 | + first_time = 0; | |
12525 | + return; | |
12526 | + } | |
12527 | + kdb_printf(" Assuming %s is 'pass through' with %d register " | |
12528 | + "parameters\n", | |
12529 | + bb_func_name, REGPARM); | |
12530 | +} | |
12531 | + | |
12532 | +static void | |
12533 | +bb_pass2(void) | |
12534 | +{ | |
12535 | + int allow_missing; | |
12536 | + if (KDB_DEBUG(BB) | KDB_DEBUG(BB_SUMM)) | |
12537 | + kdb_printf("%s: start\n", __FUNCTION__); | |
12538 | + | |
12539 | + kdb_di.fprintf_func = bb_dis_pass2; | |
12540 | + kdb_di.print_address_func = bb_printaddr_pass2; | |
12541 | + | |
12542 | + bb_reg_state = debug_kmalloc(sizeof(*bb_reg_state), GFP_ATOMIC); | |
12543 | + if (!bb_reg_state) { | |
12544 | + kdb_printf("\n\n%s: out of debug_kmalloc\n", __FUNCTION__); | |
12545 | + bb_giveup = 1; | |
12546 | + return; | |
12547 | + } | |
12548 | + bb_list[0]->changed = 1; | |
12549 | + | |
12550 | + /* If a block does not have all its input states available then it is | |
12551 | + * possible for a register to initially appear to hold a known value, | |
12552 | + * but when other inputs are available then it becomes a variable | |
12553 | + * value. The initial false state of "known" can generate false values | |
12554 | + * for other registers and can even make it look like stack locations | |
12555 | + * are being changed. | |
12556 | + * | |
12557 | + * To avoid these false positives, only process blocks which have all | |
12558 | + * their inputs defined. That gives a clean depth first traversal of | |
12559 | + * the tree, except for loops. If there are any loops, then start | |
12560 | + * processing blocks with one missing input, then two missing inputs | |
12561 | + * etc. | |
12562 | + * | |
12563 | + * Absolute worst case is we have to iterate over all the jmp entries, | |
12564 | + * each iteration allowing one more missing input. Any more loops than | |
12565 | + * that is a bug. Watch out for the corner case of 0 jmp entries. | |
12566 | + */ | |
12567 | + for (allow_missing = 0; allow_missing <= bb_jmp_count; ++allow_missing) { | |
12568 | + if (!bb_pass2_do_changed_blocks(allow_missing)) | |
12569 | + break; | |
12570 | + if (bb_giveup) | |
12571 | + break; | |
12572 | + } | |
12573 | + if (allow_missing > bb_jmp_count) { | |
12574 | + kdb_printf("\n\n%s maxloops reached\n", | |
12575 | + __FUNCTION__); | |
12576 | + bb_giveup = 1; | |
12577 | + return; | |
12578 | + } | |
12579 | + | |
12580 | + if (bb_memory_params && bb_reg_params) | |
12581 | + bb_reg_params = REGPARM; | |
12582 | + if (REGPARM && | |
12583 | + bb_memory_params && | |
12584 | + !bb_reg_params) | |
12585 | + bb_assume_pass_through(); | |
12586 | + if (KDB_DEBUG(BB) | KDB_DEBUG(BB_SUMM)) { | |
12587 | + kdb_printf("%s: end bb_reg_params %d bb_memory_params %d\n", | |
12588 | + __FUNCTION__, bb_reg_params, bb_memory_params); | |
12589 | + if (bb_exit_state) { | |
12590 | + kdb_printf("%s: bb_exit_state at " kdb_bfd_vma_fmt0 "\n", | |
12591 | + __FUNCTION__, bb_exit_addr); | |
12592 | + bb_do_reg_state_print(bb_exit_state); | |
12593 | + } | |
12594 | + } | |
12595 | +} | |
12596 | + | |
12597 | +static void | |
12598 | +bb_cleanup(void) | |
12599 | +{ | |
12600 | + int i; | |
12601 | + struct bb* bb; | |
12602 | + struct bb_reg_state *state; | |
12603 | + while (bb_count) { | |
12604 | + bb = bb_list[0]; | |
12605 | + bb_delete(0); | |
12606 | + } | |
12607 | + debug_kfree(bb_list); | |
12608 | + bb_list = NULL; | |
12609 | + bb_count = bb_max = 0; | |
12610 | + for (i = 0; i < bb_jmp_count; ++i) { | |
12611 | + state = bb_jmp_list[i].state; | |
12612 | + if (state && --state->ref_count == 0) | |
12613 | + debug_kfree(state); | |
12614 | + } | |
12615 | + debug_kfree(bb_jmp_list); | |
12616 | + bb_jmp_list = NULL; | |
12617 | + bb_jmp_count = bb_jmp_max = 0; | |
12618 | + debug_kfree(bb_reg_state); | |
12619 | + bb_reg_state = NULL; | |
12620 | + bb_reg_state_max = 0; | |
12621 | + debug_kfree(bb_exit_state); | |
12622 | + bb_exit_state = NULL; | |
12623 | + bb_reg_params = bb_memory_params = 0; | |
12624 | + bb_giveup = 0; | |
12625 | +} | |
12626 | + | |
12627 | +static int | |
12628 | +bb_spurious_global_label(const char *func_name) | |
12629 | +{ | |
12630 | + int i; | |
12631 | + for (i = 0; i < ARRAY_SIZE(bb_spurious); ++i) { | |
12632 | + if (strcmp(bb_spurious[i], func_name) == 0) | |
12633 | + return 1; | |
12634 | + } | |
12635 | + return 0; | |
12636 | +} | |
12637 | + | |
12638 | +/* Given the current actual register contents plus the exit state deduced from | |
12639 | + * a basic block analysis of the current function, rollback the actual register | |
12640 | + * contents to the values they had on entry to this function. | |
12641 | + */ | |
12642 | + | |
12643 | +static void | |
12644 | +bb_actual_rollback(const struct kdb_activation_record *ar) | |
12645 | +{ | |
12646 | + int i, offset_address; | |
12647 | + struct bb_memory_contains *c; | |
12648 | + enum bb_reg_code reg; | |
12649 | + unsigned long address, osp = 0; | |
12650 | + struct bb_actual new[ARRAY_SIZE(bb_actual)]; | |
12651 | + | |
12652 | + | |
12653 | + if (!bb_exit_state) { | |
12654 | + kdb_printf("%s: no bb_exit_state, cannot rollback\n", | |
12655 | + __FUNCTION__); | |
12656 | + bb_giveup = 1; | |
12657 | + return; | |
12658 | + } | |
12659 | + memcpy(bb_reg_state, bb_exit_state, bb_reg_state_size(bb_exit_state)); | |
12660 | + memset(new, 0, sizeof(new)); | |
12661 | + | |
12662 | + /* The most important register for obtaining saved state is rsp so get | |
12663 | + * its new value first. Prefer rsp if it is valid, then other | |
12664 | + * registers. Saved values of rsp in memory are unusable without a | |
12665 | + * register that points to memory. | |
12666 | + */ | |
12667 | + if (!bb_actual_valid(BBRG_RSP)) { | |
12668 | + kdb_printf("%s: no starting value for RSP, cannot rollback\n", | |
12669 | + __FUNCTION__); | |
12670 | + bb_giveup = 1; | |
12671 | + return; | |
12672 | + } | |
12673 | + if (KDB_DEBUG(BB) | KDB_DEBUG(BB_SUMM)) | |
12674 | + kdb_printf("%s: rsp " kdb_bfd_vma_fmt0, | |
12675 | + __FUNCTION__, bb_actual_value(BBRG_RSP)); | |
12676 | + i = BBRG_RSP; | |
12677 | + if (!bb_is_osp_defined(i)) { | |
12678 | + for (i = BBRG_RAX; i < BBRG_RAX + KDB_INT_REGISTERS; ++i) { | |
12679 | + if (bb_is_osp_defined(i) && bb_actual_valid(i)) | |
12680 | + break; | |
12681 | + } | |
12682 | + } | |
12683 | + if (bb_is_osp_defined(i) && bb_actual_valid(i)) { | |
12684 | + osp = new[BBRG_RSP - BBRG_RAX].value = | |
12685 | + bb_actual_value(i) - bb_reg_code_offset(i); | |
12686 | + new[BBRG_RSP - BBRG_RAX].valid = 1; | |
12687 | + if (KDB_DEBUG(BB) | KDB_DEBUG(BB_SUMM)) | |
12688 | + kdb_printf(" -> osp " kdb_bfd_vma_fmt0 "\n", osp); | |
12689 | + } else { | |
12690 | + bb_actual_set_valid(BBRG_RSP, 0); | |
12691 | + if (KDB_DEBUG(BB) | KDB_DEBUG(BB_SUMM)) | |
12692 | + kdb_printf(" -> undefined\n"); | |
12693 | + kdb_printf("%s: no ending value for RSP, cannot rollback\n", | |
12694 | + __FUNCTION__); | |
12695 | + bb_giveup = 1; | |
12696 | + return; | |
12697 | + } | |
12698 | + | |
12699 | + /* Now the other registers. First look at register values that have | |
12700 | + * been copied to other registers. | |
12701 | + */ | |
12702 | + for (i = BBRG_RAX; i < BBRG_RAX + KDB_INT_REGISTERS; ++i) { | |
12703 | + reg = bb_reg_code_value(i); | |
12704 | + if (bb_is_int_reg(reg)) { | |
12705 | + new[reg - BBRG_RAX] = bb_actual[i - BBRG_RAX]; | |
12706 | + if (KDB_DEBUG(BB) | KDB_DEBUG(BB_SUMM)) { | |
12707 | + kdb_printf("%s: %s is in %s ", | |
12708 | + __FUNCTION__, | |
12709 | + bbrg_name[reg], | |
12710 | + bbrg_name[i]); | |
12711 | + if (bb_actual_valid(i)) | |
12712 | + kdb_printf(" -> " kdb_bfd_vma_fmt0 "\n", | |
12713 | + bb_actual_value(i)); | |
12714 | + else | |
12715 | + kdb_printf("(invalid)\n"); | |
12716 | + } | |
12717 | + } | |
12718 | + } | |
12719 | + | |
12720 | + /* Finally register values that have been saved on stack */ | |
12721 | + for (i = 0, c = bb_reg_state->memory; | |
12722 | + i < bb_reg_state->mem_count; | |
12723 | + ++i, ++c) { | |
12724 | + offset_address = c->offset_address; | |
12725 | + reg = c->value; | |
12726 | + if (!bb_is_int_reg(reg)) | |
12727 | + continue; | |
12728 | + address = osp + offset_address; | |
12729 | + if (address < ar->stack.logical_start || | |
12730 | + address >= ar->stack.logical_end) { | |
12731 | + new[reg - BBRG_RAX].value = 0; | |
12732 | + new[reg - BBRG_RAX].valid = 0; | |
12733 | + if (KDB_DEBUG(BB) | KDB_DEBUG(BB_SUMM)) | |
12734 | + kdb_printf("%s: %s -> undefined\n", | |
12735 | + __FUNCTION__, | |
12736 | + bbrg_name[reg]); | |
12737 | + } else { | |
12738 | + if (KDB_DEBUG(BB) | KDB_DEBUG(BB_SUMM)) { | |
12739 | + kdb_printf("%s: %s -> *(osp", | |
12740 | + __FUNCTION__, | |
12741 | + bbrg_name[reg]); | |
12742 | + KDB_DEBUG_BB_OFFSET_PRINTF(offset_address, "", " "); | |
12743 | + kdb_printf(kdb_bfd_vma_fmt0, address); | |
12744 | + } | |
12745 | + new[reg - BBRG_RAX].value = *(bfd_vma *)address; | |
12746 | + new[reg - BBRG_RAX].valid = 1; | |
12747 | + if (KDB_DEBUG(BB) | KDB_DEBUG(BB_SUMM)) | |
12748 | + kdb_printf(") = " kdb_bfd_vma_fmt0 "\n", | |
12749 | + new[reg - BBRG_RAX].value); | |
12750 | + } | |
12751 | + } | |
12752 | + | |
12753 | + memcpy(bb_actual, new, sizeof(bb_actual)); | |
12754 | +} | |
12755 | + | |
12756 | +/* Return true if the current function is an interrupt handler */ | |
12757 | + | |
12758 | +static bool | |
12759 | +bb_interrupt_handler(kdb_machreg_t rip) | |
12760 | +{ | |
12761 | + unsigned long disp8, disp32, target, addr = (unsigned long)rip; | |
12762 | + unsigned char code[5]; | |
12763 | + int i; | |
12764 | + | |
12765 | + for (i = 0; i < ARRAY_SIZE(bb_hardware_handlers); ++i) | |
12766 | + if (strcmp(bb_func_name, bb_hardware_handlers[i]) == 0) | |
12767 | + return 1; | |
12768 | + | |
12769 | + /* Given the large number of interrupt handlers, it is easiest to look | |
12770 | + * at the next instruction and see if it is a jmp to the common exit | |
12771 | + * routines. | |
12772 | + */ | |
12773 | + if (kdb_getarea(code, addr) || | |
12774 | + kdb_getword(&disp32, addr+1, 4) || | |
12775 | + kdb_getword(&disp8, addr+1, 1)) | |
12776 | + return 0; /* not a valid code address */ | |
12777 | + if (code[0] == 0xe9) { | |
12778 | + target = addr + (s32) disp32 + 5; /* jmp disp32 */ | |
12779 | + if (target == bb_ret_from_intr || | |
12780 | + target == bb_common_interrupt || | |
12781 | + target == bb_error_entry) | |
12782 | + return 1; | |
12783 | + } | |
12784 | + if (code[0] == 0xeb) { | |
12785 | + target = addr + (s8) disp8 + 2; /* jmp disp8 */ | |
12786 | + if (target == bb_ret_from_intr || | |
12787 | + target == bb_common_interrupt || | |
12788 | + target == bb_error_entry) | |
12789 | + return 1; | |
12790 | + } | |
12791 | + | |
12792 | + return 0; | |
12793 | +} | |
12794 | + | |
12795 | +/* Copy argument information that was deduced by the basic block analysis and | |
12796 | + * rollback into the kdb stack activation record. | |
12797 | + */ | |
12798 | + | |
12799 | +static void | |
12800 | +bb_arguments(struct kdb_activation_record *ar) | |
12801 | +{ | |
12802 | + int i; | |
12803 | + enum bb_reg_code reg; | |
12804 | + kdb_machreg_t rsp; | |
12805 | + ar->args = bb_reg_params + bb_memory_params; | |
12806 | + bitmap_zero(ar->valid.bits, KDBA_MAXARGS); | |
12807 | + for (i = 0; i < bb_reg_params; ++i) { | |
12808 | + reg = bb_param_reg[i]; | |
12809 | + if (bb_actual_valid(reg)) { | |
12810 | + ar->arg[i] = bb_actual_value(reg); | |
12811 | + set_bit(i, ar->valid.bits); | |
12812 | + } | |
12813 | + } | |
12814 | + if (!bb_actual_valid(BBRG_RSP)) | |
12815 | + return; | |
12816 | + rsp = bb_actual_value(BBRG_RSP); | |
12817 | + for (i = bb_reg_params; i < ar->args; ++i) { | |
12818 | + rsp += KDB_WORD_SIZE; | |
12819 | + if (kdb_getarea(ar->arg[i], rsp) == 0) | |
12820 | + set_bit(i, ar->valid.bits); | |
12821 | + } | |
12822 | +} | |
12823 | + | |
12824 | +/* Given an exit address from a function, decompose the entire function into | |
12825 | + * basic blocks and determine the register state at the exit point. | |
12826 | + */ | |
12827 | + | |
12828 | +static void | |
12829 | +kdb_bb(unsigned long exit) | |
12830 | +{ | |
12831 | + kdb_symtab_t symtab; | |
12832 | + if (!kdbnearsym(exit, &symtab)) { | |
12833 | + kdb_printf("%s: address " kdb_bfd_vma_fmt0 " not recognised\n", | |
12834 | + __FUNCTION__, exit); | |
12835 | + bb_giveup = 1; | |
12836 | + return; | |
12837 | + } | |
12838 | + bb_exit_addr = exit; | |
12839 | + bb_mod_name = symtab.mod_name; | |
12840 | + bb_func_name = symtab.sym_name; | |
12841 | + bb_func_start = symtab.sym_start; | |
12842 | + bb_func_end = symtab.sym_end; | |
12843 | + /* Various global labels exist in the middle of assembler code and have | |
12844 | + * a non-standard state. Ignore these labels and use the start of the | |
12845 | + * previous label instead. | |
12846 | + */ | |
12847 | + while (bb_spurious_global_label(symtab.sym_name)) { | |
12848 | + if (!kdbnearsym(symtab.sym_start - 1, &symtab)) | |
12849 | + break; | |
12850 | + bb_func_start = symtab.sym_start; | |
12851 | + } | |
12852 | + bb_mod_name = symtab.mod_name; | |
12853 | + bb_func_name = symtab.sym_name; | |
12854 | + bb_func_start = symtab.sym_start; | |
12855 | + /* Ignore spurious labels past this point and use the next non-spurious | |
12856 | + * label as the end point. | |
12857 | + */ | |
12858 | + if (kdbnearsym(bb_func_end, &symtab)) { | |
12859 | + while (bb_spurious_global_label(symtab.sym_name)) { | |
12860 | + bb_func_end = symtab.sym_end; | |
12861 | + if (!kdbnearsym(symtab.sym_end + 1, &symtab)) | |
12862 | + break; | |
12863 | + } | |
12864 | + } | |
12865 | + bb_pass1(); | |
12866 | + if (!bb_giveup) | |
12867 | + bb_pass2(); | |
12868 | + if (bb_giveup) | |
12869 | + kdb_printf("%s: " kdb_bfd_vma_fmt0 | |
12870 | + " [%s]%s failed at " kdb_bfd_vma_fmt0 "\n\n", | |
12871 | + __FUNCTION__, exit, | |
12872 | + bb_mod_name, bb_func_name, bb_curr_addr); | |
12873 | +} | |
12874 | + | |
12875 | +static int | |
12876 | +kdb_bb1(int argc, const char **argv) | |
12877 | +{ | |
12878 | + int diag; | |
12879 | + unsigned long addr; | |
12880 | + bb_cleanup(); /* in case previous command was interrupted */ | |
12881 | + kdba_id_init(&kdb_di); | |
12882 | + if (argc != 1) | |
12883 | + return KDB_ARGCOUNT; | |
12884 | + if ((diag = kdbgetularg((char *)argv[1], &addr))) | |
12885 | + return diag; | |
12886 | + kdb_save_flags(); | |
12887 | + kdb_flags |= KDB_DEBUG_FLAG_BB << KDB_DEBUG_FLAG_SHIFT; | |
12888 | + kdb_bb(addr); | |
12889 | + bb_cleanup(); | |
12890 | + kdb_restore_flags(); | |
12891 | + kdbnearsym_cleanup(); | |
12892 | + return 0; | |
12893 | +} | |
12894 | + | |
12895 | +/* Run a basic block analysis on every function in the base kernel. Used as a | |
12896 | + * global sanity check to find errors in the basic block code. | |
12897 | + */ | |
12898 | + | |
12899 | +static int | |
12900 | +kdb_bb_all(int argc, const char **argv) | |
12901 | +{ | |
12902 | + loff_t pos = 0; | |
12903 | + const char *symname; | |
12904 | + unsigned long addr; | |
12905 | + int i, max_errors = 20; | |
12906 | + struct bb_name_state *r; | |
12907 | + kdb_printf("%s: build variables:" | |
12908 | + " CCVERSION \"" __stringify(CCVERSION) "\"" | |
12909 | +#ifdef CONFIG_X86_64 | |
12910 | + " CONFIG_X86_64" | |
12911 | +#endif | |
12912 | +#ifdef CONFIG_4KSTACKS | |
12913 | + " CONFIG_4KSTACKS" | |
12914 | +#endif | |
12915 | +#ifdef CONFIG_PREEMPT | |
12916 | + " CONFIG_PREEMPT" | |
12917 | +#endif | |
12918 | +#ifdef CONFIG_VM86 | |
12919 | + " CONFIG_VM86" | |
12920 | +#endif | |
12921 | +#ifdef CONFIG_FRAME_POINTER | |
12922 | + " CONFIG_FRAME_POINTER" | |
12923 | +#endif | |
12924 | +#ifdef CONFIG_TRACE_IRQFLAGS | |
12925 | + " CONFIG_TRACE_IRQFLAGS" | |
12926 | +#endif | |
12927 | +#ifdef CONFIG_HIBERNATION | |
12928 | + " CONFIG_HIBERNATION" | |
12929 | +#endif | |
12930 | +#ifdef CONFIG_KPROBES | |
12931 | + " CONFIG_KPROBES" | |
12932 | +#endif | |
12933 | +#ifdef CONFIG_KEXEC | |
12934 | + " CONFIG_KEXEC" | |
12935 | +#endif | |
12936 | +#ifdef CONFIG_MATH_EMULATION | |
12937 | + " CONFIG_MATH_EMULATION" | |
12938 | +#endif | |
12939 | +#ifdef CONFIG_XEN | |
12940 | + " CONFIG_XEN" | |
12941 | +#endif | |
12942 | +#ifdef CONFIG_DEBUG_INFO | |
12943 | + " CONFIG_DEBUG_INFO" | |
12944 | +#endif | |
12945 | +#ifdef NO_SIBLINGS | |
12946 | + " NO_SIBLINGS" | |
12947 | +#endif | |
12948 | + " REGPARM=" __stringify(REGPARM) | |
12949 | + "\n\n", __FUNCTION__); | |
12950 | + for (i = 0, r = bb_special_cases; | |
12951 | + i < ARRAY_SIZE(bb_special_cases); | |
12952 | + ++i, ++r) { | |
12953 | + if (!r->address) | |
12954 | + kdb_printf("%s: cannot find special_case name %s\n", | |
12955 | + __FUNCTION__, r->name); | |
12956 | + } | |
12957 | + for (i = 0; i < ARRAY_SIZE(bb_spurious); ++i) { | |
12958 | + if (!kallsyms_lookup_name(bb_spurious[i])) | |
12959 | + kdb_printf("%s: cannot find spurious label %s\n", | |
12960 | + __FUNCTION__, bb_spurious[i]); | |
12961 | + } | |
12962 | + while ((symname = kdb_walk_kallsyms(&pos))) { | |
12963 | + if (strcmp(symname, "_stext") == 0 || | |
12964 | + strcmp(symname, "stext") == 0) | |
12965 | + break; | |
12966 | + } | |
12967 | + if (!symname) { | |
12968 | + kdb_printf("%s: cannot find _stext\n", __FUNCTION__); | |
12969 | + return 0; | |
12970 | + } | |
12971 | + kdba_id_init(&kdb_di); | |
12972 | + i = 0; | |
12973 | + while ((symname = kdb_walk_kallsyms(&pos))) { | |
12974 | + if (strcmp(symname, "_etext") == 0) | |
12975 | + break; | |
12976 | + if (i++ % 100 == 0) | |
12977 | + kdb_printf("."); | |
12978 | + /* x86_64 has some 16 bit functions that appear between stext | |
12979 | + * and _etext. Skip them. | |
12980 | + */ | |
12981 | + if (strcmp(symname, "verify_cpu") == 0 || | |
12982 | + strcmp(symname, "verify_cpu_noamd") == 0 || | |
12983 | + strcmp(symname, "verify_cpu_sse_test") == 0 || | |
12984 | + strcmp(symname, "verify_cpu_no_longmode") == 0 || | |
12985 | + strcmp(symname, "verify_cpu_sse_ok") == 0 || | |
12986 | + strcmp(symname, "mode_seta") == 0 || | |
12987 | + strcmp(symname, "bad_address") == 0 || | |
12988 | + strcmp(symname, "wakeup_code") == 0 || | |
12989 | + strcmp(symname, "wakeup_code_start") == 0 || | |
12990 | + strcmp(symname, "wakeup_start") == 0 || | |
12991 | + strcmp(symname, "wakeup_32_vector") == 0 || | |
12992 | + strcmp(symname, "wakeup_32") == 0 || | |
12993 | + strcmp(symname, "wakeup_long64_vector") == 0 || | |
12994 | + strcmp(symname, "wakeup_long64") == 0 || | |
12995 | + strcmp(symname, "gdta") == 0 || | |
12996 | + strcmp(symname, "idt_48a") == 0 || | |
12997 | + strcmp(symname, "gdt_48a") == 0 || | |
12998 | + strcmp(symname, "bogus_real_magic") == 0 || | |
12999 | + strcmp(symname, "bogus_64_magic") == 0 || | |
13000 | + strcmp(symname, "no_longmode") == 0 || | |
13001 | + strcmp(symname, "mode_set") == 0 || | |
13002 | + strcmp(symname, "mode_seta") == 0 || | |
13003 | + strcmp(symname, "setbada") == 0 || | |
13004 | + strcmp(symname, "check_vesa") == 0 || | |
13005 | + strcmp(symname, "check_vesaa") == 0 || | |
13006 | + strcmp(symname, "_setbada") == 0 || | |
13007 | + strcmp(symname, "wakeup_stack_begin") == 0 || | |
13008 | + strcmp(symname, "wakeup_stack") == 0 || | |
13009 | + strcmp(symname, "wakeup_level4_pgt") == 0 || | |
13010 | + strcmp(symname, "acpi_copy_wakeup_routine") == 0 || | |
13011 | + strcmp(symname, "wakeup_end") == 0 || | |
13012 | + strcmp(symname, "do_suspend_lowlevel_s4bios") == 0 || | |
13013 | + strcmp(symname, "do_suspend_lowlevel") == 0 || | |
13014 | + strcmp(symname, "wakeup_pmode_return") == 0 || | |
13015 | + strcmp(symname, "restore_registers") == 0) | |
13016 | + continue; | |
13017 | + /* __kprobes_text_end contains branches to the middle of code, | |
13018 | + * with undefined states. | |
13019 | + */ | |
13020 | + if (strcmp(symname, "__kprobes_text_end") == 0) | |
13021 | + continue; | |
13022 | + /* Data in the middle of the text segment :( */ | |
13023 | + if (strcmp(symname, "level2_kernel_pgt") == 0 || | |
13024 | + strcmp(symname, "level3_kernel_pgt") == 0) | |
13025 | + continue; | |
13026 | + if (bb_spurious_global_label(symname)) | |
13027 | + continue; | |
13028 | + if ((addr = kallsyms_lookup_name(symname)) == 0) | |
13029 | + continue; | |
13030 | + // kdb_printf("BB " kdb_bfd_vma_fmt0 " %s\n", addr, symname); | |
13031 | + bb_cleanup(); /* in case previous command was interrupted */ | |
13032 | + kdbnearsym_cleanup(); | |
13033 | + kdb_bb(addr); | |
13034 | + touch_nmi_watchdog(); | |
13035 | + if (bb_giveup) { | |
13036 | + if (max_errors-- == 0) { | |
13037 | + kdb_printf("%s: max_errors reached, giving up\n", | |
13038 | + __FUNCTION__); | |
13039 | + break; | |
13040 | + } else { | |
13041 | + bb_giveup = 0; | |
13042 | + } | |
13043 | + } | |
13044 | + } | |
13045 | + kdb_printf("\n"); | |
13046 | + bb_cleanup(); | |
13047 | + kdbnearsym_cleanup(); | |
13048 | + return 0; | |
13049 | +} | |
13050 | + | |
13051 | +/* | |
13052 | + *============================================================================= | |
13053 | + * | |
13054 | + * Everything above this line is doing basic block analysis, function by | |
13055 | + * function. Everything below this line uses the basic block data to do a | |
13056 | + * complete backtrace over all functions that are used by a process. | |
13057 | + * | |
13058 | + *============================================================================= | |
13059 | + */ | |
13060 | + | |
13061 | + | |
13062 | +/*============================================================================*/ | |
13063 | +/* */ | |
13064 | +/* Most of the backtrace code and data is common to x86_64 and i386. This */ | |
13065 | +/* large ifdef contains all of the differences between the two architectures. */ | |
13066 | +/* */ | |
13067 | +/* Make sure you update the correct section of this ifdef. */ | |
13068 | +/* */ | |
13069 | +/*============================================================================*/ | |
13070 | +#define XCS "cs" | |
13071 | +#define RSP "sp" | |
13072 | +#define RIP "ip" | |
13073 | +#define ARCH_RSP sp | |
13074 | +#define ARCH_RIP ip | |
13075 | + | |
13076 | +#ifdef CONFIG_X86_64 | |
13077 | + | |
13078 | +#define ARCH_NORMAL_PADDING (16 * 8) | |
13079 | + | |
13080 | +/* x86_64 has multiple alternate stacks, with different sizes and different | |
13081 | + * offsets to get the link from one stack to the next. Some of the stacks are | |
13082 | + * referenced via cpu_pda, some via per_cpu orig_ist. Debug events can even | |
13083 | + * have multiple nested stacks within the single physical stack, each nested | |
13084 | + * stack has its own link and some of those links are wrong. | |
13085 | + * | |
13086 | + * Consistent it's not! | |
13087 | + * | |
13088 | + * Do not assume that these stacks are aligned on their size. | |
13089 | + */ | |
13090 | +#define INTERRUPT_STACK (N_EXCEPTION_STACKS + 1) | |
13091 | +void | |
13092 | +kdba_get_stack_info_alternate(kdb_machreg_t addr, int cpu, | |
13093 | + struct kdb_activation_record *ar) | |
13094 | +{ | |
13095 | + static struct { | |
13096 | + const char *id; | |
13097 | + unsigned int total_size; | |
13098 | + unsigned int nested_size; | |
13099 | + unsigned int next; | |
13100 | + } *sdp, stack_data[] = { | |
13101 | + [STACKFAULT_STACK - 1] = { "stackfault", EXCEPTION_STKSZ, EXCEPTION_STKSZ, EXCEPTION_STKSZ - 2*sizeof(void *) }, | |
13102 | + [DOUBLEFAULT_STACK - 1] = { "doublefault", EXCEPTION_STKSZ, EXCEPTION_STKSZ, EXCEPTION_STKSZ - 2*sizeof(void *) }, | |
13103 | + [NMI_STACK - 1] = { "nmi", EXCEPTION_STKSZ, EXCEPTION_STKSZ, EXCEPTION_STKSZ - 2*sizeof(void *) }, | |
13104 | + [DEBUG_STACK - 1] = { "debug", DEBUG_STKSZ, EXCEPTION_STKSZ, EXCEPTION_STKSZ - 2*sizeof(void *) }, | |
13105 | + [MCE_STACK - 1] = { "machine check", EXCEPTION_STKSZ, EXCEPTION_STKSZ, EXCEPTION_STKSZ - 2*sizeof(void *) }, | |
13106 | + [INTERRUPT_STACK - 1] = { "interrupt", IRQSTACKSIZE, IRQSTACKSIZE, IRQSTACKSIZE - sizeof(void *) }, | |
13107 | + }; | |
13108 | + unsigned long total_start = 0, total_size, total_end; | |
13109 | + int sd, found = 0; | |
13110 | + extern unsigned long kdba_orig_ist(int, int); | |
13111 | + | |
13112 | + for (sd = 0, sdp = stack_data; | |
13113 | + sd < ARRAY_SIZE(stack_data); | |
13114 | + ++sd, ++sdp) { | |
13115 | + total_size = sdp->total_size; | |
13116 | + if (!total_size) | |
13117 | + continue; /* in case stack_data[] has any holes */ | |
13118 | + if (cpu < 0) { | |
13119 | + /* Arbitrary address which can be on any cpu, see if it | |
13120 | + * falls within any of the alternate stacks | |
13121 | + */ | |
13122 | + int c; | |
13123 | + for_each_online_cpu(c) { | |
13124 | + if (sd == INTERRUPT_STACK - 1) | |
13125 | + total_end = (unsigned long)cpu_pda(c)->irqstackptr; | |
13126 | + else | |
13127 | + total_end = per_cpu(orig_ist, c).ist[sd]; | |
13128 | + total_start = total_end - total_size; | |
13129 | + if (addr >= total_start && addr < total_end) { | |
13130 | + found = 1; | |
13131 | + cpu = c; | |
13132 | + break; | |
13133 | + } | |
13134 | + } | |
13135 | + if (!found) | |
13136 | + continue; | |
13137 | + } | |
13138 | + /* Only check the supplied or found cpu */ | |
13139 | + if (sd == INTERRUPT_STACK - 1) | |
13140 | + total_end = (unsigned long)cpu_pda(cpu)->irqstackptr; | |
13141 | + else | |
13142 | + total_end = per_cpu(orig_ist, cpu).ist[sd]; | |
13143 | + total_start = total_end - total_size; | |
13144 | + if (addr >= total_start && addr < total_end) { | |
13145 | + found = 1; | |
13146 | + break; | |
13147 | + } | |
13148 | + } | |
13149 | + if (!found) | |
13150 | + return; | |
13151 | + /* find which nested stack the address is in */ | |
13152 | + while (addr > total_start + sdp->nested_size) | |
13153 | + total_start += sdp->nested_size; | |
13154 | + ar->stack.physical_start = total_start; | |
13155 | + ar->stack.physical_end = total_start + sdp->nested_size; | |
13156 | + ar->stack.logical_start = total_start; | |
13157 | + ar->stack.logical_end = total_start + sdp->next; | |
13158 | + ar->stack.next = *(unsigned long *)ar->stack.logical_end; | |
13159 | + ar->stack.id = sdp->id; | |
13160 | + | |
13161 | + /* Nasty: when switching to the interrupt stack, the stack state of the | |
13162 | + * caller is split over two stacks, the original stack and the | |
13163 | + * interrupt stack. One word (the previous frame pointer) is stored on | |
13164 | + * the interrupt stack, the rest of the interrupt data is in the old | |
13165 | + * frame. To make the interrupted stack state look as though it is | |
13166 | + * contiguous, copy the missing word from the interrupt stack to the | |
13167 | + * original stack and adjust the new stack pointer accordingly. | |
13168 | + */ | |
13169 | + | |
13170 | + if (sd == INTERRUPT_STACK - 1) { | |
13171 | + *(unsigned long *)(ar->stack.next - KDB_WORD_SIZE) = | |
13172 | + ar->stack.next; | |
13173 | + ar->stack.next -= KDB_WORD_SIZE; | |
13174 | + } | |
13175 | +} | |
13176 | + | |
13177 | +/* rip is not in the thread struct for x86_64. We know that the stack value | |
13178 | + * was saved in schedule near the label thread_return. Setting rip to | |
13179 | + * thread_return lets the stack trace find that we are in schedule and | |
13180 | + * correctly decode its prologue. | |
13181 | + */ | |
13182 | + | |
13183 | +static kdb_machreg_t | |
13184 | +kdba_bt_stack_rip(const struct task_struct *p) | |
13185 | +{ | |
13186 | + return bb_thread_return; | |
13187 | +} | |
13188 | + | |
13189 | +#else /* !CONFIG_X86_64 */ | |
13190 | + | |
13191 | +#define ARCH_NORMAL_PADDING (19 * 4) | |
13192 | + | |
13193 | +#ifdef CONFIG_4KSTACKS | |
13194 | +static struct thread_info **kdba_hardirq_ctx, **kdba_softirq_ctx; | |
13195 | +#endif /* CONFIG_4KSTACKS */ | |
13196 | + | |
13197 | +/* On a 4K stack kernel, hardirq_ctx and softirq_ctx are [NR_CPUS] arrays. The | |
13198 | + * first element of each per-cpu stack is a struct thread_info. | |
13199 | + */ | |
13200 | +void | |
13201 | +kdba_get_stack_info_alternate(kdb_machreg_t addr, int cpu, | |
13202 | + struct kdb_activation_record *ar) | |
13203 | +{ | |
13204 | +#ifdef CONFIG_4KSTACKS | |
13205 | + struct thread_info *tinfo; | |
13206 | + tinfo = (struct thread_info *)(addr & -THREAD_SIZE); | |
13207 | + if (cpu < 0) { | |
13208 | + /* Arbitrary address, see if it falls within any of the irq | |
13209 | + * stacks | |
13210 | + */ | |
13211 | + int found = 0; | |
13212 | + for_each_online_cpu(cpu) { | |
13213 | + if (tinfo == kdba_hardirq_ctx[cpu] || | |
13214 | + tinfo == kdba_softirq_ctx[cpu]) { | |
13215 | + found = 1; | |
13216 | + break; | |
13217 | + } | |
13218 | + } | |
13219 | + if (!found) | |
13220 | + return; | |
13221 | + } | |
13222 | + if (tinfo == kdba_hardirq_ctx[cpu] || | |
13223 | + tinfo == kdba_softirq_ctx[cpu]) { | |
13224 | + ar->stack.physical_start = (kdb_machreg_t)tinfo; | |
13225 | + ar->stack.physical_end = ar->stack.physical_start + THREAD_SIZE; | |
13226 | + ar->stack.logical_start = ar->stack.physical_start + | |
13227 | + sizeof(struct thread_info); | |
13228 | + ar->stack.logical_end = ar->stack.physical_end; | |
13229 | + ar->stack.next = tinfo->previous_esp; | |
13230 | + if (tinfo == kdba_hardirq_ctx[cpu]) | |
13231 | + ar->stack.id = "hardirq_ctx"; | |
13232 | + else | |
13233 | + ar->stack.id = "softirq_ctx"; | |
13234 | + } | |
13235 | +#endif /* CONFIG_4KSTACKS */ | |
13236 | +} | |
13237 | + | |
13238 | +/* rip is in the thread struct for i386 */ | |
13239 | + | |
13240 | +static kdb_machreg_t | |
13241 | +kdba_bt_stack_rip(const struct task_struct *p) | |
13242 | +{ | |
13243 | + return p->thread.ip; | |
13244 | +} | |
13245 | + | |
13246 | +#endif /* CONFIG_X86_64 */ | |
13247 | + | |
13248 | +/* Given an address which claims to be on a stack, an optional cpu number and | |
13249 | + * an optional task address, get information about the stack. | |
13250 | + * | |
13251 | + * t == NULL, cpu < 0 indicates an arbitrary stack address with no associated | |
13252 | + * struct task, the address can be in an alternate stack or any task's normal | |
13253 | + * stack. | |
13254 | + * | |
13255 | + * t != NULL, cpu >= 0 indicates a running task, the address can be in an | |
13256 | + * alternate stack or that task's normal stack. | |
13257 | + * | |
13258 | + * t != NULL, cpu < 0 indicates a blocked task, the address can only be in that | |
13259 | + * task's normal stack. | |
13260 | + * | |
13261 | + * t == NULL, cpu >= 0 is not a valid combination. | |
13262 | + */ | |
13263 | + | |
13264 | +static void | |
13265 | +kdba_get_stack_info(kdb_machreg_t rsp, int cpu, | |
13266 | + struct kdb_activation_record *ar, | |
13267 | + const struct task_struct *t) | |
13268 | +{ | |
13269 | + struct thread_info *tinfo; | |
13270 | + struct task_struct *g, *p; | |
13271 | + memset(&ar->stack, 0, sizeof(ar->stack)); | |
13272 | + if (KDB_DEBUG(ARA)) | |
13273 | + kdb_printf("%s: " RSP "=0x%lx cpu=%d task=%p\n", | |
13274 | + __FUNCTION__, rsp, cpu, t); | |
13275 | + if (t == NULL || cpu >= 0) { | |
13276 | + kdba_get_stack_info_alternate(rsp, cpu, ar); | |
13277 | + if (ar->stack.logical_start) | |
13278 | + goto out; | |
13279 | + } | |
13280 | + rsp &= -THREAD_SIZE; | |
13281 | + tinfo = (struct thread_info *)rsp; | |
13282 | + if (t == NULL) { | |
13283 | + /* Arbitrary stack address without an associated task, see if | |
13284 | + * it falls within any normal process stack, including the idle | |
13285 | + * tasks. | |
13286 | + */ | |
13287 | + kdb_do_each_thread(g, p) { | |
13288 | + if (tinfo == task_thread_info(p)) { | |
13289 | + t = p; | |
13290 | + goto found; | |
13291 | + } | |
13292 | + } kdb_while_each_thread(g, p); | |
13293 | + for_each_online_cpu(cpu) { | |
13294 | + p = idle_task(cpu); | |
13295 | + if (tinfo == task_thread_info(p)) { | |
13296 | + t = p; | |
13297 | + goto found; | |
13298 | + } | |
13299 | + } | |
13300 | + found: | |
13301 | + if (KDB_DEBUG(ARA)) | |
13302 | + kdb_printf("%s: found task %p\n", __FUNCTION__, t); | |
13303 | + } else if (cpu >= 0) { | |
13304 | + /* running task */ | |
13305 | + struct kdb_running_process *krp = kdb_running_process + cpu; | |
13306 | + if (krp->p != t || tinfo != task_thread_info(t)) | |
13307 | + t = NULL; | |
13308 | + if (KDB_DEBUG(ARA)) | |
13309 | + kdb_printf("%s: running task %p\n", __FUNCTION__, t); | |
13310 | + } else { | |
13311 | + /* blocked task */ | |
13312 | + if (tinfo != task_thread_info(t)) | |
13313 | + t = NULL; | |
13314 | + if (KDB_DEBUG(ARA)) | |
13315 | + kdb_printf("%s: blocked task %p\n", __FUNCTION__, t); | |
13316 | + } | |
13317 | + if (t) { | |
13318 | + ar->stack.physical_start = rsp; | |
13319 | + ar->stack.physical_end = rsp + THREAD_SIZE; | |
13320 | + ar->stack.logical_start = rsp + sizeof(struct thread_info); | |
13321 | + ar->stack.logical_end = ar->stack.physical_end - ARCH_NORMAL_PADDING; | |
13322 | + ar->stack.next = 0; | |
13323 | + ar->stack.id = "normal"; | |
13324 | + } | |
13325 | +out: | |
13326 | + if (ar->stack.physical_start && KDB_DEBUG(ARA)) { | |
13327 | + kdb_printf("%s: ar->stack\n", __FUNCTION__); | |
13328 | + kdb_printf(" physical_start=0x%lx\n", ar->stack.physical_start); | |
13329 | + kdb_printf(" physical_end=0x%lx\n", ar->stack.physical_end); | |
13330 | + kdb_printf(" logical_start=0x%lx\n", ar->stack.logical_start); | |
13331 | + kdb_printf(" logical_end=0x%lx\n", ar->stack.logical_end); | |
13332 | + kdb_printf(" next=0x%lx\n", ar->stack.next); | |
13333 | + kdb_printf(" id=%s\n", ar->stack.id); | |
13334 | + kdb_printf(" set MDCOUNT %ld\n", | |
13335 | + (ar->stack.physical_end - ar->stack.physical_start) / | |
13336 | + KDB_WORD_SIZE); | |
13337 | + kdb_printf(" mds " kdb_machreg_fmt0 "\n", | |
13338 | + ar->stack.physical_start); | |
13339 | + } | |
13340 | +} | |
13341 | + | |
13342 | +static void | |
13343 | +bt_print_one(kdb_machreg_t rip, kdb_machreg_t rsp, | |
13344 | + const struct kdb_activation_record *ar, | |
13345 | + const kdb_symtab_t *symtab, int argcount) | |
13346 | +{ | |
13347 | + int btsymarg = 0; | |
13348 | + int nosect = 0; | |
13349 | + | |
13350 | + kdbgetintenv("BTSYMARG", &btsymarg); | |
13351 | + kdbgetintenv("NOSECT", &nosect); | |
13352 | + | |
13353 | + kdb_printf(kdb_machreg_fmt0, rsp); | |
13354 | + kdb_symbol_print(rip, symtab, | |
13355 | + KDB_SP_SPACEB|KDB_SP_VALUE); | |
13356 | + if (argcount && ar->args) { | |
13357 | + int i, argc = ar->args; | |
13358 | + kdb_printf(" ("); | |
13359 | + if (argc > argcount) | |
13360 | + argc = argcount; | |
13361 | + for (i = 0; i < argc; i++) { | |
13362 | + if (i) | |
13363 | + kdb_printf(", "); | |
13364 | + if (test_bit(i, ar->valid.bits)) | |
13365 | + kdb_printf("0x%lx", ar->arg[i]); | |
13366 | + else | |
13367 | + kdb_printf("invalid"); | |
13368 | + } | |
13369 | + kdb_printf(")"); | |
13370 | + } | |
13371 | + kdb_printf("\n"); | |
13372 | + if (symtab->sym_name) { | |
13373 | + if (!nosect) { | |
13374 | + kdb_printf(" %s", | |
13375 | + symtab->mod_name); | |
13376 | + if (symtab->sec_name && symtab->sec_start) | |
13377 | + kdb_printf(" 0x%lx 0x%lx", | |
13378 | + symtab->sec_start, symtab->sec_end); | |
13379 | + kdb_printf(" 0x%lx 0x%lx\n", | |
13380 | + symtab->sym_start, symtab->sym_end); | |
13381 | + } | |
13382 | + } | |
13383 | + if (argcount && ar->args && btsymarg) { | |
13384 | + int i, argc = ar->args; | |
13385 | + kdb_symtab_t arg_symtab; | |
13386 | + for (i = 0; i < argc; i++) { | |
13387 | + kdb_machreg_t arg = ar->arg[i]; | |
13388 | + if (test_bit(i, ar->valid.bits) && | |
13389 | + kdbnearsym(arg, &arg_symtab)) { | |
13390 | + kdb_printf(" ARG %2d ", i); | |
13391 | + kdb_symbol_print(arg, &arg_symtab, | |
13392 | + KDB_SP_DEFAULT|KDB_SP_NEWLINE); | |
13393 | + } | |
13394 | + } | |
13395 | + } | |
13396 | +} | |
13397 | + | |
13398 | +static void | |
13399 | +kdba_bt_new_stack(struct kdb_activation_record *ar, kdb_machreg_t *rsp, | |
13400 | + int *count, int *suppress) | |
13401 | +{ | |
13402 | + /* Nasty: common_interrupt builds a partial pt_regs, with r15 through | |
13403 | + * rbx not being filled in. It passes struct pt_regs* to do_IRQ (in | |
13404 | + * rdi) but the stack pointer is not adjusted to account for r15 | |
13405 | + * through rbx. This has two effects :- | |
13406 | + * | |
13407 | + * (1) struct pt_regs on an external interrupt actually overlaps with | |
13408 | + * the local stack area used by do_IRQ. Not only are r15-rbx | |
13409 | + * undefined, the area that claims to hold their values can even | |
13410 | + * change as the irq is processed. | |
13411 | + * | |
13412 | + * (2) The back stack pointer saved for the new frame is not pointing | |
13413 | + * at pt_regs, it is pointing at rbx within the pt_regs passed to | |
13414 | + * do_IRQ. | |
13415 | + * | |
13416 | + * There is nothing that I can do about (1) but I have to fix (2) | |
13417 | + * because kdb backtrace looks for the "start" address of pt_regs as it | |
13418 | + * walks back through the stacks. When switching from the interrupt | |
13419 | + * stack to another stack, we have to assume that pt_regs has been | |
13420 | + * seen and turn off backtrace supression. | |
13421 | + */ | |
13422 | + int probable_pt_regs = strcmp(ar->stack.id, "interrupt") == 0; | |
13423 | + *rsp = ar->stack.next; | |
13424 | + if (KDB_DEBUG(ARA)) | |
13425 | + kdb_printf("new " RSP "=" kdb_machreg_fmt0 "\n", *rsp); | |
13426 | + bb_actual_set_value(BBRG_RSP, *rsp); | |
13427 | + kdba_get_stack_info(*rsp, -1, ar, NULL); | |
13428 | + if (!ar->stack.physical_start) { | |
13429 | + kdb_printf("+++ Cannot resolve next stack\n"); | |
13430 | + } else if (!*suppress) { | |
13431 | + kdb_printf(" ======================= <%s>\n", | |
13432 | + ar->stack.id); | |
13433 | + ++*count; | |
13434 | + } | |
13435 | + if (probable_pt_regs) | |
13436 | + *suppress = 0; | |
13437 | +} | |
13438 | + | |
13439 | +/* | |
13440 | + * kdba_bt_stack | |
13441 | + * | |
13442 | + * Inputs: | |
13443 | + * addr Address provided to 'bt' command, if any. | |
13444 | + * argcount | |
13445 | + * p Pointer to task for 'btp' command. | |
13446 | + * Outputs: | |
13447 | + * None. | |
13448 | + * Returns: | |
13449 | + * zero for success, a kdb diagnostic if error | |
13450 | + * Locking: | |
13451 | + * none. | |
13452 | + * Remarks: | |
13453 | + * Ultimately all the bt* commands come through this routine. If | |
13454 | + * old_style is 0 then it uses the basic block analysis to get an accurate | |
13455 | + * backtrace with arguments, otherwise it falls back to the old method of | |
13456 | + * printing anything on stack that looks like a kernel address. | |
13457 | + * | |
13458 | + * Allowing for the stack data pushed by the hardware is tricky. We | |
13459 | + * deduce the presence of hardware pushed data by looking for interrupt | |
13460 | + * handlers, either by name or by the code that they contain. This | |
13461 | + * information must be applied to the next function up the stack, because | |
13462 | + * the hardware data is above the saved rip for the interrupted (next) | |
13463 | + * function. | |
13464 | + * | |
13465 | + * To make things worse, the amount of data pushed is arch specific and | |
13466 | + * may depend on the rsp for the next function, not the current function. | |
13467 | + * The number of bytes pushed by hardware cannot be calculated until we | |
13468 | + * are actually processing the stack for the interrupted function and have | |
13469 | + * its rsp. | |
13470 | + * | |
13471 | + * It is also possible for an interrupt to occur in user space and for the | |
13472 | + * interrupt handler to also be interrupted. Check the code selector | |
13473 | + * whenever the previous function is an interrupt handler and stop | |
13474 | + * backtracing if the interrupt was not in kernel space. | |
13475 | + */ | |
13476 | + | |
13477 | +static int | |
13478 | +kdba_bt_stack(kdb_machreg_t addr, int argcount, const struct task_struct *p, | |
13479 | + int old_style) | |
13480 | +{ | |
13481 | + struct kdb_activation_record ar; | |
13482 | + kdb_machreg_t rip = 0, rsp = 0, prev_rsp, cs; | |
13483 | + kdb_symtab_t symtab; | |
13484 | + int rip_at_rsp = 0, count = 0, btsp = 0, suppress, | |
13485 | + interrupt_handler = 0, prev_interrupt_handler = 0, hardware_pushed, | |
13486 | + prev_noret = 0; | |
13487 | + struct pt_regs *regs = NULL; | |
13488 | + | |
13489 | + kdbgetintenv("BTSP", &btsp); | |
13490 | + suppress = !btsp; | |
13491 | + memset(&ar, 0, sizeof(ar)); | |
13492 | + if (old_style) | |
13493 | + kdb_printf("Using old style backtrace, unreliable with no arguments\n"); | |
13494 | + | |
13495 | + /* | |
13496 | + * The caller may have supplied an address at which the stack traceback | |
13497 | + * operation should begin. This address is assumed by this code to | |
13498 | + * point to a return address on the stack to be traced back. | |
13499 | + * | |
13500 | + * Warning: type in the wrong address and you will get garbage in the | |
13501 | + * backtrace. | |
13502 | + */ | |
13503 | + if (addr) { | |
13504 | + rsp = addr; | |
13505 | + kdb_getword(&rip, rsp, sizeof(rip)); | |
13506 | + rip_at_rsp = 1; | |
13507 | + suppress = 0; | |
13508 | + kdba_get_stack_info(rsp, -1, &ar, NULL); | |
13509 | + } else { | |
13510 | + if (task_curr(p)) { | |
13511 | + struct kdb_running_process *krp = | |
13512 | + kdb_running_process + task_cpu(p); | |
13513 | + kdb_machreg_t cs; | |
13514 | + regs = krp->regs; | |
13515 | + if (krp->seqno && | |
13516 | + krp->p == p && | |
13517 | + krp->seqno >= kdb_seqno - 1 && | |
13518 | + !KDB_NULL_REGS(regs)) { | |
13519 | + /* valid saved state, continue processing */ | |
13520 | + } else { | |
13521 | + kdb_printf | |
13522 | + ("Process did not save state, cannot backtrace\n"); | |
13523 | + kdb_ps1(p); | |
13524 | + return 0; | |
13525 | + } | |
13526 | + kdba_getregcontents(XCS, regs, &cs); | |
13527 | + if ((cs & 0xffff) != __KERNEL_CS) { | |
13528 | + kdb_printf("Stack is not in kernel space, backtrace not available\n"); | |
13529 | + return 0; | |
13530 | + } | |
13531 | + rip = krp->arch.ARCH_RIP; | |
13532 | + rsp = krp->arch.ARCH_RSP; | |
13533 | + kdba_get_stack_info(rsp, kdb_process_cpu(p), &ar, p); | |
13534 | + } else { | |
13535 | + /* Not on cpu, assume blocked. Blocked tasks do not | |
13536 | + * have pt_regs. p->thread contains some data, alas | |
13537 | + * what it contains differs between i386 and x86_64. | |
13538 | + */ | |
13539 | + rip = kdba_bt_stack_rip(p); | |
13540 | + rsp = p->thread.sp; | |
13541 | + suppress = 0; | |
13542 | + kdba_get_stack_info(rsp, -1, &ar, p); | |
13543 | + } | |
13544 | + } | |
13545 | + if (!ar.stack.physical_start) { | |
13546 | + kdb_printf(RSP "=0x%lx is not in a valid kernel stack, backtrace not available\n", | |
13547 | + rsp); | |
13548 | + return 0; | |
13549 | + } | |
13550 | + memset(&bb_actual, 0, sizeof(bb_actual)); | |
13551 | + bb_actual_set_value(BBRG_RSP, rsp); | |
13552 | + bb_actual_set_valid(BBRG_RSP, 1); | |
13553 | + | |
13554 | + kdb_printf(RSP "%*s" RIP "%*sFunction (args)\n", | |
13555 | + 2*KDB_WORD_SIZE, " ", | |
13556 | + 2*KDB_WORD_SIZE, " "); | |
13557 | + if (ar.stack.next && !suppress) | |
13558 | + kdb_printf(" ======================= <%s>\n", | |
13559 | + ar.stack.id); | |
13560 | + | |
13561 | + bb_cleanup(); | |
13562 | + /* Run through all the stacks */ | |
13563 | + while (ar.stack.physical_start) { | |
13564 | + if (rip_at_rsp) { | |
13565 | + rip = *(kdb_machreg_t *)rsp; | |
13566 | + /* I wish that gcc was fixed to include a nop | |
13567 | + * instruction after ATTRIB_NORET functions. The lack | |
13568 | + * of a nop means that the return address points to the | |
13569 | + * start of next function, so fudge it to point to one | |
13570 | + * byte previous. | |
13571 | + * | |
13572 | + * No, we cannot just decrement all rip values. | |
13573 | + * Sometimes an rip legally points to the start of a | |
13574 | + * function, e.g. interrupted code or hand crafted | |
13575 | + * assembler. | |
13576 | + */ | |
13577 | + if (prev_noret) { | |
13578 | + kdbnearsym(rip, &symtab); | |
13579 | + if (rip == symtab.sym_start) { | |
13580 | + --rip; | |
13581 | + if (KDB_DEBUG(ARA)) | |
13582 | + kdb_printf("\tprev_noret, " RIP | |
13583 | + "=0x%lx\n", rip); | |
13584 | + } | |
13585 | + } | |
13586 | + } | |
13587 | + kdbnearsym(rip, &symtab); | |
13588 | + if (old_style) { | |
13589 | + if (__kernel_text_address(rip) && !suppress) { | |
13590 | + bt_print_one(rip, rsp, &ar, &symtab, 0); | |
13591 | + ++count; | |
13592 | + } | |
13593 | + if (rsp == (unsigned long)regs) { | |
13594 | + if (ar.stack.next && suppress) | |
13595 | + kdb_printf(" ======================= <%s>\n", | |
13596 | + ar.stack.id); | |
13597 | + ++count; | |
13598 | + suppress = 0; | |
13599 | + } | |
13600 | + rsp += sizeof(rip); | |
13601 | + rip_at_rsp = 1; | |
13602 | + if (rsp >= ar.stack.logical_end) { | |
13603 | + if (!ar.stack.next) | |
13604 | + break; | |
13605 | + kdba_bt_new_stack(&ar, &rsp, &count, &suppress); | |
13606 | + rip_at_rsp = 0; | |
13607 | + continue; | |
13608 | + } | |
13609 | + } else { | |
13610 | + /* Start each analysis with no dynamic data from the | |
13611 | + * previous kdb_bb() run. | |
13612 | + */ | |
13613 | + bb_cleanup(); | |
13614 | + kdb_bb(rip); | |
13615 | + if (bb_giveup) | |
13616 | + break; | |
13617 | + prev_interrupt_handler = interrupt_handler; | |
13618 | + interrupt_handler = bb_interrupt_handler(rip); | |
13619 | + prev_rsp = rsp; | |
13620 | + if (rip_at_rsp) { | |
13621 | + if (prev_interrupt_handler) { | |
13622 | + cs = *((kdb_machreg_t *)rsp + 1) & 0xffff; | |
13623 | + hardware_pushed = | |
13624 | + bb_hardware_pushed_arch(rsp, &ar); | |
13625 | + } else { | |
13626 | + cs = __KERNEL_CS; | |
13627 | + hardware_pushed = 0; | |
13628 | + } | |
13629 | + rsp += sizeof(rip) + hardware_pushed; | |
13630 | + if (KDB_DEBUG(ARA)) | |
13631 | + kdb_printf("%s: " RSP " " | |
13632 | + kdb_machreg_fmt0 | |
13633 | + " -> " kdb_machreg_fmt0 | |
13634 | + " hardware_pushed %d" | |
13635 | + " prev_interrupt_handler %d" | |
13636 | + " cs 0x%lx\n", | |
13637 | + __FUNCTION__, | |
13638 | + prev_rsp, | |
13639 | + rsp, | |
13640 | + hardware_pushed, | |
13641 | + prev_interrupt_handler, | |
13642 | + cs); | |
13643 | + if (rsp >= ar.stack.logical_end && | |
13644 | + ar.stack.next) { | |
13645 | + kdba_bt_new_stack(&ar, &rsp, &count, | |
13646 | + &suppress); | |
13647 | + rip_at_rsp = 0; | |
13648 | + continue; | |
13649 | + } | |
13650 | + bb_actual_set_value(BBRG_RSP, rsp); | |
13651 | + } else { | |
13652 | + cs = __KERNEL_CS; | |
13653 | + } | |
13654 | + rip_at_rsp = 1; | |
13655 | + bb_actual_rollback(&ar); | |
13656 | + if (bb_giveup) | |
13657 | + break; | |
13658 | + if (bb_actual_value(BBRG_RSP) < rsp) { | |
13659 | + kdb_printf("%s: " RSP " is going backwards, " | |
13660 | + kdb_machreg_fmt0 " -> " | |
13661 | + kdb_machreg_fmt0 "\n", | |
13662 | + __FUNCTION__, | |
13663 | + rsp, | |
13664 | + bb_actual_value(BBRG_RSP)); | |
13665 | + bb_giveup = 1; | |
13666 | + break; | |
13667 | + } | |
13668 | + bb_arguments(&ar); | |
13669 | + if (!suppress) { | |
13670 | + bt_print_one(rip, prev_rsp, &ar, &symtab, argcount); | |
13671 | + ++count; | |
13672 | + } | |
13673 | + /* Functions that terminate the backtrace */ | |
13674 | + if (strcmp(bb_func_name, "cpu_idle") == 0 || | |
13675 | + strcmp(bb_func_name, "child_rip") == 0) | |
13676 | + break; | |
13677 | + if (rsp >= ar.stack.logical_end && | |
13678 | + !ar.stack.next) | |
13679 | + break; | |
13680 | + if (rsp <= (unsigned long)regs && | |
13681 | + bb_actual_value(BBRG_RSP) > (unsigned long)regs) { | |
13682 | + if (ar.stack.next && suppress) | |
13683 | + kdb_printf(" ======================= <%s>\n", | |
13684 | + ar.stack.id); | |
13685 | + ++count; | |
13686 | + suppress = 0; | |
13687 | + } | |
13688 | + if (cs != __KERNEL_CS) { | |
13689 | + kdb_printf("Reached user space\n"); | |
13690 | + break; | |
13691 | + } | |
13692 | + rsp = bb_actual_value(BBRG_RSP); | |
13693 | + } | |
13694 | + prev_noret = bb_noret(bb_func_name); | |
13695 | + if (count > 200) | |
13696 | + break; | |
13697 | + } | |
13698 | + if (bb_giveup) | |
13699 | + return 1; | |
13700 | + bb_cleanup(); | |
13701 | + kdbnearsym_cleanup(); | |
13702 | + | |
13703 | + if (count > 200) { | |
13704 | + kdb_printf("bt truncated, count limit reached\n"); | |
13705 | + return 1; | |
13706 | + } else if (suppress) { | |
13707 | + kdb_printf | |
13708 | + ("bt did not find pt_regs - no trace produced. Suggest 'set BTSP 1'\n"); | |
13709 | + return 1; | |
13710 | + } | |
13711 | + | |
13712 | + return 0; | |
13713 | +} | |
13714 | + | |
13715 | +/* | |
13716 | + * kdba_bt_address | |
13717 | + * | |
13718 | + * Do a backtrace starting at a specified stack address. Use this if the | |
13719 | + * heuristics get the stack decode wrong. | |
13720 | + * | |
13721 | + * Inputs: | |
13722 | + * addr Address provided to 'bt' command. | |
13723 | + * argcount | |
13724 | + * Outputs: | |
13725 | + * None. | |
13726 | + * Returns: | |
13727 | + * zero for success, a kdb diagnostic if error | |
13728 | + * Locking: | |
13729 | + * none. | |
13730 | + * Remarks: | |
13731 | + * mds %rsp comes in handy when examining the stack to do a manual | |
13732 | + * traceback. | |
13733 | + */ | |
13734 | + | |
13735 | +int kdba_bt_address(kdb_machreg_t addr, int argcount) | |
13736 | +{ | |
13737 | + int ret; | |
13738 | + kdba_id_init(&kdb_di); /* kdb_bb needs this done once */ | |
13739 | + ret = kdba_bt_stack(addr, argcount, NULL, 0); | |
13740 | + if (ret == 1) | |
13741 | + ret = kdba_bt_stack(addr, argcount, NULL, 1); | |
13742 | + return ret; | |
13743 | +} | |
13744 | + | |
13745 | +/* | |
13746 | + * kdba_bt_process | |
13747 | + * | |
13748 | + * Do a backtrace for a specified process. | |
13749 | + * | |
13750 | + * Inputs: | |
13751 | + * p Struct task pointer extracted by 'bt' command. | |
13752 | + * argcount | |
13753 | + * Outputs: | |
13754 | + * None. | |
13755 | + * Returns: | |
13756 | + * zero for success, a kdb diagnostic if error | |
13757 | + * Locking: | |
13758 | + * none. | |
13759 | + */ | |
13760 | + | |
13761 | +int kdba_bt_process(const struct task_struct *p, int argcount) | |
13762 | +{ | |
13763 | + int ret; | |
13764 | + kdba_id_init(&kdb_di); /* kdb_bb needs this done once */ | |
13765 | + ret = kdba_bt_stack(0, argcount, p, 0); | |
13766 | + if (ret == 1) | |
13767 | + ret = kdba_bt_stack(0, argcount, p, 1); | |
13768 | + return ret; | |
13769 | +} | |
13770 | + | |
13771 | +static int __init kdba_bt_x86_init(void) | |
13772 | +{ | |
13773 | + int i, c, cp = -1; | |
13774 | + struct bb_name_state *r; | |
13775 | + | |
13776 | + kdb_register_repeat("bb1", kdb_bb1, "<vaddr>", "Analyse one basic block", 0, KDB_REPEAT_NONE); | |
13777 | + kdb_register_repeat("bb_all", kdb_bb_all, "", "Backtrace check on all built in functions", 0, KDB_REPEAT_NONE); | |
13778 | + | |
13779 | + /* Split the opcode usage table by the first letter of each set of | |
13780 | + * opcodes, for faster mapping of opcode to its operand usage. | |
13781 | + */ | |
13782 | + for (i = 0; i < ARRAY_SIZE(bb_opcode_usage_all); ++i) { | |
13783 | + c = bb_opcode_usage_all[i].opcode[0] - 'a'; | |
13784 | + if (c != cp) { | |
13785 | + cp = c; | |
13786 | + bb_opcode_usage[c].opcode = bb_opcode_usage_all + i; | |
13787 | + } | |
13788 | + ++bb_opcode_usage[c].size; | |
13789 | + } | |
13790 | + | |
13791 | + bb_common_interrupt = kallsyms_lookup_name("common_interrupt"); | |
13792 | + bb_error_entry = kallsyms_lookup_name("error_entry"); | |
13793 | + bb_ret_from_intr = kallsyms_lookup_name("ret_from_intr"); | |
13794 | + bb_thread_return = kallsyms_lookup_name("thread_return"); | |
13795 | + bb_sync_regs = kallsyms_lookup_name("sync_regs"); | |
13796 | + bb_save_v86_state = kallsyms_lookup_name("save_v86_state"); | |
13797 | + bb__sched_text_start = kallsyms_lookup_name("__sched_text_start"); | |
13798 | + bb__sched_text_end = kallsyms_lookup_name("__sched_text_end"); | |
13799 | + for (i = 0, r = bb_special_cases; | |
13800 | + i < ARRAY_SIZE(bb_special_cases); | |
13801 | + ++i, ++r) { | |
13802 | + r->address = kallsyms_lookup_name(r->name); | |
13803 | + } | |
13804 | + | |
13805 | +#ifdef CONFIG_4KSTACKS | |
13806 | + kdba_hardirq_ctx = (struct thread_info **)kallsyms_lookup_name("hardirq_ctx"); | |
13807 | + kdba_softirq_ctx = (struct thread_info **)kallsyms_lookup_name("softirq_ctx"); | |
13808 | +#endif /* CONFIG_4KSTACKS */ | |
13809 | + | |
13810 | + return 0; | |
13811 | +} | |
13812 | + | |
13813 | +static void __exit kdba_bt_x86_exit(void) | |
13814 | +{ | |
13815 | + kdb_unregister("bb1"); | |
13816 | + kdb_unregister("bb_all"); | |
13817 | +} | |
13818 | + | |
13819 | +module_init(kdba_bt_x86_init) | |
13820 | +module_exit(kdba_bt_x86_exit) | |
13821 | --- /dev/null | |
13822 | +++ b/arch/x86/kdb/kdba_id.c | |
13823 | @@ -0,0 +1,261 @@ | |
13824 | +/* | |
13825 | + * Kernel Debugger Architecture Dependent Instruction Disassembly | |
13826 | + * | |
13827 | + * This file is subject to the terms and conditions of the GNU General Public | |
13828 | + * License. See the file "COPYING" in the main directory of this archive | |
13829 | + * for more details. | |
13830 | + * | |
13831 | + * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved. | |
13832 | + */ | |
13833 | + | |
13834 | +#include <stdarg.h> | |
13835 | +#include <linux/kernel.h> | |
13836 | +#include <linux/init.h> | |
13837 | +#include <linux/ctype.h> | |
13838 | +#include <linux/string.h> | |
13839 | +#include <linux/kdb.h> | |
13840 | +#include <linux/kdbprivate.h> | |
13841 | + | |
13842 | +/* | |
13843 | + * kdba_dis_getsym | |
13844 | + * | |
13845 | + * Get a symbol for the disassembler. | |
13846 | + * | |
13847 | + * Parameters: | |
13848 | + * addr Address for which to get symbol | |
13849 | + * dip Pointer to disassemble_info | |
13850 | + * Returns: | |
13851 | + * 0 | |
13852 | + * Locking: | |
13853 | + * Remarks: | |
13854 | + * Not used for kdb. | |
13855 | + */ | |
13856 | + | |
13857 | +/* ARGSUSED */ | |
13858 | +static int | |
13859 | +kdba_dis_getsym(bfd_vma addr, disassemble_info *dip) | |
13860 | +{ | |
13861 | + | |
13862 | + return 0; | |
13863 | +} | |
13864 | + | |
13865 | +/* | |
13866 | + * kdba_printaddress | |
13867 | + * | |
13868 | + * Print (symbolically) an address. | |
13869 | + * | |
13870 | + * Parameters: | |
13871 | + * addr Address for which to get symbol | |
13872 | + * dip Pointer to disassemble_info | |
13873 | + * flag True if a ":<tab>" sequence should follow the address | |
13874 | + * Returns: | |
13875 | + * 0 | |
13876 | + * Locking: | |
13877 | + * Remarks: | |
13878 | + * | |
13879 | + */ | |
13880 | + | |
13881 | +/* ARGSUSED */ | |
13882 | +static void | |
13883 | +kdba_printaddress(kdb_machreg_t addr, disassemble_info *dip, int flag) | |
13884 | +{ | |
13885 | + kdb_symtab_t symtab; | |
13886 | + int spaces = 5; | |
13887 | + unsigned int offset; | |
13888 | + | |
13889 | + /* | |
13890 | + * Print a symbol name or address as necessary. | |
13891 | + */ | |
13892 | + kdbnearsym(addr, &symtab); | |
13893 | + if (symtab.sym_name) { | |
13894 | + /* Do not use kdb_symbol_print here, it always does | |
13895 | + * kdb_printf but we want dip->fprintf_func. | |
13896 | + */ | |
13897 | + dip->fprintf_func(dip->stream, | |
13898 | + "0x%0*lx %s", | |
13899 | + (int)(2*sizeof(addr)), addr, symtab.sym_name); | |
13900 | + if ((offset = addr - symtab.sym_start) == 0) { | |
13901 | + spaces += 4; | |
13902 | + } | |
13903 | + else { | |
13904 | + unsigned int o = offset; | |
13905 | + while (o >>= 4) | |
13906 | + --spaces; | |
13907 | + dip->fprintf_func(dip->stream, "+0x%x", offset); | |
13908 | + } | |
13909 | + | |
13910 | + } else { | |
13911 | + dip->fprintf_func(dip->stream, "0x%lx", addr); | |
13912 | + } | |
13913 | + | |
13914 | + if (flag) { | |
13915 | + if (spaces < 1) { | |
13916 | + spaces = 1; | |
13917 | + } | |
13918 | + dip->fprintf_func(dip->stream, ":%*s", spaces, " "); | |
13919 | + } | |
13920 | +} | |
13921 | + | |
13922 | +/* | |
13923 | + * kdba_dis_printaddr | |
13924 | + * | |
13925 | + * Print (symbolically) an address. Called by GNU disassembly | |
13926 | + * code via disassemble_info structure. | |
13927 | + * | |
13928 | + * Parameters: | |
13929 | + * addr Address for which to get symbol | |
13930 | + * dip Pointer to disassemble_info | |
13931 | + * Returns: | |
13932 | + * 0 | |
13933 | + * Locking: | |
13934 | + * Remarks: | |
13935 | + * This function will never append ":<tab>" to the printed | |
13936 | + * symbolic address. | |
13937 | + */ | |
13938 | + | |
13939 | +static void | |
13940 | +kdba_dis_printaddr(bfd_vma addr, disassemble_info *dip) | |
13941 | +{ | |
13942 | + kdba_printaddress(addr, dip, 0); | |
13943 | +} | |
13944 | + | |
13945 | +/* | |
13946 | + * kdba_dis_getmem | |
13947 | + * | |
13948 | + * Fetch 'length' bytes from 'addr' into 'buf'. | |
13949 | + * | |
13950 | + * Parameters: | |
13951 | + * addr Address for which to get symbol | |
13952 | + * buf Address of buffer to fill with bytes from 'addr' | |
13953 | + * length Number of bytes to fetch | |
13954 | + * dip Pointer to disassemble_info | |
13955 | + * Returns: | |
13956 | + * 0 if data is available, otherwise error. | |
13957 | + * Locking: | |
13958 | + * Remarks: | |
13959 | + * | |
13960 | + */ | |
13961 | + | |
13962 | +/* ARGSUSED */ | |
13963 | +static int | |
13964 | +kdba_dis_getmem(bfd_vma addr, bfd_byte *buf, unsigned int length, disassemble_info *dip) | |
13965 | +{ | |
13966 | + return kdb_getarea_size(buf, addr, length); | |
13967 | +} | |
13968 | + | |
13969 | +/* | |
13970 | + * kdba_id_parsemode | |
13971 | + * | |
13972 | + * Parse IDMODE environment variable string and | |
13973 | + * set appropriate value into "disassemble_info" structure. | |
13974 | + * | |
13975 | + * Parameters: | |
13976 | + * mode Mode string | |
13977 | + * dip Disassemble_info structure pointer | |
13978 | + * Returns: | |
13979 | + * Locking: | |
13980 | + * Remarks: | |
13981 | + * We handle the values 'x86' and '8086' to enable either | |
13982 | + * 32-bit instruction set or 16-bit legacy instruction set. | |
13983 | + */ | |
13984 | + | |
13985 | +int | |
13986 | +kdba_id_parsemode(const char *mode, disassemble_info *dip) | |
13987 | +{ | |
13988 | + if (mode) { | |
13989 | + if (strcmp(mode, "x86_64") == 0) { | |
13990 | + dip->mach = bfd_mach_x86_64; | |
13991 | + } else if (strcmp(mode, "x86") == 0) { | |
13992 | + dip->mach = bfd_mach_i386_i386; | |
13993 | + } else if (strcmp(mode, "8086") == 0) { | |
13994 | + dip->mach = bfd_mach_i386_i8086; | |
13995 | + } else { | |
13996 | + return KDB_BADMODE; | |
13997 | + } | |
13998 | + } | |
13999 | + | |
14000 | + return 0; | |
14001 | +} | |
14002 | + | |
14003 | +/* | |
14004 | + * kdba_check_pc | |
14005 | + * | |
14006 | + * Check that the pc is satisfactory. | |
14007 | + * | |
14008 | + * Parameters: | |
14009 | + * pc Program Counter Value. | |
14010 | + * Returns: | |
14011 | + * None | |
14012 | + * Locking: | |
14013 | + * None. | |
14014 | + * Remarks: | |
14015 | + * Can change pc. | |
14016 | + */ | |
14017 | + | |
14018 | +void | |
14019 | +kdba_check_pc(kdb_machreg_t *pc) | |
14020 | +{ | |
14021 | + /* No action */ | |
14022 | +} | |
14023 | + | |
14024 | +/* | |
14025 | + * kdba_id_printinsn | |
14026 | + * | |
14027 | + * Format and print a single instruction at 'pc'. Return the | |
14028 | + * length of the instruction. | |
14029 | + * | |
14030 | + * Parameters: | |
14031 | + * pc Program Counter Value. | |
14032 | + * dip Disassemble_info structure pointer | |
14033 | + * Returns: | |
14034 | + * Length of instruction, -1 for error. | |
14035 | + * Locking: | |
14036 | + * None. | |
14037 | + * Remarks: | |
14038 | + * Depends on 'IDMODE' environment variable. | |
14039 | + */ | |
14040 | + | |
14041 | +int | |
14042 | +kdba_id_printinsn(kdb_machreg_t pc, disassemble_info *dip) | |
14043 | +{ | |
14044 | + kdba_printaddress(pc, dip, 1); | |
14045 | + return print_insn_i386_att(pc, dip); | |
14046 | +} | |
14047 | + | |
14048 | +/* | |
14049 | + * kdba_id_init | |
14050 | + * | |
14051 | + * Initialize the architecture dependent elements of | |
14052 | + * the disassembly information structure | |
14053 | + * for the GNU disassembler. | |
14054 | + * | |
14055 | + * Parameters: | |
14056 | + * None. | |
14057 | + * Outputs: | |
14058 | + * None. | |
14059 | + * Returns: | |
14060 | + * None. | |
14061 | + * Locking: | |
14062 | + * None. | |
14063 | + * Remarks: | |
14064 | + */ | |
14065 | + | |
14066 | +void | |
14067 | +kdba_id_init(disassemble_info *dip) | |
14068 | +{ | |
14069 | + dip->read_memory_func = kdba_dis_getmem; | |
14070 | + dip->print_address_func = kdba_dis_printaddr; | |
14071 | + dip->symbol_at_address_func = kdba_dis_getsym; | |
14072 | + | |
14073 | + dip->flavour = bfd_target_elf_flavour; | |
14074 | + dip->arch = bfd_arch_i386; | |
14075 | +#ifdef CONFIG_X86_64 | |
14076 | + dip->mach = bfd_mach_x86_64; | |
14077 | +#endif | |
14078 | +#ifdef CONFIG_X86_32 | |
14079 | + dip->mach = bfd_mach_i386_i386; | |
14080 | +#endif | |
14081 | + dip->endian = BFD_ENDIAN_LITTLE; | |
14082 | + | |
14083 | + dip->display_endian = BFD_ENDIAN_LITTLE; | |
14084 | +} | |
14085 | --- /dev/null | |
14086 | +++ b/arch/x86/kdb/kdba_io.c | |
14087 | @@ -0,0 +1,609 @@ | |
14088 | +/* | |
14089 | + * Kernel Debugger Architecture Dependent Console I/O handler | |
14090 | + * | |
14091 | + * This file is subject to the terms and conditions of the GNU General Public | |
14092 | + * License. See the file "COPYING" in the main directory of this archive | |
14093 | + * for more details. | |
14094 | + * | |
14095 | + * Copyright (c) 1999-2006 Silicon Graphics, Inc. All Rights Reserved. | |
14096 | + */ | |
14097 | + | |
14098 | +#include <linux/sched.h> | |
14099 | +#include <linux/kernel.h> | |
14100 | +#include <asm/io.h> | |
14101 | +#include <linux/delay.h> | |
14102 | +#include <linux/console.h> | |
14103 | +#include <linux/ctype.h> | |
14104 | +#include <linux/keyboard.h> | |
14105 | +#include <linux/serial.h> | |
14106 | +#include <linux/serial_reg.h> | |
14107 | + | |
14108 | +#include <linux/kdb.h> | |
14109 | +#include <linux/kdbprivate.h> | |
14110 | +#include <pc_keyb.h> | |
14111 | + | |
14112 | +#ifdef CONFIG_VT_CONSOLE | |
14113 | +#define KDB_BLINK_LED 1 | |
14114 | +#else | |
14115 | +#undef KDB_BLINK_LED | |
14116 | +#endif | |
14117 | + | |
14118 | +#ifdef CONFIG_KDB_USB | |
14119 | + | |
14120 | +/* support up to 8 USB keyboards (probably excessive, but...) */ | |
14121 | +#define KDB_USB_NUM_KEYBOARDS 8 | |
14122 | +struct kdb_usb_kbd_info kdb_usb_kbds[KDB_USB_NUM_KEYBOARDS]; | |
14123 | + | |
14124 | +extern int kdb_no_usb; | |
14125 | + | |
14126 | +static unsigned char kdb_usb_keycode[256] = { | |
14127 | + 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, | |
14128 | + 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, | |
14129 | + 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, | |
14130 | + 27, 43, 84, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64, | |
14131 | + 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106, | |
14132 | + 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71, | |
14133 | + 72, 73, 82, 83, 86,127,116,117, 85, 89, 90, 91, 92, 93, 94, 95, | |
14134 | + 120,121,122,123,134,138,130,132,128,129,131,137,133,135,136,113, | |
14135 | + 115,114, 0, 0, 0,124, 0,181,182,183,184,185,186,187,188,189, | |
14136 | + 190,191,192,193,194,195,196,197,198, 0, 0, 0, 0, 0, 0, 0, | |
14137 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
14138 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
14139 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
14140 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
14141 | + 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113, | |
14142 | + 150,158,159,128,136,177,178,176,142,152,173,140 | |
14143 | +}; | |
14144 | + | |
14145 | +/* | |
14146 | + * kdb_usb_keyboard_attach() | |
14147 | + * Attach a USB keyboard to kdb. | |
14148 | + */ | |
14149 | +int | |
14150 | +kdb_usb_keyboard_attach(struct urb *urb, unsigned char *buffer, void *poll_func) | |
14151 | +{ | |
14152 | + int i; | |
14153 | + int rc = -1; | |
14154 | + | |
14155 | + if (kdb_no_usb) | |
14156 | + return 0; | |
14157 | + | |
14158 | + /* | |
14159 | + * Search through the array of KDB USB keyboards (kdb_usb_kbds) | |
14160 | + * looking for a free index. If found, assign the keyboard to | |
14161 | + * the array index. | |
14162 | + */ | |
14163 | + | |
14164 | + for (i = 0; i < KDB_USB_NUM_KEYBOARDS; i++) { | |
14165 | + if (kdb_usb_kbds[i].urb) /* index is already assigned */ | |
14166 | + continue; | |
14167 | + | |
14168 | + /* found a free array index */ | |
14169 | + kdb_usb_kbds[i].urb = urb; | |
14170 | + kdb_usb_kbds[i].buffer = buffer; | |
14171 | + kdb_usb_kbds[i].poll_func = poll_func; | |
14172 | + | |
14173 | + rc = 0; /* success */ | |
14174 | + | |
14175 | + break; | |
14176 | + } | |
14177 | + | |
14178 | + return rc; | |
14179 | +} | |
14180 | +EXPORT_SYMBOL_GPL (kdb_usb_keyboard_attach); | |
14181 | + | |
14182 | +/* | |
14183 | + * kdb_usb_keyboard_detach() | |
14184 | + * Detach a USB keyboard from kdb. | |
14185 | + */ | |
14186 | +int | |
14187 | +kdb_usb_keyboard_detach(struct urb *urb) | |
14188 | +{ | |
14189 | + int i; | |
14190 | + int rc = -1; | |
14191 | + | |
14192 | + if (kdb_no_usb) | |
14193 | + return 0; | |
14194 | + | |
14195 | + /* | |
14196 | + * Search through the array of KDB USB keyboards (kdb_usb_kbds) | |
14197 | + * looking for the index with the matching URB. If found, | |
14198 | + * clear the array index. | |
14199 | + */ | |
14200 | + | |
14201 | + for (i = 0; i < KDB_USB_NUM_KEYBOARDS; i++) { | |
14202 | + if (kdb_usb_kbds[i].urb != urb) | |
14203 | + continue; | |
14204 | + | |
14205 | + /* found it, clear the index */ | |
14206 | + kdb_usb_kbds[i].urb = NULL; | |
14207 | + kdb_usb_kbds[i].buffer = NULL; | |
14208 | + kdb_usb_kbds[i].poll_func = NULL; | |
14209 | + kdb_usb_kbds[i].caps_lock = 0; | |
14210 | + | |
14211 | + rc = 0; /* success */ | |
14212 | + | |
14213 | + break; | |
14214 | + } | |
14215 | + | |
14216 | + return rc; | |
14217 | +} | |
14218 | +EXPORT_SYMBOL_GPL (kdb_usb_keyboard_detach); | |
14219 | + | |
14220 | +/* | |
14221 | + * get_usb_char | |
14222 | + * This function drives the USB attached keyboards. | |
14223 | + * Fetch the USB scancode and decode it. | |
14224 | + */ | |
14225 | +static int | |
14226 | +get_usb_char(void) | |
14227 | +{ | |
14228 | + int i; | |
14229 | + int ret; | |
14230 | + unsigned char keycode, spec; | |
14231 | + extern u_short plain_map[], shift_map[], ctrl_map[]; | |
14232 | + | |
14233 | + if (kdb_no_usb) | |
14234 | + return -1; | |
14235 | + | |
14236 | + /* | |
14237 | + * Loop through all the USB keyboard(s) and return | |
14238 | + * the first character obtained from them. | |
14239 | + */ | |
14240 | + | |
14241 | + for (i = 0; i < KDB_USB_NUM_KEYBOARDS; i++) { | |
14242 | + /* skip uninitialized keyboard array entries */ | |
14243 | + if (!kdb_usb_kbds[i].urb || !kdb_usb_kbds[i].buffer || | |
14244 | + !kdb_usb_kbds[i].poll_func) | |
14245 | + continue; | |
14246 | + | |
14247 | + /* Transfer char */ | |
14248 | + ret = (*kdb_usb_kbds[i].poll_func)(kdb_usb_kbds[i].urb); | |
14249 | + if (ret == -EBUSY && kdb_usb_kbds[i].poll_ret != -EBUSY) | |
14250 | + kdb_printf("NOTICE: USB HD driver BUSY. " | |
14251 | + "USB keyboard has been disabled.\n"); | |
14252 | + | |
14253 | + kdb_usb_kbds[i].poll_ret = ret; | |
14254 | + | |
14255 | + if (ret < 0) /* error or no characters, try the next kbd */ | |
14256 | + continue; | |
14257 | + | |
14258 | + spec = kdb_usb_kbds[i].buffer[0]; | |
14259 | + keycode = kdb_usb_kbds[i].buffer[2]; | |
14260 | + kdb_usb_kbds[i].buffer[0] = (char)0; | |
14261 | + kdb_usb_kbds[i].buffer[2] = (char)0; | |
14262 | + | |
14263 | + if(kdb_usb_kbds[i].buffer[3]) { | |
14264 | + kdb_usb_kbds[i].buffer[3] = (char)0; | |
14265 | + continue; | |
14266 | + } | |
14267 | + | |
14268 | + /* A normal key is pressed, decode it */ | |
14269 | + if(keycode) | |
14270 | + keycode = kdb_usb_keycode[keycode]; | |
14271 | + | |
14272 | + /* 2 Keys pressed at one time ? */ | |
14273 | + if (spec && keycode) { | |
14274 | + switch(spec) | |
14275 | + { | |
14276 | + case 0x2: | |
14277 | + case 0x20: /* Shift */ | |
14278 | + return shift_map[keycode]; | |
14279 | + case 0x1: | |
14280 | + case 0x10: /* Ctrl */ | |
14281 | + return ctrl_map[keycode]; | |
14282 | + case 0x4: | |
14283 | + case 0x40: /* Alt */ | |
14284 | + break; | |
14285 | + } | |
14286 | + } else if (keycode) { /* If only one key pressed */ | |
14287 | + switch(keycode) | |
14288 | + { | |
14289 | + case 0x1C: /* Enter */ | |
14290 | + return 13; | |
14291 | + | |
14292 | + case 0x3A: /* Capslock */ | |
14293 | + kdb_usb_kbds[i].caps_lock = !(kdb_usb_kbds[i].caps_lock); | |
14294 | + break; | |
14295 | + case 0x0E: /* Backspace */ | |
14296 | + return 8; | |
14297 | + case 0x0F: /* TAB */ | |
14298 | + return 9; | |
14299 | + case 0x77: /* Pause */ | |
14300 | + break ; | |
14301 | + default: | |
14302 | + if(!kdb_usb_kbds[i].caps_lock) { | |
14303 | + return plain_map[keycode]; | |
14304 | + } | |
14305 | + else { | |
14306 | + return shift_map[keycode]; | |
14307 | + } | |
14308 | + } | |
14309 | + } | |
14310 | + } | |
14311 | + | |
14312 | + /* no chars were returned from any of the USB keyboards */ | |
14313 | + | |
14314 | + return -1; | |
14315 | +} | |
14316 | +#endif /* CONFIG_KDB_USB */ | |
14317 | + | |
14318 | +/* | |
14319 | + * This module contains code to read characters from the keyboard or a serial | |
14320 | + * port. | |
14321 | + * | |
14322 | + * It is used by the kernel debugger, and is polled, not interrupt driven. | |
14323 | + * | |
14324 | + */ | |
14325 | + | |
14326 | +#ifdef KDB_BLINK_LED | |
14327 | +/* | |
14328 | + * send: Send a byte to the keyboard controller. Used primarily to | |
14329 | + * alter LED settings. | |
14330 | + */ | |
14331 | + | |
14332 | +static void | |
14333 | +kdb_kbdsend(unsigned char byte) | |
14334 | +{ | |
14335 | + int timeout; | |
14336 | + for (timeout = 200 * 1000; timeout && (inb(KBD_STATUS_REG) & KBD_STAT_IBF); timeout--); | |
14337 | + outb(byte, KBD_DATA_REG); | |
14338 | + udelay(40); | |
14339 | + for (timeout = 200 * 1000; timeout && (~inb(KBD_STATUS_REG) & KBD_STAT_OBF); timeout--); | |
14340 | + inb(KBD_DATA_REG); | |
14341 | + udelay(40); | |
14342 | +} | |
14343 | + | |
14344 | +static void | |
14345 | +kdb_toggleled(int led) | |
14346 | +{ | |
14347 | + static int leds; | |
14348 | + | |
14349 | + leds ^= led; | |
14350 | + | |
14351 | + kdb_kbdsend(KBD_CMD_SET_LEDS); | |
14352 | + kdb_kbdsend((unsigned char)leds); | |
14353 | +} | |
14354 | +#endif /* KDB_BLINK_LED */ | |
14355 | + | |
14356 | +#if defined(CONFIG_SERIAL_8250_CONSOLE) || defined(CONFIG_SERIAL_CORE_CONSOLE) | |
14357 | +#define CONFIG_SERIAL_CONSOLE | |
14358 | +#endif | |
14359 | + | |
14360 | +#if defined(CONFIG_SERIAL_CONSOLE) | |
14361 | + | |
14362 | +struct kdb_serial kdb_serial; | |
14363 | + | |
14364 | +static unsigned int | |
14365 | +serial_inp(struct kdb_serial *kdb_serial, unsigned long offset) | |
14366 | +{ | |
14367 | + offset <<= kdb_serial->ioreg_shift; | |
14368 | + | |
14369 | + switch (kdb_serial->io_type) { | |
14370 | + case SERIAL_IO_MEM: | |
14371 | + return readb((void __iomem *)(kdb_serial->iobase + offset)); | |
14372 | + break; | |
14373 | + default: | |
14374 | + return inb(kdb_serial->iobase + offset); | |
14375 | + break; | |
14376 | + } | |
14377 | +} | |
14378 | + | |
14379 | +/* Check if there is a byte ready at the serial port */ | |
14380 | +static int get_serial_char(void) | |
14381 | +{ | |
14382 | + unsigned char ch; | |
14383 | + | |
14384 | + if (kdb_serial.iobase == 0) | |
14385 | + return -1; | |
14386 | + | |
14387 | + if (serial_inp(&kdb_serial, UART_LSR) & UART_LSR_DR) { | |
14388 | + ch = serial_inp(&kdb_serial, UART_RX); | |
14389 | + if (ch == 0x7f) | |
14390 | + ch = 8; | |
14391 | + return ch; | |
14392 | + } | |
14393 | + return -1; | |
14394 | +} | |
14395 | +#endif /* CONFIG_SERIAL_CONSOLE */ | |
14396 | + | |
14397 | +#ifdef CONFIG_VT_CONSOLE | |
14398 | + | |
14399 | +static int kbd_exists; | |
14400 | + | |
14401 | +/* | |
14402 | + * Check if the keyboard controller has a keypress for us. | |
14403 | + * Some parts (Enter Release, LED change) are still blocking polled here, | |
14404 | + * but hopefully they are all short. | |
14405 | + */ | |
14406 | +static int get_kbd_char(void) | |
14407 | +{ | |
14408 | + int scancode, scanstatus; | |
14409 | + static int shift_lock; /* CAPS LOCK state (0-off, 1-on) */ | |
14410 | + static int shift_key; /* Shift next keypress */ | |
14411 | + static int ctrl_key; | |
14412 | + u_short keychar; | |
14413 | + extern u_short plain_map[], shift_map[], ctrl_map[]; | |
14414 | + | |
14415 | + if (KDB_FLAG(NO_I8042) || KDB_FLAG(NO_VT_CONSOLE) || | |
14416 | + (inb(KBD_STATUS_REG) == 0xff && inb(KBD_DATA_REG) == 0xff)) { | |
14417 | + kbd_exists = 0; | |
14418 | + return -1; | |
14419 | + } | |
14420 | + kbd_exists = 1; | |
14421 | + | |
14422 | + if ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) | |
14423 | + return -1; | |
14424 | + | |
14425 | + /* | |
14426 | + * Fetch the scancode | |
14427 | + */ | |
14428 | + scancode = inb(KBD_DATA_REG); | |
14429 | + scanstatus = inb(KBD_STATUS_REG); | |
14430 | + | |
14431 | + /* | |
14432 | + * Ignore mouse events. | |
14433 | + */ | |
14434 | + if (scanstatus & KBD_STAT_MOUSE_OBF) | |
14435 | + return -1; | |
14436 | + | |
14437 | + /* | |
14438 | + * Ignore release, trigger on make | |
14439 | + * (except for shift keys, where we want to | |
14440 | + * keep the shift state so long as the key is | |
14441 | + * held down). | |
14442 | + */ | |
14443 | + | |
14444 | + if (((scancode&0x7f) == 0x2a) || ((scancode&0x7f) == 0x36)) { | |
14445 | + /* | |
14446 | + * Next key may use shift table | |
14447 | + */ | |
14448 | + if ((scancode & 0x80) == 0) { | |
14449 | + shift_key=1; | |
14450 | + } else { | |
14451 | + shift_key=0; | |
14452 | + } | |
14453 | + return -1; | |
14454 | + } | |
14455 | + | |
14456 | + if ((scancode&0x7f) == 0x1d) { | |
14457 | + /* | |
14458 | + * Left ctrl key | |
14459 | + */ | |
14460 | + if ((scancode & 0x80) == 0) { | |
14461 | + ctrl_key = 1; | |
14462 | + } else { | |
14463 | + ctrl_key = 0; | |
14464 | + } | |
14465 | + return -1; | |
14466 | + } | |
14467 | + | |
14468 | + if ((scancode & 0x80) != 0) | |
14469 | + return -1; | |
14470 | + | |
14471 | + scancode &= 0x7f; | |
14472 | + | |
14473 | + /* | |
14474 | + * Translate scancode | |
14475 | + */ | |
14476 | + | |
14477 | + if (scancode == 0x3a) { | |
14478 | + /* | |
14479 | + * Toggle caps lock | |
14480 | + */ | |
14481 | + shift_lock ^= 1; | |
14482 | + | |
14483 | +#ifdef KDB_BLINK_LED | |
14484 | + kdb_toggleled(0x4); | |
14485 | +#endif | |
14486 | + return -1; | |
14487 | + } | |
14488 | + | |
14489 | + if (scancode == 0x0e) { | |
14490 | + /* | |
14491 | + * Backspace | |
14492 | + */ | |
14493 | + return 8; | |
14494 | + } | |
14495 | + | |
14496 | + /* Special Key */ | |
14497 | + switch (scancode) { | |
14498 | + case 0xF: /* Tab */ | |
14499 | + return 9; | |
14500 | + case 0x53: /* Del */ | |
14501 | + return 4; | |
14502 | + case 0x47: /* Home */ | |
14503 | + return 1; | |
14504 | + case 0x4F: /* End */ | |
14505 | + return 5; | |
14506 | + case 0x4B: /* Left */ | |
14507 | + return 2; | |
14508 | + case 0x48: /* Up */ | |
14509 | + return 16; | |
14510 | + case 0x50: /* Down */ | |
14511 | + return 14; | |
14512 | + case 0x4D: /* Right */ | |
14513 | + return 6; | |
14514 | + } | |
14515 | + | |
14516 | + if (scancode == 0xe0) { | |
14517 | + return -1; | |
14518 | + } | |
14519 | + | |
14520 | + /* | |
14521 | + * For Japanese 86/106 keyboards | |
14522 | + * See comment in drivers/char/pc_keyb.c. | |
14523 | + * - Masahiro Adegawa | |
14524 | + */ | |
14525 | + if (scancode == 0x73) { | |
14526 | + scancode = 0x59; | |
14527 | + } else if (scancode == 0x7d) { | |
14528 | + scancode = 0x7c; | |
14529 | + } | |
14530 | + | |
14531 | + if (!shift_lock && !shift_key && !ctrl_key) { | |
14532 | + keychar = plain_map[scancode]; | |
14533 | + } else if (shift_lock || shift_key) { | |
14534 | + keychar = shift_map[scancode]; | |
14535 | + } else if (ctrl_key) { | |
14536 | + keychar = ctrl_map[scancode]; | |
14537 | + } else { | |
14538 | + keychar = 0x0020; | |
14539 | + kdb_printf("Unknown state/scancode (%d)\n", scancode); | |
14540 | + } | |
14541 | + keychar &= 0x0fff; | |
14542 | + if (keychar == '\t') | |
14543 | + keychar = ' '; | |
14544 | + switch (KTYP(keychar)) { | |
14545 | + case KT_LETTER: | |
14546 | + case KT_LATIN: | |
14547 | + if (isprint(keychar)) | |
14548 | + break; /* printable characters */ | |
14549 | + /* drop through */ | |
14550 | + case KT_SPEC: | |
14551 | + if (keychar == K_ENTER) | |
14552 | + break; | |
14553 | + /* drop through */ | |
14554 | + default: | |
14555 | + return(-1); /* ignore unprintables */ | |
14556 | + } | |
14557 | + | |
14558 | + if ((scancode & 0x7f) == 0x1c) { | |
14559 | + /* | |
14560 | + * enter key. All done. Absorb the release scancode. | |
14561 | + */ | |
14562 | + while ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) | |
14563 | + ; | |
14564 | + | |
14565 | + /* | |
14566 | + * Fetch the scancode | |
14567 | + */ | |
14568 | + scancode = inb(KBD_DATA_REG); | |
14569 | + scanstatus = inb(KBD_STATUS_REG); | |
14570 | + | |
14571 | + while (scanstatus & KBD_STAT_MOUSE_OBF) { | |
14572 | + scancode = inb(KBD_DATA_REG); | |
14573 | + scanstatus = inb(KBD_STATUS_REG); | |
14574 | + } | |
14575 | + | |
14576 | + if (scancode != 0x9c) { | |
14577 | + /* | |
14578 | + * Wasn't an enter-release, why not? | |
14579 | + */ | |
14580 | + kdb_printf("kdb: expected enter got 0x%x status 0x%x\n", | |
14581 | + scancode, scanstatus); | |
14582 | + } | |
14583 | + | |
14584 | + kdb_printf("\n"); | |
14585 | + return 13; | |
14586 | + } | |
14587 | + | |
14588 | + return keychar & 0xff; | |
14589 | +} | |
14590 | +#endif /* CONFIG_VT_CONSOLE */ | |
14591 | + | |
14592 | +#ifdef KDB_BLINK_LED | |
14593 | + | |
14594 | +/* Leave numlock alone, setting it messes up laptop keyboards with the keypad | |
14595 | + * mapped over normal keys. | |
14596 | + */ | |
14597 | +static int kdba_blink_mask = 0x1 | 0x4; | |
14598 | + | |
14599 | +#define BOGOMIPS (boot_cpu_data.loops_per_jiffy/(500000/HZ)) | |
14600 | +static int blink_led(void) | |
14601 | +{ | |
14602 | + static long delay; | |
14603 | + | |
14604 | + if (kbd_exists == 0) | |
14605 | + return -1; | |
14606 | + | |
14607 | + if (--delay < 0) { | |
14608 | + if (BOGOMIPS == 0) /* early kdb */ | |
14609 | + delay = 150000000/1000; /* arbitrary bogomips */ | |
14610 | + else | |
14611 | + delay = 150000000/BOGOMIPS; /* Roughly 1 second when polling */ | |
14612 | + kdb_toggleled(kdba_blink_mask); | |
14613 | + } | |
14614 | + return -1; | |
14615 | +} | |
14616 | +#endif | |
14617 | + | |
14618 | +get_char_func poll_funcs[] = { | |
14619 | +#if defined(CONFIG_VT_CONSOLE) | |
14620 | + get_kbd_char, | |
14621 | +#endif | |
14622 | +#if defined(CONFIG_SERIAL_CONSOLE) | |
14623 | + get_serial_char, | |
14624 | +#endif | |
14625 | +#ifdef KDB_BLINK_LED | |
14626 | + blink_led, | |
14627 | +#endif | |
14628 | +#ifdef CONFIG_KDB_USB | |
14629 | + get_usb_char, | |
14630 | +#endif | |
14631 | + NULL | |
14632 | +}; | |
14633 | + | |
14634 | +/* | |
14635 | + * On some Compaq Deskpro's, there is a keyboard freeze many times after | |
14636 | + * exiting from the kdb. As kdb's keyboard handler is not interrupt-driven and | |
14637 | + * uses a polled interface, it makes more sense to disable motherboard keyboard | |
14638 | + * controller's OBF interrupts during kdb's polling.In case, of interrupts | |
14639 | + * remaining enabled during kdb's polling, it may cause un-necessary | |
14640 | + * interrupts being signalled during keypresses, which are also sometimes seen | |
14641 | + * as spurious interrupts after exiting from kdb. This hack to disable OBF | |
14642 | + * interrupts before entry to kdb and re-enabling them at kdb exit point also | |
14643 | + * solves the keyboard freeze issue. These functions are called from | |
14644 | + * kdb_local(), hence these are arch. specific setup and cleanup functions | |
14645 | + * executing only on the local processor - ashishk@sco.com | |
14646 | + */ | |
14647 | + | |
14648 | +void kdba_local_arch_setup(void) | |
14649 | +{ | |
14650 | +#ifdef CONFIG_VT_CONSOLE | |
14651 | + int timeout; | |
14652 | + unsigned char c; | |
14653 | + | |
14654 | + while (kbd_read_status() & KBD_STAT_IBF); | |
14655 | + kbd_write_command(KBD_CCMD_READ_MODE); | |
14656 | + mdelay(1); | |
14657 | + while (kbd_read_status() & KBD_STAT_IBF); | |
14658 | + for (timeout = 200 * 1000; timeout && | |
14659 | + (!(kbd_read_status() & KBD_STAT_OBF)); timeout--); | |
14660 | + c = kbd_read_input(); | |
14661 | + c &= ~KBD_MODE_KBD_INT; | |
14662 | + while (kbd_read_status() & KBD_STAT_IBF); | |
14663 | + kbd_write_command(KBD_CCMD_WRITE_MODE); | |
14664 | + mdelay(1); | |
14665 | + while (kbd_read_status() & KBD_STAT_IBF); | |
14666 | + kbd_write_output(c); | |
14667 | + mdelay(1); | |
14668 | + while (kbd_read_status() & KBD_STAT_IBF); | |
14669 | + mdelay(1); | |
14670 | +#endif /* CONFIG_VT_CONSOLE */ | |
14671 | +} | |
14672 | + | |
14673 | +void kdba_local_arch_cleanup(void) | |
14674 | +{ | |
14675 | +#ifdef CONFIG_VT_CONSOLE | |
14676 | + int timeout; | |
14677 | + unsigned char c; | |
14678 | + | |
14679 | + while (kbd_read_status() & KBD_STAT_IBF); | |
14680 | + kbd_write_command(KBD_CCMD_READ_MODE); | |
14681 | + mdelay(1); | |
14682 | + while (kbd_read_status() & KBD_STAT_IBF); | |
14683 | + for (timeout = 200 * 1000; timeout && | |
14684 | + (!(kbd_read_status() & KBD_STAT_OBF)); timeout--); | |
14685 | + c = kbd_read_input(); | |
14686 | + c |= KBD_MODE_KBD_INT; | |
14687 | + while (kbd_read_status() & KBD_STAT_IBF); | |
14688 | + kbd_write_command(KBD_CCMD_WRITE_MODE); | |
14689 | + mdelay(1); | |
14690 | + while (kbd_read_status() & KBD_STAT_IBF); | |
14691 | + kbd_write_output(c); | |
14692 | + mdelay(1); | |
14693 | + while (kbd_read_status() & KBD_STAT_IBF); | |
14694 | + mdelay(1); | |
14695 | +#endif /* CONFIG_VT_CONSOLE */ | |
14696 | +} | |
14697 | --- /dev/null | |
14698 | +++ b/arch/x86/kdb/kdbasupport_32.c | |
14699 | @@ -0,0 +1,1072 @@ | |
14700 | +/* | |
14701 | + * Kernel Debugger Architecture Independent Support Functions | |
14702 | + * | |
14703 | + * This file is subject to the terms and conditions of the GNU General Public | |
14704 | + * License. See the file "COPYING" in the main directory of this archive | |
14705 | + * for more details. | |
14706 | + * | |
14707 | + * Copyright (c) 1999-2006 Silicon Graphics, Inc. All Rights Reserved. | |
14708 | + */ | |
14709 | + | |
14710 | +#include <linux/string.h> | |
14711 | +#include <linux/stddef.h> | |
14712 | +#include <linux/kernel.h> | |
14713 | +#include <linux/module.h> | |
14714 | +#include <linux/init.h> | |
14715 | +#include <linux/irq.h> | |
14716 | +#include <linux/ptrace.h> | |
14717 | +#include <linux/mm.h> | |
14718 | +#include <linux/sched.h> | |
14719 | +#include <linux/hardirq.h> | |
14720 | +#include <linux/kdb.h> | |
14721 | +#include <linux/kdbprivate.h> | |
14722 | + | |
14723 | +#include <asm/processor.h> | |
14724 | +#include <asm/msr.h> | |
14725 | +#include <asm/uaccess.h> | |
14726 | +#include <asm/desc.h> | |
14727 | + | |
14728 | +static kdb_machreg_t | |
14729 | +kdba_getcr(int regnum) | |
14730 | +{ | |
14731 | + kdb_machreg_t contents = 0; | |
14732 | + switch(regnum) { | |
14733 | + case 0: | |
14734 | + __asm__ ("movl %%cr0,%0\n\t":"=r"(contents)); | |
14735 | + break; | |
14736 | + case 1: | |
14737 | + break; | |
14738 | + case 2: | |
14739 | + __asm__ ("movl %%cr2,%0\n\t":"=r"(contents)); | |
14740 | + break; | |
14741 | + case 3: | |
14742 | + __asm__ ("movl %%cr3,%0\n\t":"=r"(contents)); | |
14743 | + break; | |
14744 | + case 4: | |
14745 | + __asm__ ("movl %%cr4,%0\n\t":"=r"(contents)); | |
14746 | + break; | |
14747 | + default: | |
14748 | + break; | |
14749 | + } | |
14750 | + | |
14751 | + return contents; | |
14752 | +} | |
14753 | + | |
14754 | +static void | |
14755 | +kdba_putdr(int regnum, kdb_machreg_t contents) | |
14756 | +{ | |
14757 | + switch(regnum) { | |
14758 | + case 0: | |
14759 | + __asm__ ("movl %0,%%db0\n\t"::"r"(contents)); | |
14760 | + break; | |
14761 | + case 1: | |
14762 | + __asm__ ("movl %0,%%db1\n\t"::"r"(contents)); | |
14763 | + break; | |
14764 | + case 2: | |
14765 | + __asm__ ("movl %0,%%db2\n\t"::"r"(contents)); | |
14766 | + break; | |
14767 | + case 3: | |
14768 | + __asm__ ("movl %0,%%db3\n\t"::"r"(contents)); | |
14769 | + break; | |
14770 | + case 4: | |
14771 | + case 5: | |
14772 | + break; | |
14773 | + case 6: | |
14774 | + __asm__ ("movl %0,%%db6\n\t"::"r"(contents)); | |
14775 | + break; | |
14776 | + case 7: | |
14777 | + __asm__ ("movl %0,%%db7\n\t"::"r"(contents)); | |
14778 | + break; | |
14779 | + default: | |
14780 | + break; | |
14781 | + } | |
14782 | +} | |
14783 | + | |
14784 | +kdb_machreg_t | |
14785 | +kdba_getdr(int regnum) | |
14786 | +{ | |
14787 | + kdb_machreg_t contents = 0; | |
14788 | + switch(regnum) { | |
14789 | + case 0: | |
14790 | + __asm__ ("movl %%db0,%0\n\t":"=r"(contents)); | |
14791 | + break; | |
14792 | + case 1: | |
14793 | + __asm__ ("movl %%db1,%0\n\t":"=r"(contents)); | |
14794 | + break; | |
14795 | + case 2: | |
14796 | + __asm__ ("movl %%db2,%0\n\t":"=r"(contents)); | |
14797 | + break; | |
14798 | + case 3: | |
14799 | + __asm__ ("movl %%db3,%0\n\t":"=r"(contents)); | |
14800 | + break; | |
14801 | + case 4: | |
14802 | + case 5: | |
14803 | + break; | |
14804 | + case 6: | |
14805 | + __asm__ ("movl %%db6,%0\n\t":"=r"(contents)); | |
14806 | + break; | |
14807 | + case 7: | |
14808 | + __asm__ ("movl %%db7,%0\n\t":"=r"(contents)); | |
14809 | + break; | |
14810 | + default: | |
14811 | + break; | |
14812 | + } | |
14813 | + | |
14814 | + return contents; | |
14815 | +} | |
14816 | + | |
14817 | +kdb_machreg_t | |
14818 | +kdba_getdr6(void) | |
14819 | +{ | |
14820 | + return kdba_getdr(6); | |
14821 | +} | |
14822 | + | |
14823 | +kdb_machreg_t | |
14824 | +kdba_getdr7(void) | |
14825 | +{ | |
14826 | + return kdba_getdr(7); | |
14827 | +} | |
14828 | + | |
14829 | +void | |
14830 | +kdba_putdr6(kdb_machreg_t contents) | |
14831 | +{ | |
14832 | + kdba_putdr(6, contents); | |
14833 | +} | |
14834 | + | |
14835 | +static void | |
14836 | +kdba_putdr7(kdb_machreg_t contents) | |
14837 | +{ | |
14838 | + kdba_putdr(7, contents); | |
14839 | +} | |
14840 | + | |
14841 | +void | |
14842 | +kdba_installdbreg(kdb_bp_t *bp) | |
14843 | +{ | |
14844 | + int cpu = smp_processor_id(); | |
14845 | + | |
14846 | + kdb_machreg_t dr7; | |
14847 | + | |
14848 | + dr7 = kdba_getdr7(); | |
14849 | + | |
14850 | + kdba_putdr(bp->bp_hard[cpu]->bph_reg, bp->bp_addr); | |
14851 | + | |
14852 | + dr7 |= DR7_GE; | |
14853 | + if (cpu_has_de) | |
14854 | + set_in_cr4(X86_CR4_DE); | |
14855 | + | |
14856 | + switch (bp->bp_hard[cpu]->bph_reg){ | |
14857 | + case 0: | |
14858 | + DR7_RW0SET(dr7,bp->bp_hard[cpu]->bph_mode); | |
14859 | + DR7_LEN0SET(dr7,bp->bp_hard[cpu]->bph_length); | |
14860 | + DR7_G0SET(dr7); | |
14861 | + break; | |
14862 | + case 1: | |
14863 | + DR7_RW1SET(dr7,bp->bp_hard[cpu]->bph_mode); | |
14864 | + DR7_LEN1SET(dr7,bp->bp_hard[cpu]->bph_length); | |
14865 | + DR7_G1SET(dr7); | |
14866 | + break; | |
14867 | + case 2: | |
14868 | + DR7_RW2SET(dr7,bp->bp_hard[cpu]->bph_mode); | |
14869 | + DR7_LEN2SET(dr7,bp->bp_hard[cpu]->bph_length); | |
14870 | + DR7_G2SET(dr7); | |
14871 | + break; | |
14872 | + case 3: | |
14873 | + DR7_RW3SET(dr7,bp->bp_hard[cpu]->bph_mode); | |
14874 | + DR7_LEN3SET(dr7,bp->bp_hard[cpu]->bph_length); | |
14875 | + DR7_G3SET(dr7); | |
14876 | + break; | |
14877 | + default: | |
14878 | + kdb_printf("kdb: Bad debug register!! %ld\n", | |
14879 | + bp->bp_hard[cpu]->bph_reg); | |
14880 | + break; | |
14881 | + } | |
14882 | + | |
14883 | + kdba_putdr7(dr7); | |
14884 | + return; | |
14885 | +} | |
14886 | + | |
14887 | +void | |
14888 | +kdba_removedbreg(kdb_bp_t *bp) | |
14889 | +{ | |
14890 | + int regnum; | |
14891 | + kdb_machreg_t dr7; | |
14892 | + int cpu = smp_processor_id(); | |
14893 | + | |
14894 | + if (!bp->bp_hard[cpu]) | |
14895 | + return; | |
14896 | + | |
14897 | + regnum = bp->bp_hard[cpu]->bph_reg; | |
14898 | + | |
14899 | + dr7 = kdba_getdr7(); | |
14900 | + | |
14901 | + kdba_putdr(regnum, 0); | |
14902 | + | |
14903 | + switch (regnum) { | |
14904 | + case 0: | |
14905 | + DR7_G0CLR(dr7); | |
14906 | + DR7_L0CLR(dr7); | |
14907 | + break; | |
14908 | + case 1: | |
14909 | + DR7_G1CLR(dr7); | |
14910 | + DR7_L1CLR(dr7); | |
14911 | + break; | |
14912 | + case 2: | |
14913 | + DR7_G2CLR(dr7); | |
14914 | + DR7_L2CLR(dr7); | |
14915 | + break; | |
14916 | + case 3: | |
14917 | + DR7_G3CLR(dr7); | |
14918 | + DR7_L3CLR(dr7); | |
14919 | + break; | |
14920 | + default: | |
14921 | + kdb_printf("kdb: Bad debug register!! %d\n", regnum); | |
14922 | + break; | |
14923 | + } | |
14924 | + | |
14925 | + kdba_putdr7(dr7); | |
14926 | +} | |
14927 | + | |
14928 | + | |
14929 | +/* | |
14930 | + * kdba_getregcontents | |
14931 | + * | |
14932 | + * Return the contents of the register specified by the | |
14933 | + * input string argument. Return an error if the string | |
14934 | + * does not match a machine register. | |
14935 | + * | |
14936 | + * The following pseudo register names are supported: | |
14937 | + * ®s - Prints address of exception frame | |
14938 | + * kesp - Prints kernel stack pointer at time of fault | |
14939 | + * cesp - Prints current kernel stack pointer, inside kdb | |
14940 | + * ceflags - Prints current flags, inside kdb | |
14941 | + * %<regname> - Uses the value of the registers at the | |
14942 | + * last time the user process entered kernel | |
14943 | + * mode, instead of the registers at the time | |
14944 | + * kdb was entered. | |
14945 | + * | |
14946 | + * Parameters: | |
14947 | + * regname Pointer to string naming register | |
14948 | + * regs Pointer to structure containing registers. | |
14949 | + * Outputs: | |
14950 | + * *contents Pointer to unsigned long to recieve register contents | |
14951 | + * Returns: | |
14952 | + * 0 Success | |
14953 | + * KDB_BADREG Invalid register name | |
14954 | + * Locking: | |
14955 | + * None. | |
14956 | + * Remarks: | |
14957 | + * If kdb was entered via an interrupt from the kernel itself then | |
14958 | + * ss and sp are *not* on the stack. | |
14959 | + */ | |
14960 | + | |
14961 | +static struct kdbregs { | |
14962 | + char *reg_name; | |
14963 | + size_t reg_offset; | |
14964 | +} kdbreglist[] = { | |
14965 | + { "ax", offsetof(struct pt_regs, ax) }, | |
14966 | + { "bx", offsetof(struct pt_regs, bx) }, | |
14967 | + { "cx", offsetof(struct pt_regs, cx) }, | |
14968 | + { "dx", offsetof(struct pt_regs, dx) }, | |
14969 | + | |
14970 | + { "si", offsetof(struct pt_regs, si) }, | |
14971 | + { "di", offsetof(struct pt_regs, di) }, | |
14972 | + { "sp", offsetof(struct pt_regs, sp) }, | |
14973 | + { "ip", offsetof(struct pt_regs, ip) }, | |
14974 | + | |
14975 | + { "bp", offsetof(struct pt_regs, bp) }, | |
14976 | + { "ss", offsetof(struct pt_regs, ss) }, | |
14977 | + { "cs", offsetof(struct pt_regs, cs) }, | |
14978 | + { "flags", offsetof(struct pt_regs, flags) }, | |
14979 | + | |
14980 | + { "ds", offsetof(struct pt_regs, ds) }, | |
14981 | + { "es", offsetof(struct pt_regs, es) }, | |
14982 | + { "origax", offsetof(struct pt_regs, orig_ax) }, | |
14983 | + | |
14984 | +}; | |
14985 | + | |
14986 | +static const int nkdbreglist = sizeof(kdbreglist) / sizeof(struct kdbregs); | |
14987 | + | |
14988 | +static struct kdbregs dbreglist[] = { | |
14989 | + { "dr0", 0 }, | |
14990 | + { "dr1", 1 }, | |
14991 | + { "dr2", 2 }, | |
14992 | + { "dr3", 3 }, | |
14993 | + { "dr6", 6 }, | |
14994 | + { "dr7", 7 }, | |
14995 | +}; | |
14996 | + | |
14997 | +static const int ndbreglist = sizeof(dbreglist) / sizeof(struct kdbregs); | |
14998 | + | |
14999 | +int | |
15000 | +kdba_getregcontents(const char *regname, | |
15001 | + struct pt_regs *regs, | |
15002 | + kdb_machreg_t *contents) | |
15003 | +{ | |
15004 | + int i; | |
15005 | + | |
15006 | + if (strcmp(regname, "cesp") == 0) { | |
15007 | + asm volatile("movl %%esp,%0":"=m" (*contents)); | |
15008 | + return 0; | |
15009 | + } | |
15010 | + | |
15011 | + if (strcmp(regname, "ceflags") == 0) { | |
15012 | + unsigned long flags; | |
15013 | + local_save_flags(flags); | |
15014 | + *contents = flags; | |
15015 | + return 0; | |
15016 | + } | |
15017 | + | |
15018 | + if (regname[0] == '%') { | |
15019 | + /* User registers: %%e[a-c]x, etc */ | |
15020 | + regname++; | |
15021 | + regs = (struct pt_regs *) | |
15022 | + (kdb_current_task->thread.sp0 - sizeof(struct pt_regs)); | |
15023 | + } | |
15024 | + | |
15025 | + for (i=0; i<ndbreglist; i++) { | |
15026 | + if (strnicmp(dbreglist[i].reg_name, | |
15027 | + regname, | |
15028 | + strlen(regname)) == 0) | |
15029 | + break; | |
15030 | + } | |
15031 | + | |
15032 | + if ((i < ndbreglist) | |
15033 | + && (strlen(dbreglist[i].reg_name) == strlen(regname))) { | |
15034 | + *contents = kdba_getdr(dbreglist[i].reg_offset); | |
15035 | + return 0; | |
15036 | + } | |
15037 | + | |
15038 | + if (!regs) { | |
15039 | + kdb_printf("%s: pt_regs not available, use bt* or pid to select a different task\n", __FUNCTION__); | |
15040 | + return KDB_BADREG; | |
15041 | + } | |
15042 | + | |
15043 | + if (strcmp(regname, "®s") == 0) { | |
15044 | + *contents = (unsigned long)regs; | |
15045 | + return 0; | |
15046 | + } | |
15047 | + | |
15048 | + if (strcmp(regname, "kesp") == 0) { | |
15049 | + *contents = (unsigned long)regs + sizeof(struct pt_regs); | |
15050 | + if ((regs->cs & 0xffff) == __KERNEL_CS) { | |
15051 | + /* sp and ss are not on stack */ | |
15052 | + *contents -= 2*4; | |
15053 | + } | |
15054 | + return 0; | |
15055 | + } | |
15056 | + | |
15057 | + for (i=0; i<nkdbreglist; i++) { | |
15058 | + if (strnicmp(kdbreglist[i].reg_name, | |
15059 | + regname, | |
15060 | + strlen(regname)) == 0) | |
15061 | + break; | |
15062 | + } | |
15063 | + | |
15064 | + if ((i < nkdbreglist) | |
15065 | + && (strlen(kdbreglist[i].reg_name) == strlen(regname))) { | |
15066 | + if ((regs->cs & 0xffff) == __KERNEL_CS) { | |
15067 | + /* No cpl switch, sp and ss are not on stack */ | |
15068 | + if (strcmp(kdbreglist[i].reg_name, "sp") == 0) { | |
15069 | + *contents = (kdb_machreg_t)regs + | |
15070 | + sizeof(struct pt_regs) - 2*4; | |
15071 | + return(0); | |
15072 | + } | |
15073 | + if (strcmp(kdbreglist[i].reg_name, "xss") == 0) { | |
15074 | + asm volatile( | |
15075 | + "pushl %%ss\n" | |
15076 | + "popl %0\n" | |
15077 | + :"=m" (*contents)); | |
15078 | + return(0); | |
15079 | + } | |
15080 | + } | |
15081 | + *contents = *(unsigned long *)((unsigned long)regs + | |
15082 | + kdbreglist[i].reg_offset); | |
15083 | + return(0); | |
15084 | + } | |
15085 | + | |
15086 | + return KDB_BADREG; | |
15087 | +} | |
15088 | + | |
15089 | +/* | |
15090 | + * kdba_setregcontents | |
15091 | + * | |
15092 | + * Set the contents of the register specified by the | |
15093 | + * input string argument. Return an error if the string | |
15094 | + * does not match a machine register. | |
15095 | + * | |
15096 | + * Supports modification of user-mode registers via | |
15097 | + * %<register-name> | |
15098 | + * | |
15099 | + * Parameters: | |
15100 | + * regname Pointer to string naming register | |
15101 | + * regs Pointer to structure containing registers. | |
15102 | + * contents Unsigned long containing new register contents | |
15103 | + * Outputs: | |
15104 | + * Returns: | |
15105 | + * 0 Success | |
15106 | + * KDB_BADREG Invalid register name | |
15107 | + * Locking: | |
15108 | + * None. | |
15109 | + * Remarks: | |
15110 | + */ | |
15111 | + | |
15112 | +int | |
15113 | +kdba_setregcontents(const char *regname, | |
15114 | + struct pt_regs *regs, | |
15115 | + unsigned long contents) | |
15116 | +{ | |
15117 | + int i; | |
15118 | + | |
15119 | + if (regname[0] == '%') { | |
15120 | + regname++; | |
15121 | + regs = (struct pt_regs *) | |
15122 | + (kdb_current_task->thread.sp0 - sizeof(struct pt_regs)); | |
15123 | + } | |
15124 | + | |
15125 | + for (i=0; i<ndbreglist; i++) { | |
15126 | + if (strnicmp(dbreglist[i].reg_name, | |
15127 | + regname, | |
15128 | + strlen(regname)) == 0) | |
15129 | + break; | |
15130 | + } | |
15131 | + | |
15132 | + if ((i < ndbreglist) | |
15133 | + && (strlen(dbreglist[i].reg_name) == strlen(regname))) { | |
15134 | + kdba_putdr(dbreglist[i].reg_offset, contents); | |
15135 | + return 0; | |
15136 | + } | |
15137 | + | |
15138 | + if (!regs) { | |
15139 | + kdb_printf("%s: pt_regs not available, use bt* or pid to select a different task\n", __FUNCTION__); | |
15140 | + return KDB_BADREG; | |
15141 | + } | |
15142 | + | |
15143 | + for (i=0; i<nkdbreglist; i++) { | |
15144 | + if (strnicmp(kdbreglist[i].reg_name, | |
15145 | + regname, | |
15146 | + strlen(regname)) == 0) | |
15147 | + break; | |
15148 | + } | |
15149 | + | |
15150 | + if ((i < nkdbreglist) | |
15151 | + && (strlen(kdbreglist[i].reg_name) == strlen(regname))) { | |
15152 | + *(unsigned long *)((unsigned long)regs | |
15153 | + + kdbreglist[i].reg_offset) = contents; | |
15154 | + return 0; | |
15155 | + } | |
15156 | + | |
15157 | + return KDB_BADREG; | |
15158 | +} | |
15159 | + | |
15160 | +/* | |
15161 | + * kdba_dumpregs | |
15162 | + * | |
15163 | + * Dump the specified register set to the display. | |
15164 | + * | |
15165 | + * Parameters: | |
15166 | + * regs Pointer to structure containing registers. | |
15167 | + * type Character string identifying register set to dump | |
15168 | + * extra string further identifying register (optional) | |
15169 | + * Outputs: | |
15170 | + * Returns: | |
15171 | + * 0 Success | |
15172 | + * Locking: | |
15173 | + * None. | |
15174 | + * Remarks: | |
15175 | + * This function will dump the general register set if the type | |
15176 | + * argument is NULL (struct pt_regs). The alternate register | |
15177 | + * set types supported by this function: | |
15178 | + * | |
15179 | + * d Debug registers | |
15180 | + * c Control registers | |
15181 | + * u User registers at most recent entry to kernel | |
15182 | + * for the process currently selected with "pid" command. | |
15183 | + * Following not yet implemented: | |
15184 | + * r Memory Type Range Registers (extra defines register) | |
15185 | + * | |
15186 | + * MSR on i386/x86_64 are handled by rdmsr/wrmsr commands. | |
15187 | + */ | |
15188 | + | |
15189 | +int | |
15190 | +kdba_dumpregs(struct pt_regs *regs, | |
15191 | + const char *type, | |
15192 | + const char *extra) | |
15193 | +{ | |
15194 | + int i; | |
15195 | + int count = 0; | |
15196 | + | |
15197 | + if (type | |
15198 | + && (type[0] == 'u')) { | |
15199 | + type = NULL; | |
15200 | + regs = (struct pt_regs *) | |
15201 | + (kdb_current_task->thread.sp0 - sizeof(struct pt_regs)); | |
15202 | + } | |
15203 | + | |
15204 | + if (type == NULL) { | |
15205 | + struct kdbregs *rlp; | |
15206 | + kdb_machreg_t contents; | |
15207 | + | |
15208 | + if (!regs) { | |
15209 | + kdb_printf("%s: pt_regs not available, use bt* or pid to select a different task\n", __FUNCTION__); | |
15210 | + return KDB_BADREG; | |
15211 | + } | |
15212 | + | |
15213 | + for (i=0, rlp=kdbreglist; i<nkdbreglist; i++,rlp++) { | |
15214 | + kdb_printf("%s = ", rlp->reg_name); | |
15215 | + kdba_getregcontents(rlp->reg_name, regs, &contents); | |
15216 | + kdb_printf("0x%08lx ", contents); | |
15217 | + if ((++count % 4) == 0) | |
15218 | + kdb_printf("\n"); | |
15219 | + } | |
15220 | + | |
15221 | + kdb_printf("®s = 0x%p\n", regs); | |
15222 | + | |
15223 | + return 0; | |
15224 | + } | |
15225 | + | |
15226 | + switch (type[0]) { | |
15227 | + case 'd': | |
15228 | + { | |
15229 | + unsigned long dr[8]; | |
15230 | + | |
15231 | + for(i=0; i<8; i++) { | |
15232 | + if ((i == 4) || (i == 5)) continue; | |
15233 | + dr[i] = kdba_getdr(i); | |
15234 | + } | |
15235 | + kdb_printf("dr0 = 0x%08lx dr1 = 0x%08lx dr2 = 0x%08lx dr3 = 0x%08lx\n", | |
15236 | + dr[0], dr[1], dr[2], dr[3]); | |
15237 | + kdb_printf("dr6 = 0x%08lx dr7 = 0x%08lx\n", | |
15238 | + dr[6], dr[7]); | |
15239 | + return 0; | |
15240 | + } | |
15241 | + case 'c': | |
15242 | + { | |
15243 | + unsigned long cr[5]; | |
15244 | + | |
15245 | + for (i=0; i<5; i++) { | |
15246 | + cr[i] = kdba_getcr(i); | |
15247 | + } | |
15248 | + kdb_printf("cr0 = 0x%08lx cr1 = 0x%08lx cr2 = 0x%08lx cr3 = 0x%08lx\ncr4 = 0x%08lx\n", | |
15249 | + cr[0], cr[1], cr[2], cr[3], cr[4]); | |
15250 | + return 0; | |
15251 | + } | |
15252 | + case 'r': | |
15253 | + break; | |
15254 | + default: | |
15255 | + return KDB_BADREG; | |
15256 | + } | |
15257 | + | |
15258 | + /* NOTREACHED */ | |
15259 | + return 0; | |
15260 | +} | |
15261 | +EXPORT_SYMBOL(kdba_dumpregs); | |
15262 | + | |
15263 | +kdb_machreg_t | |
15264 | +kdba_getpc(struct pt_regs *regs) | |
15265 | +{ | |
15266 | + return regs ? regs->ip : 0; | |
15267 | +} | |
15268 | + | |
15269 | +int | |
15270 | +kdba_setpc(struct pt_regs *regs, kdb_machreg_t newpc) | |
15271 | +{ | |
15272 | + if (KDB_NULL_REGS(regs)) | |
15273 | + return KDB_BADREG; | |
15274 | + regs->ip = newpc; | |
15275 | + KDB_STATE_SET(IP_ADJUSTED); | |
15276 | + return 0; | |
15277 | +} | |
15278 | + | |
15279 | +/* | |
15280 | + * kdba_main_loop | |
15281 | + * | |
15282 | + * Do any architecture specific set up before entering the main kdb loop. | |
15283 | + * The primary function of this routine is to make all processes look the | |
15284 | + * same to kdb, kdb must be able to list a process without worrying if the | |
15285 | + * process is running or blocked, so make all process look as though they | |
15286 | + * are blocked. | |
15287 | + * | |
15288 | + * Inputs: | |
15289 | + * reason The reason KDB was invoked | |
15290 | + * error The hardware-defined error code | |
15291 | + * error2 kdb's current reason code. Initially error but can change | |
15292 | + * acording to kdb state. | |
15293 | + * db_result Result from break or debug point. | |
15294 | + * regs The exception frame at time of fault/breakpoint. If reason | |
15295 | + * is SILENT or CPU_UP then regs is NULL, otherwise it should | |
15296 | + * always be valid. | |
15297 | + * Returns: | |
15298 | + * 0 KDB was invoked for an event which it wasn't responsible | |
15299 | + * 1 KDB handled the event for which it was invoked. | |
15300 | + * Outputs: | |
15301 | + * Sets ip and sp in current->thread. | |
15302 | + * Locking: | |
15303 | + * None. | |
15304 | + * Remarks: | |
15305 | + * none. | |
15306 | + */ | |
15307 | + | |
15308 | +int | |
15309 | +kdba_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error, | |
15310 | + kdb_dbtrap_t db_result, struct pt_regs *regs) | |
15311 | +{ | |
15312 | + int ret; | |
15313 | + ret = kdb_save_running(regs, reason, reason2, error, db_result); | |
15314 | + kdb_unsave_running(regs); | |
15315 | + return ret; | |
15316 | +} | |
15317 | + | |
15318 | +void | |
15319 | +kdba_disableint(kdb_intstate_t *state) | |
15320 | +{ | |
15321 | + unsigned long *fp = (unsigned long *)state; | |
15322 | + unsigned long flags; | |
15323 | + | |
15324 | + local_irq_save(flags); | |
15325 | + | |
15326 | + *fp = flags; | |
15327 | +} | |
15328 | + | |
15329 | +void | |
15330 | +kdba_restoreint(kdb_intstate_t *state) | |
15331 | +{ | |
15332 | + unsigned long flags = *(int *)state; | |
15333 | + local_irq_restore(flags); | |
15334 | +} | |
15335 | + | |
15336 | +void | |
15337 | +kdba_setsinglestep(struct pt_regs *regs) | |
15338 | +{ | |
15339 | + if (KDB_NULL_REGS(regs)) | |
15340 | + return; | |
15341 | + if (regs->flags & EF_IE) | |
15342 | + KDB_STATE_SET(A_IF); | |
15343 | + else | |
15344 | + KDB_STATE_CLEAR(A_IF); | |
15345 | + regs->flags = (regs->flags | EF_TF) & ~EF_IE; | |
15346 | +} | |
15347 | + | |
15348 | +void | |
15349 | +kdba_clearsinglestep(struct pt_regs *regs) | |
15350 | +{ | |
15351 | + if (KDB_NULL_REGS(regs)) | |
15352 | + return; | |
15353 | + if (KDB_STATE(A_IF)) | |
15354 | + regs->flags |= EF_IE; | |
15355 | + else | |
15356 | + regs->flags &= ~EF_IE; | |
15357 | +} | |
15358 | + | |
15359 | +int asmlinkage | |
15360 | +kdba_setjmp(kdb_jmp_buf *jb) | |
15361 | +{ | |
15362 | +#if defined(CONFIG_FRAME_POINTER) | |
15363 | + __asm__ ("movl 8(%esp), %eax\n\t" | |
15364 | + "movl %ebx, 0(%eax)\n\t" | |
15365 | + "movl %esi, 4(%eax)\n\t" | |
15366 | + "movl %edi, 8(%eax)\n\t" | |
15367 | + "movl (%esp), %ecx\n\t" | |
15368 | + "movl %ecx, 12(%eax)\n\t" | |
15369 | + "leal 8(%esp), %ecx\n\t" | |
15370 | + "movl %ecx, 16(%eax)\n\t" | |
15371 | + "movl 4(%esp), %ecx\n\t" | |
15372 | + "movl %ecx, 20(%eax)\n\t"); | |
15373 | +#else /* CONFIG_FRAME_POINTER */ | |
15374 | + __asm__ ("movl 4(%esp), %eax\n\t" | |
15375 | + "movl %ebx, 0(%eax)\n\t" | |
15376 | + "movl %esi, 4(%eax)\n\t" | |
15377 | + "movl %edi, 8(%eax)\n\t" | |
15378 | + "movl %ebp, 12(%eax)\n\t" | |
15379 | + "leal 4(%esp), %ecx\n\t" | |
15380 | + "movl %ecx, 16(%eax)\n\t" | |
15381 | + "movl 0(%esp), %ecx\n\t" | |
15382 | + "movl %ecx, 20(%eax)\n\t"); | |
15383 | +#endif /* CONFIG_FRAME_POINTER */ | |
15384 | + return 0; | |
15385 | +} | |
15386 | + | |
15387 | +void asmlinkage | |
15388 | +kdba_longjmp(kdb_jmp_buf *jb, int reason) | |
15389 | +{ | |
15390 | +#if defined(CONFIG_FRAME_POINTER) | |
15391 | + __asm__("movl 8(%esp), %ecx\n\t" | |
15392 | + "movl 12(%esp), %eax\n\t" | |
15393 | + "movl 20(%ecx), %edx\n\t" | |
15394 | + "movl 0(%ecx), %ebx\n\t" | |
15395 | + "movl 4(%ecx), %esi\n\t" | |
15396 | + "movl 8(%ecx), %edi\n\t" | |
15397 | + "movl 12(%ecx), %ebp\n\t" | |
15398 | + "movl 16(%ecx), %esp\n\t" | |
15399 | + "jmp *%edx\n"); | |
15400 | +#else /* CONFIG_FRAME_POINTER */ | |
15401 | + __asm__("movl 4(%esp), %ecx\n\t" | |
15402 | + "movl 8(%esp), %eax\n\t" | |
15403 | + "movl 20(%ecx), %edx\n\t" | |
15404 | + "movl 0(%ecx), %ebx\n\t" | |
15405 | + "movl 4(%ecx), %esi\n\t" | |
15406 | + "movl 8(%ecx), %edi\n\t" | |
15407 | + "movl 12(%ecx), %ebp\n\t" | |
15408 | + "movl 16(%ecx), %esp\n\t" | |
15409 | + "jmp *%edx\n"); | |
15410 | +#endif /* CONFIG_FRAME_POINTER */ | |
15411 | +} | |
15412 | + | |
15413 | +/* | |
15414 | + * kdba_pt_regs | |
15415 | + * | |
15416 | + * Format a struct pt_regs | |
15417 | + * | |
15418 | + * Inputs: | |
15419 | + * argc argument count | |
15420 | + * argv argument vector | |
15421 | + * Outputs: | |
15422 | + * None. | |
15423 | + * Returns: | |
15424 | + * zero for success, a kdb diagnostic if error | |
15425 | + * Locking: | |
15426 | + * none. | |
15427 | + * Remarks: | |
15428 | + * If no address is supplied, it uses the last irq pt_regs. | |
15429 | + */ | |
15430 | + | |
15431 | +static int | |
15432 | +kdba_pt_regs(int argc, const char **argv) | |
15433 | +{ | |
15434 | + int diag; | |
15435 | + kdb_machreg_t addr; | |
15436 | + long offset = 0; | |
15437 | + int nextarg; | |
15438 | + struct pt_regs *p; | |
15439 | + static const char *fmt = " %-11.11s 0x%lx\n"; | |
15440 | + | |
15441 | + if (argc == 0) { | |
15442 | + addr = (kdb_machreg_t) get_irq_regs(); | |
15443 | + } else if (argc == 1) { | |
15444 | + nextarg = 1; | |
15445 | + diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL); | |
15446 | + if (diag) | |
15447 | + return diag; | |
15448 | + } else { | |
15449 | + return KDB_ARGCOUNT; | |
15450 | + } | |
15451 | + | |
15452 | + p = (struct pt_regs *) addr; | |
15453 | + kdb_printf("struct pt_regs 0x%p-0x%p\n", p, (unsigned char *)p + sizeof(*p) - 1); | |
15454 | + kdb_print_nameval("bx", p->bx); | |
15455 | + kdb_print_nameval("cx", p->cx); | |
15456 | + kdb_print_nameval("dx", p->dx); | |
15457 | + kdb_print_nameval("si", p->si); | |
15458 | + kdb_print_nameval("di", p->di); | |
15459 | + kdb_print_nameval("bp", p->bp); | |
15460 | + kdb_print_nameval("ax", p->ax); | |
15461 | + kdb_printf(fmt, "ds", p->ds); | |
15462 | + kdb_printf(fmt, "es", p->es); | |
15463 | + kdb_print_nameval("orig_ax", p->orig_ax); | |
15464 | + kdb_print_nameval("ip", p->ip); | |
15465 | + kdb_printf(fmt, "cs", p->cs); | |
15466 | + kdb_printf(fmt, "flags", p->flags); | |
15467 | + kdb_printf(fmt, "sp", p->sp); | |
15468 | + kdb_printf(fmt, "ss", p->ss); | |
15469 | + return 0; | |
15470 | +} | |
15471 | + | |
15472 | +/* | |
15473 | + * kdba_stackdepth | |
15474 | + * | |
15475 | + * Print processes that are using more than a specific percentage of their | |
15476 | + * stack. | |
15477 | + * | |
15478 | + * Inputs: | |
15479 | + * argc argument count | |
15480 | + * argv argument vector | |
15481 | + * Outputs: | |
15482 | + * None. | |
15483 | + * Returns: | |
15484 | + * zero for success, a kdb diagnostic if error | |
15485 | + * Locking: | |
15486 | + * none. | |
15487 | + * Remarks: | |
15488 | + * If no percentage is supplied, it uses 60. | |
15489 | + */ | |
15490 | + | |
15491 | +static void | |
15492 | +kdba_stackdepth1(struct task_struct *p, unsigned long sp) | |
15493 | +{ | |
15494 | + struct thread_info *tinfo; | |
15495 | + int used; | |
15496 | + const char *type; | |
15497 | + kdb_ps1(p); | |
15498 | + do { | |
15499 | + tinfo = (struct thread_info *)(sp & -THREAD_SIZE); | |
15500 | + used = sizeof(*tinfo) + THREAD_SIZE - (sp & (THREAD_SIZE-1)); | |
15501 | + type = NULL; | |
15502 | + if (kdb_task_has_cpu(p)) { | |
15503 | + struct kdb_activation_record ar; | |
15504 | + memset(&ar, 0, sizeof(ar)); | |
15505 | + kdba_get_stack_info_alternate(sp, -1, &ar); | |
15506 | + type = ar.stack.id; | |
15507 | + } | |
15508 | + if (!type) | |
15509 | + type = "process"; | |
15510 | + kdb_printf(" %s stack %p sp %lx used %d\n", type, tinfo, sp, used); | |
15511 | + sp = tinfo->previous_esp; | |
15512 | + } while (sp); | |
15513 | +} | |
15514 | + | |
15515 | +static int | |
15516 | +kdba_stackdepth(int argc, const char **argv) | |
15517 | +{ | |
15518 | + int diag, cpu, threshold, used, over; | |
15519 | + unsigned long percentage; | |
15520 | + unsigned long esp; | |
15521 | + long offset = 0; | |
15522 | + int nextarg; | |
15523 | + struct task_struct *p, *g; | |
15524 | + struct kdb_running_process *krp; | |
15525 | + struct thread_info *tinfo; | |
15526 | + | |
15527 | + if (argc == 0) { | |
15528 | + percentage = 60; | |
15529 | + } else if (argc == 1) { | |
15530 | + nextarg = 1; | |
15531 | + diag = kdbgetaddrarg(argc, argv, &nextarg, &percentage, &offset, NULL); | |
15532 | + if (diag) | |
15533 | + return diag; | |
15534 | + } else { | |
15535 | + return KDB_ARGCOUNT; | |
15536 | + } | |
15537 | + percentage = max_t(int, percentage, 1); | |
15538 | + percentage = min_t(int, percentage, 100); | |
15539 | + threshold = ((2 * THREAD_SIZE * percentage) / 100 + 1) >> 1; | |
15540 | + kdb_printf("stackdepth: processes using more than %ld%% (%d bytes) of stack\n", | |
15541 | + percentage, threshold); | |
15542 | + | |
15543 | + /* Run the active tasks first, they can have multiple stacks */ | |
15544 | + for (cpu = 0, krp = kdb_running_process; cpu < NR_CPUS; ++cpu, ++krp) { | |
15545 | + if (!cpu_online(cpu)) | |
15546 | + continue; | |
15547 | + p = krp->p; | |
15548 | + esp = krp->arch.sp; | |
15549 | + over = 0; | |
15550 | + do { | |
15551 | + tinfo = (struct thread_info *)(esp & -THREAD_SIZE); | |
15552 | + used = sizeof(*tinfo) + THREAD_SIZE - (esp & (THREAD_SIZE-1)); | |
15553 | + if (used >= threshold) | |
15554 | + over = 1; | |
15555 | + esp = tinfo->previous_esp; | |
15556 | + } while (esp); | |
15557 | + if (over) | |
15558 | + kdba_stackdepth1(p, krp->arch.sp); | |
15559 | + } | |
15560 | + /* Now the tasks that are not on cpus */ | |
15561 | + kdb_do_each_thread(g, p) { | |
15562 | + if (kdb_task_has_cpu(p)) | |
15563 | + continue; | |
15564 | + esp = p->thread.sp; | |
15565 | + used = sizeof(*tinfo) + THREAD_SIZE - (esp & (THREAD_SIZE-1)); | |
15566 | + over = used >= threshold; | |
15567 | + if (over) | |
15568 | + kdba_stackdepth1(p, esp); | |
15569 | + } kdb_while_each_thread(g, p); | |
15570 | + | |
15571 | + return 0; | |
15572 | +} | |
15573 | + | |
15574 | +asmlinkage int kdb_call(void); | |
15575 | + | |
15576 | +/* Executed once on each cpu at startup. */ | |
15577 | +void | |
15578 | +kdba_cpu_up(void) | |
15579 | +{ | |
15580 | +} | |
15581 | + | |
15582 | +static int __init | |
15583 | +kdba_arch_init(void) | |
15584 | +{ | |
15585 | +#ifdef CONFIG_SMP | |
15586 | + set_intr_gate(KDB_VECTOR, kdb_interrupt); | |
15587 | +#endif | |
15588 | + set_intr_gate(KDBENTER_VECTOR, kdb_call); | |
15589 | + return 0; | |
15590 | +} | |
15591 | + | |
15592 | +arch_initcall(kdba_arch_init); | |
15593 | + | |
15594 | +/* | |
15595 | + * kdba_init | |
15596 | + * | |
15597 | + * Architecture specific initialization. | |
15598 | + * | |
15599 | + * Parameters: | |
15600 | + * None. | |
15601 | + * Returns: | |
15602 | + * None. | |
15603 | + * Locking: | |
15604 | + * None. | |
15605 | + * Remarks: | |
15606 | + * None. | |
15607 | + */ | |
15608 | + | |
15609 | +void __init | |
15610 | +kdba_init(void) | |
15611 | +{ | |
15612 | + kdba_arch_init(); /* Need to register KDBENTER_VECTOR early */ | |
15613 | + kdb_register("pt_regs", kdba_pt_regs, "address", "Format struct pt_regs", 0); | |
15614 | + kdb_register("stackdepth", kdba_stackdepth, "[percentage]", "Print processes using >= stack percentage", 0); | |
15615 | + | |
15616 | + return; | |
15617 | +} | |
15618 | + | |
15619 | +/* | |
15620 | + * kdba_adjust_ip | |
15621 | + * | |
15622 | + * Architecture specific adjustment of instruction pointer before leaving | |
15623 | + * kdb. | |
15624 | + * | |
15625 | + * Parameters: | |
15626 | + * reason The reason KDB was invoked | |
15627 | + * error The hardware-defined error code | |
15628 | + * regs The exception frame at time of fault/breakpoint. If reason | |
15629 | + * is SILENT or CPU_UP then regs is NULL, otherwise it should | |
15630 | + * always be valid. | |
15631 | + * Returns: | |
15632 | + * None. | |
15633 | + * Locking: | |
15634 | + * None. | |
15635 | + * Remarks: | |
15636 | + * noop on ix86. | |
15637 | + */ | |
15638 | + | |
15639 | +void | |
15640 | +kdba_adjust_ip(kdb_reason_t reason, int error, struct pt_regs *regs) | |
15641 | +{ | |
15642 | + return; | |
15643 | +} | |
15644 | + | |
15645 | +void | |
15646 | +kdba_set_current_task(const struct task_struct *p) | |
15647 | +{ | |
15648 | + kdb_current_task = p; | |
15649 | + if (kdb_task_has_cpu(p)) { | |
15650 | + struct kdb_running_process *krp = kdb_running_process + kdb_process_cpu(p); | |
15651 | + kdb_current_regs = krp->regs; | |
15652 | + return; | |
15653 | + } | |
15654 | + kdb_current_regs = NULL; | |
15655 | +} | |
15656 | + | |
15657 | +/* | |
15658 | + * asm-i386 uaccess.h supplies __copy_to_user which relies on MMU to | |
15659 | + * trap invalid addresses in the _xxx fields. Verify the other address | |
15660 | + * of the pair is valid by accessing the first and last byte ourselves, | |
15661 | + * then any access violations should only be caused by the _xxx | |
15662 | + * addresses, | |
15663 | + */ | |
15664 | + | |
15665 | +int | |
15666 | +kdba_putarea_size(unsigned long to_xxx, void *from, size_t size) | |
15667 | +{ | |
15668 | + mm_segment_t oldfs = get_fs(); | |
15669 | + int r; | |
15670 | + char c; | |
15671 | + c = *((volatile char *)from); | |
15672 | + c = *((volatile char *)from + size - 1); | |
15673 | + | |
15674 | + if (to_xxx < PAGE_OFFSET) { | |
15675 | + return kdb_putuserarea_size(to_xxx, from, size); | |
15676 | + } | |
15677 | + | |
15678 | + set_fs(KERNEL_DS); | |
15679 | + r = __copy_to_user_inatomic((void __user *)to_xxx, from, size); | |
15680 | + set_fs(oldfs); | |
15681 | + return r; | |
15682 | +} | |
15683 | + | |
15684 | +int | |
15685 | +kdba_getarea_size(void *to, unsigned long from_xxx, size_t size) | |
15686 | +{ | |
15687 | + mm_segment_t oldfs = get_fs(); | |
15688 | + int r; | |
15689 | + *((volatile char *)to) = '\0'; | |
15690 | + *((volatile char *)to + size - 1) = '\0'; | |
15691 | + | |
15692 | + if (from_xxx < PAGE_OFFSET) { | |
15693 | + return kdb_getuserarea_size(to, from_xxx, size); | |
15694 | + } | |
15695 | + | |
15696 | + set_fs(KERNEL_DS); | |
15697 | + switch (size) { | |
15698 | + case 1: | |
15699 | + r = __copy_to_user_inatomic((void __user *)to, (void *)from_xxx, 1); | |
15700 | + break; | |
15701 | + case 2: | |
15702 | + r = __copy_to_user_inatomic((void __user *)to, (void *)from_xxx, 2); | |
15703 | + break; | |
15704 | + case 4: | |
15705 | + r = __copy_to_user_inatomic((void __user *)to, (void *)from_xxx, 4); | |
15706 | + break; | |
15707 | + case 8: | |
15708 | + r = __copy_to_user_inatomic((void __user *)to, (void *)from_xxx, 8); | |
15709 | + break; | |
15710 | + default: | |
15711 | + r = __copy_to_user_inatomic((void __user *)to, (void *)from_xxx, size); | |
15712 | + break; | |
15713 | + } | |
15714 | + set_fs(oldfs); | |
15715 | + return r; | |
15716 | +} | |
15717 | + | |
15718 | +int | |
15719 | +kdba_verify_rw(unsigned long addr, size_t size) | |
15720 | +{ | |
15721 | + unsigned char data[size]; | |
15722 | + return(kdba_getarea_size(data, addr, size) || kdba_putarea_size(addr, data, size)); | |
15723 | +} | |
15724 | + | |
15725 | +#ifdef CONFIG_SMP | |
15726 | + | |
15727 | +#include <mach_ipi.h> | |
15728 | + | |
15729 | +/* When first entering KDB, try a normal IPI. That reduces backtrace problems | |
15730 | + * on the other cpus. | |
15731 | + */ | |
15732 | +void | |
15733 | +smp_kdb_stop(void) | |
15734 | +{ | |
15735 | + if (!KDB_FLAG(NOIPI)) | |
15736 | + send_IPI_allbutself(KDB_VECTOR); | |
15737 | +} | |
15738 | + | |
15739 | +/* The normal KDB IPI handler */ | |
15740 | +void | |
15741 | +smp_kdb_interrupt(struct pt_regs *regs) | |
15742 | +{ | |
15743 | + struct pt_regs *old_regs = set_irq_regs(regs); | |
15744 | + ack_APIC_irq(); | |
15745 | + irq_enter(); | |
15746 | + kdb_ipi(regs, NULL); | |
15747 | + irq_exit(); | |
15748 | + set_irq_regs(old_regs); | |
15749 | +} | |
15750 | + | |
15751 | +/* Invoked once from kdb_wait_for_cpus when waiting for cpus. For those cpus | |
15752 | + * that have not responded to the normal KDB interrupt yet, hit them with an | |
15753 | + * NMI event. | |
15754 | + */ | |
15755 | +void | |
15756 | +kdba_wait_for_cpus(void) | |
15757 | +{ | |
15758 | + int c; | |
15759 | + if (KDB_FLAG(CATASTROPHIC)) | |
15760 | + return; | |
15761 | + kdb_printf(" Sending NMI to non-responding cpu(s): "); | |
15762 | + for_each_online_cpu(c) { | |
15763 | + if (kdb_running_process[c].seqno < kdb_seqno - 1) { | |
15764 | + kdb_printf(" %d", c); | |
15765 | + send_IPI_mask(&cpumask_of_cpu(c), NMI_VECTOR); | |
15766 | + } | |
15767 | + } | |
15768 | + kdb_printf(".\n"); | |
15769 | +} | |
15770 | + | |
15771 | +#endif /* CONFIG_SMP */ | |
15772 | --- /dev/null | |
15773 | +++ b/arch/x86/kdb/kdbasupport_64.c | |
15774 | @@ -0,0 +1,1022 @@ | |
15775 | +/* | |
15776 | + * Kernel Debugger Architecture Independent Support Functions | |
15777 | + * | |
15778 | + * This file is subject to the terms and conditions of the GNU General Public | |
15779 | + * License. See the file "COPYING" in the main directory of this archive | |
15780 | + * for more details. | |
15781 | + * | |
15782 | + * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved. | |
15783 | + */ | |
15784 | + | |
15785 | +#include <linux/string.h> | |
15786 | +#include <linux/stddef.h> | |
15787 | +#include <linux/kernel.h> | |
15788 | +#include <linux/init.h> | |
15789 | +#include <linux/ptrace.h> | |
15790 | +#include <linux/mm.h> | |
15791 | +#include <linux/sched.h> | |
15792 | +#include <linux/hardirq.h> | |
15793 | +#include <linux/kdb.h> | |
15794 | +#include <linux/kdbprivate.h> | |
15795 | +#include <linux/interrupt.h> | |
15796 | +#include <linux/module.h> | |
15797 | +#include <linux/kdebug.h> | |
15798 | +#include <asm/processor.h> | |
15799 | +#include <asm/msr.h> | |
15800 | +#include <asm/uaccess.h> | |
15801 | +#include <asm/hw_irq.h> | |
15802 | +#include <asm/desc.h> | |
15803 | + | |
15804 | +kdb_machreg_t | |
15805 | +kdba_getdr6(void) | |
15806 | +{ | |
15807 | + return kdba_getdr(6); | |
15808 | +} | |
15809 | + | |
15810 | +kdb_machreg_t | |
15811 | +kdba_getdr7(void) | |
15812 | +{ | |
15813 | + return kdba_getdr(7); | |
15814 | +} | |
15815 | + | |
15816 | +void | |
15817 | +kdba_putdr6(kdb_machreg_t contents) | |
15818 | +{ | |
15819 | + kdba_putdr(6, contents); | |
15820 | +} | |
15821 | + | |
15822 | +static void | |
15823 | +kdba_putdr7(kdb_machreg_t contents) | |
15824 | +{ | |
15825 | + kdba_putdr(7, contents); | |
15826 | +} | |
15827 | + | |
15828 | +void | |
15829 | +kdba_installdbreg(kdb_bp_t *bp) | |
15830 | +{ | |
15831 | + int cpu = smp_processor_id(); | |
15832 | + | |
15833 | + kdb_machreg_t dr7; | |
15834 | + | |
15835 | + dr7 = kdba_getdr7(); | |
15836 | + | |
15837 | + kdba_putdr(bp->bp_hard[cpu]->bph_reg, bp->bp_addr); | |
15838 | + | |
15839 | + dr7 |= DR7_GE; | |
15840 | + if (cpu_has_de) | |
15841 | + set_in_cr4(X86_CR4_DE); | |
15842 | + | |
15843 | + switch (bp->bp_hard[cpu]->bph_reg){ | |
15844 | + case 0: | |
15845 | + DR7_RW0SET(dr7,bp->bp_hard[cpu]->bph_mode); | |
15846 | + DR7_LEN0SET(dr7,bp->bp_hard[cpu]->bph_length); | |
15847 | + DR7_G0SET(dr7); | |
15848 | + break; | |
15849 | + case 1: | |
15850 | + DR7_RW1SET(dr7,bp->bp_hard[cpu]->bph_mode); | |
15851 | + DR7_LEN1SET(dr7,bp->bp_hard[cpu]->bph_length); | |
15852 | + DR7_G1SET(dr7); | |
15853 | + break; | |
15854 | + case 2: | |
15855 | + DR7_RW2SET(dr7,bp->bp_hard[cpu]->bph_mode); | |
15856 | + DR7_LEN2SET(dr7,bp->bp_hard[cpu]->bph_length); | |
15857 | + DR7_G2SET(dr7); | |
15858 | + break; | |
15859 | + case 3: | |
15860 | + DR7_RW3SET(dr7,bp->bp_hard[cpu]->bph_mode); | |
15861 | + DR7_LEN3SET(dr7,bp->bp_hard[cpu]->bph_length); | |
15862 | + DR7_G3SET(dr7); | |
15863 | + break; | |
15864 | + default: | |
15865 | + kdb_printf("kdb: Bad debug register!! %ld\n", | |
15866 | + bp->bp_hard[cpu]->bph_reg); | |
15867 | + break; | |
15868 | + } | |
15869 | + | |
15870 | + kdba_putdr7(dr7); | |
15871 | + return; | |
15872 | +} | |
15873 | + | |
15874 | +void | |
15875 | +kdba_removedbreg(kdb_bp_t *bp) | |
15876 | +{ | |
15877 | + int regnum; | |
15878 | + kdb_machreg_t dr7; | |
15879 | + int cpu = smp_processor_id(); | |
15880 | + | |
15881 | + if (!bp->bp_hard[cpu]) | |
15882 | + return; | |
15883 | + | |
15884 | + regnum = bp->bp_hard[cpu]->bph_reg; | |
15885 | + | |
15886 | + dr7 = kdba_getdr7(); | |
15887 | + | |
15888 | + kdba_putdr(regnum, 0); | |
15889 | + | |
15890 | + switch (regnum) { | |
15891 | + case 0: | |
15892 | + DR7_G0CLR(dr7); | |
15893 | + DR7_L0CLR(dr7); | |
15894 | + break; | |
15895 | + case 1: | |
15896 | + DR7_G1CLR(dr7); | |
15897 | + DR7_L1CLR(dr7); | |
15898 | + break; | |
15899 | + case 2: | |
15900 | + DR7_G2CLR(dr7); | |
15901 | + DR7_L2CLR(dr7); | |
15902 | + break; | |
15903 | + case 3: | |
15904 | + DR7_G3CLR(dr7); | |
15905 | + DR7_L3CLR(dr7); | |
15906 | + break; | |
15907 | + default: | |
15908 | + kdb_printf("kdb: Bad debug register!! %d\n", regnum); | |
15909 | + break; | |
15910 | + } | |
15911 | + | |
15912 | + kdba_putdr7(dr7); | |
15913 | +} | |
15914 | + | |
15915 | +kdb_machreg_t | |
15916 | +kdba_getdr(int regnum) | |
15917 | +{ | |
15918 | + kdb_machreg_t contents = 0; | |
15919 | + switch(regnum) { | |
15920 | + case 0: | |
15921 | + __asm__ ("movq %%db0,%0\n\t":"=r"(contents)); | |
15922 | + break; | |
15923 | + case 1: | |
15924 | + __asm__ ("movq %%db1,%0\n\t":"=r"(contents)); | |
15925 | + break; | |
15926 | + case 2: | |
15927 | + __asm__ ("movq %%db2,%0\n\t":"=r"(contents)); | |
15928 | + break; | |
15929 | + case 3: | |
15930 | + __asm__ ("movq %%db3,%0\n\t":"=r"(contents)); | |
15931 | + break; | |
15932 | + case 4: | |
15933 | + case 5: | |
15934 | + break; | |
15935 | + case 6: | |
15936 | + __asm__ ("movq %%db6,%0\n\t":"=r"(contents)); | |
15937 | + break; | |
15938 | + case 7: | |
15939 | + __asm__ ("movq %%db7,%0\n\t":"=r"(contents)); | |
15940 | + break; | |
15941 | + default: | |
15942 | + break; | |
15943 | + } | |
15944 | + | |
15945 | + return contents; | |
15946 | +} | |
15947 | + | |
15948 | + | |
15949 | +kdb_machreg_t | |
15950 | +kdb_getcr(int regnum) | |
15951 | +{ | |
15952 | + kdb_machreg_t contents = 0; | |
15953 | + switch(regnum) { | |
15954 | + case 0: | |
15955 | + __asm__ ("movq %%cr0,%0\n\t":"=r"(contents)); | |
15956 | + break; | |
15957 | + case 1: | |
15958 | + break; | |
15959 | + case 2: | |
15960 | + __asm__ ("movq %%cr2,%0\n\t":"=r"(contents)); | |
15961 | + break; | |
15962 | + case 3: | |
15963 | + __asm__ ("movq %%cr3,%0\n\t":"=r"(contents)); | |
15964 | + break; | |
15965 | + case 4: | |
15966 | + __asm__ ("movq %%cr4,%0\n\t":"=r"(contents)); | |
15967 | + break; | |
15968 | + default: | |
15969 | + break; | |
15970 | + } | |
15971 | + | |
15972 | + return contents; | |
15973 | +} | |
15974 | + | |
15975 | +void | |
15976 | +kdba_putdr(int regnum, kdb_machreg_t contents) | |
15977 | +{ | |
15978 | + switch(regnum) { | |
15979 | + case 0: | |
15980 | + __asm__ ("movq %0,%%db0\n\t"::"r"(contents)); | |
15981 | + break; | |
15982 | + case 1: | |
15983 | + __asm__ ("movq %0,%%db1\n\t"::"r"(contents)); | |
15984 | + break; | |
15985 | + case 2: | |
15986 | + __asm__ ("movq %0,%%db2\n\t"::"r"(contents)); | |
15987 | + break; | |
15988 | + case 3: | |
15989 | + __asm__ ("movq %0,%%db3\n\t"::"r"(contents)); | |
15990 | + break; | |
15991 | + case 4: | |
15992 | + case 5: | |
15993 | + break; | |
15994 | + case 6: | |
15995 | + __asm__ ("movq %0,%%db6\n\t"::"r"(contents)); | |
15996 | + break; | |
15997 | + case 7: | |
15998 | + __asm__ ("movq %0,%%db7\n\t"::"r"(contents)); | |
15999 | + break; | |
16000 | + default: | |
16001 | + break; | |
16002 | + } | |
16003 | +} | |
16004 | + | |
16005 | +/* | |
16006 | + * kdba_getregcontents | |
16007 | + * | |
16008 | + * Return the contents of the register specified by the | |
16009 | + * input string argument. Return an error if the string | |
16010 | + * does not match a machine register. | |
16011 | + * | |
16012 | + * The following pseudo register names are supported: | |
16013 | + * ®s - Prints address of exception frame | |
16014 | + * krsp - Prints kernel stack pointer at time of fault | |
16015 | + * crsp - Prints current kernel stack pointer, inside kdb | |
16016 | + * ceflags - Prints current flags, inside kdb | |
16017 | + * %<regname> - Uses the value of the registers at the | |
16018 | + * last time the user process entered kernel | |
16019 | + * mode, instead of the registers at the time | |
16020 | + * kdb was entered. | |
16021 | + * | |
16022 | + * Parameters: | |
16023 | + * regname Pointer to string naming register | |
16024 | + * regs Pointer to structure containing registers. | |
16025 | + * Outputs: | |
16026 | + * *contents Pointer to unsigned long to recieve register contents | |
16027 | + * Returns: | |
16028 | + * 0 Success | |
16029 | + * KDB_BADREG Invalid register name | |
16030 | + * Locking: | |
16031 | + * None. | |
16032 | + * Remarks: | |
16033 | + * If kdb was entered via an interrupt from the kernel itself then | |
16034 | + * ss and sp are *not* on the stack. | |
16035 | + */ | |
16036 | + | |
16037 | +static struct kdbregs { | |
16038 | + char *reg_name; | |
16039 | + size_t reg_offset; | |
16040 | +} kdbreglist[] = { | |
16041 | + { "r15", offsetof(struct pt_regs, r15) }, | |
16042 | + { "r14", offsetof(struct pt_regs, r14) }, | |
16043 | + { "r13", offsetof(struct pt_regs, r13) }, | |
16044 | + { "r12", offsetof(struct pt_regs, r12) }, | |
16045 | + { "bp", offsetof(struct pt_regs, bp) }, | |
16046 | + { "bx", offsetof(struct pt_regs, bx) }, | |
16047 | + { "r11", offsetof(struct pt_regs, r11) }, | |
16048 | + { "r10", offsetof(struct pt_regs, r10) }, | |
16049 | + { "r9", offsetof(struct pt_regs, r9) }, | |
16050 | + { "r8", offsetof(struct pt_regs, r8) }, | |
16051 | + { "ax", offsetof(struct pt_regs, ax) }, | |
16052 | + { "cx", offsetof(struct pt_regs, cx) }, | |
16053 | + { "dx", offsetof(struct pt_regs, dx) }, | |
16054 | + { "si", offsetof(struct pt_regs, si) }, | |
16055 | + { "di", offsetof(struct pt_regs, di) }, | |
16056 | + { "orig_ax", offsetof(struct pt_regs, orig_ax) }, | |
16057 | + { "ip", offsetof(struct pt_regs, ip) }, | |
16058 | + { "cs", offsetof(struct pt_regs, cs) }, | |
16059 | + { "flags", offsetof(struct pt_regs, flags) }, | |
16060 | + { "sp", offsetof(struct pt_regs, sp) }, | |
16061 | + { "ss", offsetof(struct pt_regs, ss) }, | |
16062 | +}; | |
16063 | + | |
16064 | +static const int nkdbreglist = sizeof(kdbreglist) / sizeof(struct kdbregs); | |
16065 | + | |
16066 | +static struct kdbregs dbreglist[] = { | |
16067 | + { "dr0", 0 }, | |
16068 | + { "dr1", 1 }, | |
16069 | + { "dr2", 2 }, | |
16070 | + { "dr3", 3 }, | |
16071 | + { "dr6", 6 }, | |
16072 | + { "dr7", 7 }, | |
16073 | +}; | |
16074 | + | |
16075 | +static const int ndbreglist = sizeof(dbreglist) / sizeof(struct kdbregs); | |
16076 | + | |
16077 | +int | |
16078 | +kdba_getregcontents(const char *regname, | |
16079 | + struct pt_regs *regs, | |
16080 | + kdb_machreg_t *contents) | |
16081 | +{ | |
16082 | + int i; | |
16083 | + | |
16084 | + if (strcmp(regname, "®s") == 0) { | |
16085 | + *contents = (unsigned long)regs; | |
16086 | + return 0; | |
16087 | + } | |
16088 | + | |
16089 | + if (strcmp(regname, "krsp") == 0) { | |
16090 | + *contents = (unsigned long)regs + sizeof(struct pt_regs); | |
16091 | + if ((regs->cs & 0xffff) == __KERNEL_CS) { | |
16092 | + /* sp and ss are not on stack */ | |
16093 | + *contents -= 2*4; | |
16094 | + } | |
16095 | + return 0; | |
16096 | + } | |
16097 | + | |
16098 | + if (strcmp(regname, "crsp") == 0) { | |
16099 | + asm volatile("movq %%rsp,%0":"=m" (*contents)); | |
16100 | + return 0; | |
16101 | + } | |
16102 | + | |
16103 | + if (strcmp(regname, "ceflags") == 0) { | |
16104 | + unsigned long flags; | |
16105 | + local_save_flags(flags); | |
16106 | + *contents = flags; | |
16107 | + return 0; | |
16108 | + } | |
16109 | + | |
16110 | + if (regname[0] == '%') { | |
16111 | + /* User registers: %%r[a-c]x, etc */ | |
16112 | + regname++; | |
16113 | + regs = (struct pt_regs *) | |
16114 | + (current->thread.sp0 - sizeof(struct pt_regs)); | |
16115 | + } | |
16116 | + | |
16117 | + for (i=0; i<nkdbreglist; i++) { | |
16118 | + if (strnicmp(kdbreglist[i].reg_name, | |
16119 | + regname, | |
16120 | + strlen(regname)) == 0) | |
16121 | + break; | |
16122 | + } | |
16123 | + | |
16124 | + if ((i < nkdbreglist) | |
16125 | + && (strlen(kdbreglist[i].reg_name) == strlen(regname))) { | |
16126 | + if ((regs->cs & 0xffff) == __KERNEL_CS) { | |
16127 | + /* No cpl switch, sp is not on stack */ | |
16128 | + if (strcmp(kdbreglist[i].reg_name, "sp") == 0) { | |
16129 | + *contents = (kdb_machreg_t)regs + | |
16130 | + sizeof(struct pt_regs) - 2*8; | |
16131 | + return(0); | |
16132 | + } | |
16133 | +#if 0 /* FIXME */ | |
16134 | + if (strcmp(kdbreglist[i].reg_name, "ss") == 0) { | |
16135 | + kdb_machreg_t r; | |
16136 | + | |
16137 | + r = (kdb_machreg_t)regs + | |
16138 | + sizeof(struct pt_regs) - 2*8; | |
16139 | + *contents = (kdb_machreg_t)SS(r); /* XXX */ | |
16140 | + return(0); | |
16141 | + } | |
16142 | +#endif | |
16143 | + } | |
16144 | + *contents = *(unsigned long *)((unsigned long)regs + | |
16145 | + kdbreglist[i].reg_offset); | |
16146 | + return(0); | |
16147 | + } | |
16148 | + | |
16149 | + for (i=0; i<ndbreglist; i++) { | |
16150 | + if (strnicmp(dbreglist[i].reg_name, | |
16151 | + regname, | |
16152 | + strlen(regname)) == 0) | |
16153 | + break; | |
16154 | + } | |
16155 | + | |
16156 | + if ((i < ndbreglist) | |
16157 | + && (strlen(dbreglist[i].reg_name) == strlen(regname))) { | |
16158 | + *contents = kdba_getdr(dbreglist[i].reg_offset); | |
16159 | + return 0; | |
16160 | + } | |
16161 | + return KDB_BADREG; | |
16162 | +} | |
16163 | + | |
16164 | +/* | |
16165 | + * kdba_setregcontents | |
16166 | + * | |
16167 | + * Set the contents of the register specified by the | |
16168 | + * input string argument. Return an error if the string | |
16169 | + * does not match a machine register. | |
16170 | + * | |
16171 | + * Supports modification of user-mode registers via | |
16172 | + * %<register-name> | |
16173 | + * | |
16174 | + * Parameters: | |
16175 | + * regname Pointer to string naming register | |
16176 | + * regs Pointer to structure containing registers. | |
16177 | + * contents Unsigned long containing new register contents | |
16178 | + * Outputs: | |
16179 | + * Returns: | |
16180 | + * 0 Success | |
16181 | + * KDB_BADREG Invalid register name | |
16182 | + * Locking: | |
16183 | + * None. | |
16184 | + * Remarks: | |
16185 | + */ | |
16186 | + | |
16187 | +int | |
16188 | +kdba_setregcontents(const char *regname, | |
16189 | + struct pt_regs *regs, | |
16190 | + unsigned long contents) | |
16191 | +{ | |
16192 | + int i; | |
16193 | + | |
16194 | + if (regname[0] == '%') { | |
16195 | + regname++; | |
16196 | + regs = (struct pt_regs *) | |
16197 | + (current->thread.sp0 - sizeof(struct pt_regs)); | |
16198 | + } | |
16199 | + | |
16200 | + for (i=0; i<nkdbreglist; i++) { | |
16201 | + if (strnicmp(kdbreglist[i].reg_name, | |
16202 | + regname, | |
16203 | + strlen(regname)) == 0) | |
16204 | + break; | |
16205 | + } | |
16206 | + | |
16207 | + if ((i < nkdbreglist) | |
16208 | + && (strlen(kdbreglist[i].reg_name) == strlen(regname))) { | |
16209 | + *(unsigned long *)((unsigned long)regs | |
16210 | + + kdbreglist[i].reg_offset) = contents; | |
16211 | + return 0; | |
16212 | + } | |
16213 | + | |
16214 | + for (i=0; i<ndbreglist; i++) { | |
16215 | + if (strnicmp(dbreglist[i].reg_name, | |
16216 | + regname, | |
16217 | + strlen(regname)) == 0) | |
16218 | + break; | |
16219 | + } | |
16220 | + | |
16221 | + if ((i < ndbreglist) | |
16222 | + && (strlen(dbreglist[i].reg_name) == strlen(regname))) { | |
16223 | + kdba_putdr(dbreglist[i].reg_offset, contents); | |
16224 | + return 0; | |
16225 | + } | |
16226 | + | |
16227 | + return KDB_BADREG; | |
16228 | +} | |
16229 | + | |
16230 | +/* | |
16231 | + * kdba_dumpregs | |
16232 | + * | |
16233 | + * Dump the specified register set to the display. | |
16234 | + * | |
16235 | + * Parameters: | |
16236 | + * regs Pointer to structure containing registers. | |
16237 | + * type Character string identifying register set to dump | |
16238 | + * extra string further identifying register (optional) | |
16239 | + * Outputs: | |
16240 | + * Returns: | |
16241 | + * 0 Success | |
16242 | + * Locking: | |
16243 | + * None. | |
16244 | + * Remarks: | |
16245 | + * This function will dump the general register set if the type | |
16246 | + * argument is NULL (struct pt_regs). The alternate register | |
16247 | + * set types supported by this function: | |
16248 | + * | |
16249 | + * d Debug registers | |
16250 | + * c Control registers | |
16251 | + * u User registers at most recent entry to kernel | |
16252 | + * Following not yet implemented: | |
16253 | + * r Memory Type Range Registers (extra defines register) | |
16254 | + * | |
16255 | + * MSR on i386/x86_64 are handled by rdmsr/wrmsr commands. | |
16256 | + */ | |
16257 | + | |
16258 | +int | |
16259 | +kdba_dumpregs(struct pt_regs *regs, | |
16260 | + const char *type, | |
16261 | + const char *extra) | |
16262 | +{ | |
16263 | + int i; | |
16264 | + int count = 0; | |
16265 | + | |
16266 | + if (type | |
16267 | + && (type[0] == 'u')) { | |
16268 | + type = NULL; | |
16269 | + regs = (struct pt_regs *) | |
16270 | + (current->thread.sp0 - sizeof(struct pt_regs)); | |
16271 | + } | |
16272 | + | |
16273 | + if (type == NULL) { | |
16274 | + struct kdbregs *rlp; | |
16275 | + kdb_machreg_t contents; | |
16276 | + | |
16277 | + for (i=0, rlp=kdbreglist; i<nkdbreglist; i++,rlp++) { | |
16278 | + kdb_printf("%8s = ", rlp->reg_name); | |
16279 | + kdba_getregcontents(rlp->reg_name, regs, &contents); | |
16280 | + kdb_printf("0x%016lx ", contents); | |
16281 | + if ((++count % 2) == 0) | |
16282 | + kdb_printf("\n"); | |
16283 | + } | |
16284 | + | |
16285 | + kdb_printf("®s = 0x%p\n", regs); | |
16286 | + | |
16287 | + return 0; | |
16288 | + } | |
16289 | + | |
16290 | + switch (type[0]) { | |
16291 | + case 'd': | |
16292 | + { | |
16293 | + unsigned long dr[8]; | |
16294 | + | |
16295 | + for(i=0; i<8; i++) { | |
16296 | + if ((i == 4) || (i == 5)) continue; | |
16297 | + dr[i] = kdba_getdr(i); | |
16298 | + } | |
16299 | + kdb_printf("dr0 = 0x%08lx dr1 = 0x%08lx dr2 = 0x%08lx dr3 = 0x%08lx\n", | |
16300 | + dr[0], dr[1], dr[2], dr[3]); | |
16301 | + kdb_printf("dr6 = 0x%08lx dr7 = 0x%08lx\n", | |
16302 | + dr[6], dr[7]); | |
16303 | + return 0; | |
16304 | + } | |
16305 | + case 'c': | |
16306 | + { | |
16307 | + unsigned long cr[5]; | |
16308 | + | |
16309 | + for (i=0; i<5; i++) { | |
16310 | + cr[i] = kdb_getcr(i); | |
16311 | + } | |
16312 | + kdb_printf("cr0 = 0x%08lx cr1 = 0x%08lx cr2 = 0x%08lx cr3 = 0x%08lx\ncr4 = 0x%08lx\n", | |
16313 | + cr[0], cr[1], cr[2], cr[3], cr[4]); | |
16314 | + return 0; | |
16315 | + } | |
16316 | + case 'r': | |
16317 | + break; | |
16318 | + default: | |
16319 | + return KDB_BADREG; | |
16320 | + } | |
16321 | + | |
16322 | + /* NOTREACHED */ | |
16323 | + return 0; | |
16324 | +} | |
16325 | +EXPORT_SYMBOL(kdba_dumpregs); | |
16326 | + | |
16327 | +kdb_machreg_t | |
16328 | +kdba_getpc(struct pt_regs *regs) | |
16329 | +{ | |
16330 | + return regs->ip; | |
16331 | +} | |
16332 | + | |
16333 | +int | |
16334 | +kdba_setpc(struct pt_regs *regs, kdb_machreg_t newpc) | |
16335 | +{ | |
16336 | + if (KDB_NULL_REGS(regs)) | |
16337 | + return KDB_BADREG; | |
16338 | + regs->ip = newpc; | |
16339 | + KDB_STATE_SET(IP_ADJUSTED); | |
16340 | + return 0; | |
16341 | +} | |
16342 | + | |
16343 | +/* | |
16344 | + * kdba_main_loop | |
16345 | + * | |
16346 | + * Do any architecture specific set up before entering the main kdb loop. | |
16347 | + * The primary function of this routine is to make all processes look the | |
16348 | + * same to kdb, kdb must be able to list a process without worrying if the | |
16349 | + * process is running or blocked, so make all process look as though they | |
16350 | + * are blocked. | |
16351 | + * | |
16352 | + * Inputs: | |
16353 | + * reason The reason KDB was invoked | |
16354 | + * error The hardware-defined error code | |
16355 | + * error2 kdb's current reason code. Initially error but can change | |
16356 | + * acording to kdb state. | |
16357 | + * db_result Result from break or debug point. | |
16358 | + * ef The exception frame at time of fault/breakpoint. If reason | |
16359 | + * is SILENT or CPU_UP then regs is NULL, otherwise it should | |
16360 | + * always be valid. | |
16361 | + * Returns: | |
16362 | + * 0 KDB was invoked for an event which it wasn't responsible | |
16363 | + * 1 KDB handled the event for which it was invoked. | |
16364 | + * Outputs: | |
16365 | + * Sets ip and sp in current->thread. | |
16366 | + * Locking: | |
16367 | + * None. | |
16368 | + * Remarks: | |
16369 | + * none. | |
16370 | + */ | |
16371 | + | |
16372 | +int | |
16373 | +kdba_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error, | |
16374 | + kdb_dbtrap_t db_result, struct pt_regs *regs) | |
16375 | +{ | |
16376 | + int ret; | |
16377 | + | |
16378 | + if (regs) | |
16379 | + kdba_getregcontents("sp", regs, &(current->thread.sp)); | |
16380 | + ret = kdb_save_running(regs, reason, reason2, error, db_result); | |
16381 | + kdb_unsave_running(regs); | |
16382 | + return ret; | |
16383 | +} | |
16384 | + | |
16385 | +void | |
16386 | +kdba_disableint(kdb_intstate_t *state) | |
16387 | +{ | |
16388 | + unsigned long *fp = (unsigned long *)state; | |
16389 | + unsigned long flags; | |
16390 | + | |
16391 | + local_irq_save(flags); | |
16392 | + *fp = flags; | |
16393 | +} | |
16394 | + | |
16395 | +void | |
16396 | +kdba_restoreint(kdb_intstate_t *state) | |
16397 | +{ | |
16398 | + unsigned long flags = *(unsigned long *)state; | |
16399 | + local_irq_restore(flags); | |
16400 | +} | |
16401 | + | |
16402 | +void | |
16403 | +kdba_setsinglestep(struct pt_regs *regs) | |
16404 | +{ | |
16405 | + if (KDB_NULL_REGS(regs)) | |
16406 | + return; | |
16407 | + if (regs->flags & X86_EFLAGS_IF) | |
16408 | + KDB_STATE_SET(A_IF); | |
16409 | + else | |
16410 | + KDB_STATE_CLEAR(A_IF); | |
16411 | + regs->flags = (regs->flags | X86_EFLAGS_TF) & ~X86_EFLAGS_IF; | |
16412 | +} | |
16413 | + | |
16414 | +void | |
16415 | +kdba_clearsinglestep(struct pt_regs *regs) | |
16416 | +{ | |
16417 | + if (KDB_NULL_REGS(regs)) | |
16418 | + return; | |
16419 | + if (KDB_STATE(A_IF)) | |
16420 | + regs->flags |= X86_EFLAGS_IF; | |
16421 | + else | |
16422 | + regs->flags &= ~X86_EFLAGS_IF; | |
16423 | +} | |
16424 | + | |
16425 | +int asmlinkage | |
16426 | +kdba_setjmp(kdb_jmp_buf *jb) | |
16427 | +{ | |
16428 | +#ifdef CONFIG_FRAME_POINTER | |
16429 | + __asm__ __volatile__ | |
16430 | + ("movq %%rbx, (0*8)(%%rdi);" | |
16431 | + "movq %%rcx, (1*8)(%%rdi);" | |
16432 | + "movq %%r12, (2*8)(%%rdi);" | |
16433 | + "movq %%r13, (3*8)(%%rdi);" | |
16434 | + "movq %%r14, (4*8)(%%rdi);" | |
16435 | + "movq %%r15, (5*8)(%%rdi);" | |
16436 | + "leaq 16(%%rsp), %%rdx;" | |
16437 | + "movq %%rdx, (6*8)(%%rdi);" | |
16438 | + "movq %%rax, (7*8)(%%rdi)" | |
16439 | + : | |
16440 | + : "a" (__builtin_return_address(0)), | |
16441 | + "c" (__builtin_frame_address(1)) | |
16442 | + ); | |
16443 | +#else /* !CONFIG_FRAME_POINTER */ | |
16444 | + __asm__ __volatile__ | |
16445 | + ("movq %%rbx, (0*8)(%%rdi);" | |
16446 | + "movq %%rbp, (1*8)(%%rdi);" | |
16447 | + "movq %%r12, (2*8)(%%rdi);" | |
16448 | + "movq %%r13, (3*8)(%%rdi);" | |
16449 | + "movq %%r14, (4*8)(%%rdi);" | |
16450 | + "movq %%r15, (5*8)(%%rdi);" | |
16451 | + "leaq 8(%%rsp), %%rdx;" | |
16452 | + "movq %%rdx, (6*8)(%%rdi);" | |
16453 | + "movq %%rax, (7*8)(%%rdi)" | |
16454 | + : | |
16455 | + : "a" (__builtin_return_address(0)) | |
16456 | + ); | |
16457 | +#endif /* CONFIG_FRAME_POINTER */ | |
16458 | + return 0; | |
16459 | +} | |
16460 | + | |
16461 | +void asmlinkage | |
16462 | +kdba_longjmp(kdb_jmp_buf *jb, int reason) | |
16463 | +{ | |
16464 | + __asm__("movq (0*8)(%rdi),%rbx;" | |
16465 | + "movq (1*8)(%rdi),%rbp;" | |
16466 | + "movq (2*8)(%rdi),%r12;" | |
16467 | + "movq (3*8)(%rdi),%r13;" | |
16468 | + "movq (4*8)(%rdi),%r14;" | |
16469 | + "movq (5*8)(%rdi),%r15;" | |
16470 | + "movq (7*8)(%rdi),%rdx;" | |
16471 | + "movq (6*8)(%rdi),%rsp;" | |
16472 | + "mov %rsi, %rax;" | |
16473 | + "jmpq *%rdx"); | |
16474 | +} | |
16475 | + | |
16476 | +/* | |
16477 | + * kdba_pt_regs | |
16478 | + * | |
16479 | + * Format a struct pt_regs | |
16480 | + * | |
16481 | + * Inputs: | |
16482 | + * argc argument count | |
16483 | + * argv argument vector | |
16484 | + * Outputs: | |
16485 | + * None. | |
16486 | + * Returns: | |
16487 | + * zero for success, a kdb diagnostic if error | |
16488 | + * Locking: | |
16489 | + * none. | |
16490 | + * Remarks: | |
16491 | + * If no address is supplied, it uses the current irq pt_regs. | |
16492 | + */ | |
16493 | + | |
16494 | +static int | |
16495 | +kdba_pt_regs(int argc, const char **argv) | |
16496 | +{ | |
16497 | + int diag; | |
16498 | + kdb_machreg_t addr; | |
16499 | + long offset = 0; | |
16500 | + int nextarg; | |
16501 | + struct pt_regs *p; | |
16502 | + static const char *fmt = " %-11.11s 0x%lx\n"; | |
16503 | + static int first_time = 1; | |
16504 | + | |
16505 | + if (argc == 0) { | |
16506 | + addr = (kdb_machreg_t) get_irq_regs(); | |
16507 | + } else if (argc == 1) { | |
16508 | + nextarg = 1; | |
16509 | + diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL); | |
16510 | + if (diag) | |
16511 | + return diag; | |
16512 | + } else { | |
16513 | + return KDB_ARGCOUNT; | |
16514 | + } | |
16515 | + | |
16516 | + p = (struct pt_regs *) addr; | |
16517 | + if (first_time) { | |
16518 | + first_time = 0; | |
16519 | + kdb_printf("\n+++ Warning: x86_64 pt_regs are not always " | |
16520 | + "completely defined, r15-bx may be invalid\n\n"); | |
16521 | + } | |
16522 | + kdb_printf("struct pt_regs 0x%p-0x%p\n", p, (unsigned char *)p + sizeof(*p) - 1); | |
16523 | + kdb_print_nameval("r15", p->r15); | |
16524 | + kdb_print_nameval("r14", p->r14); | |
16525 | + kdb_print_nameval("r13", p->r13); | |
16526 | + kdb_print_nameval("r12", p->r12); | |
16527 | + kdb_print_nameval("bp", p->bp); | |
16528 | + kdb_print_nameval("bx", p->bx); | |
16529 | + kdb_print_nameval("r11", p->r11); | |
16530 | + kdb_print_nameval("r10", p->r10); | |
16531 | + kdb_print_nameval("r9", p->r9); | |
16532 | + kdb_print_nameval("r8", p->r8); | |
16533 | + kdb_print_nameval("ax", p->ax); | |
16534 | + kdb_print_nameval("cx", p->cx); | |
16535 | + kdb_print_nameval("dx", p->dx); | |
16536 | + kdb_print_nameval("si", p->si); | |
16537 | + kdb_print_nameval("di", p->di); | |
16538 | + kdb_print_nameval("orig_ax", p->orig_ax); | |
16539 | + kdb_print_nameval("ip", p->ip); | |
16540 | + kdb_printf(fmt, "cs", p->cs); | |
16541 | + kdb_printf(fmt, "flags", p->flags); | |
16542 | + kdb_printf(fmt, "sp", p->sp); | |
16543 | + kdb_printf(fmt, "ss", p->ss); | |
16544 | + return 0; | |
16545 | +} | |
16546 | + | |
16547 | +/* | |
16548 | + * kdba_cpu_pda | |
16549 | + * | |
16550 | + * Format a struct cpu_pda | |
16551 | + * | |
16552 | + * Inputs: | |
16553 | + * argc argument count | |
16554 | + * argv argument vector | |
16555 | + * Outputs: | |
16556 | + * None. | |
16557 | + * Returns: | |
16558 | + * zero for success, a kdb diagnostic if error | |
16559 | + * Locking: | |
16560 | + * none. | |
16561 | + * Remarks: | |
16562 | + * If no cpu is supplied, it prints the current cpu. If the cpu is '*' | |
16563 | + * then it prints all cpus. | |
16564 | + */ | |
16565 | + | |
16566 | +static int | |
16567 | +kdba_cpu_pda(int argc, const char **argv) | |
16568 | +{ | |
16569 | + int diag, nextarg, all_cpus = 0; | |
16570 | + long offset = 0; | |
16571 | + unsigned long cpu; | |
16572 | + struct x8664_pda *c; | |
16573 | + static const char *fmtl = " %-17.17s 0x%lx\n"; | |
16574 | + static const char *fmtd = " %-17.17s %d\n"; | |
16575 | + static const char *fmtp = " %-17.17s 0x%p\n"; | |
16576 | + | |
16577 | + if (argc == 0) { | |
16578 | + cpu = smp_processor_id(); | |
16579 | + } else if (argc == 1) { | |
16580 | + if (strcmp(argv[1], "*") == 0) { | |
16581 | + all_cpus = 1; | |
16582 | + cpu = 0; | |
16583 | + } else { | |
16584 | + nextarg = 1; | |
16585 | + diag = kdbgetaddrarg(argc, argv, &nextarg, &cpu, &offset, NULL); | |
16586 | + if (diag) | |
16587 | + return diag; | |
16588 | + } | |
16589 | + } else { | |
16590 | + return KDB_ARGCOUNT; | |
16591 | + } | |
16592 | + | |
16593 | + for (; cpu < NR_CPUS; ++cpu) { | |
16594 | + if (cpu_online(cpu)) { | |
16595 | + c = cpu_pda(cpu); | |
16596 | + kdb_printf("struct cpu_pda 0x%p-0x%p\n", c, (unsigned char *)c + sizeof(*c) - 1); | |
16597 | + kdb_printf(fmtp, "pcurrent", c->pcurrent); | |
16598 | + kdb_printf(fmtl, "data_offset", c->data_offset); | |
16599 | + kdb_printf(fmtl, "kernelstack", c->kernelstack); | |
16600 | + kdb_printf(fmtl, "oldrsp", c->oldrsp); | |
16601 | + kdb_printf(fmtd, "irqcount", c->irqcount); | |
16602 | + kdb_printf(fmtd, "cpunumber", c->cpunumber); | |
16603 | + kdb_printf(fmtp, "irqstackptr", c->irqstackptr); | |
16604 | + kdb_printf(fmtp, "nodenumber", cpu_to_node(cpu)); | |
16605 | + kdb_printf(fmtd, "__softirq_pending", c->__softirq_pending); | |
16606 | + kdb_printf(fmtd, "__nmi_count", c->__nmi_count); | |
16607 | + kdb_printf(fmtd, "mmu_state", c->mmu_state); | |
16608 | + kdb_printf(fmtp, "active_mm", c->active_mm); | |
16609 | + kdb_printf(fmtd, "apic_timer_irqs", c->apic_timer_irqs); | |
16610 | + } | |
16611 | + if (!all_cpus) | |
16612 | + break; | |
16613 | + } | |
16614 | + return 0; | |
16615 | +} | |
16616 | + | |
16617 | +/* | |
16618 | + * kdba_entry | |
16619 | + * | |
16620 | + * This is the interface routine between | |
16621 | + * the notifier die_chain and kdb | |
16622 | + */ | |
16623 | +static int kdba_entry( struct notifier_block *b, unsigned long val, void *v) | |
16624 | +{ | |
16625 | + struct die_args *args = v; | |
16626 | + int err, trap, ret = 0; | |
16627 | + struct pt_regs *regs; | |
16628 | + | |
16629 | + regs = args->regs; | |
16630 | + err = args->err; | |
16631 | + trap = args->trapnr; | |
16632 | + switch (val){ | |
16633 | +#ifdef CONFIG_SMP | |
16634 | + case DIE_NMI_IPI: | |
16635 | + ret = kdb_ipi(regs, NULL); | |
16636 | + break; | |
16637 | +#endif /* CONFIG_SMP */ | |
16638 | + case DIE_OOPS: | |
16639 | + ret = kdb(KDB_REASON_OOPS, err, regs); | |
16640 | + break; | |
16641 | + case DIE_CALL: | |
16642 | + ret = kdb(KDB_REASON_ENTER, err, regs); | |
16643 | + break; | |
16644 | + case DIE_DEBUG: | |
16645 | + ret = kdb(KDB_REASON_DEBUG, err, regs); | |
16646 | + break; | |
16647 | + case DIE_NMIWATCHDOG: | |
16648 | + ret = kdb(KDB_REASON_NMI, err, regs); | |
16649 | + break; | |
16650 | + case DIE_INT3: | |
16651 | + ret = kdb(KDB_REASON_BREAK, err, regs); | |
16652 | + // falls thru | |
16653 | + default: | |
16654 | + break; | |
16655 | + } | |
16656 | + return (ret ? NOTIFY_STOP : NOTIFY_DONE); | |
16657 | +} | |
16658 | + | |
16659 | +/* | |
16660 | + * notifier block for kdb entry | |
16661 | + */ | |
16662 | +static struct notifier_block kdba_notifier = { | |
16663 | + .notifier_call = kdba_entry | |
16664 | +}; | |
16665 | + | |
16666 | +asmlinkage int kdb_call(void); | |
16667 | + | |
16668 | +/* Executed once on each cpu at startup. */ | |
16669 | +void | |
16670 | +kdba_cpu_up(void) | |
16671 | +{ | |
16672 | +} | |
16673 | + | |
16674 | +static int __init | |
16675 | +kdba_arch_init(void) | |
16676 | +{ | |
16677 | +#ifdef CONFIG_SMP | |
16678 | + set_intr_gate(KDB_VECTOR, kdb_interrupt); | |
16679 | +#endif | |
16680 | + set_intr_gate(KDBENTER_VECTOR, kdb_call); | |
16681 | + return 0; | |
16682 | +} | |
16683 | + | |
16684 | +arch_initcall(kdba_arch_init); | |
16685 | + | |
16686 | +/* | |
16687 | + * kdba_init | |
16688 | + * | |
16689 | + * Architecture specific initialization. | |
16690 | + * | |
16691 | + * Parameters: | |
16692 | + * None. | |
16693 | + * Returns: | |
16694 | + * None. | |
16695 | + * Locking: | |
16696 | + * None. | |
16697 | + * Remarks: | |
16698 | + * None. | |
16699 | + */ | |
16700 | + | |
16701 | +void __init | |
16702 | +kdba_init(void) | |
16703 | +{ | |
16704 | + kdba_arch_init(); /* Need to register KDBENTER_VECTOR early */ | |
16705 | + kdb_register("pt_regs", kdba_pt_regs, "address", "Format struct pt_regs", 0); | |
16706 | + kdb_register("cpu_pda", kdba_cpu_pda, "<cpu>", "Format struct cpu_pda", 0); | |
16707 | + register_die_notifier(&kdba_notifier); | |
16708 | + return; | |
16709 | +} | |
16710 | + | |
16711 | +/* | |
16712 | + * kdba_adjust_ip | |
16713 | + * | |
16714 | + * Architecture specific adjustment of instruction pointer before leaving | |
16715 | + * kdb. | |
16716 | + * | |
16717 | + * Parameters: | |
16718 | + * reason The reason KDB was invoked | |
16719 | + * error The hardware-defined error code | |
16720 | + * ef The exception frame at time of fault/breakpoint. If reason | |
16721 | + * is SILENT or CPU_UP then regs is NULL, otherwise it should | |
16722 | + * always be valid. | |
16723 | + * Returns: | |
16724 | + * None. | |
16725 | + * Locking: | |
16726 | + * None. | |
16727 | + * Remarks: | |
16728 | + * noop on ix86. | |
16729 | + */ | |
16730 | + | |
16731 | +void | |
16732 | +kdba_adjust_ip(kdb_reason_t reason, int error, struct pt_regs *ef) | |
16733 | +{ | |
16734 | + return; | |
16735 | +} | |
16736 | + | |
16737 | +void | |
16738 | +kdba_set_current_task(const struct task_struct *p) | |
16739 | +{ | |
16740 | + kdb_current_task = p; | |
16741 | + if (kdb_task_has_cpu(p)) { | |
16742 | + struct kdb_running_process *krp = kdb_running_process + kdb_process_cpu(p); | |
16743 | + kdb_current_regs = krp->regs; | |
16744 | + return; | |
16745 | + } | |
16746 | + kdb_current_regs = NULL; | |
16747 | +} | |
16748 | + | |
16749 | +#ifdef CONFIG_SMP | |
16750 | + | |
16751 | +#include <mach_ipi.h> | |
16752 | + | |
16753 | +/* When first entering KDB, try a normal IPI. That reduces backtrace problems | |
16754 | + * on the other cpus. | |
16755 | + */ | |
16756 | +void | |
16757 | +smp_kdb_stop(void) | |
16758 | +{ | |
16759 | + if (!KDB_FLAG(NOIPI)) | |
16760 | + send_IPI_allbutself(KDB_VECTOR); | |
16761 | +} | |
16762 | + | |
16763 | +/* The normal KDB IPI handler */ | |
16764 | +extern asmlinkage void smp_kdb_interrupt(struct pt_regs *regs); /* for sparse */ | |
16765 | +asmlinkage void | |
16766 | +smp_kdb_interrupt(struct pt_regs *regs) | |
16767 | +{ | |
16768 | + struct pt_regs *old_regs = set_irq_regs(regs); | |
16769 | + ack_APIC_irq(); | |
16770 | + irq_enter(); | |
16771 | + kdb_ipi(regs, NULL); | |
16772 | + irq_exit(); | |
16773 | + set_irq_regs(old_regs); | |
16774 | +} | |
16775 | + | |
16776 | +/* Invoked once from kdb_wait_for_cpus when waiting for cpus. For those cpus | |
16777 | + * that have not responded to the normal KDB interrupt yet, hit them with an | |
16778 | + * NMI event. | |
16779 | + */ | |
16780 | +void | |
16781 | +kdba_wait_for_cpus(void) | |
16782 | +{ | |
16783 | + int c; | |
16784 | + if (KDB_FLAG(CATASTROPHIC)) | |
16785 | + return; | |
16786 | + kdb_printf(" Sending NMI to non-responding cpus: "); | |
16787 | + for_each_online_cpu(c) { | |
16788 | + if (kdb_running_process[c].seqno < kdb_seqno - 1) { | |
16789 | + kdb_printf(" %d", c); | |
16790 | + send_IPI_mask(&cpumask_of_cpu(c), NMI_VECTOR); | |
16791 | + } | |
16792 | + } | |
16793 | + kdb_printf(".\n"); | |
16794 | +} | |
16795 | + | |
16796 | +#endif /* CONFIG_SMP */ | |
16797 | --- /dev/null | |
16798 | +++ b/arch/x86/kdb/kdba_support.c | |
16799 | @@ -0,0 +1,59 @@ | |
16800 | +/* | |
16801 | + * Kernel Debugger Architecture Independent Support Functions | |
16802 | + * | |
16803 | + * This file is subject to the terms and conditions of the GNU General Public | |
16804 | + * License. See the file "COPYING" in the main directory of this archive | |
16805 | + * for more details. | |
16806 | + * | |
16807 | + * Copyright (c) 1999-2008 Silicon Graphics, Inc. All Rights Reserved. | |
16808 | + */ | |
16809 | + | |
16810 | +#include <linux/string.h> | |
16811 | +#include <linux/stddef.h> | |
16812 | +#include <linux/kernel.h> | |
16813 | +#include <linux/init.h> | |
16814 | +#include <linux/ptrace.h> | |
16815 | +#include <linux/mm.h> | |
16816 | +#include <linux/sched.h> | |
16817 | +#include <linux/hardirq.h> | |
16818 | +#include <linux/kdb.h> | |
16819 | +#include <linux/kdbprivate.h> | |
16820 | +#include <linux/interrupt.h> | |
16821 | +#include <linux/module.h> | |
16822 | +#include <linux/kdebug.h> | |
16823 | +#include <asm/processor.h> | |
16824 | +#include <asm/msr.h> | |
16825 | +#include <asm/uaccess.h> | |
16826 | +#include <asm/hw_irq.h> | |
16827 | +#include <asm/desc.h> | |
16828 | + | |
16829 | +#ifdef CONFIG_KDB_KDUMP | |
16830 | +void kdba_kdump_prepare(struct pt_regs *regs) | |
16831 | +{ | |
16832 | + int i; | |
16833 | + struct pt_regs r; | |
16834 | + if (regs == NULL) | |
16835 | + regs = &r; | |
16836 | + | |
16837 | + machine_crash_shutdown_begin(); | |
16838 | + | |
16839 | + for (i = 1; i < NR_CPUS; ++i) { | |
16840 | + if (!cpu_online(i)) | |
16841 | + continue; | |
16842 | + | |
16843 | + KDB_STATE_SET_CPU(KEXEC, i); | |
16844 | + } | |
16845 | + | |
16846 | + machine_crash_shutdown_end(regs); | |
16847 | +} | |
16848 | + | |
16849 | +extern void halt_current_cpu(struct pt_regs *); | |
16850 | + | |
16851 | +void kdba_kdump_shutdown_slave(struct pt_regs *regs) | |
16852 | +{ | |
16853 | +#ifndef CONFIG_XEN | |
16854 | + halt_current_cpu(regs); | |
16855 | +#endif /* CONFIG_XEN */ | |
16856 | +} | |
16857 | + | |
16858 | +#endif | |
16859 | --- /dev/null | |
16860 | +++ b/arch/x86/kdb/kdb_cmds_32 | |
16861 | @@ -0,0 +1,17 @@ | |
16862 | +# Standard architecture specific commands for kdb. | |
16863 | +# These commands are appended to those in kdb/kdb_cmds, see that file for | |
16864 | +# restrictions. | |
16865 | + | |
16866 | +# Standard debugging information for first level support, invoked from archkdb* | |
16867 | +# commands that are defined in kdb/kdb_cmds. | |
16868 | + | |
16869 | +defcmd archkdbcommon "" "Common arch debugging" | |
16870 | + set LINES 2000000 | |
16871 | + set BTAPROMPT 0 | |
16872 | + -summary | |
16873 | + -id %eip-24 | |
16874 | + -cpu | |
16875 | + -ps | |
16876 | + -dmesg 600 | |
16877 | + -bt | |
16878 | +endefcmd | |
16879 | --- /dev/null | |
16880 | +++ b/arch/x86/kdb/kdb_cmds_64 | |
16881 | @@ -0,0 +1,18 @@ | |
16882 | +# Standard architecture specific commands for kdb. | |
16883 | +# These commands are appended to those in kdb/kdb_cmds, see that file for | |
16884 | +# restrictions. | |
16885 | + | |
16886 | +# Standard debugging information for first level support, invoked from archkdb* | |
16887 | +# commands that are defined in kdb/kdb_cmds. | |
16888 | + | |
16889 | +defcmd archkdbcommon "" "Common arch debugging" | |
16890 | + set LINES 2000000 | |
16891 | + set BTAPROMPT 0 | |
16892 | + -summary | |
16893 | + -id %rip-24 | |
16894 | + -cpu | |
16895 | + -ps | |
16896 | + -dmesg 600 | |
16897 | + -bt | |
16898 | + -cpu_pda * | |
16899 | +endefcmd | |
16900 | --- /dev/null | |
16901 | +++ b/arch/x86/kdb/Makefile | |
16902 | @@ -0,0 +1,5 @@ | |
16903 | +ifeq ($(CONFIG_X86_32),y) | |
16904 | +include ${srctree}/arch/x86/kdb/Makefile_32 | |
16905 | +else | |
16906 | +include ${srctree}/arch/x86/kdb/Makefile_64 | |
16907 | +endif | |
16908 | --- /dev/null | |
16909 | +++ b/arch/x86/kdb/Makefile_32 | |
16910 | @@ -0,0 +1,25 @@ | |
16911 | +# | |
16912 | +# This file is subject to the terms and conditions of the GNU General Public | |
16913 | +# License. See the file "COPYING" in the main directory of this archive | |
16914 | +# for more details. | |
16915 | +# | |
16916 | +# Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved. | |
16917 | +# | |
16918 | + | |
16919 | +obj-$(CONFIG_KDB) := kdba_bp_32.o kdbasupport_32.o i386-dis.o | |
16920 | + | |
16921 | +# The i386 and x86_64 backtrace commands are handled by common code. | |
16922 | +obj-y += kdba_bt.o kdba_io.o kdba_id.o kdba_support.o | |
16923 | +ifneq (,$(findstring -fno-optimize-sibling-calls,$(KBUILD_CFLAGS))) | |
16924 | + CFLAGS_kdba_bt.o += -DNO_SIBLINGS | |
16925 | +endif | |
16926 | +REGPARM := $(subst -mregparm=,,$(filter -mregparm=%,$(KBUILD_CFLAGS))) | |
16927 | +ifeq (,$(REGPARM)) | |
16928 | + REGPARM := 3 | |
16929 | +endif | |
16930 | + | |
16931 | +CFLAGS_kdba_bt.o += -DREGPARM=$(REGPARM) -DCCVERSION="$(CCVERSION)" | |
16932 | + | |
16933 | +override CFLAGS := $(CFLAGS:%-pg=% ) | |
16934 | + | |
16935 | +CFLAGS_kdba_io.o += -I $(TOPDIR)/arch/$(SRCARCH)/kdb | |
16936 | --- /dev/null | |
16937 | +++ b/arch/x86/kdb/Makefile_64 | |
16938 | @@ -0,0 +1,25 @@ | |
16939 | +# | |
16940 | +# This file is subject to the terms and conditions of the GNU General Public | |
16941 | +# License. See the file "COPYING" in the main directory of this archive | |
16942 | +# for more details. | |
16943 | +# | |
16944 | +# Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved. | |
16945 | +# | |
16946 | + | |
16947 | +obj-$(CONFIG_KDB) := kdba_bp_64.o kdbasupport_64.o x86_64-dis.o | |
16948 | + | |
16949 | +# The i386 and x86_64 backtrace commands are handled by common code. | |
16950 | +obj-y += kdba_bt.o kdba_io.o kdba_id.o kdba_support.o | |
16951 | +ifneq (,$(findstring -fno-optimize-sibling-calls,$(KBUILD_CFLAGS))) | |
16952 | + CFLAGS_kdba_bt.o += -DNO_SIBLINGS | |
16953 | +endif | |
16954 | +REGPARM := $(subst -mregparm=,,$(filter -mregparm=%,$(KBUILD_CFLAGS))) | |
16955 | +ifeq (,$(REGPARM)) | |
16956 | + REGPARM := 6 | |
16957 | +endif | |
16958 | + | |
16959 | +CFLAGS_kdba_bt.o += -DREGPARM=$(REGPARM) -DCCVERSION="$(CCVERSION)" | |
16960 | + | |
16961 | +override CFLAGS := $(CFLAGS:%-pg=% ) | |
16962 | + | |
16963 | +CFLAGS_kdba_io.o += -I $(TOPDIR)/arch/$(SRCARCH)/kdb | |
16964 | --- /dev/null | |
16965 | +++ b/arch/x86/kdb/pc_keyb.h | |
16966 | @@ -0,0 +1,137 @@ | |
16967 | +/* | |
16968 | + * include/linux/pc_keyb.h | |
16969 | + * | |
16970 | + * PC Keyboard And Keyboard Controller | |
16971 | + * | |
16972 | + * (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> | |
16973 | + */ | |
16974 | + | |
16975 | +/* | |
16976 | + * Configuration Switches | |
16977 | + */ | |
16978 | + | |
16979 | +#undef KBD_REPORT_ERR /* Report keyboard errors */ | |
16980 | +#define KBD_REPORT_UNKN /* Report unknown scan codes */ | |
16981 | +#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */ | |
16982 | +#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */ | |
16983 | +#undef INITIALIZE_MOUSE /* Define if your PS/2 mouse needs initialization. */ | |
16984 | + | |
16985 | + | |
16986 | + | |
16987 | +#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */ | |
16988 | +#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */ | |
16989 | +#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */ | |
16990 | + | |
16991 | +/* | |
16992 | + * Internal variables of the driver | |
16993 | + */ | |
16994 | + | |
16995 | +extern unsigned char pckbd_read_mask; | |
16996 | +extern unsigned char aux_device_present; | |
16997 | + | |
16998 | +/* | |
16999 | + * Keyboard Controller Registers on normal PCs. | |
17000 | + */ | |
17001 | + | |
17002 | +#define KBD_STATUS_REG 0x64 /* Status register (R) */ | |
17003 | +#define KBD_CNTL_REG 0x64 /* Controller command register (W) */ | |
17004 | +#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */ | |
17005 | + | |
17006 | +/* | |
17007 | + * Keyboard Controller Commands | |
17008 | + */ | |
17009 | + | |
17010 | +#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */ | |
17011 | +#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */ | |
17012 | +#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */ | |
17013 | +#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */ | |
17014 | +#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */ | |
17015 | +#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */ | |
17016 | +#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */ | |
17017 | +#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */ | |
17018 | +#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */ | |
17019 | +#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */ | |
17020 | +#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if | |
17021 | + initiated by the auxiliary device */ | |
17022 | +#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */ | |
17023 | + | |
17024 | +/* | |
17025 | + * Keyboard Commands | |
17026 | + */ | |
17027 | + | |
17028 | +#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */ | |
17029 | +#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */ | |
17030 | +#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */ | |
17031 | +#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */ | |
17032 | +#define KBD_CMD_RESET 0xFF /* Reset */ | |
17033 | + | |
17034 | +/* | |
17035 | + * Keyboard Replies | |
17036 | + */ | |
17037 | + | |
17038 | +#define KBD_REPLY_POR 0xAA /* Power on reset */ | |
17039 | +#define KBD_REPLY_ACK 0xFA /* Command ACK */ | |
17040 | +#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */ | |
17041 | + | |
17042 | +/* | |
17043 | + * Status Register Bits | |
17044 | + */ | |
17045 | + | |
17046 | +#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */ | |
17047 | +#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */ | |
17048 | +#define KBD_STAT_SELFTEST 0x04 /* Self test successful */ | |
17049 | +#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */ | |
17050 | +#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */ | |
17051 | +#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */ | |
17052 | +#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */ | |
17053 | +#define KBD_STAT_PERR 0x80 /* Parity error */ | |
17054 | + | |
17055 | +#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF) | |
17056 | + | |
17057 | +/* | |
17058 | + * Controller Mode Register Bits | |
17059 | + */ | |
17060 | + | |
17061 | +#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */ | |
17062 | +#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */ | |
17063 | +#define KBD_MODE_SYS 0x04 /* The system flag (?) */ | |
17064 | +#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */ | |
17065 | +#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */ | |
17066 | +#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */ | |
17067 | +#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */ | |
17068 | +#define KBD_MODE_RFU 0x80 | |
17069 | + | |
17070 | +/* | |
17071 | + * Mouse Commands | |
17072 | + */ | |
17073 | + | |
17074 | +#define AUX_SET_RES 0xE8 /* Set resolution */ | |
17075 | +#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */ | |
17076 | +#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */ | |
17077 | +#define AUX_GET_SCALE 0xE9 /* Get scaling factor */ | |
17078 | +#define AUX_SET_STREAM 0xEA /* Set stream mode */ | |
17079 | +#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */ | |
17080 | +#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */ | |
17081 | +#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */ | |
17082 | +#define AUX_RESET 0xFF /* Reset aux device */ | |
17083 | +#define AUX_ACK 0xFA /* Command byte ACK. */ | |
17084 | + | |
17085 | +#define AUX_BUF_SIZE 2048 /* This might be better divisible by | |
17086 | + three to make overruns stay in sync | |
17087 | + but then the read function would need | |
17088 | + a lock etc - ick */ | |
17089 | + | |
17090 | +struct aux_queue { | |
17091 | + unsigned long head; | |
17092 | + unsigned long tail; | |
17093 | + wait_queue_head_t proc_list; | |
17094 | + struct fasync_struct *fasync; | |
17095 | + unsigned char buf[AUX_BUF_SIZE]; | |
17096 | +}; | |
17097 | + | |
17098 | + | |
17099 | +/* How to access the keyboard macros on this platform. */ | |
17100 | +#define kbd_read_input() inb(KBD_DATA_REG) | |
17101 | +#define kbd_read_status() inb(KBD_STATUS_REG) | |
17102 | +#define kbd_write_output(val) outb(val, KBD_DATA_REG) | |
17103 | +#define kbd_write_command(val) outb(val, KBD_CNTL_REG) | |
17104 | --- /dev/null | |
17105 | +++ b/arch/x86/kdb/x86_64-dis.c | |
17106 | @@ -0,0 +1,4686 @@ | |
17107 | +/* Print i386 instructions for GDB, the GNU debugger. | |
17108 | + Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, | |
17109 | + 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. | |
17110 | + | |
17111 | + This file is part of GDB. | |
17112 | + | |
17113 | + This program is free software; you can redistribute it and/or modify | |
17114 | + it under the terms of the GNU General Public License as published by | |
17115 | + the Free Software Foundation; either version 2 of the License, or | |
17116 | + (at your option) any later version. | |
17117 | + | |
17118 | + This program is distributed in the hope that it will be useful, | |
17119 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17120 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17121 | + GNU General Public License for more details. | |
17122 | + | |
17123 | + You should have received a copy of the GNU General Public License | |
17124 | + along with this program; if not, write to the Free Software | |
17125 | + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ | |
17126 | + | |
17127 | +/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use. | |
17128 | + * Run through col -b to remove trailing whitespace and various #ifdef/ifndef | |
17129 | + * __KERNEL__ added. | |
17130 | + * Keith Owens <kaos@sgi.com> 15 May 2006 | |
17131 | + */ | |
17132 | + | |
17133 | +/* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu) | |
17134 | + July 1988 | |
17135 | + modified by John Hassey (hassey@dg-rtp.dg.com) | |
17136 | + x86-64 support added by Jan Hubicka (jh@suse.cz) | |
17137 | + VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */ | |
17138 | + | |
17139 | +/* The main tables describing the instructions is essentially a copy | |
17140 | + of the "Opcode Map" chapter (Appendix A) of the Intel 80386 | |
17141 | + Programmers Manual. Usually, there is a capital letter, followed | |
17142 | + by a small letter. The capital letter tell the addressing mode, | |
17143 | + and the small letter tells about the operand size. Refer to | |
17144 | + the Intel manual for details. */ | |
17145 | + | |
17146 | +#ifdef __KERNEL__ | |
17147 | +#include <linux/kernel.h> | |
17148 | +#include <linux/string.h> | |
17149 | +#include <linux/dis-asm.h> | |
17150 | +#include <linux/kdb.h> | |
17151 | +#define abort() BUG() | |
17152 | +#else /* __KERNEL__ */ | |
17153 | +#include "dis-asm.h" | |
17154 | +#include "sysdep.h" | |
17155 | +#include "opintl.h" | |
17156 | +#endif /* __KERNEL__ */ | |
17157 | + | |
17158 | +#define MAXLEN 20 | |
17159 | + | |
17160 | +#ifndef __KERNEL__ | |
17161 | +#include <setjmp.h> | |
17162 | +#endif /* __KERNEL__ */ | |
17163 | + | |
17164 | +#ifndef UNIXWARE_COMPAT | |
17165 | +/* Set non-zero for broken, compatible instructions. Set to zero for | |
17166 | + non-broken opcodes. */ | |
17167 | +#define UNIXWARE_COMPAT 1 | |
17168 | +#endif | |
17169 | + | |
17170 | +static int fetch_data (struct disassemble_info *, bfd_byte *); | |
17171 | +static void ckprefix (void); | |
17172 | +static const char *prefix_name (int, int); | |
17173 | +static int print_insn (bfd_vma, disassemble_info *); | |
17174 | +static void dofloat (int); | |
17175 | +static void OP_ST (int, int); | |
17176 | +static void OP_STi (int, int); | |
17177 | +static int putop (const char *, int); | |
17178 | +static void oappend (const char *); | |
17179 | +static void append_seg (void); | |
17180 | +static void OP_indirE (int, int); | |
17181 | +static void print_operand_value (char *, int, bfd_vma); | |
17182 | +static void OP_E (int, int); | |
17183 | +static void OP_G (int, int); | |
17184 | +static bfd_vma get64 (void); | |
17185 | +static bfd_signed_vma get32 (void); | |
17186 | +static bfd_signed_vma get32s (void); | |
17187 | +static int get16 (void); | |
17188 | +static void set_op (bfd_vma, int); | |
17189 | +static void OP_REG (int, int); | |
17190 | +static void OP_IMREG (int, int); | |
17191 | +static void OP_I (int, int); | |
17192 | +static void OP_I64 (int, int); | |
17193 | +static void OP_sI (int, int); | |
17194 | +static void OP_J (int, int); | |
17195 | +static void OP_SEG (int, int); | |
17196 | +static void OP_DIR (int, int); | |
17197 | +static void OP_OFF (int, int); | |
17198 | +static void OP_OFF64 (int, int); | |
17199 | +static void ptr_reg (int, int); | |
17200 | +static void OP_ESreg (int, int); | |
17201 | +static void OP_DSreg (int, int); | |
17202 | +static void OP_C (int, int); | |
17203 | +static void OP_D (int, int); | |
17204 | +static void OP_T (int, int); | |
17205 | +static void OP_Rd (int, int); | |
17206 | +static void OP_MMX (int, int); | |
17207 | +static void OP_XMM (int, int); | |
17208 | +static void OP_EM (int, int); | |
17209 | +static void OP_EX (int, int); | |
17210 | +static void OP_MS (int, int); | |
17211 | +static void OP_XS (int, int); | |
17212 | +static void OP_M (int, int); | |
17213 | +static void OP_VMX (int, int); | |
17214 | +static void OP_0fae (int, int); | |
17215 | +static void OP_0f07 (int, int); | |
17216 | +static void NOP_Fixup (int, int); | |
17217 | +static void OP_3DNowSuffix (int, int); | |
17218 | +static void OP_SIMD_Suffix (int, int); | |
17219 | +static void SIMD_Fixup (int, int); | |
17220 | +static void PNI_Fixup (int, int); | |
17221 | +static void SVME_Fixup (int, int); | |
17222 | +static void INVLPG_Fixup (int, int); | |
17223 | +static void BadOp (void); | |
17224 | +static void SEG_Fixup (int, int); | |
17225 | +static void VMX_Fixup (int, int); | |
17226 | + | |
17227 | +struct dis_private { | |
17228 | + /* Points to first byte not fetched. */ | |
17229 | + bfd_byte *max_fetched; | |
17230 | + bfd_byte the_buffer[MAXLEN]; | |
17231 | + bfd_vma insn_start; | |
17232 | + int orig_sizeflag; | |
17233 | +#ifndef __KERNEL__ | |
17234 | + jmp_buf bailout; | |
17235 | +#endif /* __KERNEL__ */ | |
17236 | +}; | |
17237 | + | |
17238 | +/* The opcode for the fwait instruction, which we treat as a prefix | |
17239 | + when we can. */ | |
17240 | +#define FWAIT_OPCODE (0x9b) | |
17241 | + | |
17242 | +/* Set to 1 for 64bit mode disassembly. */ | |
17243 | +static int mode_64bit; | |
17244 | + | |
17245 | +/* Flags for the prefixes for the current instruction. See below. */ | |
17246 | +static int prefixes; | |
17247 | + | |
17248 | +/* REX prefix the current instruction. See below. */ | |
17249 | +static int rex; | |
17250 | +/* Bits of REX we've already used. */ | |
17251 | +static int rex_used; | |
17252 | +#define REX_MODE64 8 | |
17253 | +#define REX_EXTX 4 | |
17254 | +#define REX_EXTY 2 | |
17255 | +#define REX_EXTZ 1 | |
17256 | +/* Mark parts used in the REX prefix. When we are testing for | |
17257 | + empty prefix (for 8bit register REX extension), just mask it | |
17258 | + out. Otherwise test for REX bit is excuse for existence of REX | |
17259 | + only in case value is nonzero. */ | |
17260 | +#define USED_REX(value) \ | |
17261 | + { \ | |
17262 | + if (value) \ | |
17263 | + rex_used |= (rex & value) ? (value) | 0x40 : 0; \ | |
17264 | + else \ | |
17265 | + rex_used |= 0x40; \ | |
17266 | + } | |
17267 | + | |
17268 | +/* Flags for prefixes which we somehow handled when printing the | |
17269 | + current instruction. */ | |
17270 | +static int used_prefixes; | |
17271 | + | |
17272 | +/* Flags stored in PREFIXES. */ | |
17273 | +#define PREFIX_REPZ 1 | |
17274 | +#define PREFIX_REPNZ 2 | |
17275 | +#define PREFIX_LOCK 4 | |
17276 | +#define PREFIX_CS 8 | |
17277 | +#define PREFIX_SS 0x10 | |
17278 | +#define PREFIX_DS 0x20 | |
17279 | +#define PREFIX_ES 0x40 | |
17280 | +#define PREFIX_FS 0x80 | |
17281 | +#define PREFIX_GS 0x100 | |
17282 | +#define PREFIX_DATA 0x200 | |
17283 | +#define PREFIX_ADDR 0x400 | |
17284 | +#define PREFIX_FWAIT 0x800 | |
17285 | + | |
17286 | +/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) | |
17287 | + to ADDR (exclusive) are valid. Returns 1 for success, longjmps | |
17288 | + on error. */ | |
17289 | +#define FETCH_DATA(info, addr) \ | |
17290 | + ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \ | |
17291 | + ? 1 : fetch_data ((info), (addr))) | |
17292 | + | |
17293 | +static int | |
17294 | +fetch_data (struct disassemble_info *info, bfd_byte *addr) | |
17295 | +{ | |
17296 | + int status; | |
17297 | + struct dis_private *priv = (struct dis_private *) info->private_data; | |
17298 | + bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer); | |
17299 | + | |
17300 | + status = (*info->read_memory_func) (start, | |
17301 | + priv->max_fetched, | |
17302 | + addr - priv->max_fetched, | |
17303 | + info); | |
17304 | + if (status != 0) | |
17305 | + { | |
17306 | + /* If we did manage to read at least one byte, then | |
17307 | + print_insn_i386 will do something sensible. Otherwise, print | |
17308 | + an error. We do that here because this is where we know | |
17309 | + STATUS. */ | |
17310 | + if (priv->max_fetched == priv->the_buffer) | |
17311 | + (*info->memory_error_func) (status, start, info); | |
17312 | +#ifndef __KERNEL__ | |
17313 | + longjmp (priv->bailout, 1); | |
17314 | +#else /* __KERNEL__ */ | |
17315 | + /* XXX - what to do? */ | |
17316 | + kdb_printf("Hmm. longjmp.\n"); | |
17317 | +#endif /* __KERNEL__ */ | |
17318 | + } | |
17319 | + else | |
17320 | + priv->max_fetched = addr; | |
17321 | + return 1; | |
17322 | +} | |
17323 | + | |
17324 | +#define XX NULL, 0 | |
17325 | + | |
17326 | +#define Eb OP_E, b_mode | |
17327 | +#define Ev OP_E, v_mode | |
17328 | +#define Ed OP_E, d_mode | |
17329 | +#define Eq OP_E, q_mode | |
17330 | +#define Edq OP_E, dq_mode | |
17331 | +#define Edqw OP_E, dqw_mode | |
17332 | +#define indirEv OP_indirE, branch_v_mode | |
17333 | +#define indirEp OP_indirE, f_mode | |
17334 | +#define Em OP_E, m_mode | |
17335 | +#define Ew OP_E, w_mode | |
17336 | +#define Ma OP_E, v_mode | |
17337 | +#define M OP_M, 0 /* lea, lgdt, etc. */ | |
17338 | +#define Mp OP_M, f_mode /* 32 or 48 bit memory operand for LDS, LES etc */ | |
17339 | +#define Gb OP_G, b_mode | |
17340 | +#define Gv OP_G, v_mode | |
17341 | +#define Gd OP_G, d_mode | |
17342 | +#define Gdq OP_G, dq_mode | |
17343 | +#define Gm OP_G, m_mode | |
17344 | +#define Gw OP_G, w_mode | |
17345 | +#define Rd OP_Rd, d_mode | |
17346 | +#define Rm OP_Rd, m_mode | |
17347 | +#define Ib OP_I, b_mode | |
17348 | +#define sIb OP_sI, b_mode /* sign extened byte */ | |
17349 | +#define Iv OP_I, v_mode | |
17350 | +#define Iq OP_I, q_mode | |
17351 | +#define Iv64 OP_I64, v_mode | |
17352 | +#define Iw OP_I, w_mode | |
17353 | +#define I1 OP_I, const_1_mode | |
17354 | +#define Jb OP_J, b_mode | |
17355 | +#define Jv OP_J, v_mode | |
17356 | +#define Cm OP_C, m_mode | |
17357 | +#define Dm OP_D, m_mode | |
17358 | +#define Td OP_T, d_mode | |
17359 | +#define Sv SEG_Fixup, v_mode | |
17360 | + | |
17361 | +#define RMeAX OP_REG, eAX_reg | |
17362 | +#define RMeBX OP_REG, eBX_reg | |
17363 | +#define RMeCX OP_REG, eCX_reg | |
17364 | +#define RMeDX OP_REG, eDX_reg | |
17365 | +#define RMeSP OP_REG, eSP_reg | |
17366 | +#define RMeBP OP_REG, eBP_reg | |
17367 | +#define RMeSI OP_REG, eSI_reg | |
17368 | +#define RMeDI OP_REG, eDI_reg | |
17369 | +#define RMrAX OP_REG, rAX_reg | |
17370 | +#define RMrBX OP_REG, rBX_reg | |
17371 | +#define RMrCX OP_REG, rCX_reg | |
17372 | +#define RMrDX OP_REG, rDX_reg | |
17373 | +#define RMrSP OP_REG, rSP_reg | |
17374 | +#define RMrBP OP_REG, rBP_reg | |
17375 | +#define RMrSI OP_REG, rSI_reg | |
17376 | +#define RMrDI OP_REG, rDI_reg | |
17377 | +#define RMAL OP_REG, al_reg | |
17378 | +#define RMAL OP_REG, al_reg | |
17379 | +#define RMCL OP_REG, cl_reg | |
17380 | +#define RMDL OP_REG, dl_reg | |
17381 | +#define RMBL OP_REG, bl_reg | |
17382 | +#define RMAH OP_REG, ah_reg | |
17383 | +#define RMCH OP_REG, ch_reg | |
17384 | +#define RMDH OP_REG, dh_reg | |
17385 | +#define RMBH OP_REG, bh_reg | |
17386 | +#define RMAX OP_REG, ax_reg | |
17387 | +#define RMDX OP_REG, dx_reg | |
17388 | + | |
17389 | +#define eAX OP_IMREG, eAX_reg | |
17390 | +#define eBX OP_IMREG, eBX_reg | |
17391 | +#define eCX OP_IMREG, eCX_reg | |
17392 | +#define eDX OP_IMREG, eDX_reg | |
17393 | +#define eSP OP_IMREG, eSP_reg | |
17394 | +#define eBP OP_IMREG, eBP_reg | |
17395 | +#define eSI OP_IMREG, eSI_reg | |
17396 | +#define eDI OP_IMREG, eDI_reg | |
17397 | +#define AL OP_IMREG, al_reg | |
17398 | +#define AL OP_IMREG, al_reg | |
17399 | +#define CL OP_IMREG, cl_reg | |
17400 | +#define DL OP_IMREG, dl_reg | |
17401 | +#define BL OP_IMREG, bl_reg | |
17402 | +#define AH OP_IMREG, ah_reg | |
17403 | +#define CH OP_IMREG, ch_reg | |
17404 | +#define DH OP_IMREG, dh_reg | |
17405 | +#define BH OP_IMREG, bh_reg | |
17406 | +#define AX OP_IMREG, ax_reg | |
17407 | +#define DX OP_IMREG, dx_reg | |
17408 | +#define indirDX OP_IMREG, indir_dx_reg | |
17409 | + | |
17410 | +#define Sw OP_SEG, w_mode | |
17411 | +#define Ap OP_DIR, 0 | |
17412 | +#define Ob OP_OFF, b_mode | |
17413 | +#define Ob64 OP_OFF64, b_mode | |
17414 | +#define Ov OP_OFF, v_mode | |
17415 | +#define Ov64 OP_OFF64, v_mode | |
17416 | +#define Xb OP_DSreg, eSI_reg | |
17417 | +#define Xv OP_DSreg, eSI_reg | |
17418 | +#define Yb OP_ESreg, eDI_reg | |
17419 | +#define Yv OP_ESreg, eDI_reg | |
17420 | +#define DSBX OP_DSreg, eBX_reg | |
17421 | + | |
17422 | +#define es OP_REG, es_reg | |
17423 | +#define ss OP_REG, ss_reg | |
17424 | +#define cs OP_REG, cs_reg | |
17425 | +#define ds OP_REG, ds_reg | |
17426 | +#define fs OP_REG, fs_reg | |
17427 | +#define gs OP_REG, gs_reg | |
17428 | + | |
17429 | +#define MX OP_MMX, 0 | |
17430 | +#define XM OP_XMM, 0 | |
17431 | +#define EM OP_EM, v_mode | |
17432 | +#define EX OP_EX, v_mode | |
17433 | +#define MS OP_MS, v_mode | |
17434 | +#define XS OP_XS, v_mode | |
17435 | +#define VM OP_VMX, q_mode | |
17436 | +#define OPSUF OP_3DNowSuffix, 0 | |
17437 | +#define OPSIMD OP_SIMD_Suffix, 0 | |
17438 | + | |
17439 | +#define cond_jump_flag NULL, cond_jump_mode | |
17440 | +#define loop_jcxz_flag NULL, loop_jcxz_mode | |
17441 | + | |
17442 | +/* bits in sizeflag */ | |
17443 | +#define SUFFIX_ALWAYS 4 | |
17444 | +#define AFLAG 2 | |
17445 | +#define DFLAG 1 | |
17446 | + | |
17447 | +#define b_mode 1 /* byte operand */ | |
17448 | +#define v_mode 2 /* operand size depends on prefixes */ | |
17449 | +#define w_mode 3 /* word operand */ | |
17450 | +#define d_mode 4 /* double word operand */ | |
17451 | +#define q_mode 5 /* quad word operand */ | |
17452 | +#define t_mode 6 /* ten-byte operand */ | |
17453 | +#define x_mode 7 /* 16-byte XMM operand */ | |
17454 | +#define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */ | |
17455 | +#define cond_jump_mode 9 | |
17456 | +#define loop_jcxz_mode 10 | |
17457 | +#define dq_mode 11 /* operand size depends on REX prefixes. */ | |
17458 | +#define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */ | |
17459 | +#define f_mode 13 /* 4- or 6-byte pointer operand */ | |
17460 | +#define const_1_mode 14 | |
17461 | +#define branch_v_mode 15 /* v_mode for branch. */ | |
17462 | + | |
17463 | +#define es_reg 100 | |
17464 | +#define cs_reg 101 | |
17465 | +#define ss_reg 102 | |
17466 | +#define ds_reg 103 | |
17467 | +#define fs_reg 104 | |
17468 | +#define gs_reg 105 | |
17469 | + | |
17470 | +#define eAX_reg 108 | |
17471 | +#define eCX_reg 109 | |
17472 | +#define eDX_reg 110 | |
17473 | +#define eBX_reg 111 | |
17474 | +#define eSP_reg 112 | |
17475 | +#define eBP_reg 113 | |
17476 | +#define eSI_reg 114 | |
17477 | +#define eDI_reg 115 | |
17478 | + | |
17479 | +#define al_reg 116 | |
17480 | +#define cl_reg 117 | |
17481 | +#define dl_reg 118 | |
17482 | +#define bl_reg 119 | |
17483 | +#define ah_reg 120 | |
17484 | +#define ch_reg 121 | |
17485 | +#define dh_reg 122 | |
17486 | +#define bh_reg 123 | |
17487 | + | |
17488 | +#define ax_reg 124 | |
17489 | +#define cx_reg 125 | |
17490 | +#define dx_reg 126 | |
17491 | +#define bx_reg 127 | |
17492 | +#define sp_reg 128 | |
17493 | +#define bp_reg 129 | |
17494 | +#define si_reg 130 | |
17495 | +#define di_reg 131 | |
17496 | + | |
17497 | +#define rAX_reg 132 | |
17498 | +#define rCX_reg 133 | |
17499 | +#define rDX_reg 134 | |
17500 | +#define rBX_reg 135 | |
17501 | +#define rSP_reg 136 | |
17502 | +#define rBP_reg 137 | |
17503 | +#define rSI_reg 138 | |
17504 | +#define rDI_reg 139 | |
17505 | + | |
17506 | +#define indir_dx_reg 150 | |
17507 | + | |
17508 | +#define FLOATCODE 1 | |
17509 | +#define USE_GROUPS 2 | |
17510 | +#define USE_PREFIX_USER_TABLE 3 | |
17511 | +#define X86_64_SPECIAL 4 | |
17512 | + | |
17513 | +#define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0 | |
17514 | + | |
17515 | +#define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0 | |
17516 | +#define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0 | |
17517 | +#define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0 | |
17518 | +#define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0 | |
17519 | +#define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0 | |
17520 | +#define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0 | |
17521 | +#define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0 | |
17522 | +#define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0 | |
17523 | +#define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0 | |
17524 | +#define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0 | |
17525 | +#define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0 | |
17526 | +#define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0 | |
17527 | +#define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0 | |
17528 | +#define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0 | |
17529 | +#define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0 | |
17530 | +#define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0 | |
17531 | +#define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0 | |
17532 | +#define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0 | |
17533 | +#define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0 | |
17534 | +#define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0 | |
17535 | +#define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0 | |
17536 | +#define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0 | |
17537 | +#define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0 | |
17538 | +#define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0 | |
17539 | +#define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0 | |
17540 | + | |
17541 | +#define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0 | |
17542 | +#define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0 | |
17543 | +#define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0 | |
17544 | +#define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0 | |
17545 | +#define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0 | |
17546 | +#define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0 | |
17547 | +#define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0 | |
17548 | +#define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0 | |
17549 | +#define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0 | |
17550 | +#define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0 | |
17551 | +#define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0 | |
17552 | +#define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0 | |
17553 | +#define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0 | |
17554 | +#define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0 | |
17555 | +#define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0 | |
17556 | +#define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0 | |
17557 | +#define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0 | |
17558 | +#define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0 | |
17559 | +#define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0 | |
17560 | +#define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0 | |
17561 | +#define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0 | |
17562 | +#define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0 | |
17563 | +#define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0 | |
17564 | +#define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0 | |
17565 | +#define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0 | |
17566 | +#define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0 | |
17567 | +#define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0 | |
17568 | +#define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0 | |
17569 | +#define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0 | |
17570 | +#define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0 | |
17571 | +#define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0 | |
17572 | +#define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0 | |
17573 | +#define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0 | |
17574 | + | |
17575 | +#define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0 | |
17576 | + | |
17577 | +typedef void (*op_rtn) (int bytemode, int sizeflag); | |
17578 | + | |
17579 | +struct dis386 { | |
17580 | + const char *name; | |
17581 | + op_rtn op1; | |
17582 | + int bytemode1; | |
17583 | + op_rtn op2; | |
17584 | + int bytemode2; | |
17585 | + op_rtn op3; | |
17586 | + int bytemode3; | |
17587 | +}; | |
17588 | + | |
17589 | +/* Upper case letters in the instruction names here are macros. | |
17590 | + 'A' => print 'b' if no register operands or suffix_always is true | |
17591 | + 'B' => print 'b' if suffix_always is true | |
17592 | + 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand | |
17593 | + . size prefix | |
17594 | + 'E' => print 'e' if 32-bit form of jcxz | |
17595 | + 'F' => print 'w' or 'l' depending on address size prefix (loop insns) | |
17596 | + 'H' => print ",pt" or ",pn" branch hint | |
17597 | + 'I' => honor following macro letter even in Intel mode (implemented only | |
17598 | + . for some of the macro letters) | |
17599 | + 'J' => print 'l' | |
17600 | + 'L' => print 'l' if suffix_always is true | |
17601 | + 'N' => print 'n' if instruction has no wait "prefix" | |
17602 | + 'O' => print 'd', or 'o' | |
17603 | + 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix, | |
17604 | + . or suffix_always is true. print 'q' if rex prefix is present. | |
17605 | + 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always | |
17606 | + . is true | |
17607 | + 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode) | |
17608 | + 'S' => print 'w', 'l' or 'q' if suffix_always is true | |
17609 | + 'T' => print 'q' in 64bit mode and behave as 'P' otherwise | |
17610 | + 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise | |
17611 | + 'W' => print 'b' or 'w' ("w" or "de" in intel mode) | |
17612 | + 'X' => print 's', 'd' depending on data16 prefix (for XMM) | |
17613 | + 'Y' => 'q' if instruction has an REX 64bit overwrite prefix | |
17614 | + | |
17615 | + Many of the above letters print nothing in Intel mode. See "putop" | |
17616 | + for the details. | |
17617 | + | |
17618 | + Braces '{' and '}', and vertical bars '|', indicate alternative | |
17619 | + mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel | |
17620 | + modes. In cases where there are only two alternatives, the X86_64 | |
17621 | + instruction is reserved, and "(bad)" is printed. | |
17622 | +*/ | |
17623 | + | |
17624 | +static const struct dis386 dis386[] = { | |
17625 | + /* 00 */ | |
17626 | + { "addB", Eb, Gb, XX }, | |
17627 | + { "addS", Ev, Gv, XX }, | |
17628 | + { "addB", Gb, Eb, XX }, | |
17629 | + { "addS", Gv, Ev, XX }, | |
17630 | + { "addB", AL, Ib, XX }, | |
17631 | + { "addS", eAX, Iv, XX }, | |
17632 | + { "push{T|}", es, XX, XX }, | |
17633 | + { "pop{T|}", es, XX, XX }, | |
17634 | + /* 08 */ | |
17635 | + { "orB", Eb, Gb, XX }, | |
17636 | + { "orS", Ev, Gv, XX }, | |
17637 | + { "orB", Gb, Eb, XX }, | |
17638 | + { "orS", Gv, Ev, XX }, | |
17639 | + { "orB", AL, Ib, XX }, | |
17640 | + { "orS", eAX, Iv, XX }, | |
17641 | + { "push{T|}", cs, XX, XX }, | |
17642 | + { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */ | |
17643 | + /* 10 */ | |
17644 | + { "adcB", Eb, Gb, XX }, | |
17645 | + { "adcS", Ev, Gv, XX }, | |
17646 | + { "adcB", Gb, Eb, XX }, | |
17647 | + { "adcS", Gv, Ev, XX }, | |
17648 | + { "adcB", AL, Ib, XX }, | |
17649 | + { "adcS", eAX, Iv, XX }, | |
17650 | + { "push{T|}", ss, XX, XX }, | |
17651 | + { "popT|}", ss, XX, XX }, | |
17652 | + /* 18 */ | |
17653 | + { "sbbB", Eb, Gb, XX }, | |
17654 | + { "sbbS", Ev, Gv, XX }, | |
17655 | + { "sbbB", Gb, Eb, XX }, | |
17656 | + { "sbbS", Gv, Ev, XX }, | |
17657 | + { "sbbB", AL, Ib, XX }, | |
17658 | + { "sbbS", eAX, Iv, XX }, | |
17659 | + { "push{T|}", ds, XX, XX }, | |
17660 | + { "pop{T|}", ds, XX, XX }, | |
17661 | + /* 20 */ | |
17662 | + { "andB", Eb, Gb, XX }, | |
17663 | + { "andS", Ev, Gv, XX }, | |
17664 | + { "andB", Gb, Eb, XX }, | |
17665 | + { "andS", Gv, Ev, XX }, | |
17666 | + { "andB", AL, Ib, XX }, | |
17667 | + { "andS", eAX, Iv, XX }, | |
17668 | + { "(bad)", XX, XX, XX }, /* SEG ES prefix */ | |
17669 | + { "daa{|}", XX, XX, XX }, | |
17670 | + /* 28 */ | |
17671 | + { "subB", Eb, Gb, XX }, | |
17672 | + { "subS", Ev, Gv, XX }, | |
17673 | + { "subB", Gb, Eb, XX }, | |
17674 | + { "subS", Gv, Ev, XX }, | |
17675 | + { "subB", AL, Ib, XX }, | |
17676 | + { "subS", eAX, Iv, XX }, | |
17677 | + { "(bad)", XX, XX, XX }, /* SEG CS prefix */ | |
17678 | + { "das{|}", XX, XX, XX }, | |
17679 | + /* 30 */ | |
17680 | + { "xorB", Eb, Gb, XX }, | |
17681 | + { "xorS", Ev, Gv, XX }, | |
17682 | + { "xorB", Gb, Eb, XX }, | |
17683 | + { "xorS", Gv, Ev, XX }, | |
17684 | + { "xorB", AL, Ib, XX }, | |
17685 | + { "xorS", eAX, Iv, XX }, | |
17686 | + { "(bad)", XX, XX, XX }, /* SEG SS prefix */ | |
17687 | + { "aaa{|}", XX, XX, XX }, | |
17688 | + /* 38 */ | |
17689 | + { "cmpB", Eb, Gb, XX }, | |
17690 | + { "cmpS", Ev, Gv, XX }, | |
17691 | + { "cmpB", Gb, Eb, XX }, | |
17692 | + { "cmpS", Gv, Ev, XX }, | |
17693 | + { "cmpB", AL, Ib, XX }, | |
17694 | + { "cmpS", eAX, Iv, XX }, | |
17695 | + { "(bad)", XX, XX, XX }, /* SEG DS prefix */ | |
17696 | + { "aas{|}", XX, XX, XX }, | |
17697 | + /* 40 */ | |
17698 | + { "inc{S|}", RMeAX, XX, XX }, | |
17699 | + { "inc{S|}", RMeCX, XX, XX }, | |
17700 | + { "inc{S|}", RMeDX, XX, XX }, | |
17701 | + { "inc{S|}", RMeBX, XX, XX }, | |
17702 | + { "inc{S|}", RMeSP, XX, XX }, | |
17703 | + { "inc{S|}", RMeBP, XX, XX }, | |
17704 | + { "inc{S|}", RMeSI, XX, XX }, | |
17705 | + { "inc{S|}", RMeDI, XX, XX }, | |
17706 | + /* 48 */ | |
17707 | + { "dec{S|}", RMeAX, XX, XX }, | |
17708 | + { "dec{S|}", RMeCX, XX, XX }, | |
17709 | + { "dec{S|}", RMeDX, XX, XX }, | |
17710 | + { "dec{S|}", RMeBX, XX, XX }, | |
17711 | + { "dec{S|}", RMeSP, XX, XX }, | |
17712 | + { "dec{S|}", RMeBP, XX, XX }, | |
17713 | + { "dec{S|}", RMeSI, XX, XX }, | |
17714 | + { "dec{S|}", RMeDI, XX, XX }, | |
17715 | + /* 50 */ | |
17716 | + { "pushS", RMrAX, XX, XX }, | |
17717 | + { "pushS", RMrCX, XX, XX }, | |
17718 | + { "pushS", RMrDX, XX, XX }, | |
17719 | + { "pushS", RMrBX, XX, XX }, | |
17720 | + { "pushS", RMrSP, XX, XX }, | |
17721 | + { "pushS", RMrBP, XX, XX }, | |
17722 | + { "pushS", RMrSI, XX, XX }, | |
17723 | + { "pushS", RMrDI, XX, XX }, | |
17724 | + /* 58 */ | |
17725 | + { "popS", RMrAX, XX, XX }, | |
17726 | + { "popS", RMrCX, XX, XX }, | |
17727 | + { "popS", RMrDX, XX, XX }, | |
17728 | + { "popS", RMrBX, XX, XX }, | |
17729 | + { "popS", RMrSP, XX, XX }, | |
17730 | + { "popS", RMrBP, XX, XX }, | |
17731 | + { "popS", RMrSI, XX, XX }, | |
17732 | + { "popS", RMrDI, XX, XX }, | |
17733 | + /* 60 */ | |
17734 | + { "pusha{P|}", XX, XX, XX }, | |
17735 | + { "popa{P|}", XX, XX, XX }, | |
17736 | + { "bound{S|}", Gv, Ma, XX }, | |
17737 | + { X86_64_0 }, | |
17738 | + { "(bad)", XX, XX, XX }, /* seg fs */ | |
17739 | + { "(bad)", XX, XX, XX }, /* seg gs */ | |
17740 | + { "(bad)", XX, XX, XX }, /* op size prefix */ | |
17741 | + { "(bad)", XX, XX, XX }, /* adr size prefix */ | |
17742 | + /* 68 */ | |
17743 | + { "pushT", Iq, XX, XX }, | |
17744 | + { "imulS", Gv, Ev, Iv }, | |
17745 | + { "pushT", sIb, XX, XX }, | |
17746 | + { "imulS", Gv, Ev, sIb }, | |
17747 | + { "ins{b||b|}", Yb, indirDX, XX }, | |
17748 | + { "ins{R||R|}", Yv, indirDX, XX }, | |
17749 | + { "outs{b||b|}", indirDX, Xb, XX }, | |
17750 | + { "outs{R||R|}", indirDX, Xv, XX }, | |
17751 | + /* 70 */ | |
17752 | + { "joH", Jb, XX, cond_jump_flag }, | |
17753 | + { "jnoH", Jb, XX, cond_jump_flag }, | |
17754 | + { "jbH", Jb, XX, cond_jump_flag }, | |
17755 | + { "jaeH", Jb, XX, cond_jump_flag }, | |
17756 | + { "jeH", Jb, XX, cond_jump_flag }, | |
17757 | + { "jneH", Jb, XX, cond_jump_flag }, | |
17758 | + { "jbeH", Jb, XX, cond_jump_flag }, | |
17759 | + { "jaH", Jb, XX, cond_jump_flag }, | |
17760 | + /* 78 */ | |
17761 | + { "jsH", Jb, XX, cond_jump_flag }, | |
17762 | + { "jnsH", Jb, XX, cond_jump_flag }, | |
17763 | + { "jpH", Jb, XX, cond_jump_flag }, | |
17764 | + { "jnpH", Jb, XX, cond_jump_flag }, | |
17765 | + { "jlH", Jb, XX, cond_jump_flag }, | |
17766 | + { "jgeH", Jb, XX, cond_jump_flag }, | |
17767 | + { "jleH", Jb, XX, cond_jump_flag }, | |
17768 | + { "jgH", Jb, XX, cond_jump_flag }, | |
17769 | + /* 80 */ | |
17770 | + { GRP1b }, | |
17771 | + { GRP1S }, | |
17772 | + { "(bad)", XX, XX, XX }, | |
17773 | + { GRP1Ss }, | |
17774 | + { "testB", Eb, Gb, XX }, | |
17775 | + { "testS", Ev, Gv, XX }, | |
17776 | + { "xchgB", Eb, Gb, XX }, | |
17777 | + { "xchgS", Ev, Gv, XX }, | |
17778 | + /* 88 */ | |
17779 | + { "movB", Eb, Gb, XX }, | |
17780 | + { "movS", Ev, Gv, XX }, | |
17781 | + { "movB", Gb, Eb, XX }, | |
17782 | + { "movS", Gv, Ev, XX }, | |
17783 | + { "movQ", Sv, Sw, XX }, | |
17784 | + { "leaS", Gv, M, XX }, | |
17785 | + { "movQ", Sw, Sv, XX }, | |
17786 | + { "popU", Ev, XX, XX }, | |
17787 | + /* 90 */ | |
17788 | + { "nop", NOP_Fixup, 0, XX, XX }, | |
17789 | + { "xchgS", RMeCX, eAX, XX }, | |
17790 | + { "xchgS", RMeDX, eAX, XX }, | |
17791 | + { "xchgS", RMeBX, eAX, XX }, | |
17792 | + { "xchgS", RMeSP, eAX, XX }, | |
17793 | + { "xchgS", RMeBP, eAX, XX }, | |
17794 | + { "xchgS", RMeSI, eAX, XX }, | |
17795 | + { "xchgS", RMeDI, eAX, XX }, | |
17796 | + /* 98 */ | |
17797 | + { "cW{tR||tR|}", XX, XX, XX }, | |
17798 | + { "cR{tO||tO|}", XX, XX, XX }, | |
17799 | + { "Jcall{T|}", Ap, XX, XX }, | |
17800 | + { "(bad)", XX, XX, XX }, /* fwait */ | |
17801 | + { "pushfT", XX, XX, XX }, | |
17802 | + { "popfT", XX, XX, XX }, | |
17803 | + { "sahf{|}", XX, XX, XX }, | |
17804 | + { "lahf{|}", XX, XX, XX }, | |
17805 | + /* a0 */ | |
17806 | + { "movB", AL, Ob64, XX }, | |
17807 | + { "movS", eAX, Ov64, XX }, | |
17808 | + { "movB", Ob64, AL, XX }, | |
17809 | + { "movS", Ov64, eAX, XX }, | |
17810 | + { "movs{b||b|}", Yb, Xb, XX }, | |
17811 | + { "movs{R||R|}", Yv, Xv, XX }, | |
17812 | + { "cmps{b||b|}", Xb, Yb, XX }, | |
17813 | + { "cmps{R||R|}", Xv, Yv, XX }, | |
17814 | + /* a8 */ | |
17815 | + { "testB", AL, Ib, XX }, | |
17816 | + { "testS", eAX, Iv, XX }, | |
17817 | + { "stosB", Yb, AL, XX }, | |
17818 | + { "stosS", Yv, eAX, XX }, | |
17819 | + { "lodsB", AL, Xb, XX }, | |
17820 | + { "lodsS", eAX, Xv, XX }, | |
17821 | + { "scasB", AL, Yb, XX }, | |
17822 | + { "scasS", eAX, Yv, XX }, | |
17823 | + /* b0 */ | |
17824 | + { "movB", RMAL, Ib, XX }, | |
17825 | + { "movB", RMCL, Ib, XX }, | |
17826 | + { "movB", RMDL, Ib, XX }, | |
17827 | + { "movB", RMBL, Ib, XX }, | |
17828 | + { "movB", RMAH, Ib, XX }, | |
17829 | + { "movB", RMCH, Ib, XX }, | |
17830 | + { "movB", RMDH, Ib, XX }, | |
17831 | + { "movB", RMBH, Ib, XX }, | |
17832 | + /* b8 */ | |
17833 | + { "movS", RMeAX, Iv64, XX }, | |
17834 | + { "movS", RMeCX, Iv64, XX }, | |
17835 | + { "movS", RMeDX, Iv64, XX }, | |
17836 | + { "movS", RMeBX, Iv64, XX }, | |
17837 | + { "movS", RMeSP, Iv64, XX }, | |
17838 | + { "movS", RMeBP, Iv64, XX }, | |
17839 | + { "movS", RMeSI, Iv64, XX }, | |
17840 | + { "movS", RMeDI, Iv64, XX }, | |
17841 | + /* c0 */ | |
17842 | + { GRP2b }, | |
17843 | + { GRP2S }, | |
17844 | + { "retT", Iw, XX, XX }, | |
17845 | + { "retT", XX, XX, XX }, | |
17846 | + { "les{S|}", Gv, Mp, XX }, | |
17847 | + { "ldsS", Gv, Mp, XX }, | |
17848 | + { "movA", Eb, Ib, XX }, | |
17849 | + { "movQ", Ev, Iv, XX }, | |
17850 | + /* c8 */ | |
17851 | + { "enterT", Iw, Ib, XX }, | |
17852 | + { "leaveT", XX, XX, XX }, | |
17853 | + { "lretP", Iw, XX, XX }, | |
17854 | + { "lretP", XX, XX, XX }, | |
17855 | + { "int3", XX, XX, XX }, | |
17856 | + { "int", Ib, XX, XX }, | |
17857 | + { "into{|}", XX, XX, XX }, | |
17858 | + { "iretP", XX, XX, XX }, | |
17859 | + /* d0 */ | |
17860 | + { GRP2b_one }, | |
17861 | + { GRP2S_one }, | |
17862 | + { GRP2b_cl }, | |
17863 | + { GRP2S_cl }, | |
17864 | + { "aam{|}", sIb, XX, XX }, | |
17865 | + { "aad{|}", sIb, XX, XX }, | |
17866 | + { "(bad)", XX, XX, XX }, | |
17867 | + { "xlat", DSBX, XX, XX }, | |
17868 | + /* d8 */ | |
17869 | + { FLOAT }, | |
17870 | + { FLOAT }, | |
17871 | + { FLOAT }, | |
17872 | + { FLOAT }, | |
17873 | + { FLOAT }, | |
17874 | + { FLOAT }, | |
17875 | + { FLOAT }, | |
17876 | + { FLOAT }, | |
17877 | + /* e0 */ | |
17878 | + { "loopneFH", Jb, XX, loop_jcxz_flag }, | |
17879 | + { "loopeFH", Jb, XX, loop_jcxz_flag }, | |
17880 | + { "loopFH", Jb, XX, loop_jcxz_flag }, | |
17881 | + { "jEcxzH", Jb, XX, loop_jcxz_flag }, | |
17882 | + { "inB", AL, Ib, XX }, | |
17883 | + { "inS", eAX, Ib, XX }, | |
17884 | + { "outB", Ib, AL, XX }, | |
17885 | + { "outS", Ib, eAX, XX }, | |
17886 | + /* e8 */ | |
17887 | + { "callT", Jv, XX, XX }, | |
17888 | + { "jmpT", Jv, XX, XX }, | |
17889 | + { "Jjmp{T|}", Ap, XX, XX }, | |
17890 | + { "jmp", Jb, XX, XX }, | |
17891 | + { "inB", AL, indirDX, XX }, | |
17892 | + { "inS", eAX, indirDX, XX }, | |
17893 | + { "outB", indirDX, AL, XX }, | |
17894 | + { "outS", indirDX, eAX, XX }, | |
17895 | + /* f0 */ | |
17896 | + { "(bad)", XX, XX, XX }, /* lock prefix */ | |
17897 | + { "icebp", XX, XX, XX }, | |
17898 | + { "(bad)", XX, XX, XX }, /* repne */ | |
17899 | + { "(bad)", XX, XX, XX }, /* repz */ | |
17900 | + { "hlt", XX, XX, XX }, | |
17901 | + { "cmc", XX, XX, XX }, | |
17902 | + { GRP3b }, | |
17903 | + { GRP3S }, | |
17904 | + /* f8 */ | |
17905 | + { "clc", XX, XX, XX }, | |
17906 | + { "stc", XX, XX, XX }, | |
17907 | + { "cli", XX, XX, XX }, | |
17908 | + { "sti", XX, XX, XX }, | |
17909 | + { "cld", XX, XX, XX }, | |
17910 | + { "std", XX, XX, XX }, | |
17911 | + { GRP4 }, | |
17912 | + { GRP5 }, | |
17913 | +}; | |
17914 | + | |
17915 | +static const struct dis386 dis386_twobyte[] = { | |
17916 | + /* 00 */ | |
17917 | + { GRP6 }, | |
17918 | + { GRP7 }, | |
17919 | + { "larS", Gv, Ew, XX }, | |
17920 | + { "lslS", Gv, Ew, XX }, | |
17921 | + { "(bad)", XX, XX, XX }, | |
17922 | + { "syscall", XX, XX, XX }, | |
17923 | + { "clts", XX, XX, XX }, | |
17924 | + { "sysretP", XX, XX, XX }, | |
17925 | + /* 08 */ | |
17926 | + { "invd", XX, XX, XX }, | |
17927 | + { "wbinvd", XX, XX, XX }, | |
17928 | + { "(bad)", XX, XX, XX }, | |
17929 | + { "ud2a", XX, XX, XX }, | |
17930 | + { "(bad)", XX, XX, XX }, | |
17931 | + { GRPAMD }, | |
17932 | + { "femms", XX, XX, XX }, | |
17933 | + { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix. */ | |
17934 | + /* 10 */ | |
17935 | + { PREGRP8 }, | |
17936 | + { PREGRP9 }, | |
17937 | + { PREGRP30 }, | |
17938 | + { "movlpX", EX, XM, SIMD_Fixup, 'h' }, | |
17939 | + { "unpcklpX", XM, EX, XX }, | |
17940 | + { "unpckhpX", XM, EX, XX }, | |
17941 | + { PREGRP31 }, | |
17942 | + { "movhpX", EX, XM, SIMD_Fixup, 'l' }, | |
17943 | + /* 18 */ | |
17944 | + { GRP14 }, | |
17945 | + { "(bad)", XX, XX, XX }, | |
17946 | + { "(bad)", XX, XX, XX }, | |
17947 | + { "(bad)", XX, XX, XX }, | |
17948 | + { "(bad)", XX, XX, XX }, | |
17949 | + { "(bad)", XX, XX, XX }, | |
17950 | + { "(bad)", XX, XX, XX }, | |
17951 | + { "(bad)", XX, XX, XX }, | |
17952 | + /* 20 */ | |
17953 | + { "movL", Rm, Cm, XX }, | |
17954 | + { "movL", Rm, Dm, XX }, | |
17955 | + { "movL", Cm, Rm, XX }, | |
17956 | + { "movL", Dm, Rm, XX }, | |
17957 | + { "movL", Rd, Td, XX }, | |
17958 | + { "(bad)", XX, XX, XX }, | |
17959 | + { "movL", Td, Rd, XX }, | |
17960 | + { "(bad)", XX, XX, XX }, | |
17961 | + /* 28 */ | |
17962 | + { "movapX", XM, EX, XX }, | |
17963 | + { "movapX", EX, XM, XX }, | |
17964 | + { PREGRP2 }, | |
17965 | + { "movntpX", Ev, XM, XX }, | |
17966 | + { PREGRP4 }, | |
17967 | + { PREGRP3 }, | |
17968 | + { "ucomisX", XM,EX, XX }, | |
17969 | + { "comisX", XM,EX, XX }, | |
17970 | + /* 30 */ | |
17971 | + { "wrmsr", XX, XX, XX }, | |
17972 | + { "rdtsc", XX, XX, XX }, | |
17973 | + { "rdmsr", XX, XX, XX }, | |
17974 | + { "rdpmc", XX, XX, XX }, | |
17975 | + { "sysenter", XX, XX, XX }, | |
17976 | + { "sysexit", XX, XX, XX }, | |
17977 | + { "(bad)", XX, XX, XX }, | |
17978 | + { "(bad)", XX, XX, XX }, | |
17979 | + /* 38 */ | |
17980 | + { "(bad)", XX, XX, XX }, | |
17981 | + { "(bad)", XX, XX, XX }, | |
17982 | + { "(bad)", XX, XX, XX }, | |
17983 | + { "(bad)", XX, XX, XX }, | |
17984 | + { "(bad)", XX, XX, XX }, | |
17985 | + { "(bad)", XX, XX, XX }, | |
17986 | + { "(bad)", XX, XX, XX }, | |
17987 | + { "(bad)", XX, XX, XX }, | |
17988 | + /* 40 */ | |
17989 | + { "cmovo", Gv, Ev, XX }, | |
17990 | + { "cmovno", Gv, Ev, XX }, | |
17991 | + { "cmovb", Gv, Ev, XX }, | |
17992 | + { "cmovae", Gv, Ev, XX }, | |
17993 | + { "cmove", Gv, Ev, XX }, | |
17994 | + { "cmovne", Gv, Ev, XX }, | |
17995 | + { "cmovbe", Gv, Ev, XX }, | |
17996 | + { "cmova", Gv, Ev, XX }, | |
17997 | + /* 48 */ | |
17998 | + { "cmovs", Gv, Ev, XX }, | |
17999 | + { "cmovns", Gv, Ev, XX }, | |
18000 | + { "cmovp", Gv, Ev, XX }, | |
18001 | + { "cmovnp", Gv, Ev, XX }, | |
18002 | + { "cmovl", Gv, Ev, XX }, | |
18003 | + { "cmovge", Gv, Ev, XX }, | |
18004 | + { "cmovle", Gv, Ev, XX }, | |
18005 | + { "cmovg", Gv, Ev, XX }, | |
18006 | + /* 50 */ | |
18007 | + { "movmskpX", Gdq, XS, XX }, | |
18008 | + { PREGRP13 }, | |
18009 | + { PREGRP12 }, | |
18010 | + { PREGRP11 }, | |
18011 | + { "andpX", XM, EX, XX }, | |
18012 | + { "andnpX", XM, EX, XX }, | |
18013 | + { "orpX", XM, EX, XX }, | |
18014 | + { "xorpX", XM, EX, XX }, | |
18015 | + /* 58 */ | |
18016 | + { PREGRP0 }, | |
18017 | + { PREGRP10 }, | |
18018 | + { PREGRP17 }, | |
18019 | + { PREGRP16 }, | |
18020 | + { PREGRP14 }, | |
18021 | + { PREGRP7 }, | |
18022 | + { PREGRP5 }, | |
18023 | + { PREGRP6 }, | |
18024 | + /* 60 */ | |
18025 | + { "punpcklbw", MX, EM, XX }, | |
18026 | + { "punpcklwd", MX, EM, XX }, | |
18027 | + { "punpckldq", MX, EM, XX }, | |
18028 | + { "packsswb", MX, EM, XX }, | |
18029 | + { "pcmpgtb", MX, EM, XX }, | |
18030 | + { "pcmpgtw", MX, EM, XX }, | |
18031 | + { "pcmpgtd", MX, EM, XX }, | |
18032 | + { "packuswb", MX, EM, XX }, | |
18033 | + /* 68 */ | |
18034 | + { "punpckhbw", MX, EM, XX }, | |
18035 | + { "punpckhwd", MX, EM, XX }, | |
18036 | + { "punpckhdq", MX, EM, XX }, | |
18037 | + { "packssdw", MX, EM, XX }, | |
18038 | + { PREGRP26 }, | |
18039 | + { PREGRP24 }, | |
18040 | + { "movd", MX, Edq, XX }, | |
18041 | + { PREGRP19 }, | |
18042 | + /* 70 */ | |
18043 | + { PREGRP22 }, | |
18044 | + { GRP10 }, | |
18045 | + { GRP11 }, | |
18046 | + { GRP12 }, | |
18047 | + { "pcmpeqb", MX, EM, XX }, | |
18048 | + { "pcmpeqw", MX, EM, XX }, | |
18049 | + { "pcmpeqd", MX, EM, XX }, | |
18050 | + { "emms", XX, XX, XX }, | |
18051 | + /* 78 */ | |
18052 | + { "vmread", Em, Gm, XX }, | |
18053 | + { "vmwrite", Gm, Em, XX }, | |
18054 | + { "(bad)", XX, XX, XX }, | |
18055 | + { "(bad)", XX, XX, XX }, | |
18056 | + { PREGRP28 }, | |
18057 | + { PREGRP29 }, | |
18058 | + { PREGRP23 }, | |
18059 | + { PREGRP20 }, | |
18060 | + /* 80 */ | |
18061 | + { "joH", Jv, XX, cond_jump_flag }, | |
18062 | + { "jnoH", Jv, XX, cond_jump_flag }, | |
18063 | + { "jbH", Jv, XX, cond_jump_flag }, | |
18064 | + { "jaeH", Jv, XX, cond_jump_flag }, | |
18065 | + { "jeH", Jv, XX, cond_jump_flag }, | |
18066 | + { "jneH", Jv, XX, cond_jump_flag }, | |
18067 | + { "jbeH", Jv, XX, cond_jump_flag }, | |
18068 | + { "jaH", Jv, XX, cond_jump_flag }, | |
18069 | + /* 88 */ | |
18070 | + { "jsH", Jv, XX, cond_jump_flag }, | |
18071 | + { "jnsH", Jv, XX, cond_jump_flag }, | |
18072 | + { "jpH", Jv, XX, cond_jump_flag }, | |
18073 | + { "jnpH", Jv, XX, cond_jump_flag }, | |
18074 | + { "jlH", Jv, XX, cond_jump_flag }, | |
18075 | + { "jgeH", Jv, XX, cond_jump_flag }, | |
18076 | + { "jleH", Jv, XX, cond_jump_flag }, | |
18077 | + { "jgH", Jv, XX, cond_jump_flag }, | |
18078 | + /* 90 */ | |
18079 | + { "seto", Eb, XX, XX }, | |
18080 | + { "setno", Eb, XX, XX }, | |
18081 | + { "setb", Eb, XX, XX }, | |
18082 | + { "setae", Eb, XX, XX }, | |
18083 | + { "sete", Eb, XX, XX }, | |
18084 | + { "setne", Eb, XX, XX }, | |
18085 | + { "setbe", Eb, XX, XX }, | |
18086 | + { "seta", Eb, XX, XX }, | |
18087 | + /* 98 */ | |
18088 | + { "sets", Eb, XX, XX }, | |
18089 | + { "setns", Eb, XX, XX }, | |
18090 | + { "setp", Eb, XX, XX }, | |
18091 | + { "setnp", Eb, XX, XX }, | |
18092 | + { "setl", Eb, XX, XX }, | |
18093 | + { "setge", Eb, XX, XX }, | |
18094 | + { "setle", Eb, XX, XX }, | |
18095 | + { "setg", Eb, XX, XX }, | |
18096 | + /* a0 */ | |
18097 | + { "pushT", fs, XX, XX }, | |
18098 | + { "popT", fs, XX, XX }, | |
18099 | + { "cpuid", XX, XX, XX }, | |
18100 | + { "btS", Ev, Gv, XX }, | |
18101 | + { "shldS", Ev, Gv, Ib }, | |
18102 | + { "shldS", Ev, Gv, CL }, | |
18103 | + { GRPPADLCK2 }, | |
18104 | + { GRPPADLCK1 }, | |
18105 | + /* a8 */ | |
18106 | + { "pushT", gs, XX, XX }, | |
18107 | + { "popT", gs, XX, XX }, | |
18108 | + { "rsm", XX, XX, XX }, | |
18109 | + { "btsS", Ev, Gv, XX }, | |
18110 | + { "shrdS", Ev, Gv, Ib }, | |
18111 | + { "shrdS", Ev, Gv, CL }, | |
18112 | + { GRP13 }, | |
18113 | + { "imulS", Gv, Ev, XX }, | |
18114 | + /* b0 */ | |
18115 | + { "cmpxchgB", Eb, Gb, XX }, | |
18116 | + { "cmpxchgS", Ev, Gv, XX }, | |
18117 | + { "lssS", Gv, Mp, XX }, | |
18118 | + { "btrS", Ev, Gv, XX }, | |
18119 | + { "lfsS", Gv, Mp, XX }, | |
18120 | + { "lgsS", Gv, Mp, XX }, | |
18121 | + { "movz{bR|x|bR|x}", Gv, Eb, XX }, | |
18122 | + { "movz{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movzww ! */ | |
18123 | + /* b8 */ | |
18124 | + { "(bad)", XX, XX, XX }, | |
18125 | + { "ud2b", XX, XX, XX }, | |
18126 | + { GRP8 }, | |
18127 | + { "btcS", Ev, Gv, XX }, | |
18128 | + { "bsfS", Gv, Ev, XX }, | |
18129 | + { "bsrS", Gv, Ev, XX }, | |
18130 | + { "movs{bR|x|bR|x}", Gv, Eb, XX }, | |
18131 | + { "movs{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movsww ! */ | |
18132 | + /* c0 */ | |
18133 | + { "xaddB", Eb, Gb, XX }, | |
18134 | + { "xaddS", Ev, Gv, XX }, | |
18135 | + { PREGRP1 }, | |
18136 | + { "movntiS", Ev, Gv, XX }, | |
18137 | + { "pinsrw", MX, Edqw, Ib }, | |
18138 | + { "pextrw", Gdq, MS, Ib }, | |
18139 | + { "shufpX", XM, EX, Ib }, | |
18140 | + { GRP9 }, | |
18141 | + /* c8 */ | |
18142 | + { "bswap", RMeAX, XX, XX }, | |
18143 | + { "bswap", RMeCX, XX, XX }, | |
18144 | + { "bswap", RMeDX, XX, XX }, | |
18145 | + { "bswap", RMeBX, XX, XX }, | |
18146 | + { "bswap", RMeSP, XX, XX }, | |
18147 | + { "bswap", RMeBP, XX, XX }, | |
18148 | + { "bswap", RMeSI, XX, XX }, | |
18149 | + { "bswap", RMeDI, XX, XX }, | |
18150 | + /* d0 */ | |
18151 | + { PREGRP27 }, | |
18152 | + { "psrlw", MX, EM, XX }, | |
18153 | + { "psrld", MX, EM, XX }, | |
18154 | + { "psrlq", MX, EM, XX }, | |
18155 | + { "paddq", MX, EM, XX }, | |
18156 | + { "pmullw", MX, EM, XX }, | |
18157 | + { PREGRP21 }, | |
18158 | + { "pmovmskb", Gdq, MS, XX }, | |
18159 | + /* d8 */ | |
18160 | + { "psubusb", MX, EM, XX }, | |
18161 | + { "psubusw", MX, EM, XX }, | |
18162 | + { "pminub", MX, EM, XX }, | |
18163 | + { "pand", MX, EM, XX }, | |
18164 | + { "paddusb", MX, EM, XX }, | |
18165 | + { "paddusw", MX, EM, XX }, | |
18166 | + { "pmaxub", MX, EM, XX }, | |
18167 | + { "pandn", MX, EM, XX }, | |
18168 | + /* e0 */ | |
18169 | + { "pavgb", MX, EM, XX }, | |
18170 | + { "psraw", MX, EM, XX }, | |
18171 | + { "psrad", MX, EM, XX }, | |
18172 | + { "pavgw", MX, EM, XX }, | |
18173 | + { "pmulhuw", MX, EM, XX }, | |
18174 | + { "pmulhw", MX, EM, XX }, | |
18175 | + { PREGRP15 }, | |
18176 | + { PREGRP25 }, | |
18177 | + /* e8 */ | |
18178 | + { "psubsb", MX, EM, XX }, | |
18179 | + { "psubsw", MX, EM, XX }, | |
18180 | + { "pminsw", MX, EM, XX }, | |
18181 | + { "por", MX, EM, XX }, | |
18182 | + { "paddsb", MX, EM, XX }, | |
18183 | + { "paddsw", MX, EM, XX }, | |
18184 | + { "pmaxsw", MX, EM, XX }, | |
18185 | + { "pxor", MX, EM, XX }, | |
18186 | + /* f0 */ | |
18187 | + { PREGRP32 }, | |
18188 | + { "psllw", MX, EM, XX }, | |
18189 | + { "pslld", MX, EM, XX }, | |
18190 | + { "psllq", MX, EM, XX }, | |
18191 | + { "pmuludq", MX, EM, XX }, | |
18192 | + { "pmaddwd", MX, EM, XX }, | |
18193 | + { "psadbw", MX, EM, XX }, | |
18194 | + { PREGRP18 }, | |
18195 | + /* f8 */ | |
18196 | + { "psubb", MX, EM, XX }, | |
18197 | + { "psubw", MX, EM, XX }, | |
18198 | + { "psubd", MX, EM, XX }, | |
18199 | + { "psubq", MX, EM, XX }, | |
18200 | + { "paddb", MX, EM, XX }, | |
18201 | + { "paddw", MX, EM, XX }, | |
18202 | + { "paddd", MX, EM, XX }, | |
18203 | + { "(bad)", XX, XX, XX } | |
18204 | +}; | |
18205 | + | |
18206 | +static const unsigned char onebyte_has_modrm[256] = { | |
18207 | + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | |
18208 | + /* ------------------------------- */ | |
18209 | + /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */ | |
18210 | + /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */ | |
18211 | + /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */ | |
18212 | + /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */ | |
18213 | + /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */ | |
18214 | + /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */ | |
18215 | + /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */ | |
18216 | + /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */ | |
18217 | + /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */ | |
18218 | + /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */ | |
18219 | + /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */ | |
18220 | + /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */ | |
18221 | + /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */ | |
18222 | + /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */ | |
18223 | + /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */ | |
18224 | + /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */ | |
18225 | + /* ------------------------------- */ | |
18226 | + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | |
18227 | +}; | |
18228 | + | |
18229 | +static const unsigned char twobyte_has_modrm[256] = { | |
18230 | + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | |
18231 | + /* ------------------------------- */ | |
18232 | + /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */ | |
18233 | + /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */ | |
18234 | + /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */ | |
18235 | + /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */ | |
18236 | + /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */ | |
18237 | + /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */ | |
18238 | + /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */ | |
18239 | + /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */ | |
18240 | + /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */ | |
18241 | + /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */ | |
18242 | + /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */ | |
18243 | + /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */ | |
18244 | + /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */ | |
18245 | + /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */ | |
18246 | + /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */ | |
18247 | + /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */ | |
18248 | + /* ------------------------------- */ | |
18249 | + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | |
18250 | +}; | |
18251 | + | |
18252 | +static const unsigned char twobyte_uses_SSE_prefix[256] = { | |
18253 | + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | |
18254 | + /* ------------------------------- */ | |
18255 | + /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */ | |
18256 | + /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */ | |
18257 | + /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */ | |
18258 | + /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */ | |
18259 | + /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */ | |
18260 | + /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */ | |
18261 | + /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */ | |
18262 | + /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, /* 7f */ | |
18263 | + /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */ | |
18264 | + /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */ | |
18265 | + /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */ | |
18266 | + /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */ | |
18267 | + /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */ | |
18268 | + /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */ | |
18269 | + /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */ | |
18270 | + /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */ | |
18271 | + /* ------------------------------- */ | |
18272 | + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | |
18273 | +}; | |
18274 | + | |
18275 | +static char obuf[100]; | |
18276 | +static char *obufp; | |
18277 | +static char scratchbuf[100]; | |
18278 | +static unsigned char *start_codep; | |
18279 | +static unsigned char *insn_codep; | |
18280 | +static unsigned char *codep; | |
18281 | +static disassemble_info *the_info; | |
18282 | +static int mod; | |
18283 | +static int rm; | |
18284 | +static int reg; | |
18285 | +static unsigned char need_modrm; | |
18286 | + | |
18287 | +/* If we are accessing mod/rm/reg without need_modrm set, then the | |
18288 | + values are stale. Hitting this abort likely indicates that you | |
18289 | + need to update onebyte_has_modrm or twobyte_has_modrm. */ | |
18290 | +#define MODRM_CHECK if (!need_modrm) abort () | |
18291 | + | |
18292 | +static const char **names64; | |
18293 | +static const char **names32; | |
18294 | +static const char **names16; | |
18295 | +static const char **names8; | |
18296 | +static const char **names8rex; | |
18297 | +static const char **names_seg; | |
18298 | +static const char **index16; | |
18299 | + | |
18300 | +static const char *intel_names64[] = { | |
18301 | + "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", | |
18302 | + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" | |
18303 | +}; | |
18304 | +static const char *intel_names32[] = { | |
18305 | + "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", | |
18306 | + "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" | |
18307 | +}; | |
18308 | +static const char *intel_names16[] = { | |
18309 | + "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", | |
18310 | + "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w" | |
18311 | +}; | |
18312 | +static const char *intel_names8[] = { | |
18313 | + "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", | |
18314 | +}; | |
18315 | +static const char *intel_names8rex[] = { | |
18316 | + "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", | |
18317 | + "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" | |
18318 | +}; | |
18319 | +static const char *intel_names_seg[] = { | |
18320 | + "es", "cs", "ss", "ds", "fs", "gs", "?", "?", | |
18321 | +}; | |
18322 | +static const char *intel_index16[] = { | |
18323 | + "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx" | |
18324 | +}; | |
18325 | + | |
18326 | +static const char *att_names64[] = { | |
18327 | + "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi", | |
18328 | + "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" | |
18329 | +}; | |
18330 | +static const char *att_names32[] = { | |
18331 | + "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi", | |
18332 | + "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d" | |
18333 | +}; | |
18334 | +static const char *att_names16[] = { | |
18335 | + "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di", | |
18336 | + "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w" | |
18337 | +}; | |
18338 | +static const char *att_names8[] = { | |
18339 | + "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh", | |
18340 | +}; | |
18341 | +static const char *att_names8rex[] = { | |
18342 | + "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil", | |
18343 | + "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b" | |
18344 | +}; | |
18345 | +static const char *att_names_seg[] = { | |
18346 | + "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?", | |
18347 | +}; | |
18348 | +static const char *att_index16[] = { | |
18349 | + "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx" | |
18350 | +}; | |
18351 | + | |
18352 | +static const struct dis386 grps[][8] = { | |
18353 | + /* GRP1b */ | |
18354 | + { | |
18355 | + { "addA", Eb, Ib, XX }, | |
18356 | + { "orA", Eb, Ib, XX }, | |
18357 | + { "adcA", Eb, Ib, XX }, | |
18358 | + { "sbbA", Eb, Ib, XX }, | |
18359 | + { "andA", Eb, Ib, XX }, | |
18360 | + { "subA", Eb, Ib, XX }, | |
18361 | + { "xorA", Eb, Ib, XX }, | |
18362 | + { "cmpA", Eb, Ib, XX } | |
18363 | + }, | |
18364 | + /* GRP1S */ | |
18365 | + { | |
18366 | + { "addQ", Ev, Iv, XX }, | |
18367 | + { "orQ", Ev, Iv, XX }, | |
18368 | + { "adcQ", Ev, Iv, XX }, | |
18369 | + { "sbbQ", Ev, Iv, XX }, | |
18370 | + { "andQ", Ev, Iv, XX }, | |
18371 | + { "subQ", Ev, Iv, XX }, | |
18372 | + { "xorQ", Ev, Iv, XX }, | |
18373 | + { "cmpQ", Ev, Iv, XX } | |
18374 | + }, | |
18375 | + /* GRP1Ss */ | |
18376 | + { | |
18377 | + { "addQ", Ev, sIb, XX }, | |
18378 | + { "orQ", Ev, sIb, XX }, | |
18379 | + { "adcQ", Ev, sIb, XX }, | |
18380 | + { "sbbQ", Ev, sIb, XX }, | |
18381 | + { "andQ", Ev, sIb, XX }, | |
18382 | + { "subQ", Ev, sIb, XX }, | |
18383 | + { "xorQ", Ev, sIb, XX }, | |
18384 | + { "cmpQ", Ev, sIb, XX } | |
18385 | + }, | |
18386 | + /* GRP2b */ | |
18387 | + { | |
18388 | + { "rolA", Eb, Ib, XX }, | |
18389 | + { "rorA", Eb, Ib, XX }, | |
18390 | + { "rclA", Eb, Ib, XX }, | |
18391 | + { "rcrA", Eb, Ib, XX }, | |
18392 | + { "shlA", Eb, Ib, XX }, | |
18393 | + { "shrA", Eb, Ib, XX }, | |
18394 | + { "(bad)", XX, XX, XX }, | |
18395 | + { "sarA", Eb, Ib, XX }, | |
18396 | + }, | |
18397 | + /* GRP2S */ | |
18398 | + { | |
18399 | + { "rolQ", Ev, Ib, XX }, | |
18400 | + { "rorQ", Ev, Ib, XX }, | |
18401 | + { "rclQ", Ev, Ib, XX }, | |
18402 | + { "rcrQ", Ev, Ib, XX }, | |
18403 | + { "shlQ", Ev, Ib, XX }, | |
18404 | + { "shrQ", Ev, Ib, XX }, | |
18405 | + { "(bad)", XX, XX, XX }, | |
18406 | + { "sarQ", Ev, Ib, XX }, | |
18407 | + }, | |
18408 | + /* GRP2b_one */ | |
18409 | + { | |
18410 | + { "rolA", Eb, I1, XX }, | |
18411 | + { "rorA", Eb, I1, XX }, | |
18412 | + { "rclA", Eb, I1, XX }, | |
18413 | + { "rcrA", Eb, I1, XX }, | |
18414 | + { "shlA", Eb, I1, XX }, | |
18415 | + { "shrA", Eb, I1, XX }, | |
18416 | + { "(bad)", XX, XX, XX }, | |
18417 | + { "sarA", Eb, I1, XX }, | |
18418 | + }, | |
18419 | + /* GRP2S_one */ | |
18420 | + { | |
18421 | + { "rolQ", Ev, I1, XX }, | |
18422 | + { "rorQ", Ev, I1, XX }, | |
18423 | + { "rclQ", Ev, I1, XX }, | |
18424 | + { "rcrQ", Ev, I1, XX }, | |
18425 | + { "shlQ", Ev, I1, XX }, | |
18426 | + { "shrQ", Ev, I1, XX }, | |
18427 | + { "(bad)", XX, XX, XX}, | |
18428 | + { "sarQ", Ev, I1, XX }, | |
18429 | + }, | |
18430 | + /* GRP2b_cl */ | |
18431 | + { | |
18432 | + { "rolA", Eb, CL, XX }, | |
18433 | + { "rorA", Eb, CL, XX }, | |
18434 | + { "rclA", Eb, CL, XX }, | |
18435 | + { "rcrA", Eb, CL, XX }, | |
18436 | + { "shlA", Eb, CL, XX }, | |
18437 | + { "shrA", Eb, CL, XX }, | |
18438 | + { "(bad)", XX, XX, XX }, | |
18439 | + { "sarA", Eb, CL, XX }, | |
18440 | + }, | |
18441 | + /* GRP2S_cl */ | |
18442 | + { | |
18443 | + { "rolQ", Ev, CL, XX }, | |
18444 | + { "rorQ", Ev, CL, XX }, | |
18445 | + { "rclQ", Ev, CL, XX }, | |
18446 | + { "rcrQ", Ev, CL, XX }, | |
18447 | + { "shlQ", Ev, CL, XX }, | |
18448 | + { "shrQ", Ev, CL, XX }, | |
18449 | + { "(bad)", XX, XX, XX }, | |
18450 | + { "sarQ", Ev, CL, XX } | |
18451 | + }, | |
18452 | + /* GRP3b */ | |
18453 | + { | |
18454 | + { "testA", Eb, Ib, XX }, | |
18455 | + { "(bad)", Eb, XX, XX }, | |
18456 | + { "notA", Eb, XX, XX }, | |
18457 | + { "negA", Eb, XX, XX }, | |
18458 | + { "mulA", Eb, XX, XX }, /* Don't print the implicit %al register, */ | |
18459 | + { "imulA", Eb, XX, XX }, /* to distinguish these opcodes from other */ | |
18460 | + { "divA", Eb, XX, XX }, /* mul/imul opcodes. Do the same for div */ | |
18461 | + { "idivA", Eb, XX, XX } /* and idiv for consistency. */ | |
18462 | + }, | |
18463 | + /* GRP3S */ | |
18464 | + { | |
18465 | + { "testQ", Ev, Iv, XX }, | |
18466 | + { "(bad)", XX, XX, XX }, | |
18467 | + { "notQ", Ev, XX, XX }, | |
18468 | + { "negQ", Ev, XX, XX }, | |
18469 | + { "mulQ", Ev, XX, XX }, /* Don't print the implicit register. */ | |
18470 | + { "imulQ", Ev, XX, XX }, | |
18471 | + { "divQ", Ev, XX, XX }, | |
18472 | + { "idivQ", Ev, XX, XX }, | |
18473 | + }, | |
18474 | + /* GRP4 */ | |
18475 | + { | |
18476 | + { "incA", Eb, XX, XX }, | |
18477 | + { "decA", Eb, XX, XX }, | |
18478 | + { "(bad)", XX, XX, XX }, | |
18479 | + { "(bad)", XX, XX, XX }, | |
18480 | + { "(bad)", XX, XX, XX }, | |
18481 | + { "(bad)", XX, XX, XX }, | |
18482 | + { "(bad)", XX, XX, XX }, | |
18483 | + { "(bad)", XX, XX, XX }, | |
18484 | + }, | |
18485 | + /* GRP5 */ | |
18486 | + { | |
18487 | + { "incQ", Ev, XX, XX }, | |
18488 | + { "decQ", Ev, XX, XX }, | |
18489 | + { "callT", indirEv, XX, XX }, | |
18490 | + { "JcallT", indirEp, XX, XX }, | |
18491 | + { "jmpT", indirEv, XX, XX }, | |
18492 | + { "JjmpT", indirEp, XX, XX }, | |
18493 | + { "pushU", Ev, XX, XX }, | |
18494 | + { "(bad)", XX, XX, XX }, | |
18495 | + }, | |
18496 | + /* GRP6 */ | |
18497 | + { | |
18498 | + { "sldtQ", Ev, XX, XX }, | |
18499 | + { "strQ", Ev, XX, XX }, | |
18500 | + { "lldt", Ew, XX, XX }, | |
18501 | + { "ltr", Ew, XX, XX }, | |
18502 | + { "verr", Ew, XX, XX }, | |
18503 | + { "verw", Ew, XX, XX }, | |
18504 | + { "(bad)", XX, XX, XX }, | |
18505 | + { "(bad)", XX, XX, XX } | |
18506 | + }, | |
18507 | + /* GRP7 */ | |
18508 | + { | |
18509 | + { "sgdtIQ", VMX_Fixup, 0, XX, XX }, | |
18510 | + { "sidtIQ", PNI_Fixup, 0, XX, XX }, | |
18511 | + { "lgdt{Q|Q||}", M, XX, XX }, | |
18512 | + { "lidt{Q|Q||}", SVME_Fixup, 0, XX, XX }, | |
18513 | + { "smswQ", Ev, XX, XX }, | |
18514 | + { "(bad)", XX, XX, XX }, | |
18515 | + { "lmsw", Ew, XX, XX }, | |
18516 | + { "invlpg", INVLPG_Fixup, w_mode, XX, XX }, | |
18517 | + }, | |
18518 | + /* GRP8 */ | |
18519 | + { | |
18520 | + { "(bad)", XX, XX, XX }, | |
18521 | + { "(bad)", XX, XX, XX }, | |
18522 | + { "(bad)", XX, XX, XX }, | |
18523 | + { "(bad)", XX, XX, XX }, | |
18524 | + { "btQ", Ev, Ib, XX }, | |
18525 | + { "btsQ", Ev, Ib, XX }, | |
18526 | + { "btrQ", Ev, Ib, XX }, | |
18527 | + { "btcQ", Ev, Ib, XX }, | |
18528 | + }, | |
18529 | + /* GRP9 */ | |
18530 | + { | |
18531 | + { "(bad)", XX, XX, XX }, | |
18532 | + { "cmpxchg8b", Eq, XX, XX }, | |
18533 | + { "(bad)", XX, XX, XX }, | |
18534 | + { "(bad)", XX, XX, XX }, | |
18535 | + { "(bad)", XX, XX, XX }, | |
18536 | + { "(bad)", XX, XX, XX }, | |
18537 | + { "", VM, XX, XX }, /* See OP_VMX. */ | |
18538 | + { "vmptrst", Eq, XX, XX }, | |
18539 | + }, | |
18540 | + /* GRP10 */ | |
18541 | + { | |
18542 | + { "(bad)", XX, XX, XX }, | |
18543 | + { "(bad)", XX, XX, XX }, | |
18544 | + { "psrlw", MS, Ib, XX }, | |
18545 | + { "(bad)", XX, XX, XX }, | |
18546 | + { "psraw", MS, Ib, XX }, | |
18547 | + { "(bad)", XX, XX, XX }, | |
18548 | + { "psllw", MS, Ib, XX }, | |
18549 | + { "(bad)", XX, XX, XX }, | |
18550 | + }, | |
18551 | + /* GRP11 */ | |
18552 | + { | |
18553 | + { "(bad)", XX, XX, XX }, | |
18554 | + { "(bad)", XX, XX, XX }, | |
18555 | + { "psrld", MS, Ib, XX }, | |
18556 | + { "(bad)", XX, XX, XX }, | |
18557 | + { "psrad", MS, Ib, XX }, | |
18558 | + { "(bad)", XX, XX, XX }, | |
18559 | + { "pslld", MS, Ib, XX }, | |
18560 | + { "(bad)", XX, XX, XX }, | |
18561 | + }, | |
18562 | + /* GRP12 */ | |
18563 | + { | |
18564 | + { "(bad)", XX, XX, XX }, | |
18565 | + { "(bad)", XX, XX, XX }, | |
18566 | + { "psrlq", MS, Ib, XX }, | |
18567 | + { "psrldq", MS, Ib, XX }, | |
18568 | + { "(bad)", XX, XX, XX }, | |
18569 | + { "(bad)", XX, XX, XX }, | |
18570 | + { "psllq", MS, Ib, XX }, | |
18571 | + { "pslldq", MS, Ib, XX }, | |
18572 | + }, | |
18573 | + /* GRP13 */ | |
18574 | + { | |
18575 | + { "fxsave", Ev, XX, XX }, | |
18576 | + { "fxrstor", Ev, XX, XX }, | |
18577 | + { "ldmxcsr", Ev, XX, XX }, | |
18578 | + { "stmxcsr", Ev, XX, XX }, | |
18579 | + { "(bad)", XX, XX, XX }, | |
18580 | + { "lfence", OP_0fae, 0, XX, XX }, | |
18581 | + { "mfence", OP_0fae, 0, XX, XX }, | |
18582 | + { "clflush", OP_0fae, 0, XX, XX }, | |
18583 | + }, | |
18584 | + /* GRP14 */ | |
18585 | + { | |
18586 | + { "prefetchnta", Ev, XX, XX }, | |
18587 | + { "prefetcht0", Ev, XX, XX }, | |
18588 | + { "prefetcht1", Ev, XX, XX }, | |
18589 | + { "prefetcht2", Ev, XX, XX }, | |
18590 | + { "(bad)", XX, XX, XX }, | |
18591 | + { "(bad)", XX, XX, XX }, | |
18592 | + { "(bad)", XX, XX, XX }, | |
18593 | + { "(bad)", XX, XX, XX }, | |
18594 | + }, | |
18595 | + /* GRPAMD */ | |
18596 | + { | |
18597 | + { "prefetch", Eb, XX, XX }, | |
18598 | + { "prefetchw", Eb, XX, XX }, | |
18599 | + { "(bad)", XX, XX, XX }, | |
18600 | + { "(bad)", XX, XX, XX }, | |
18601 | + { "(bad)", XX, XX, XX }, | |
18602 | + { "(bad)", XX, XX, XX }, | |
18603 | + { "(bad)", XX, XX, XX }, | |
18604 | + { "(bad)", XX, XX, XX }, | |
18605 | + }, | |
18606 | + /* GRPPADLCK1 */ | |
18607 | + { | |
18608 | + { "xstore-rng", OP_0f07, 0, XX, XX }, | |
18609 | + { "xcrypt-ecb", OP_0f07, 0, XX, XX }, | |
18610 | + { "xcrypt-cbc", OP_0f07, 0, XX, XX }, | |
18611 | + { "xcrypt-ctr", OP_0f07, 0, XX, XX }, | |
18612 | + { "xcrypt-cfb", OP_0f07, 0, XX, XX }, | |
18613 | + { "xcrypt-ofb", OP_0f07, 0, XX, XX }, | |
18614 | + { "(bad)", OP_0f07, 0, XX, XX }, | |
18615 | + { "(bad)", OP_0f07, 0, XX, XX }, | |
18616 | + }, | |
18617 | + /* GRPPADLCK2 */ | |
18618 | + { | |
18619 | + { "montmul", OP_0f07, 0, XX, XX }, | |
18620 | + { "xsha1", OP_0f07, 0, XX, XX }, | |
18621 | + { "xsha256", OP_0f07, 0, XX, XX }, | |
18622 | + { "(bad)", OP_0f07, 0, XX, XX }, | |
18623 | + { "(bad)", OP_0f07, 0, XX, XX }, | |
18624 | + { "(bad)", OP_0f07, 0, XX, XX }, | |
18625 | + { "(bad)", OP_0f07, 0, XX, XX }, | |
18626 | + { "(bad)", OP_0f07, 0, XX, XX }, | |
18627 | + } | |
18628 | +}; | |
18629 | + | |
18630 | +static const struct dis386 prefix_user_table[][4] = { | |
18631 | + /* PREGRP0 */ | |
18632 | + { | |
18633 | + { "addps", XM, EX, XX }, | |
18634 | + { "addss", XM, EX, XX }, | |
18635 | + { "addpd", XM, EX, XX }, | |
18636 | + { "addsd", XM, EX, XX }, | |
18637 | + }, | |
18638 | + /* PREGRP1 */ | |
18639 | + { | |
18640 | + { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX. */ | |
18641 | + { "", XM, EX, OPSIMD }, | |
18642 | + { "", XM, EX, OPSIMD }, | |
18643 | + { "", XM, EX, OPSIMD }, | |
18644 | + }, | |
18645 | + /* PREGRP2 */ | |
18646 | + { | |
18647 | + { "cvtpi2ps", XM, EM, XX }, | |
18648 | + { "cvtsi2ssY", XM, Ev, XX }, | |
18649 | + { "cvtpi2pd", XM, EM, XX }, | |
18650 | + { "cvtsi2sdY", XM, Ev, XX }, | |
18651 | + }, | |
18652 | + /* PREGRP3 */ | |
18653 | + { | |
18654 | + { "cvtps2pi", MX, EX, XX }, | |
18655 | + { "cvtss2siY", Gv, EX, XX }, | |
18656 | + { "cvtpd2pi", MX, EX, XX }, | |
18657 | + { "cvtsd2siY", Gv, EX, XX }, | |
18658 | + }, | |
18659 | + /* PREGRP4 */ | |
18660 | + { | |
18661 | + { "cvttps2pi", MX, EX, XX }, | |
18662 | + { "cvttss2siY", Gv, EX, XX }, | |
18663 | + { "cvttpd2pi", MX, EX, XX }, | |
18664 | + { "cvttsd2siY", Gv, EX, XX }, | |
18665 | + }, | |
18666 | + /* PREGRP5 */ | |
18667 | + { | |
18668 | + { "divps", XM, EX, XX }, | |
18669 | + { "divss", XM, EX, XX }, | |
18670 | + { "divpd", XM, EX, XX }, | |
18671 | + { "divsd", XM, EX, XX }, | |
18672 | + }, | |
18673 | + /* PREGRP6 */ | |
18674 | + { | |
18675 | + { "maxps", XM, EX, XX }, | |
18676 | + { "maxss", XM, EX, XX }, | |
18677 | + { "maxpd", XM, EX, XX }, | |
18678 | + { "maxsd", XM, EX, XX }, | |
18679 | + }, | |
18680 | + /* PREGRP7 */ | |
18681 | + { | |
18682 | + { "minps", XM, EX, XX }, | |
18683 | + { "minss", XM, EX, XX }, | |
18684 | + { "minpd", XM, EX, XX }, | |
18685 | + { "minsd", XM, EX, XX }, | |
18686 | + }, | |
18687 | + /* PREGRP8 */ | |
18688 | + { | |
18689 | + { "movups", XM, EX, XX }, | |
18690 | + { "movss", XM, EX, XX }, | |
18691 | + { "movupd", XM, EX, XX }, | |
18692 | + { "movsd", XM, EX, XX }, | |
18693 | + }, | |
18694 | + /* PREGRP9 */ | |
18695 | + { | |
18696 | + { "movups", EX, XM, XX }, | |
18697 | + { "movss", EX, XM, XX }, | |
18698 | + { "movupd", EX, XM, XX }, | |
18699 | + { "movsd", EX, XM, XX }, | |
18700 | + }, | |
18701 | + /* PREGRP10 */ | |
18702 | + { | |
18703 | + { "mulps", XM, EX, XX }, | |
18704 | + { "mulss", XM, EX, XX }, | |
18705 | + { "mulpd", XM, EX, XX }, | |
18706 | + { "mulsd", XM, EX, XX }, | |
18707 | + }, | |
18708 | + /* PREGRP11 */ | |
18709 | + { | |
18710 | + { "rcpps", XM, EX, XX }, | |
18711 | + { "rcpss", XM, EX, XX }, | |
18712 | + { "(bad)", XM, EX, XX }, | |
18713 | + { "(bad)", XM, EX, XX }, | |
18714 | + }, | |
18715 | + /* PREGRP12 */ | |
18716 | + { | |
18717 | + { "rsqrtps", XM, EX, XX }, | |
18718 | + { "rsqrtss", XM, EX, XX }, | |
18719 | + { "(bad)", XM, EX, XX }, | |
18720 | + { "(bad)", XM, EX, XX }, | |
18721 | + }, | |
18722 | + /* PREGRP13 */ | |
18723 | + { | |
18724 | + { "sqrtps", XM, EX, XX }, | |
18725 | + { "sqrtss", XM, EX, XX }, | |
18726 | + { "sqrtpd", XM, EX, XX }, | |
18727 | + { "sqrtsd", XM, EX, XX }, | |
18728 | + }, | |
18729 | + /* PREGRP14 */ | |
18730 | + { | |
18731 | + { "subps", XM, EX, XX }, | |
18732 | + { "subss", XM, EX, XX }, | |
18733 | + { "subpd", XM, EX, XX }, | |
18734 | + { "subsd", XM, EX, XX }, | |
18735 | + }, | |
18736 | + /* PREGRP15 */ | |
18737 | + { | |
18738 | + { "(bad)", XM, EX, XX }, | |
18739 | + { "cvtdq2pd", XM, EX, XX }, | |
18740 | + { "cvttpd2dq", XM, EX, XX }, | |
18741 | + { "cvtpd2dq", XM, EX, XX }, | |
18742 | + }, | |
18743 | + /* PREGRP16 */ | |
18744 | + { | |
18745 | + { "cvtdq2ps", XM, EX, XX }, | |
18746 | + { "cvttps2dq",XM, EX, XX }, | |
18747 | + { "cvtps2dq",XM, EX, XX }, | |
18748 | + { "(bad)", XM, EX, XX }, | |
18749 | + }, | |
18750 | + /* PREGRP17 */ | |
18751 | + { | |
18752 | + { "cvtps2pd", XM, EX, XX }, | |
18753 | + { "cvtss2sd", XM, EX, XX }, | |
18754 | + { "cvtpd2ps", XM, EX, XX }, | |
18755 | + { "cvtsd2ss", XM, EX, XX }, | |
18756 | + }, | |
18757 | + /* PREGRP18 */ | |
18758 | + { | |
18759 | + { "maskmovq", MX, MS, XX }, | |
18760 | + { "(bad)", XM, EX, XX }, | |
18761 | + { "maskmovdqu", XM, EX, XX }, | |
18762 | + { "(bad)", XM, EX, XX }, | |
18763 | + }, | |
18764 | + /* PREGRP19 */ | |
18765 | + { | |
18766 | + { "movq", MX, EM, XX }, | |
18767 | + { "movdqu", XM, EX, XX }, | |
18768 | + { "movdqa", XM, EX, XX }, | |
18769 | + { "(bad)", XM, EX, XX }, | |
18770 | + }, | |
18771 | + /* PREGRP20 */ | |
18772 | + { | |
18773 | + { "movq", EM, MX, XX }, | |
18774 | + { "movdqu", EX, XM, XX }, | |
18775 | + { "movdqa", EX, XM, XX }, | |
18776 | + { "(bad)", EX, XM, XX }, | |
18777 | + }, | |
18778 | + /* PREGRP21 */ | |
18779 | + { | |
18780 | + { "(bad)", EX, XM, XX }, | |
18781 | + { "movq2dq", XM, MS, XX }, | |
18782 | + { "movq", EX, XM, XX }, | |
18783 | + { "movdq2q", MX, XS, XX }, | |
18784 | + }, | |
18785 | + /* PREGRP22 */ | |
18786 | + { | |
18787 | + { "pshufw", MX, EM, Ib }, | |
18788 | + { "pshufhw", XM, EX, Ib }, | |
18789 | + { "pshufd", XM, EX, Ib }, | |
18790 | + { "pshuflw", XM, EX, Ib }, | |
18791 | + }, | |
18792 | + /* PREGRP23 */ | |
18793 | + { | |
18794 | + { "movd", Edq, MX, XX }, | |
18795 | + { "movq", XM, EX, XX }, | |
18796 | + { "movd", Edq, XM, XX }, | |
18797 | + { "(bad)", Ed, XM, XX }, | |
18798 | + }, | |
18799 | + /* PREGRP24 */ | |
18800 | + { | |
18801 | + { "(bad)", MX, EX, XX }, | |
18802 | + { "(bad)", XM, EX, XX }, | |
18803 | + { "punpckhqdq", XM, EX, XX }, | |
18804 | + { "(bad)", XM, EX, XX }, | |
18805 | + }, | |
18806 | + /* PREGRP25 */ | |
18807 | + { | |
18808 | + { "movntq", EM, MX, XX }, | |
18809 | + { "(bad)", EM, XM, XX }, | |
18810 | + { "movntdq", EM, XM, XX }, | |
18811 | + { "(bad)", EM, XM, XX }, | |
18812 | + }, | |
18813 | + /* PREGRP26 */ | |
18814 | + { | |
18815 | + { "(bad)", MX, EX, XX }, | |
18816 | + { "(bad)", XM, EX, XX }, | |
18817 | + { "punpcklqdq", XM, EX, XX }, | |
18818 | + { "(bad)", XM, EX, XX }, | |
18819 | + }, | |
18820 | + /* PREGRP27 */ | |
18821 | + { | |
18822 | + { "(bad)", MX, EX, XX }, | |
18823 | + { "(bad)", XM, EX, XX }, | |
18824 | + { "addsubpd", XM, EX, XX }, | |
18825 | + { "addsubps", XM, EX, XX }, | |
18826 | + }, | |
18827 | + /* PREGRP28 */ | |
18828 | + { | |
18829 | + { "(bad)", MX, EX, XX }, | |
18830 | + { "(bad)", XM, EX, XX }, | |
18831 | + { "haddpd", XM, EX, XX }, | |
18832 | + { "haddps", XM, EX, XX }, | |
18833 | + }, | |
18834 | + /* PREGRP29 */ | |
18835 | + { | |
18836 | + { "(bad)", MX, EX, XX }, | |
18837 | + { "(bad)", XM, EX, XX }, | |
18838 | + { "hsubpd", XM, EX, XX }, | |
18839 | + { "hsubps", XM, EX, XX }, | |
18840 | + }, | |
18841 | + /* PREGRP30 */ | |
18842 | + { | |
18843 | + { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */ | |
18844 | + { "movsldup", XM, EX, XX }, | |
18845 | + { "movlpd", XM, EX, XX }, | |
18846 | + { "movddup", XM, EX, XX }, | |
18847 | + }, | |
18848 | + /* PREGRP31 */ | |
18849 | + { | |
18850 | + { "movhpX", XM, EX, SIMD_Fixup, 'l' }, | |
18851 | + { "movshdup", XM, EX, XX }, | |
18852 | + { "movhpd", XM, EX, XX }, | |
18853 | + { "(bad)", XM, EX, XX }, | |
18854 | + }, | |
18855 | + /* PREGRP32 */ | |
18856 | + { | |
18857 | + { "(bad)", XM, EX, XX }, | |
18858 | + { "(bad)", XM, EX, XX }, | |
18859 | + { "(bad)", XM, EX, XX }, | |
18860 | + { "lddqu", XM, M, XX }, | |
18861 | + }, | |
18862 | +}; | |
18863 | + | |
18864 | +static const struct dis386 x86_64_table[][2] = { | |
18865 | + { | |
18866 | + { "arpl", Ew, Gw, XX }, | |
18867 | + { "movs{||lq|xd}", Gv, Ed, XX }, | |
18868 | + }, | |
18869 | +}; | |
18870 | + | |
18871 | +#ifdef __KERNEL__ | |
18872 | +#define INTERNAL_DISASSEMBLER_ERROR "<internal disassembler error>" | |
18873 | +#else /* __KERNEL__ */ | |
18874 | +#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>") | |
18875 | +#endif /* __KERNEL__ */ | |
18876 | + | |
18877 | +static void | |
18878 | +ckprefix (void) | |
18879 | +{ | |
18880 | + int newrex; | |
18881 | + rex = 0; | |
18882 | + prefixes = 0; | |
18883 | + used_prefixes = 0; | |
18884 | + rex_used = 0; | |
18885 | + while (1) | |
18886 | + { | |
18887 | + FETCH_DATA (the_info, codep + 1); | |
18888 | + newrex = 0; | |
18889 | + switch (*codep) | |
18890 | + { | |
18891 | + /* REX prefixes family. */ | |
18892 | + case 0x40: | |
18893 | + case 0x41: | |
18894 | + case 0x42: | |
18895 | + case 0x43: | |
18896 | + case 0x44: | |
18897 | + case 0x45: | |
18898 | + case 0x46: | |
18899 | + case 0x47: | |
18900 | + case 0x48: | |
18901 | + case 0x49: | |
18902 | + case 0x4a: | |
18903 | + case 0x4b: | |
18904 | + case 0x4c: | |
18905 | + case 0x4d: | |
18906 | + case 0x4e: | |
18907 | + case 0x4f: | |
18908 | + if (mode_64bit) | |
18909 | + newrex = *codep; | |
18910 | + else | |
18911 | + return; | |
18912 | + break; | |
18913 | + case 0xf3: | |
18914 | + prefixes |= PREFIX_REPZ; | |
18915 | + break; | |
18916 | + case 0xf2: | |
18917 | + prefixes |= PREFIX_REPNZ; | |
18918 | + break; | |
18919 | + case 0xf0: | |
18920 | + prefixes |= PREFIX_LOCK; | |
18921 | + break; | |
18922 | + case 0x2e: | |
18923 | + prefixes |= PREFIX_CS; | |
18924 | + break; | |
18925 | + case 0x36: | |
18926 | + prefixes |= PREFIX_SS; | |
18927 | + break; | |
18928 | + case 0x3e: | |
18929 | + prefixes |= PREFIX_DS; | |
18930 | + break; | |
18931 | + case 0x26: | |
18932 | + prefixes |= PREFIX_ES; | |
18933 | + break; | |
18934 | + case 0x64: | |
18935 | + prefixes |= PREFIX_FS; | |
18936 | + break; | |
18937 | + case 0x65: | |
18938 | + prefixes |= PREFIX_GS; | |
18939 | + break; | |
18940 | + case 0x66: | |
18941 | + prefixes |= PREFIX_DATA; | |
18942 | + break; | |
18943 | + case 0x67: | |
18944 | + prefixes |= PREFIX_ADDR; | |
18945 | + break; | |
18946 | + case FWAIT_OPCODE: | |
18947 | + /* fwait is really an instruction. If there are prefixes | |
18948 | + before the fwait, they belong to the fwait, *not* to the | |
18949 | + following instruction. */ | |
18950 | + if (prefixes) | |
18951 | + { | |
18952 | + prefixes |= PREFIX_FWAIT; | |
18953 | + codep++; | |
18954 | + return; | |
18955 | + } | |
18956 | + prefixes = PREFIX_FWAIT; | |
18957 | + break; | |
18958 | + default: | |
18959 | + return; | |
18960 | + } | |
18961 | + /* Rex is ignored when followed by another prefix. */ | |
18962 | + if (rex) | |
18963 | + { | |
18964 | + oappend (prefix_name (rex, 0)); | |
18965 | + oappend (" "); | |
18966 | + } | |
18967 | + rex = newrex; | |
18968 | + codep++; | |
18969 | + } | |
18970 | +} | |
18971 | + | |
18972 | +/* Return the name of the prefix byte PREF, or NULL if PREF is not a | |
18973 | + prefix byte. */ | |
18974 | + | |
18975 | +static const char * | |
18976 | +prefix_name (int pref, int sizeflag) | |
18977 | +{ | |
18978 | + switch (pref) | |
18979 | + { | |
18980 | + /* REX prefixes family. */ | |
18981 | + case 0x40: | |
18982 | + return "rex"; | |
18983 | + case 0x41: | |
18984 | + return "rexZ"; | |
18985 | + case 0x42: | |
18986 | + return "rexY"; | |
18987 | + case 0x43: | |
18988 | + return "rexYZ"; | |
18989 | + case 0x44: | |
18990 | + return "rexX"; | |
18991 | + case 0x45: | |
18992 | + return "rexXZ"; | |
18993 | + case 0x46: | |
18994 | + return "rexXY"; | |
18995 | + case 0x47: | |
18996 | + return "rexXYZ"; | |
18997 | + case 0x48: | |
18998 | + return "rex64"; | |
18999 | + case 0x49: | |
19000 | + return "rex64Z"; | |
19001 | + case 0x4a: | |
19002 | + return "rex64Y"; | |
19003 | + case 0x4b: | |
19004 | + return "rex64YZ"; | |
19005 | + case 0x4c: | |
19006 | + return "rex64X"; | |
19007 | + case 0x4d: | |
19008 | + return "rex64XZ"; | |
19009 | + case 0x4e: | |
19010 | + return "rex64XY"; | |
19011 | + case 0x4f: | |
19012 | + return "rex64XYZ"; | |
19013 | + case 0xf3: | |
19014 | + return "repz"; | |
19015 | + case 0xf2: | |
19016 | + return "repnz"; | |
19017 | + case 0xf0: | |
19018 | + return "lock"; | |
19019 | + case 0x2e: | |
19020 | + return "cs"; | |
19021 | + case 0x36: | |
19022 | + return "ss"; | |
19023 | + case 0x3e: | |
19024 | + return "ds"; | |
19025 | + case 0x26: | |
19026 | + return "es"; | |
19027 | + case 0x64: | |
19028 | + return "fs"; | |
19029 | + case 0x65: | |
19030 | + return "gs"; | |
19031 | + case 0x66: | |
19032 | + return (sizeflag & DFLAG) ? "data16" : "data32"; | |
19033 | + case 0x67: | |
19034 | + if (mode_64bit) | |
19035 | + return (sizeflag & AFLAG) ? "addr32" : "addr64"; | |
19036 | + else | |
19037 | + return (sizeflag & AFLAG) ? "addr16" : "addr32"; | |
19038 | + case FWAIT_OPCODE: | |
19039 | + return "fwait"; | |
19040 | + default: | |
19041 | + return NULL; | |
19042 | + } | |
19043 | +} | |
19044 | + | |
19045 | +static char op1out[100], op2out[100], op3out[100]; | |
19046 | +static int op_ad, op_index[3]; | |
19047 | +static int two_source_ops; | |
19048 | +static bfd_vma op_address[3]; | |
19049 | +static bfd_vma op_riprel[3]; | |
19050 | +static bfd_vma start_pc; | |
19051 | + | |
19052 | +/* | |
19053 | + * On the 386's of 1988, the maximum length of an instruction is 15 bytes. | |
19054 | + * (see topic "Redundant prefixes" in the "Differences from 8086" | |
19055 | + * section of the "Virtual 8086 Mode" chapter.) | |
19056 | + * 'pc' should be the address of this instruction, it will | |
19057 | + * be used to print the target address if this is a relative jump or call | |
19058 | + * The function returns the length of this instruction in bytes. | |
19059 | + */ | |
19060 | + | |
19061 | +static char intel_syntax; | |
19062 | +static char open_char; | |
19063 | +static char close_char; | |
19064 | +static char separator_char; | |
19065 | +static char scale_char; | |
19066 | + | |
19067 | +/* Here for backwards compatibility. When gdb stops using | |
19068 | + print_insn_i386_att and print_insn_i386_intel these functions can | |
19069 | + disappear, and print_insn_i386 be merged into print_insn. */ | |
19070 | +int | |
19071 | +print_insn_i386_att (bfd_vma pc, disassemble_info *info) | |
19072 | +{ | |
19073 | + intel_syntax = 0; | |
19074 | + | |
19075 | + return print_insn (pc, info); | |
19076 | +} | |
19077 | + | |
19078 | +int | |
19079 | +print_insn_i386_intel (bfd_vma pc, disassemble_info *info) | |
19080 | +{ | |
19081 | + intel_syntax = 1; | |
19082 | + | |
19083 | + return print_insn (pc, info); | |
19084 | +} | |
19085 | + | |
19086 | +int | |
19087 | +print_insn_i386 (bfd_vma pc, disassemble_info *info) | |
19088 | +{ | |
19089 | + intel_syntax = -1; | |
19090 | + | |
19091 | + return print_insn (pc, info); | |
19092 | +} | |
19093 | + | |
19094 | +static int | |
19095 | +print_insn (bfd_vma pc, disassemble_info *info) | |
19096 | +{ | |
19097 | + const struct dis386 *dp; | |
19098 | + int i; | |
19099 | + char *first, *second, *third; | |
19100 | + int needcomma; | |
19101 | + unsigned char uses_SSE_prefix, uses_LOCK_prefix; | |
19102 | + int sizeflag; | |
19103 | + const char *p; | |
19104 | + struct dis_private priv; | |
19105 | + | |
19106 | + mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax | |
19107 | + || info->mach == bfd_mach_x86_64); | |
19108 | + | |
19109 | + if (intel_syntax == (char) -1) | |
19110 | + intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax | |
19111 | + || info->mach == bfd_mach_x86_64_intel_syntax); | |
19112 | + | |
19113 | + if (info->mach == bfd_mach_i386_i386 | |
19114 | + || info->mach == bfd_mach_x86_64 | |
19115 | + || info->mach == bfd_mach_i386_i386_intel_syntax | |
19116 | + || info->mach == bfd_mach_x86_64_intel_syntax) | |
19117 | + priv.orig_sizeflag = AFLAG | DFLAG; | |
19118 | + else if (info->mach == bfd_mach_i386_i8086) | |
19119 | + priv.orig_sizeflag = 0; | |
19120 | + else | |
19121 | + abort (); | |
19122 | + | |
19123 | + for (p = info->disassembler_options; p != NULL; ) | |
19124 | + { | |
19125 | + if (strncmp (p, "x86-64", 6) == 0) | |
19126 | + { | |
19127 | + mode_64bit = 1; | |
19128 | + priv.orig_sizeflag = AFLAG | DFLAG; | |
19129 | + } | |
19130 | + else if (strncmp (p, "i386", 4) == 0) | |
19131 | + { | |
19132 | + mode_64bit = 0; | |
19133 | + priv.orig_sizeflag = AFLAG | DFLAG; | |
19134 | + } | |
19135 | + else if (strncmp (p, "i8086", 5) == 0) | |
19136 | + { | |
19137 | + mode_64bit = 0; | |
19138 | + priv.orig_sizeflag = 0; | |
19139 | + } | |
19140 | + else if (strncmp (p, "intel", 5) == 0) | |
19141 | + { | |
19142 | + intel_syntax = 1; | |
19143 | + } | |
19144 | + else if (strncmp (p, "att", 3) == 0) | |
19145 | + { | |
19146 | + intel_syntax = 0; | |
19147 | + } | |
19148 | + else if (strncmp (p, "addr", 4) == 0) | |
19149 | + { | |
19150 | + if (p[4] == '1' && p[5] == '6') | |
19151 | + priv.orig_sizeflag &= ~AFLAG; | |
19152 | + else if (p[4] == '3' && p[5] == '2') | |
19153 | + priv.orig_sizeflag |= AFLAG; | |
19154 | + } | |
19155 | + else if (strncmp (p, "data", 4) == 0) | |
19156 | + { | |
19157 | + if (p[4] == '1' && p[5] == '6') | |
19158 | + priv.orig_sizeflag &= ~DFLAG; | |
19159 | + else if (p[4] == '3' && p[5] == '2') | |
19160 | + priv.orig_sizeflag |= DFLAG; | |
19161 | + } | |
19162 | + else if (strncmp (p, "suffix", 6) == 0) | |
19163 | + priv.orig_sizeflag |= SUFFIX_ALWAYS; | |
19164 | + | |
19165 | + p = strchr (p, ','); | |
19166 | + if (p != NULL) | |
19167 | + p++; | |
19168 | + } | |
19169 | + | |
19170 | + if (intel_syntax) | |
19171 | + { | |
19172 | + names64 = intel_names64; | |
19173 | + names32 = intel_names32; | |
19174 | + names16 = intel_names16; | |
19175 | + names8 = intel_names8; | |
19176 | + names8rex = intel_names8rex; | |
19177 | + names_seg = intel_names_seg; | |
19178 | + index16 = intel_index16; | |
19179 | + open_char = '['; | |
19180 | + close_char = ']'; | |
19181 | + separator_char = '+'; | |
19182 | + scale_char = '*'; | |
19183 | + } | |
19184 | + else | |
19185 | + { | |
19186 | + names64 = att_names64; | |
19187 | + names32 = att_names32; | |
19188 | + names16 = att_names16; | |
19189 | + names8 = att_names8; | |
19190 | + names8rex = att_names8rex; | |
19191 | + names_seg = att_names_seg; | |
19192 | + index16 = att_index16; | |
19193 | + open_char = '('; | |
19194 | + close_char = ')'; | |
19195 | + separator_char = ','; | |
19196 | + scale_char = ','; | |
19197 | + } | |
19198 | + | |
19199 | + /* The output looks better if we put 7 bytes on a line, since that | |
19200 | + puts most long word instructions on a single line. */ | |
19201 | + info->bytes_per_line = 7; | |
19202 | + | |
19203 | + info->private_data = &priv; | |
19204 | + priv.max_fetched = priv.the_buffer; | |
19205 | + priv.insn_start = pc; | |
19206 | + | |
19207 | + obuf[0] = 0; | |
19208 | + op1out[0] = 0; | |
19209 | + op2out[0] = 0; | |
19210 | + op3out[0] = 0; | |
19211 | + | |
19212 | + op_index[0] = op_index[1] = op_index[2] = -1; | |
19213 | + | |
19214 | + the_info = info; | |
19215 | + start_pc = pc; | |
19216 | + start_codep = priv.the_buffer; | |
19217 | + codep = priv.the_buffer; | |
19218 | + | |
19219 | +#ifndef __KERNEL__ | |
19220 | + if (setjmp (priv.bailout) != 0) | |
19221 | + { | |
19222 | + const char *name; | |
19223 | + | |
19224 | + /* Getting here means we tried for data but didn't get it. That | |
19225 | + means we have an incomplete instruction of some sort. Just | |
19226 | + print the first byte as a prefix or a .byte pseudo-op. */ | |
19227 | + if (codep > priv.the_buffer) | |
19228 | + { | |
19229 | + name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag); | |
19230 | + if (name != NULL) | |
19231 | + (*info->fprintf_func) (info->stream, "%s", name); | |
19232 | + else | |
19233 | + { | |
19234 | + /* Just print the first byte as a .byte instruction. */ | |
19235 | + (*info->fprintf_func) (info->stream, ".byte 0x%x", | |
19236 | + (unsigned int) priv.the_buffer[0]); | |
19237 | + } | |
19238 | + | |
19239 | + return 1; | |
19240 | + } | |
19241 | + | |
19242 | + return -1; | |
19243 | + } | |
19244 | +#endif /* __KERNEL__ */ | |
19245 | + | |
19246 | + obufp = obuf; | |
19247 | + ckprefix (); | |
19248 | + | |
19249 | + insn_codep = codep; | |
19250 | + sizeflag = priv.orig_sizeflag; | |
19251 | + | |
19252 | + FETCH_DATA (info, codep + 1); | |
19253 | + two_source_ops = (*codep == 0x62) || (*codep == 0xc8); | |
19254 | + | |
19255 | + if ((prefixes & PREFIX_FWAIT) | |
19256 | + && ((*codep < 0xd8) || (*codep > 0xdf))) | |
19257 | + { | |
19258 | + const char *name; | |
19259 | + | |
19260 | + /* fwait not followed by floating point instruction. Print the | |
19261 | + first prefix, which is probably fwait itself. */ | |
19262 | + name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag); | |
19263 | + if (name == NULL) | |
19264 | + name = INTERNAL_DISASSEMBLER_ERROR; | |
19265 | + (*info->fprintf_func) (info->stream, "%s", name); | |
19266 | + return 1; | |
19267 | + } | |
19268 | + | |
19269 | + if (*codep == 0x0f) | |
19270 | + { | |
19271 | + FETCH_DATA (info, codep + 2); | |
19272 | + dp = &dis386_twobyte[*++codep]; | |
19273 | + need_modrm = twobyte_has_modrm[*codep]; | |
19274 | + uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep]; | |
19275 | + uses_LOCK_prefix = (*codep & ~0x02) == 0x20; | |
19276 | + } | |
19277 | + else | |
19278 | + { | |
19279 | + dp = &dis386[*codep]; | |
19280 | + need_modrm = onebyte_has_modrm[*codep]; | |
19281 | + uses_SSE_prefix = 0; | |
19282 | + uses_LOCK_prefix = 0; | |
19283 | + } | |
19284 | + codep++; | |
19285 | + | |
19286 | + if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ)) | |
19287 | + { | |
19288 | + oappend ("repz "); | |
19289 | + used_prefixes |= PREFIX_REPZ; | |
19290 | + } | |
19291 | + if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ)) | |
19292 | + { | |
19293 | + oappend ("repnz "); | |
19294 | + used_prefixes |= PREFIX_REPNZ; | |
19295 | + } | |
19296 | + if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK)) | |
19297 | + { | |
19298 | + oappend ("lock "); | |
19299 | + used_prefixes |= PREFIX_LOCK; | |
19300 | + } | |
19301 | + | |
19302 | + if (prefixes & PREFIX_ADDR) | |
19303 | + { | |
19304 | + sizeflag ^= AFLAG; | |
19305 | + if (dp->bytemode3 != loop_jcxz_mode || intel_syntax) | |
19306 | + { | |
19307 | + if ((sizeflag & AFLAG) || mode_64bit) | |
19308 | + oappend ("addr32 "); | |
19309 | + else | |
19310 | + oappend ("addr16 "); | |
19311 | + used_prefixes |= PREFIX_ADDR; | |
19312 | + } | |
19313 | + } | |
19314 | + | |
19315 | + if (!uses_SSE_prefix && (prefixes & PREFIX_DATA)) | |
19316 | + { | |
19317 | + sizeflag ^= DFLAG; | |
19318 | + if (dp->bytemode3 == cond_jump_mode | |
19319 | + && dp->bytemode1 == v_mode | |
19320 | + && !intel_syntax) | |
19321 | + { | |
19322 | + if (sizeflag & DFLAG) | |
19323 | + oappend ("data32 "); | |
19324 | + else | |
19325 | + oappend ("data16 "); | |
19326 | + used_prefixes |= PREFIX_DATA; | |
19327 | + } | |
19328 | + } | |
19329 | + | |
19330 | + if (need_modrm) | |
19331 | + { | |
19332 | + FETCH_DATA (info, codep + 1); | |
19333 | + mod = (*codep >> 6) & 3; | |
19334 | + reg = (*codep >> 3) & 7; | |
19335 | + rm = *codep & 7; | |
19336 | + } | |
19337 | + | |
19338 | + if (dp->name == NULL && dp->bytemode1 == FLOATCODE) | |
19339 | + { | |
19340 | + dofloat (sizeflag); | |
19341 | + } | |
19342 | + else | |
19343 | + { | |
19344 | + int index; | |
19345 | + if (dp->name == NULL) | |
19346 | + { | |
19347 | + switch (dp->bytemode1) | |
19348 | + { | |
19349 | + case USE_GROUPS: | |
19350 | + dp = &grps[dp->bytemode2][reg]; | |
19351 | + break; | |
19352 | + | |
19353 | + case USE_PREFIX_USER_TABLE: | |
19354 | + index = 0; | |
19355 | + used_prefixes |= (prefixes & PREFIX_REPZ); | |
19356 | + if (prefixes & PREFIX_REPZ) | |
19357 | + index = 1; | |
19358 | + else | |
19359 | + { | |
19360 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
19361 | + if (prefixes & PREFIX_DATA) | |
19362 | + index = 2; | |
19363 | + else | |
19364 | + { | |
19365 | + used_prefixes |= (prefixes & PREFIX_REPNZ); | |
19366 | + if (prefixes & PREFIX_REPNZ) | |
19367 | + index = 3; | |
19368 | + } | |
19369 | + } | |
19370 | + dp = &prefix_user_table[dp->bytemode2][index]; | |
19371 | + break; | |
19372 | + | |
19373 | + case X86_64_SPECIAL: | |
19374 | + dp = &x86_64_table[dp->bytemode2][mode_64bit]; | |
19375 | + break; | |
19376 | + | |
19377 | + default: | |
19378 | + oappend (INTERNAL_DISASSEMBLER_ERROR); | |
19379 | + break; | |
19380 | + } | |
19381 | + } | |
19382 | + | |
19383 | + if (putop (dp->name, sizeflag) == 0) | |
19384 | + { | |
19385 | + obufp = op1out; | |
19386 | + op_ad = 2; | |
19387 | + if (dp->op1) | |
19388 | + (*dp->op1) (dp->bytemode1, sizeflag); | |
19389 | + | |
19390 | + obufp = op2out; | |
19391 | + op_ad = 1; | |
19392 | + if (dp->op2) | |
19393 | + (*dp->op2) (dp->bytemode2, sizeflag); | |
19394 | + | |
19395 | + obufp = op3out; | |
19396 | + op_ad = 0; | |
19397 | + if (dp->op3) | |
19398 | + (*dp->op3) (dp->bytemode3, sizeflag); | |
19399 | + } | |
19400 | + } | |
19401 | + | |
19402 | + /* See if any prefixes were not used. If so, print the first one | |
19403 | + separately. If we don't do this, we'll wind up printing an | |
19404 | + instruction stream which does not precisely correspond to the | |
19405 | + bytes we are disassembling. */ | |
19406 | + if ((prefixes & ~used_prefixes) != 0) | |
19407 | + { | |
19408 | + const char *name; | |
19409 | + | |
19410 | + name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag); | |
19411 | + if (name == NULL) | |
19412 | + name = INTERNAL_DISASSEMBLER_ERROR; | |
19413 | + (*info->fprintf_func) (info->stream, "%s", name); | |
19414 | + return 1; | |
19415 | + } | |
19416 | + if (rex & ~rex_used) | |
19417 | + { | |
19418 | + const char *name; | |
19419 | + name = prefix_name (rex | 0x40, priv.orig_sizeflag); | |
19420 | + if (name == NULL) | |
19421 | + name = INTERNAL_DISASSEMBLER_ERROR; | |
19422 | + (*info->fprintf_func) (info->stream, "%s ", name); | |
19423 | + } | |
19424 | + | |
19425 | + obufp = obuf + strlen (obuf); | |
19426 | + for (i = strlen (obuf); i < 6; i++) | |
19427 | + oappend (" "); | |
19428 | + oappend (" "); | |
19429 | + (*info->fprintf_func) (info->stream, "%s", obuf); | |
19430 | + | |
19431 | + /* The enter and bound instructions are printed with operands in the same | |
19432 | + order as the intel book; everything else is printed in reverse order. */ | |
19433 | + if (intel_syntax || two_source_ops) | |
19434 | + { | |
19435 | + first = op1out; | |
19436 | + second = op2out; | |
19437 | + third = op3out; | |
19438 | + op_ad = op_index[0]; | |
19439 | + op_index[0] = op_index[2]; | |
19440 | + op_index[2] = op_ad; | |
19441 | + } | |
19442 | + else | |
19443 | + { | |
19444 | + first = op3out; | |
19445 | + second = op2out; | |
19446 | + third = op1out; | |
19447 | + } | |
19448 | + needcomma = 0; | |
19449 | + if (*first) | |
19450 | + { | |
19451 | + if (op_index[0] != -1 && !op_riprel[0]) | |
19452 | + (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info); | |
19453 | + else | |
19454 | + (*info->fprintf_func) (info->stream, "%s", first); | |
19455 | + needcomma = 1; | |
19456 | + } | |
19457 | + if (*second) | |
19458 | + { | |
19459 | + if (needcomma) | |
19460 | + (*info->fprintf_func) (info->stream, ","); | |
19461 | + if (op_index[1] != -1 && !op_riprel[1]) | |
19462 | + (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info); | |
19463 | + else | |
19464 | + (*info->fprintf_func) (info->stream, "%s", second); | |
19465 | + needcomma = 1; | |
19466 | + } | |
19467 | + if (*third) | |
19468 | + { | |
19469 | + if (needcomma) | |
19470 | + (*info->fprintf_func) (info->stream, ","); | |
19471 | + if (op_index[2] != -1 && !op_riprel[2]) | |
19472 | + (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info); | |
19473 | + else | |
19474 | + (*info->fprintf_func) (info->stream, "%s", third); | |
19475 | + } | |
19476 | + for (i = 0; i < 3; i++) | |
19477 | + if (op_index[i] != -1 && op_riprel[i]) | |
19478 | + { | |
19479 | + (*info->fprintf_func) (info->stream, " # "); | |
19480 | + (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep | |
19481 | + + op_address[op_index[i]]), info); | |
19482 | + } | |
19483 | + return codep - priv.the_buffer; | |
19484 | +} | |
19485 | + | |
19486 | +static const char *float_mem[] = { | |
19487 | + /* d8 */ | |
19488 | + "fadd{s||s|}", | |
19489 | + "fmul{s||s|}", | |
19490 | + "fcom{s||s|}", | |
19491 | + "fcomp{s||s|}", | |
19492 | + "fsub{s||s|}", | |
19493 | + "fsubr{s||s|}", | |
19494 | + "fdiv{s||s|}", | |
19495 | + "fdivr{s||s|}", | |
19496 | + /* d9 */ | |
19497 | + "fld{s||s|}", | |
19498 | + "(bad)", | |
19499 | + "fst{s||s|}", | |
19500 | + "fstp{s||s|}", | |
19501 | + "fldenvIC", | |
19502 | + "fldcw", | |
19503 | + "fNstenvIC", | |
19504 | + "fNstcw", | |
19505 | + /* da */ | |
19506 | + "fiadd{l||l|}", | |
19507 | + "fimul{l||l|}", | |
19508 | + "ficom{l||l|}", | |
19509 | + "ficomp{l||l|}", | |
19510 | + "fisub{l||l|}", | |
19511 | + "fisubr{l||l|}", | |
19512 | + "fidiv{l||l|}", | |
19513 | + "fidivr{l||l|}", | |
19514 | + /* db */ | |
19515 | + "fild{l||l|}", | |
19516 | + "fisttp{l||l|}", | |
19517 | + "fist{l||l|}", | |
19518 | + "fistp{l||l|}", | |
19519 | + "(bad)", | |
19520 | + "fld{t||t|}", | |
19521 | + "(bad)", | |
19522 | + "fstp{t||t|}", | |
19523 | + /* dc */ | |
19524 | + "fadd{l||l|}", | |
19525 | + "fmul{l||l|}", | |
19526 | + "fcom{l||l|}", | |
19527 | + "fcomp{l||l|}", | |
19528 | + "fsub{l||l|}", | |
19529 | + "fsubr{l||l|}", | |
19530 | + "fdiv{l||l|}", | |
19531 | + "fdivr{l||l|}", | |
19532 | + /* dd */ | |
19533 | + "fld{l||l|}", | |
19534 | + "fisttp{ll||ll|}", | |
19535 | + "fst{l||l|}", | |
19536 | + "fstp{l||l|}", | |
19537 | + "frstorIC", | |
19538 | + "(bad)", | |
19539 | + "fNsaveIC", | |
19540 | + "fNstsw", | |
19541 | + /* de */ | |
19542 | + "fiadd", | |
19543 | + "fimul", | |
19544 | + "ficom", | |
19545 | + "ficomp", | |
19546 | + "fisub", | |
19547 | + "fisubr", | |
19548 | + "fidiv", | |
19549 | + "fidivr", | |
19550 | + /* df */ | |
19551 | + "fild", | |
19552 | + "fisttp", | |
19553 | + "fist", | |
19554 | + "fistp", | |
19555 | + "fbld", | |
19556 | + "fild{ll||ll|}", | |
19557 | + "fbstp", | |
19558 | + "fistp{ll||ll|}", | |
19559 | +}; | |
19560 | + | |
19561 | +static const unsigned char float_mem_mode[] = { | |
19562 | + /* d8 */ | |
19563 | + d_mode, | |
19564 | + d_mode, | |
19565 | + d_mode, | |
19566 | + d_mode, | |
19567 | + d_mode, | |
19568 | + d_mode, | |
19569 | + d_mode, | |
19570 | + d_mode, | |
19571 | + /* d9 */ | |
19572 | + d_mode, | |
19573 | + 0, | |
19574 | + d_mode, | |
19575 | + d_mode, | |
19576 | + 0, | |
19577 | + w_mode, | |
19578 | + 0, | |
19579 | + w_mode, | |
19580 | + /* da */ | |
19581 | + d_mode, | |
19582 | + d_mode, | |
19583 | + d_mode, | |
19584 | + d_mode, | |
19585 | + d_mode, | |
19586 | + d_mode, | |
19587 | + d_mode, | |
19588 | + d_mode, | |
19589 | + /* db */ | |
19590 | + d_mode, | |
19591 | + d_mode, | |
19592 | + d_mode, | |
19593 | + d_mode, | |
19594 | + 0, | |
19595 | + t_mode, | |
19596 | + 0, | |
19597 | + t_mode, | |
19598 | + /* dc */ | |
19599 | + q_mode, | |
19600 | + q_mode, | |
19601 | + q_mode, | |
19602 | + q_mode, | |
19603 | + q_mode, | |
19604 | + q_mode, | |
19605 | + q_mode, | |
19606 | + q_mode, | |
19607 | + /* dd */ | |
19608 | + q_mode, | |
19609 | + q_mode, | |
19610 | + q_mode, | |
19611 | + q_mode, | |
19612 | + 0, | |
19613 | + 0, | |
19614 | + 0, | |
19615 | + w_mode, | |
19616 | + /* de */ | |
19617 | + w_mode, | |
19618 | + w_mode, | |
19619 | + w_mode, | |
19620 | + w_mode, | |
19621 | + w_mode, | |
19622 | + w_mode, | |
19623 | + w_mode, | |
19624 | + w_mode, | |
19625 | + /* df */ | |
19626 | + w_mode, | |
19627 | + w_mode, | |
19628 | + w_mode, | |
19629 | + w_mode, | |
19630 | + t_mode, | |
19631 | + q_mode, | |
19632 | + t_mode, | |
19633 | + q_mode | |
19634 | +}; | |
19635 | + | |
19636 | +#define ST OP_ST, 0 | |
19637 | +#define STi OP_STi, 0 | |
19638 | + | |
19639 | +#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0 | |
19640 | +#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0 | |
19641 | +#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0 | |
19642 | +#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0 | |
19643 | +#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0 | |
19644 | +#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0 | |
19645 | +#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0 | |
19646 | +#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0 | |
19647 | +#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0 | |
19648 | + | |
19649 | +static const struct dis386 float_reg[][8] = { | |
19650 | + /* d8 */ | |
19651 | + { | |
19652 | + { "fadd", ST, STi, XX }, | |
19653 | + { "fmul", ST, STi, XX }, | |
19654 | + { "fcom", STi, XX, XX }, | |
19655 | + { "fcomp", STi, XX, XX }, | |
19656 | + { "fsub", ST, STi, XX }, | |
19657 | + { "fsubr", ST, STi, XX }, | |
19658 | + { "fdiv", ST, STi, XX }, | |
19659 | + { "fdivr", ST, STi, XX }, | |
19660 | + }, | |
19661 | + /* d9 */ | |
19662 | + { | |
19663 | + { "fld", STi, XX, XX }, | |
19664 | + { "fxch", STi, XX, XX }, | |
19665 | + { FGRPd9_2 }, | |
19666 | + { "(bad)", XX, XX, XX }, | |
19667 | + { FGRPd9_4 }, | |
19668 | + { FGRPd9_5 }, | |
19669 | + { FGRPd9_6 }, | |
19670 | + { FGRPd9_7 }, | |
19671 | + }, | |
19672 | + /* da */ | |
19673 | + { | |
19674 | + { "fcmovb", ST, STi, XX }, | |
19675 | + { "fcmove", ST, STi, XX }, | |
19676 | + { "fcmovbe",ST, STi, XX }, | |
19677 | + { "fcmovu", ST, STi, XX }, | |
19678 | + { "(bad)", XX, XX, XX }, | |
19679 | + { FGRPda_5 }, | |
19680 | + { "(bad)", XX, XX, XX }, | |
19681 | + { "(bad)", XX, XX, XX }, | |
19682 | + }, | |
19683 | + /* db */ | |
19684 | + { | |
19685 | + { "fcmovnb",ST, STi, XX }, | |
19686 | + { "fcmovne",ST, STi, XX }, | |
19687 | + { "fcmovnbe",ST, STi, XX }, | |
19688 | + { "fcmovnu",ST, STi, XX }, | |
19689 | + { FGRPdb_4 }, | |
19690 | + { "fucomi", ST, STi, XX }, | |
19691 | + { "fcomi", ST, STi, XX }, | |
19692 | + { "(bad)", XX, XX, XX }, | |
19693 | + }, | |
19694 | + /* dc */ | |
19695 | + { | |
19696 | + { "fadd", STi, ST, XX }, | |
19697 | + { "fmul", STi, ST, XX }, | |
19698 | + { "(bad)", XX, XX, XX }, | |
19699 | + { "(bad)", XX, XX, XX }, | |
19700 | +#if UNIXWARE_COMPAT | |
19701 | + { "fsub", STi, ST, XX }, | |
19702 | + { "fsubr", STi, ST, XX }, | |
19703 | + { "fdiv", STi, ST, XX }, | |
19704 | + { "fdivr", STi, ST, XX }, | |
19705 | +#else | |
19706 | + { "fsubr", STi, ST, XX }, | |
19707 | + { "fsub", STi, ST, XX }, | |
19708 | + { "fdivr", STi, ST, XX }, | |
19709 | + { "fdiv", STi, ST, XX }, | |
19710 | +#endif | |
19711 | + }, | |
19712 | + /* dd */ | |
19713 | + { | |
19714 | + { "ffree", STi, XX, XX }, | |
19715 | + { "(bad)", XX, XX, XX }, | |
19716 | + { "fst", STi, XX, XX }, | |
19717 | + { "fstp", STi, XX, XX }, | |
19718 | + { "fucom", STi, XX, XX }, | |
19719 | + { "fucomp", STi, XX, XX }, | |
19720 | + { "(bad)", XX, XX, XX }, | |
19721 | + { "(bad)", XX, XX, XX }, | |
19722 | + }, | |
19723 | + /* de */ | |
19724 | + { | |
19725 | + { "faddp", STi, ST, XX }, | |
19726 | + { "fmulp", STi, ST, XX }, | |
19727 | + { "(bad)", XX, XX, XX }, | |
19728 | + { FGRPde_3 }, | |
19729 | +#if UNIXWARE_COMPAT | |
19730 | + { "fsubp", STi, ST, XX }, | |
19731 | + { "fsubrp", STi, ST, XX }, | |
19732 | + { "fdivp", STi, ST, XX }, | |
19733 | + { "fdivrp", STi, ST, XX }, | |
19734 | +#else | |
19735 | + { "fsubrp", STi, ST, XX }, | |
19736 | + { "fsubp", STi, ST, XX }, | |
19737 | + { "fdivrp", STi, ST, XX }, | |
19738 | + { "fdivp", STi, ST, XX }, | |
19739 | +#endif | |
19740 | + }, | |
19741 | + /* df */ | |
19742 | + { | |
19743 | + { "ffreep", STi, XX, XX }, | |
19744 | + { "(bad)", XX, XX, XX }, | |
19745 | + { "(bad)", XX, XX, XX }, | |
19746 | + { "(bad)", XX, XX, XX }, | |
19747 | + { FGRPdf_4 }, | |
19748 | + { "fucomip",ST, STi, XX }, | |
19749 | + { "fcomip", ST, STi, XX }, | |
19750 | + { "(bad)", XX, XX, XX }, | |
19751 | + }, | |
19752 | +}; | |
19753 | + | |
19754 | +static char *fgrps[][8] = { | |
19755 | + /* d9_2 0 */ | |
19756 | + { | |
19757 | + "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", | |
19758 | + }, | |
19759 | + | |
19760 | + /* d9_4 1 */ | |
19761 | + { | |
19762 | + "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)", | |
19763 | + }, | |
19764 | + | |
19765 | + /* d9_5 2 */ | |
19766 | + { | |
19767 | + "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)", | |
19768 | + }, | |
19769 | + | |
19770 | + /* d9_6 3 */ | |
19771 | + { | |
19772 | + "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp", | |
19773 | + }, | |
19774 | + | |
19775 | + /* d9_7 4 */ | |
19776 | + { | |
19777 | + "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos", | |
19778 | + }, | |
19779 | + | |
19780 | + /* da_5 5 */ | |
19781 | + { | |
19782 | + "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", | |
19783 | + }, | |
19784 | + | |
19785 | + /* db_4 6 */ | |
19786 | + { | |
19787 | + "feni(287 only)","fdisi(287 only)","fNclex","fNinit", | |
19788 | + "fNsetpm(287 only)","(bad)","(bad)","(bad)", | |
19789 | + }, | |
19790 | + | |
19791 | + /* de_3 7 */ | |
19792 | + { | |
19793 | + "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", | |
19794 | + }, | |
19795 | + | |
19796 | + /* df_4 8 */ | |
19797 | + { | |
19798 | + "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)", | |
19799 | + }, | |
19800 | +}; | |
19801 | + | |
19802 | +static void | |
19803 | +dofloat (int sizeflag) | |
19804 | +{ | |
19805 | + const struct dis386 *dp; | |
19806 | + unsigned char floatop; | |
19807 | + | |
19808 | + floatop = codep[-1]; | |
19809 | + | |
19810 | + if (mod != 3) | |
19811 | + { | |
19812 | + int fp_indx = (floatop - 0xd8) * 8 + reg; | |
19813 | + | |
19814 | + putop (float_mem[fp_indx], sizeflag); | |
19815 | + obufp = op1out; | |
19816 | + OP_E (float_mem_mode[fp_indx], sizeflag); | |
19817 | + return; | |
19818 | + } | |
19819 | + /* Skip mod/rm byte. */ | |
19820 | + MODRM_CHECK; | |
19821 | + codep++; | |
19822 | + | |
19823 | + dp = &float_reg[floatop - 0xd8][reg]; | |
19824 | + if (dp->name == NULL) | |
19825 | + { | |
19826 | + putop (fgrps[dp->bytemode1][rm], sizeflag); | |
19827 | + | |
19828 | + /* Instruction fnstsw is only one with strange arg. */ | |
19829 | + if (floatop == 0xdf && codep[-1] == 0xe0) | |
19830 | + strcpy (op1out, names16[0]); | |
19831 | + } | |
19832 | + else | |
19833 | + { | |
19834 | + putop (dp->name, sizeflag); | |
19835 | + | |
19836 | + obufp = op1out; | |
19837 | + if (dp->op1) | |
19838 | + (*dp->op1) (dp->bytemode1, sizeflag); | |
19839 | + obufp = op2out; | |
19840 | + if (dp->op2) | |
19841 | + (*dp->op2) (dp->bytemode2, sizeflag); | |
19842 | + } | |
19843 | +} | |
19844 | + | |
19845 | +static void | |
19846 | +OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
19847 | +{ | |
19848 | + oappend ("%st"); | |
19849 | +} | |
19850 | + | |
19851 | +static void | |
19852 | +OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
19853 | +{ | |
19854 | + sprintf (scratchbuf, "%%st(%d)", rm); | |
19855 | + oappend (scratchbuf + intel_syntax); | |
19856 | +} | |
19857 | + | |
19858 | +/* Capital letters in template are macros. */ | |
19859 | +static int | |
19860 | +putop (const char *template, int sizeflag) | |
19861 | +{ | |
19862 | + const char *p; | |
19863 | + int alt = 0; | |
19864 | + | |
19865 | + for (p = template; *p; p++) | |
19866 | + { | |
19867 | + switch (*p) | |
19868 | + { | |
19869 | + default: | |
19870 | + *obufp++ = *p; | |
19871 | + break; | |
19872 | + case '{': | |
19873 | + alt = 0; | |
19874 | + if (intel_syntax) | |
19875 | + alt += 1; | |
19876 | + if (mode_64bit) | |
19877 | + alt += 2; | |
19878 | + while (alt != 0) | |
19879 | + { | |
19880 | + while (*++p != '|') | |
19881 | + { | |
19882 | + if (*p == '}') | |
19883 | + { | |
19884 | + /* Alternative not valid. */ | |
19885 | + strcpy (obuf, "(bad)"); | |
19886 | + obufp = obuf + 5; | |
19887 | + return 1; | |
19888 | + } | |
19889 | + else if (*p == '\0') | |
19890 | + abort (); | |
19891 | + } | |
19892 | + alt--; | |
19893 | + } | |
19894 | + /* Fall through. */ | |
19895 | + case 'I': | |
19896 | + alt = 1; | |
19897 | + continue; | |
19898 | + case '|': | |
19899 | + while (*++p != '}') | |
19900 | + { | |
19901 | + if (*p == '\0') | |
19902 | + abort (); | |
19903 | + } | |
19904 | + break; | |
19905 | + case '}': | |
19906 | + break; | |
19907 | + case 'A': | |
19908 | + if (intel_syntax) | |
19909 | + break; | |
19910 | + if (mod != 3 || (sizeflag & SUFFIX_ALWAYS)) | |
19911 | + *obufp++ = 'b'; | |
19912 | + break; | |
19913 | + case 'B': | |
19914 | + if (intel_syntax) | |
19915 | + break; | |
19916 | + if (sizeflag & SUFFIX_ALWAYS) | |
19917 | + *obufp++ = 'b'; | |
19918 | + break; | |
19919 | + case 'C': | |
19920 | + if (intel_syntax && !alt) | |
19921 | + break; | |
19922 | + if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS)) | |
19923 | + { | |
19924 | + if (sizeflag & DFLAG) | |
19925 | + *obufp++ = intel_syntax ? 'd' : 'l'; | |
19926 | + else | |
19927 | + *obufp++ = intel_syntax ? 'w' : 's'; | |
19928 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
19929 | + } | |
19930 | + break; | |
19931 | + case 'E': /* For jcxz/jecxz */ | |
19932 | + if (mode_64bit) | |
19933 | + { | |
19934 | + if (sizeflag & AFLAG) | |
19935 | + *obufp++ = 'r'; | |
19936 | + else | |
19937 | + *obufp++ = 'e'; | |
19938 | + } | |
19939 | + else | |
19940 | + if (sizeflag & AFLAG) | |
19941 | + *obufp++ = 'e'; | |
19942 | + used_prefixes |= (prefixes & PREFIX_ADDR); | |
19943 | + break; | |
19944 | + case 'F': | |
19945 | + if (intel_syntax) | |
19946 | + break; | |
19947 | + if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS)) | |
19948 | + { | |
19949 | + if (sizeflag & AFLAG) | |
19950 | + *obufp++ = mode_64bit ? 'q' : 'l'; | |
19951 | + else | |
19952 | + *obufp++ = mode_64bit ? 'l' : 'w'; | |
19953 | + used_prefixes |= (prefixes & PREFIX_ADDR); | |
19954 | + } | |
19955 | + break; | |
19956 | + case 'H': | |
19957 | + if (intel_syntax) | |
19958 | + break; | |
19959 | + if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS | |
19960 | + || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS) | |
19961 | + { | |
19962 | + used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS); | |
19963 | + *obufp++ = ','; | |
19964 | + *obufp++ = 'p'; | |
19965 | + if (prefixes & PREFIX_DS) | |
19966 | + *obufp++ = 't'; | |
19967 | + else | |
19968 | + *obufp++ = 'n'; | |
19969 | + } | |
19970 | + break; | |
19971 | + case 'J': | |
19972 | + if (intel_syntax) | |
19973 | + break; | |
19974 | + *obufp++ = 'l'; | |
19975 | + break; | |
19976 | + case 'L': | |
19977 | + if (intel_syntax) | |
19978 | + break; | |
19979 | + if (sizeflag & SUFFIX_ALWAYS) | |
19980 | + *obufp++ = 'l'; | |
19981 | + break; | |
19982 | + case 'N': | |
19983 | + if ((prefixes & PREFIX_FWAIT) == 0) | |
19984 | + *obufp++ = 'n'; | |
19985 | + else | |
19986 | + used_prefixes |= PREFIX_FWAIT; | |
19987 | + break; | |
19988 | + case 'O': | |
19989 | + USED_REX (REX_MODE64); | |
19990 | + if (rex & REX_MODE64) | |
19991 | + *obufp++ = 'o'; | |
19992 | + else | |
19993 | + *obufp++ = 'd'; | |
19994 | + break; | |
19995 | + case 'T': | |
19996 | + if (intel_syntax) | |
19997 | + break; | |
19998 | + if (mode_64bit) | |
19999 | + { | |
20000 | + *obufp++ = 'q'; | |
20001 | + break; | |
20002 | + } | |
20003 | + /* Fall through. */ | |
20004 | + case 'P': | |
20005 | + if (intel_syntax) | |
20006 | + break; | |
20007 | + if ((prefixes & PREFIX_DATA) | |
20008 | + || (rex & REX_MODE64) | |
20009 | + || (sizeflag & SUFFIX_ALWAYS)) | |
20010 | + { | |
20011 | + USED_REX (REX_MODE64); | |
20012 | + if (rex & REX_MODE64) | |
20013 | + *obufp++ = 'q'; | |
20014 | + else | |
20015 | + { | |
20016 | + if (sizeflag & DFLAG) | |
20017 | + *obufp++ = 'l'; | |
20018 | + else | |
20019 | + *obufp++ = 'w'; | |
20020 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
20021 | + } | |
20022 | + } | |
20023 | + break; | |
20024 | + case 'U': | |
20025 | + if (intel_syntax) | |
20026 | + break; | |
20027 | + if (mode_64bit) | |
20028 | + { | |
20029 | + *obufp++ = 'q'; | |
20030 | + break; | |
20031 | + } | |
20032 | + /* Fall through. */ | |
20033 | + case 'Q': | |
20034 | + if (intel_syntax && !alt) | |
20035 | + break; | |
20036 | + USED_REX (REX_MODE64); | |
20037 | + if (mod != 3 || (sizeflag & SUFFIX_ALWAYS)) | |
20038 | + { | |
20039 | + if (rex & REX_MODE64) | |
20040 | + *obufp++ = 'q'; | |
20041 | + else | |
20042 | + { | |
20043 | + if (sizeflag & DFLAG) | |
20044 | + *obufp++ = intel_syntax ? 'd' : 'l'; | |
20045 | + else | |
20046 | + *obufp++ = 'w'; | |
20047 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
20048 | + } | |
20049 | + } | |
20050 | + break; | |
20051 | + case 'R': | |
20052 | + USED_REX (REX_MODE64); | |
20053 | + if (intel_syntax) | |
20054 | + { | |
20055 | + if (rex & REX_MODE64) | |
20056 | + { | |
20057 | + *obufp++ = 'q'; | |
20058 | + *obufp++ = 't'; | |
20059 | + } | |
20060 | + else if (sizeflag & DFLAG) | |
20061 | + { | |
20062 | + *obufp++ = 'd'; | |
20063 | + *obufp++ = 'q'; | |
20064 | + } | |
20065 | + else | |
20066 | + { | |
20067 | + *obufp++ = 'w'; | |
20068 | + *obufp++ = 'd'; | |
20069 | + } | |
20070 | + } | |
20071 | + else | |
20072 | + { | |
20073 | + if (rex & REX_MODE64) | |
20074 | + *obufp++ = 'q'; | |
20075 | + else if (sizeflag & DFLAG) | |
20076 | + *obufp++ = 'l'; | |
20077 | + else | |
20078 | + *obufp++ = 'w'; | |
20079 | + } | |
20080 | + if (!(rex & REX_MODE64)) | |
20081 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
20082 | + break; | |
20083 | + case 'S': | |
20084 | + if (intel_syntax) | |
20085 | + break; | |
20086 | + if (sizeflag & SUFFIX_ALWAYS) | |
20087 | + { | |
20088 | + if (rex & REX_MODE64) | |
20089 | + *obufp++ = 'q'; | |
20090 | + else | |
20091 | + { | |
20092 | + if (sizeflag & DFLAG) | |
20093 | + *obufp++ = 'l'; | |
20094 | + else | |
20095 | + *obufp++ = 'w'; | |
20096 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
20097 | + } | |
20098 | + } | |
20099 | + break; | |
20100 | + case 'X': | |
20101 | + if (prefixes & PREFIX_DATA) | |
20102 | + *obufp++ = 'd'; | |
20103 | + else | |
20104 | + *obufp++ = 's'; | |
20105 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
20106 | + break; | |
20107 | + case 'Y': | |
20108 | + if (intel_syntax) | |
20109 | + break; | |
20110 | + if (rex & REX_MODE64) | |
20111 | + { | |
20112 | + USED_REX (REX_MODE64); | |
20113 | + *obufp++ = 'q'; | |
20114 | + } | |
20115 | + break; | |
20116 | + /* implicit operand size 'l' for i386 or 'q' for x86-64 */ | |
20117 | + case 'W': | |
20118 | + /* operand size flag for cwtl, cbtw */ | |
20119 | + USED_REX (0); | |
20120 | + if (rex) | |
20121 | + *obufp++ = 'l'; | |
20122 | + else if (sizeflag & DFLAG) | |
20123 | + *obufp++ = 'w'; | |
20124 | + else | |
20125 | + *obufp++ = 'b'; | |
20126 | + if (intel_syntax) | |
20127 | + { | |
20128 | + if (rex) | |
20129 | + { | |
20130 | + *obufp++ = 'q'; | |
20131 | + *obufp++ = 'e'; | |
20132 | + } | |
20133 | + if (sizeflag & DFLAG) | |
20134 | + { | |
20135 | + *obufp++ = 'd'; | |
20136 | + *obufp++ = 'e'; | |
20137 | + } | |
20138 | + else | |
20139 | + { | |
20140 | + *obufp++ = 'w'; | |
20141 | + } | |
20142 | + } | |
20143 | + if (!rex) | |
20144 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
20145 | + break; | |
20146 | + } | |
20147 | + alt = 0; | |
20148 | + } | |
20149 | + *obufp = 0; | |
20150 | + return 0; | |
20151 | +} | |
20152 | + | |
20153 | +static void | |
20154 | +oappend (const char *s) | |
20155 | +{ | |
20156 | + strcpy (obufp, s); | |
20157 | + obufp += strlen (s); | |
20158 | +} | |
20159 | + | |
20160 | +static void | |
20161 | +append_seg (void) | |
20162 | +{ | |
20163 | + if (prefixes & PREFIX_CS) | |
20164 | + { | |
20165 | + used_prefixes |= PREFIX_CS; | |
20166 | + oappend ("%cs:" + intel_syntax); | |
20167 | + } | |
20168 | + if (prefixes & PREFIX_DS) | |
20169 | + { | |
20170 | + used_prefixes |= PREFIX_DS; | |
20171 | + oappend ("%ds:" + intel_syntax); | |
20172 | + } | |
20173 | + if (prefixes & PREFIX_SS) | |
20174 | + { | |
20175 | + used_prefixes |= PREFIX_SS; | |
20176 | + oappend ("%ss:" + intel_syntax); | |
20177 | + } | |
20178 | + if (prefixes & PREFIX_ES) | |
20179 | + { | |
20180 | + used_prefixes |= PREFIX_ES; | |
20181 | + oappend ("%es:" + intel_syntax); | |
20182 | + } | |
20183 | + if (prefixes & PREFIX_FS) | |
20184 | + { | |
20185 | + used_prefixes |= PREFIX_FS; | |
20186 | + oappend ("%fs:" + intel_syntax); | |
20187 | + } | |
20188 | + if (prefixes & PREFIX_GS) | |
20189 | + { | |
20190 | + used_prefixes |= PREFIX_GS; | |
20191 | + oappend ("%gs:" + intel_syntax); | |
20192 | + } | |
20193 | +} | |
20194 | + | |
20195 | +static void | |
20196 | +OP_indirE (int bytemode, int sizeflag) | |
20197 | +{ | |
20198 | + if (!intel_syntax) | |
20199 | + oappend ("*"); | |
20200 | + OP_E (bytemode, sizeflag); | |
20201 | +} | |
20202 | + | |
20203 | +static void | |
20204 | +print_operand_value (char *buf, int hex, bfd_vma disp) | |
20205 | +{ | |
20206 | + if (mode_64bit) | |
20207 | + { | |
20208 | + if (hex) | |
20209 | + { | |
20210 | + char tmp[30]; | |
20211 | + int i; | |
20212 | + buf[0] = '0'; | |
20213 | + buf[1] = 'x'; | |
20214 | + sprintf_vma (tmp, disp); | |
20215 | + for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++); | |
20216 | + strcpy (buf + 2, tmp + i); | |
20217 | + } | |
20218 | + else | |
20219 | + { | |
20220 | + bfd_signed_vma v = disp; | |
20221 | + char tmp[30]; | |
20222 | + int i; | |
20223 | + if (v < 0) | |
20224 | + { | |
20225 | + *(buf++) = '-'; | |
20226 | + v = -disp; | |
20227 | + /* Check for possible overflow on 0x8000000000000000. */ | |
20228 | + if (v < 0) | |
20229 | + { | |
20230 | + strcpy (buf, "9223372036854775808"); | |
20231 | + return; | |
20232 | + } | |
20233 | + } | |
20234 | + if (!v) | |
20235 | + { | |
20236 | + strcpy (buf, "0"); | |
20237 | + return; | |
20238 | + } | |
20239 | + | |
20240 | + i = 0; | |
20241 | + tmp[29] = 0; | |
20242 | + while (v) | |
20243 | + { | |
20244 | + tmp[28 - i] = (v % 10) + '0'; | |
20245 | + v /= 10; | |
20246 | + i++; | |
20247 | + } | |
20248 | + strcpy (buf, tmp + 29 - i); | |
20249 | + } | |
20250 | + } | |
20251 | + else | |
20252 | + { | |
20253 | + if (hex) | |
20254 | + sprintf (buf, "0x%x", (unsigned int) disp); | |
20255 | + else | |
20256 | + sprintf (buf, "%d", (int) disp); | |
20257 | + } | |
20258 | +} | |
20259 | + | |
20260 | +static void | |
20261 | +OP_E (int bytemode, int sizeflag) | |
20262 | +{ | |
20263 | + bfd_vma disp; | |
20264 | + int add = 0; | |
20265 | + int riprel = 0; | |
20266 | + USED_REX (REX_EXTZ); | |
20267 | + if (rex & REX_EXTZ) | |
20268 | + add += 8; | |
20269 | + | |
20270 | + /* Skip mod/rm byte. */ | |
20271 | + MODRM_CHECK; | |
20272 | + codep++; | |
20273 | + | |
20274 | + if (mod == 3) | |
20275 | + { | |
20276 | + switch (bytemode) | |
20277 | + { | |
20278 | + case b_mode: | |
20279 | + USED_REX (0); | |
20280 | + if (rex) | |
20281 | + oappend (names8rex[rm + add]); | |
20282 | + else | |
20283 | + oappend (names8[rm + add]); | |
20284 | + break; | |
20285 | + case w_mode: | |
20286 | + oappend (names16[rm + add]); | |
20287 | + break; | |
20288 | + case d_mode: | |
20289 | + oappend (names32[rm + add]); | |
20290 | + break; | |
20291 | + case q_mode: | |
20292 | + oappend (names64[rm + add]); | |
20293 | + break; | |
20294 | + case m_mode: | |
20295 | + if (mode_64bit) | |
20296 | + oappend (names64[rm + add]); | |
20297 | + else | |
20298 | + oappend (names32[rm + add]); | |
20299 | + break; | |
20300 | + case branch_v_mode: | |
20301 | + if (mode_64bit) | |
20302 | + oappend (names64[rm + add]); | |
20303 | + else | |
20304 | + { | |
20305 | + if ((sizeflag & DFLAG) || bytemode != branch_v_mode) | |
20306 | + oappend (names32[rm + add]); | |
20307 | + else | |
20308 | + oappend (names16[rm + add]); | |
20309 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
20310 | + } | |
20311 | + break; | |
20312 | + case v_mode: | |
20313 | + case dq_mode: | |
20314 | + case dqw_mode: | |
20315 | + USED_REX (REX_MODE64); | |
20316 | + if (rex & REX_MODE64) | |
20317 | + oappend (names64[rm + add]); | |
20318 | + else if ((sizeflag & DFLAG) || bytemode != v_mode) | |
20319 | + oappend (names32[rm + add]); | |
20320 | + else | |
20321 | + oappend (names16[rm + add]); | |
20322 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
20323 | + break; | |
20324 | + case 0: | |
20325 | + break; | |
20326 | + default: | |
20327 | + oappend (INTERNAL_DISASSEMBLER_ERROR); | |
20328 | + break; | |
20329 | + } | |
20330 | + return; | |
20331 | + } | |
20332 | + | |
20333 | + disp = 0; | |
20334 | + append_seg (); | |
20335 | + | |
20336 | + if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */ | |
20337 | + { | |
20338 | + int havesib; | |
20339 | + int havebase; | |
20340 | + int base; | |
20341 | + int index = 0; | |
20342 | + int scale = 0; | |
20343 | + | |
20344 | + havesib = 0; | |
20345 | + havebase = 1; | |
20346 | + base = rm; | |
20347 | + | |
20348 | + if (base == 4) | |
20349 | + { | |
20350 | + havesib = 1; | |
20351 | + FETCH_DATA (the_info, codep + 1); | |
20352 | + index = (*codep >> 3) & 7; | |
20353 | + if (mode_64bit || index != 0x4) | |
20354 | + /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */ | |
20355 | + scale = (*codep >> 6) & 3; | |
20356 | + base = *codep & 7; | |
20357 | + USED_REX (REX_EXTY); | |
20358 | + if (rex & REX_EXTY) | |
20359 | + index += 8; | |
20360 | + codep++; | |
20361 | + } | |
20362 | + base += add; | |
20363 | + | |
20364 | + switch (mod) | |
20365 | + { | |
20366 | + case 0: | |
20367 | + if ((base & 7) == 5) | |
20368 | + { | |
20369 | + havebase = 0; | |
20370 | + if (mode_64bit && !havesib) | |
20371 | + riprel = 1; | |
20372 | + disp = get32s (); | |
20373 | + } | |
20374 | + break; | |
20375 | + case 1: | |
20376 | + FETCH_DATA (the_info, codep + 1); | |
20377 | + disp = *codep++; | |
20378 | + if ((disp & 0x80) != 0) | |
20379 | + disp -= 0x100; | |
20380 | + break; | |
20381 | + case 2: | |
20382 | + disp = get32s (); | |
20383 | + break; | |
20384 | + } | |
20385 | + | |
20386 | + if (!intel_syntax) | |
20387 | + if (mod != 0 || (base & 7) == 5) | |
20388 | + { | |
20389 | + print_operand_value (scratchbuf, !riprel, disp); | |
20390 | + oappend (scratchbuf); | |
20391 | + if (riprel) | |
20392 | + { | |
20393 | + set_op (disp, 1); | |
20394 | + oappend ("(%rip)"); | |
20395 | + } | |
20396 | + } | |
20397 | + | |
20398 | + if (havebase || (havesib && (index != 4 || scale != 0))) | |
20399 | + { | |
20400 | + if (intel_syntax) | |
20401 | + { | |
20402 | + switch (bytemode) | |
20403 | + { | |
20404 | + case b_mode: | |
20405 | + oappend ("BYTE PTR "); | |
20406 | + break; | |
20407 | + case w_mode: | |
20408 | + case dqw_mode: | |
20409 | + oappend ("WORD PTR "); | |
20410 | + break; | |
20411 | + case branch_v_mode: | |
20412 | + case v_mode: | |
20413 | + case dq_mode: | |
20414 | + USED_REX (REX_MODE64); | |
20415 | + if (rex & REX_MODE64) | |
20416 | + oappend ("QWORD PTR "); | |
20417 | + else if ((sizeflag & DFLAG) || bytemode == dq_mode) | |
20418 | + oappend ("DWORD PTR "); | |
20419 | + else | |
20420 | + oappend ("WORD PTR "); | |
20421 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
20422 | + break; | |
20423 | + case d_mode: | |
20424 | + oappend ("DWORD PTR "); | |
20425 | + break; | |
20426 | + case q_mode: | |
20427 | + oappend ("QWORD PTR "); | |
20428 | + break; | |
20429 | + case m_mode: | |
20430 | + if (mode_64bit) | |
20431 | + oappend ("QWORD PTR "); | |
20432 | + else | |
20433 | + oappend ("DWORD PTR "); | |
20434 | + break; | |
20435 | + case f_mode: | |
20436 | + if (sizeflag & DFLAG) | |
20437 | + { | |
20438 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
20439 | + oappend ("FWORD PTR "); | |
20440 | + } | |
20441 | + else | |
20442 | + oappend ("DWORD PTR "); | |
20443 | + break; | |
20444 | + case t_mode: | |
20445 | + oappend ("TBYTE PTR "); | |
20446 | + break; | |
20447 | + case x_mode: | |
20448 | + oappend ("XMMWORD PTR "); | |
20449 | + break; | |
20450 | + default: | |
20451 | + break; | |
20452 | + } | |
20453 | + } | |
20454 | + *obufp++ = open_char; | |
20455 | + if (intel_syntax && riprel) | |
20456 | + oappend ("rip + "); | |
20457 | + *obufp = '\0'; | |
20458 | + if (havebase) | |
20459 | + oappend (mode_64bit && (sizeflag & AFLAG) | |
20460 | + ? names64[base] : names32[base]); | |
20461 | + if (havesib) | |
20462 | + { | |
20463 | + if (index != 4) | |
20464 | + { | |
20465 | + if (!intel_syntax || havebase) | |
20466 | + { | |
20467 | + *obufp++ = separator_char; | |
20468 | + *obufp = '\0'; | |
20469 | + } | |
20470 | + oappend (mode_64bit && (sizeflag & AFLAG) | |
20471 | + ? names64[index] : names32[index]); | |
20472 | + } | |
20473 | + if (scale != 0 || (!intel_syntax && index != 4)) | |
20474 | + { | |
20475 | + *obufp++ = scale_char; | |
20476 | + *obufp = '\0'; | |
20477 | + sprintf (scratchbuf, "%d", 1 << scale); | |
20478 | + oappend (scratchbuf); | |
20479 | + } | |
20480 | + } | |
20481 | + if (intel_syntax && disp) | |
20482 | + { | |
20483 | + if ((bfd_signed_vma) disp > 0) | |
20484 | + { | |
20485 | + *obufp++ = '+'; | |
20486 | + *obufp = '\0'; | |
20487 | + } | |
20488 | + else if (mod != 1) | |
20489 | + { | |
20490 | + *obufp++ = '-'; | |
20491 | + *obufp = '\0'; | |
20492 | + disp = - (bfd_signed_vma) disp; | |
20493 | + } | |
20494 | + | |
20495 | + print_operand_value (scratchbuf, mod != 1, disp); | |
20496 | + oappend (scratchbuf); | |
20497 | + } | |
20498 | + | |
20499 | + *obufp++ = close_char; | |
20500 | + *obufp = '\0'; | |
20501 | + } | |
20502 | + else if (intel_syntax) | |
20503 | + { | |
20504 | + if (mod != 0 || (base & 7) == 5) | |
20505 | + { | |
20506 | + if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS | |
20507 | + | PREFIX_ES | PREFIX_FS | PREFIX_GS)) | |
20508 | + ; | |
20509 | + else | |
20510 | + { | |
20511 | + oappend (names_seg[ds_reg - es_reg]); | |
20512 | + oappend (":"); | |
20513 | + } | |
20514 | + print_operand_value (scratchbuf, 1, disp); | |
20515 | + oappend (scratchbuf); | |
20516 | + } | |
20517 | + } | |
20518 | + } | |
20519 | + else | |
20520 | + { /* 16 bit address mode */ | |
20521 | + switch (mod) | |
20522 | + { | |
20523 | + case 0: | |
20524 | + if (rm == 6) | |
20525 | + { | |
20526 | + disp = get16 (); | |
20527 | + if ((disp & 0x8000) != 0) | |
20528 | + disp -= 0x10000; | |
20529 | + } | |
20530 | + break; | |
20531 | + case 1: | |
20532 | + FETCH_DATA (the_info, codep + 1); | |
20533 | + disp = *codep++; | |
20534 | + if ((disp & 0x80) != 0) | |
20535 | + disp -= 0x100; | |
20536 | + break; | |
20537 | + case 2: | |
20538 | + disp = get16 (); | |
20539 | + if ((disp & 0x8000) != 0) | |
20540 | + disp -= 0x10000; | |
20541 | + break; | |
20542 | + } | |
20543 | + | |
20544 | + if (!intel_syntax) | |
20545 | + if (mod != 0 || rm == 6) | |
20546 | + { | |
20547 | + print_operand_value (scratchbuf, 0, disp); | |
20548 | + oappend (scratchbuf); | |
20549 | + } | |
20550 | + | |
20551 | + if (mod != 0 || rm != 6) | |
20552 | + { | |
20553 | + *obufp++ = open_char; | |
20554 | + *obufp = '\0'; | |
20555 | + oappend (index16[rm]); | |
20556 | + if (intel_syntax && disp) | |
20557 | + { | |
20558 | + if ((bfd_signed_vma) disp > 0) | |
20559 | + { | |
20560 | + *obufp++ = '+'; | |
20561 | + *obufp = '\0'; | |
20562 | + } | |
20563 | + else if (mod != 1) | |
20564 | + { | |
20565 | + *obufp++ = '-'; | |
20566 | + *obufp = '\0'; | |
20567 | + disp = - (bfd_signed_vma) disp; | |
20568 | + } | |
20569 | + | |
20570 | + print_operand_value (scratchbuf, mod != 1, disp); | |
20571 | + oappend (scratchbuf); | |
20572 | + } | |
20573 | + | |
20574 | + *obufp++ = close_char; | |
20575 | + *obufp = '\0'; | |
20576 | + } | |
20577 | + else if (intel_syntax) | |
20578 | + { | |
20579 | + if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS | |
20580 | + | PREFIX_ES | PREFIX_FS | PREFIX_GS)) | |
20581 | + ; | |
20582 | + else | |
20583 | + { | |
20584 | + oappend (names_seg[ds_reg - es_reg]); | |
20585 | + oappend (":"); | |
20586 | + } | |
20587 | + print_operand_value (scratchbuf, 1, disp & 0xffff); | |
20588 | + oappend (scratchbuf); | |
20589 | + } | |
20590 | + } | |
20591 | +} | |
20592 | + | |
20593 | +static void | |
20594 | +OP_G (int bytemode, int sizeflag) | |
20595 | +{ | |
20596 | + int add = 0; | |
20597 | + USED_REX (REX_EXTX); | |
20598 | + if (rex & REX_EXTX) | |
20599 | + add += 8; | |
20600 | + switch (bytemode) | |
20601 | + { | |
20602 | + case b_mode: | |
20603 | + USED_REX (0); | |
20604 | + if (rex) | |
20605 | + oappend (names8rex[reg + add]); | |
20606 | + else | |
20607 | + oappend (names8[reg + add]); | |
20608 | + break; | |
20609 | + case w_mode: | |
20610 | + oappend (names16[reg + add]); | |
20611 | + break; | |
20612 | + case d_mode: | |
20613 | + oappend (names32[reg + add]); | |
20614 | + break; | |
20615 | + case q_mode: | |
20616 | + oappend (names64[reg + add]); | |
20617 | + break; | |
20618 | + case v_mode: | |
20619 | + case dq_mode: | |
20620 | + case dqw_mode: | |
20621 | + USED_REX (REX_MODE64); | |
20622 | + if (rex & REX_MODE64) | |
20623 | + oappend (names64[reg + add]); | |
20624 | + else if ((sizeflag & DFLAG) || bytemode != v_mode) | |
20625 | + oappend (names32[reg + add]); | |
20626 | + else | |
20627 | + oappend (names16[reg + add]); | |
20628 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
20629 | + break; | |
20630 | + case m_mode: | |
20631 | + if (mode_64bit) | |
20632 | + oappend (names64[reg + add]); | |
20633 | + else | |
20634 | + oappend (names32[reg + add]); | |
20635 | + break; | |
20636 | + default: | |
20637 | + oappend (INTERNAL_DISASSEMBLER_ERROR); | |
20638 | + break; | |
20639 | + } | |
20640 | +} | |
20641 | + | |
20642 | +static bfd_vma | |
20643 | +get64 (void) | |
20644 | +{ | |
20645 | + bfd_vma x; | |
20646 | +#ifdef BFD64 | |
20647 | + unsigned int a; | |
20648 | + unsigned int b; | |
20649 | + | |
20650 | + FETCH_DATA (the_info, codep + 8); | |
20651 | + a = *codep++ & 0xff; | |
20652 | + a |= (*codep++ & 0xff) << 8; | |
20653 | + a |= (*codep++ & 0xff) << 16; | |
20654 | + a |= (*codep++ & 0xff) << 24; | |
20655 | + b = *codep++ & 0xff; | |
20656 | + b |= (*codep++ & 0xff) << 8; | |
20657 | + b |= (*codep++ & 0xff) << 16; | |
20658 | + b |= (*codep++ & 0xff) << 24; | |
20659 | + x = a + ((bfd_vma) b << 32); | |
20660 | +#else | |
20661 | + abort (); | |
20662 | + x = 0; | |
20663 | +#endif | |
20664 | + return x; | |
20665 | +} | |
20666 | + | |
20667 | +static bfd_signed_vma | |
20668 | +get32 (void) | |
20669 | +{ | |
20670 | + bfd_signed_vma x = 0; | |
20671 | + | |
20672 | + FETCH_DATA (the_info, codep + 4); | |
20673 | + x = *codep++ & (bfd_signed_vma) 0xff; | |
20674 | + x |= (*codep++ & (bfd_signed_vma) 0xff) << 8; | |
20675 | + x |= (*codep++ & (bfd_signed_vma) 0xff) << 16; | |
20676 | + x |= (*codep++ & (bfd_signed_vma) 0xff) << 24; | |
20677 | + return x; | |
20678 | +} | |
20679 | + | |
20680 | +static bfd_signed_vma | |
20681 | +get32s (void) | |
20682 | +{ | |
20683 | + bfd_signed_vma x = 0; | |
20684 | + | |
20685 | + FETCH_DATA (the_info, codep + 4); | |
20686 | + x = *codep++ & (bfd_signed_vma) 0xff; | |
20687 | + x |= (*codep++ & (bfd_signed_vma) 0xff) << 8; | |
20688 | + x |= (*codep++ & (bfd_signed_vma) 0xff) << 16; | |
20689 | + x |= (*codep++ & (bfd_signed_vma) 0xff) << 24; | |
20690 | + | |
20691 | + x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31); | |
20692 | + | |
20693 | + return x; | |
20694 | +} | |
20695 | + | |
20696 | +static int | |
20697 | +get16 (void) | |
20698 | +{ | |
20699 | + int x = 0; | |
20700 | + | |
20701 | + FETCH_DATA (the_info, codep + 2); | |
20702 | + x = *codep++ & 0xff; | |
20703 | + x |= (*codep++ & 0xff) << 8; | |
20704 | + return x; | |
20705 | +} | |
20706 | + | |
20707 | +static void | |
20708 | +set_op (bfd_vma op, int riprel) | |
20709 | +{ | |
20710 | + op_index[op_ad] = op_ad; | |
20711 | + if (mode_64bit) | |
20712 | + { | |
20713 | + op_address[op_ad] = op; | |
20714 | + op_riprel[op_ad] = riprel; | |
20715 | + } | |
20716 | + else | |
20717 | + { | |
20718 | + /* Mask to get a 32-bit address. */ | |
20719 | + op_address[op_ad] = op & 0xffffffff; | |
20720 | + op_riprel[op_ad] = riprel & 0xffffffff; | |
20721 | + } | |
20722 | +} | |
20723 | + | |
20724 | +static void | |
20725 | +OP_REG (int code, int sizeflag) | |
20726 | +{ | |
20727 | + const char *s; | |
20728 | + int add = 0; | |
20729 | + USED_REX (REX_EXTZ); | |
20730 | + if (rex & REX_EXTZ) | |
20731 | + add = 8; | |
20732 | + | |
20733 | + switch (code) | |
20734 | + { | |
20735 | + case indir_dx_reg: | |
20736 | + if (intel_syntax) | |
20737 | + s = "[dx]"; | |
20738 | + else | |
20739 | + s = "(%dx)"; | |
20740 | + break; | |
20741 | + case ax_reg: case cx_reg: case dx_reg: case bx_reg: | |
20742 | + case sp_reg: case bp_reg: case si_reg: case di_reg: | |
20743 | + s = names16[code - ax_reg + add]; | |
20744 | + break; | |
20745 | + case es_reg: case ss_reg: case cs_reg: | |
20746 | + case ds_reg: case fs_reg: case gs_reg: | |
20747 | + s = names_seg[code - es_reg + add]; | |
20748 | + break; | |
20749 | + case al_reg: case ah_reg: case cl_reg: case ch_reg: | |
20750 | + case dl_reg: case dh_reg: case bl_reg: case bh_reg: | |
20751 | + USED_REX (0); | |
20752 | + if (rex) | |
20753 | + s = names8rex[code - al_reg + add]; | |
20754 | + else | |
20755 | + s = names8[code - al_reg]; | |
20756 | + break; | |
20757 | + case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg: | |
20758 | + case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg: | |
20759 | + if (mode_64bit) | |
20760 | + { | |
20761 | + s = names64[code - rAX_reg + add]; | |
20762 | + break; | |
20763 | + } | |
20764 | + code += eAX_reg - rAX_reg; | |
20765 | + /* Fall through. */ | |
20766 | + case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg: | |
20767 | + case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg: | |
20768 | + USED_REX (REX_MODE64); | |
20769 | + if (rex & REX_MODE64) | |
20770 | + s = names64[code - eAX_reg + add]; | |
20771 | + else if (sizeflag & DFLAG) | |
20772 | + s = names32[code - eAX_reg + add]; | |
20773 | + else | |
20774 | + s = names16[code - eAX_reg + add]; | |
20775 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
20776 | + break; | |
20777 | + default: | |
20778 | + s = INTERNAL_DISASSEMBLER_ERROR; | |
20779 | + break; | |
20780 | + } | |
20781 | + oappend (s); | |
20782 | +} | |
20783 | + | |
20784 | +static void | |
20785 | +OP_IMREG (int code, int sizeflag) | |
20786 | +{ | |
20787 | + const char *s; | |
20788 | + | |
20789 | + switch (code) | |
20790 | + { | |
20791 | + case indir_dx_reg: | |
20792 | + if (intel_syntax) | |
20793 | + s = "[dx]"; | |
20794 | + else | |
20795 | + s = "(%dx)"; | |
20796 | + break; | |
20797 | + case ax_reg: case cx_reg: case dx_reg: case bx_reg: | |
20798 | + case sp_reg: case bp_reg: case si_reg: case di_reg: | |
20799 | + s = names16[code - ax_reg]; | |
20800 | + break; | |
20801 | + case es_reg: case ss_reg: case cs_reg: | |
20802 | + case ds_reg: case fs_reg: case gs_reg: | |
20803 | + s = names_seg[code - es_reg]; | |
20804 | + break; | |
20805 | + case al_reg: case ah_reg: case cl_reg: case ch_reg: | |
20806 | + case dl_reg: case dh_reg: case bl_reg: case bh_reg: | |
20807 | + USED_REX (0); | |
20808 | + if (rex) | |
20809 | + s = names8rex[code - al_reg]; | |
20810 | + else | |
20811 | + s = names8[code - al_reg]; | |
20812 | + break; | |
20813 | + case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg: | |
20814 | + case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg: | |
20815 | + USED_REX (REX_MODE64); | |
20816 | + if (rex & REX_MODE64) | |
20817 | + s = names64[code - eAX_reg]; | |
20818 | + else if (sizeflag & DFLAG) | |
20819 | + s = names32[code - eAX_reg]; | |
20820 | + else | |
20821 | + s = names16[code - eAX_reg]; | |
20822 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
20823 | + break; | |
20824 | + default: | |
20825 | + s = INTERNAL_DISASSEMBLER_ERROR; | |
20826 | + break; | |
20827 | + } | |
20828 | + oappend (s); | |
20829 | +} | |
20830 | + | |
20831 | +static void | |
20832 | +OP_I (int bytemode, int sizeflag) | |
20833 | +{ | |
20834 | + bfd_signed_vma op; | |
20835 | + bfd_signed_vma mask = -1; | |
20836 | + | |
20837 | + switch (bytemode) | |
20838 | + { | |
20839 | + case b_mode: | |
20840 | + FETCH_DATA (the_info, codep + 1); | |
20841 | + op = *codep++; | |
20842 | + mask = 0xff; | |
20843 | + break; | |
20844 | + case q_mode: | |
20845 | + if (mode_64bit) | |
20846 | + { | |
20847 | + op = get32s (); | |
20848 | + break; | |
20849 | + } | |
20850 | + /* Fall through. */ | |
20851 | + case v_mode: | |
20852 | + USED_REX (REX_MODE64); | |
20853 | + if (rex & REX_MODE64) | |
20854 | + op = get32s (); | |
20855 | + else if (sizeflag & DFLAG) | |
20856 | + { | |
20857 | + op = get32 (); | |
20858 | + mask = 0xffffffff; | |
20859 | + } | |
20860 | + else | |
20861 | + { | |
20862 | + op = get16 (); | |
20863 | + mask = 0xfffff; | |
20864 | + } | |
20865 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
20866 | + break; | |
20867 | + case w_mode: | |
20868 | + mask = 0xfffff; | |
20869 | + op = get16 (); | |
20870 | + break; | |
20871 | + case const_1_mode: | |
20872 | + if (intel_syntax) | |
20873 | + oappend ("1"); | |
20874 | + return; | |
20875 | + default: | |
20876 | + oappend (INTERNAL_DISASSEMBLER_ERROR); | |
20877 | + return; | |
20878 | + } | |
20879 | + | |
20880 | + op &= mask; | |
20881 | + scratchbuf[0] = '$'; | |
20882 | + print_operand_value (scratchbuf + 1, 1, op); | |
20883 | + oappend (scratchbuf + intel_syntax); | |
20884 | + scratchbuf[0] = '\0'; | |
20885 | +} | |
20886 | + | |
20887 | +static void | |
20888 | +OP_I64 (int bytemode, int sizeflag) | |
20889 | +{ | |
20890 | + bfd_signed_vma op; | |
20891 | + bfd_signed_vma mask = -1; | |
20892 | + | |
20893 | + if (!mode_64bit) | |
20894 | + { | |
20895 | + OP_I (bytemode, sizeflag); | |
20896 | + return; | |
20897 | + } | |
20898 | + | |
20899 | + switch (bytemode) | |
20900 | + { | |
20901 | + case b_mode: | |
20902 | + FETCH_DATA (the_info, codep + 1); | |
20903 | + op = *codep++; | |
20904 | + mask = 0xff; | |
20905 | + break; | |
20906 | + case v_mode: | |
20907 | + USED_REX (REX_MODE64); | |
20908 | + if (rex & REX_MODE64) | |
20909 | + op = get64 (); | |
20910 | + else if (sizeflag & DFLAG) | |
20911 | + { | |
20912 | + op = get32 (); | |
20913 | + mask = 0xffffffff; | |
20914 | + } | |
20915 | + else | |
20916 | + { | |
20917 | + op = get16 (); | |
20918 | + mask = 0xfffff; | |
20919 | + } | |
20920 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
20921 | + break; | |
20922 | + case w_mode: | |
20923 | + mask = 0xfffff; | |
20924 | + op = get16 (); | |
20925 | + break; | |
20926 | + default: | |
20927 | + oappend (INTERNAL_DISASSEMBLER_ERROR); | |
20928 | + return; | |
20929 | + } | |
20930 | + | |
20931 | + op &= mask; | |
20932 | + scratchbuf[0] = '$'; | |
20933 | + print_operand_value (scratchbuf + 1, 1, op); | |
20934 | + oappend (scratchbuf + intel_syntax); | |
20935 | + scratchbuf[0] = '\0'; | |
20936 | +} | |
20937 | + | |
20938 | +static void | |
20939 | +OP_sI (int bytemode, int sizeflag) | |
20940 | +{ | |
20941 | + bfd_signed_vma op; | |
20942 | + bfd_signed_vma mask = -1; | |
20943 | + | |
20944 | + switch (bytemode) | |
20945 | + { | |
20946 | + case b_mode: | |
20947 | + FETCH_DATA (the_info, codep + 1); | |
20948 | + op = *codep++; | |
20949 | + if ((op & 0x80) != 0) | |
20950 | + op -= 0x100; | |
20951 | + mask = 0xffffffff; | |
20952 | + break; | |
20953 | + case v_mode: | |
20954 | + USED_REX (REX_MODE64); | |
20955 | + if (rex & REX_MODE64) | |
20956 | + op = get32s (); | |
20957 | + else if (sizeflag & DFLAG) | |
20958 | + { | |
20959 | + op = get32s (); | |
20960 | + mask = 0xffffffff; | |
20961 | + } | |
20962 | + else | |
20963 | + { | |
20964 | + mask = 0xffffffff; | |
20965 | + op = get16 (); | |
20966 | + if ((op & 0x8000) != 0) | |
20967 | + op -= 0x10000; | |
20968 | + } | |
20969 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
20970 | + break; | |
20971 | + case w_mode: | |
20972 | + op = get16 (); | |
20973 | + mask = 0xffffffff; | |
20974 | + if ((op & 0x8000) != 0) | |
20975 | + op -= 0x10000; | |
20976 | + break; | |
20977 | + default: | |
20978 | + oappend (INTERNAL_DISASSEMBLER_ERROR); | |
20979 | + return; | |
20980 | + } | |
20981 | + | |
20982 | + scratchbuf[0] = '$'; | |
20983 | + print_operand_value (scratchbuf + 1, 1, op); | |
20984 | + oappend (scratchbuf + intel_syntax); | |
20985 | +} | |
20986 | + | |
20987 | +static void | |
20988 | +OP_J (int bytemode, int sizeflag) | |
20989 | +{ | |
20990 | + bfd_vma disp; | |
20991 | + bfd_vma mask = -1; | |
20992 | + | |
20993 | + switch (bytemode) | |
20994 | + { | |
20995 | + case b_mode: | |
20996 | + FETCH_DATA (the_info, codep + 1); | |
20997 | + disp = *codep++; | |
20998 | + if ((disp & 0x80) != 0) | |
20999 | + disp -= 0x100; | |
21000 | + break; | |
21001 | + case v_mode: | |
21002 | + if (sizeflag & DFLAG) | |
21003 | + disp = get32s (); | |
21004 | + else | |
21005 | + { | |
21006 | + disp = get16 (); | |
21007 | + /* For some reason, a data16 prefix on a jump instruction | |
21008 | + means that the pc is masked to 16 bits after the | |
21009 | + displacement is added! */ | |
21010 | + mask = 0xffff; | |
21011 | + } | |
21012 | + break; | |
21013 | + default: | |
21014 | + oappend (INTERNAL_DISASSEMBLER_ERROR); | |
21015 | + return; | |
21016 | + } | |
21017 | + disp = (start_pc + codep - start_codep + disp) & mask; | |
21018 | + set_op (disp, 0); | |
21019 | + print_operand_value (scratchbuf, 1, disp); | |
21020 | + oappend (scratchbuf); | |
21021 | +} | |
21022 | + | |
21023 | +static void | |
21024 | +OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
21025 | +{ | |
21026 | + oappend (names_seg[reg]); | |
21027 | +} | |
21028 | + | |
21029 | +static void | |
21030 | +OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag) | |
21031 | +{ | |
21032 | + int seg, offset; | |
21033 | + | |
21034 | + if (sizeflag & DFLAG) | |
21035 | + { | |
21036 | + offset = get32 (); | |
21037 | + seg = get16 (); | |
21038 | + } | |
21039 | + else | |
21040 | + { | |
21041 | + offset = get16 (); | |
21042 | + seg = get16 (); | |
21043 | + } | |
21044 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
21045 | + if (intel_syntax) | |
21046 | + sprintf (scratchbuf, "0x%x,0x%x", seg, offset); | |
21047 | + else | |
21048 | + sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset); | |
21049 | + oappend (scratchbuf); | |
21050 | +} | |
21051 | + | |
21052 | +static void | |
21053 | +OP_OFF (int bytemode ATTRIBUTE_UNUSED, int sizeflag) | |
21054 | +{ | |
21055 | + bfd_vma off; | |
21056 | + | |
21057 | + append_seg (); | |
21058 | + | |
21059 | + if ((sizeflag & AFLAG) || mode_64bit) | |
21060 | + off = get32 (); | |
21061 | + else | |
21062 | + off = get16 (); | |
21063 | + | |
21064 | + if (intel_syntax) | |
21065 | + { | |
21066 | + if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS | |
21067 | + | PREFIX_ES | PREFIX_FS | PREFIX_GS))) | |
21068 | + { | |
21069 | + oappend (names_seg[ds_reg - es_reg]); | |
21070 | + oappend (":"); | |
21071 | + } | |
21072 | + } | |
21073 | + print_operand_value (scratchbuf, 1, off); | |
21074 | + oappend (scratchbuf); | |
21075 | +} | |
21076 | + | |
21077 | +static void | |
21078 | +OP_OFF64 (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
21079 | +{ | |
21080 | + bfd_vma off; | |
21081 | + | |
21082 | + if (!mode_64bit) | |
21083 | + { | |
21084 | + OP_OFF (bytemode, sizeflag); | |
21085 | + return; | |
21086 | + } | |
21087 | + | |
21088 | + append_seg (); | |
21089 | + | |
21090 | + off = get64 (); | |
21091 | + | |
21092 | + if (intel_syntax) | |
21093 | + { | |
21094 | + if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS | |
21095 | + | PREFIX_ES | PREFIX_FS | PREFIX_GS))) | |
21096 | + { | |
21097 | + oappend (names_seg[ds_reg - es_reg]); | |
21098 | + oappend (":"); | |
21099 | + } | |
21100 | + } | |
21101 | + print_operand_value (scratchbuf, 1, off); | |
21102 | + oappend (scratchbuf); | |
21103 | +} | |
21104 | + | |
21105 | +static void | |
21106 | +ptr_reg (int code, int sizeflag) | |
21107 | +{ | |
21108 | + const char *s; | |
21109 | + | |
21110 | + *obufp++ = open_char; | |
21111 | + used_prefixes |= (prefixes & PREFIX_ADDR); | |
21112 | + if (mode_64bit) | |
21113 | + { | |
21114 | + if (!(sizeflag & AFLAG)) | |
21115 | + s = names32[code - eAX_reg]; | |
21116 | + else | |
21117 | + s = names64[code - eAX_reg]; | |
21118 | + } | |
21119 | + else if (sizeflag & AFLAG) | |
21120 | + s = names32[code - eAX_reg]; | |
21121 | + else | |
21122 | + s = names16[code - eAX_reg]; | |
21123 | + oappend (s); | |
21124 | + *obufp++ = close_char; | |
21125 | + *obufp = 0; | |
21126 | +} | |
21127 | + | |
21128 | +static void | |
21129 | +OP_ESreg (int code, int sizeflag) | |
21130 | +{ | |
21131 | + if (intel_syntax) | |
21132 | + { | |
21133 | + if (codep[-1] & 1) | |
21134 | + { | |
21135 | + USED_REX (REX_MODE64); | |
21136 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
21137 | + if (rex & REX_MODE64) | |
21138 | + oappend ("QWORD PTR "); | |
21139 | + else if ((sizeflag & DFLAG)) | |
21140 | + oappend ("DWORD PTR "); | |
21141 | + else | |
21142 | + oappend ("WORD PTR "); | |
21143 | + } | |
21144 | + else | |
21145 | + oappend ("BYTE PTR "); | |
21146 | + } | |
21147 | + | |
21148 | + oappend ("%es:" + intel_syntax); | |
21149 | + ptr_reg (code, sizeflag); | |
21150 | +} | |
21151 | + | |
21152 | +static void | |
21153 | +OP_DSreg (int code, int sizeflag) | |
21154 | +{ | |
21155 | + if (intel_syntax) | |
21156 | + { | |
21157 | + if (codep[-1] != 0xd7 && (codep[-1] & 1)) | |
21158 | + { | |
21159 | + USED_REX (REX_MODE64); | |
21160 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
21161 | + if (rex & REX_MODE64) | |
21162 | + oappend ("QWORD PTR "); | |
21163 | + else if ((sizeflag & DFLAG)) | |
21164 | + oappend ("DWORD PTR "); | |
21165 | + else | |
21166 | + oappend ("WORD PTR "); | |
21167 | + } | |
21168 | + else | |
21169 | + oappend ("BYTE PTR "); | |
21170 | + } | |
21171 | + | |
21172 | + if ((prefixes | |
21173 | + & (PREFIX_CS | |
21174 | + | PREFIX_DS | |
21175 | + | PREFIX_SS | |
21176 | + | PREFIX_ES | |
21177 | + | PREFIX_FS | |
21178 | + | PREFIX_GS)) == 0) | |
21179 | + prefixes |= PREFIX_DS; | |
21180 | + append_seg (); | |
21181 | + ptr_reg (code, sizeflag); | |
21182 | +} | |
21183 | + | |
21184 | +static void | |
21185 | +OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
21186 | +{ | |
21187 | + int add = 0; | |
21188 | + if (rex & REX_EXTX) | |
21189 | + { | |
21190 | + USED_REX (REX_EXTX); | |
21191 | + add = 8; | |
21192 | + } | |
21193 | + else if (!mode_64bit && (prefixes & PREFIX_LOCK)) | |
21194 | + { | |
21195 | + used_prefixes |= PREFIX_LOCK; | |
21196 | + add = 8; | |
21197 | + } | |
21198 | + sprintf (scratchbuf, "%%cr%d", reg + add); | |
21199 | + oappend (scratchbuf + intel_syntax); | |
21200 | +} | |
21201 | + | |
21202 | +static void | |
21203 | +OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
21204 | +{ | |
21205 | + int add = 0; | |
21206 | + USED_REX (REX_EXTX); | |
21207 | + if (rex & REX_EXTX) | |
21208 | + add = 8; | |
21209 | + if (intel_syntax) | |
21210 | + sprintf (scratchbuf, "db%d", reg + add); | |
21211 | + else | |
21212 | + sprintf (scratchbuf, "%%db%d", reg + add); | |
21213 | + oappend (scratchbuf); | |
21214 | +} | |
21215 | + | |
21216 | +static void | |
21217 | +OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
21218 | +{ | |
21219 | + sprintf (scratchbuf, "%%tr%d", reg); | |
21220 | + oappend (scratchbuf + intel_syntax); | |
21221 | +} | |
21222 | + | |
21223 | +static void | |
21224 | +OP_Rd (int bytemode, int sizeflag) | |
21225 | +{ | |
21226 | + if (mod == 3) | |
21227 | + OP_E (bytemode, sizeflag); | |
21228 | + else | |
21229 | + BadOp (); | |
21230 | +} | |
21231 | + | |
21232 | +static void | |
21233 | +OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
21234 | +{ | |
21235 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
21236 | + if (prefixes & PREFIX_DATA) | |
21237 | + { | |
21238 | + int add = 0; | |
21239 | + USED_REX (REX_EXTX); | |
21240 | + if (rex & REX_EXTX) | |
21241 | + add = 8; | |
21242 | + sprintf (scratchbuf, "%%xmm%d", reg + add); | |
21243 | + } | |
21244 | + else | |
21245 | + sprintf (scratchbuf, "%%mm%d", reg); | |
21246 | + oappend (scratchbuf + intel_syntax); | |
21247 | +} | |
21248 | + | |
21249 | +static void | |
21250 | +OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
21251 | +{ | |
21252 | + int add = 0; | |
21253 | + USED_REX (REX_EXTX); | |
21254 | + if (rex & REX_EXTX) | |
21255 | + add = 8; | |
21256 | + sprintf (scratchbuf, "%%xmm%d", reg + add); | |
21257 | + oappend (scratchbuf + intel_syntax); | |
21258 | +} | |
21259 | + | |
21260 | +static void | |
21261 | +OP_EM (int bytemode, int sizeflag) | |
21262 | +{ | |
21263 | + if (mod != 3) | |
21264 | + { | |
21265 | + if (intel_syntax && bytemode == v_mode) | |
21266 | + { | |
21267 | + bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode; | |
21268 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
21269 | + } | |
21270 | + OP_E (bytemode, sizeflag); | |
21271 | + return; | |
21272 | + } | |
21273 | + | |
21274 | + /* Skip mod/rm byte. */ | |
21275 | + MODRM_CHECK; | |
21276 | + codep++; | |
21277 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
21278 | + if (prefixes & PREFIX_DATA) | |
21279 | + { | |
21280 | + int add = 0; | |
21281 | + | |
21282 | + USED_REX (REX_EXTZ); | |
21283 | + if (rex & REX_EXTZ) | |
21284 | + add = 8; | |
21285 | + sprintf (scratchbuf, "%%xmm%d", rm + add); | |
21286 | + } | |
21287 | + else | |
21288 | + sprintf (scratchbuf, "%%mm%d", rm); | |
21289 | + oappend (scratchbuf + intel_syntax); | |
21290 | +} | |
21291 | + | |
21292 | +static void | |
21293 | +OP_EX (int bytemode, int sizeflag) | |
21294 | +{ | |
21295 | + int add = 0; | |
21296 | + if (mod != 3) | |
21297 | + { | |
21298 | + if (intel_syntax && bytemode == v_mode) | |
21299 | + { | |
21300 | + switch (prefixes & (PREFIX_DATA|PREFIX_REPZ|PREFIX_REPNZ)) | |
21301 | + { | |
21302 | + case 0: bytemode = x_mode; break; | |
21303 | + case PREFIX_REPZ: bytemode = d_mode; used_prefixes |= PREFIX_REPZ; break; | |
21304 | + case PREFIX_DATA: bytemode = x_mode; used_prefixes |= PREFIX_DATA; break; | |
21305 | + case PREFIX_REPNZ: bytemode = q_mode; used_prefixes |= PREFIX_REPNZ; break; | |
21306 | + default: bytemode = 0; break; | |
21307 | + } | |
21308 | + } | |
21309 | + OP_E (bytemode, sizeflag); | |
21310 | + return; | |
21311 | + } | |
21312 | + USED_REX (REX_EXTZ); | |
21313 | + if (rex & REX_EXTZ) | |
21314 | + add = 8; | |
21315 | + | |
21316 | + /* Skip mod/rm byte. */ | |
21317 | + MODRM_CHECK; | |
21318 | + codep++; | |
21319 | + sprintf (scratchbuf, "%%xmm%d", rm + add); | |
21320 | + oappend (scratchbuf + intel_syntax); | |
21321 | +} | |
21322 | + | |
21323 | +static void | |
21324 | +OP_MS (int bytemode, int sizeflag) | |
21325 | +{ | |
21326 | + if (mod == 3) | |
21327 | + OP_EM (bytemode, sizeflag); | |
21328 | + else | |
21329 | + BadOp (); | |
21330 | +} | |
21331 | + | |
21332 | +static void | |
21333 | +OP_XS (int bytemode, int sizeflag) | |
21334 | +{ | |
21335 | + if (mod == 3) | |
21336 | + OP_EX (bytemode, sizeflag); | |
21337 | + else | |
21338 | + BadOp (); | |
21339 | +} | |
21340 | + | |
21341 | +static void | |
21342 | +OP_M (int bytemode, int sizeflag) | |
21343 | +{ | |
21344 | + if (mod == 3) | |
21345 | + BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */ | |
21346 | + else | |
21347 | + OP_E (bytemode, sizeflag); | |
21348 | +} | |
21349 | + | |
21350 | +static void | |
21351 | +OP_0f07 (int bytemode, int sizeflag) | |
21352 | +{ | |
21353 | + if (mod != 3 || rm != 0) | |
21354 | + BadOp (); | |
21355 | + else | |
21356 | + OP_E (bytemode, sizeflag); | |
21357 | +} | |
21358 | + | |
21359 | +static void | |
21360 | +OP_0fae (int bytemode, int sizeflag) | |
21361 | +{ | |
21362 | + if (mod == 3) | |
21363 | + { | |
21364 | + if (reg == 7) | |
21365 | + strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence"); | |
21366 | + | |
21367 | + if (reg < 5 || rm != 0) | |
21368 | + { | |
21369 | + BadOp (); /* bad sfence, mfence, or lfence */ | |
21370 | + return; | |
21371 | + } | |
21372 | + } | |
21373 | + else if (reg != 7) | |
21374 | + { | |
21375 | + BadOp (); /* bad clflush */ | |
21376 | + return; | |
21377 | + } | |
21378 | + | |
21379 | + OP_E (bytemode, sizeflag); | |
21380 | +} | |
21381 | + | |
21382 | +static void | |
21383 | +NOP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
21384 | +{ | |
21385 | + /* NOP with REPZ prefix is called PAUSE. */ | |
21386 | + if (prefixes == PREFIX_REPZ) | |
21387 | + strcpy (obuf, "pause"); | |
21388 | +} | |
21389 | + | |
21390 | +static const char *const Suffix3DNow[] = { | |
21391 | +/* 00 */ NULL, NULL, NULL, NULL, | |
21392 | +/* 04 */ NULL, NULL, NULL, NULL, | |
21393 | +/* 08 */ NULL, NULL, NULL, NULL, | |
21394 | +/* 0C */ "pi2fw", "pi2fd", NULL, NULL, | |
21395 | +/* 10 */ NULL, NULL, NULL, NULL, | |
21396 | +/* 14 */ NULL, NULL, NULL, NULL, | |
21397 | +/* 18 */ NULL, NULL, NULL, NULL, | |
21398 | +/* 1C */ "pf2iw", "pf2id", NULL, NULL, | |
21399 | +/* 20 */ NULL, NULL, NULL, NULL, | |
21400 | +/* 24 */ NULL, NULL, NULL, NULL, | |
21401 | +/* 28 */ NULL, NULL, NULL, NULL, | |
21402 | +/* 2C */ NULL, NULL, NULL, NULL, | |
21403 | +/* 30 */ NULL, NULL, NULL, NULL, | |
21404 | +/* 34 */ NULL, NULL, NULL, NULL, | |
21405 | +/* 38 */ NULL, NULL, NULL, NULL, | |
21406 | +/* 3C */ NULL, NULL, NULL, NULL, | |
21407 | +/* 40 */ NULL, NULL, NULL, NULL, | |
21408 | +/* 44 */ NULL, NULL, NULL, NULL, | |
21409 | +/* 48 */ NULL, NULL, NULL, NULL, | |
21410 | +/* 4C */ NULL, NULL, NULL, NULL, | |
21411 | +/* 50 */ NULL, NULL, NULL, NULL, | |
21412 | +/* 54 */ NULL, NULL, NULL, NULL, | |
21413 | +/* 58 */ NULL, NULL, NULL, NULL, | |
21414 | +/* 5C */ NULL, NULL, NULL, NULL, | |
21415 | +/* 60 */ NULL, NULL, NULL, NULL, | |
21416 | +/* 64 */ NULL, NULL, NULL, NULL, | |
21417 | +/* 68 */ NULL, NULL, NULL, NULL, | |
21418 | +/* 6C */ NULL, NULL, NULL, NULL, | |
21419 | +/* 70 */ NULL, NULL, NULL, NULL, | |
21420 | +/* 74 */ NULL, NULL, NULL, NULL, | |
21421 | +/* 78 */ NULL, NULL, NULL, NULL, | |
21422 | +/* 7C */ NULL, NULL, NULL, NULL, | |
21423 | +/* 80 */ NULL, NULL, NULL, NULL, | |
21424 | +/* 84 */ NULL, NULL, NULL, NULL, | |
21425 | +/* 88 */ NULL, NULL, "pfnacc", NULL, | |
21426 | +/* 8C */ NULL, NULL, "pfpnacc", NULL, | |
21427 | +/* 90 */ "pfcmpge", NULL, NULL, NULL, | |
21428 | +/* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt", | |
21429 | +/* 98 */ NULL, NULL, "pfsub", NULL, | |
21430 | +/* 9C */ NULL, NULL, "pfadd", NULL, | |
21431 | +/* A0 */ "pfcmpgt", NULL, NULL, NULL, | |
21432 | +/* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1", | |
21433 | +/* A8 */ NULL, NULL, "pfsubr", NULL, | |
21434 | +/* AC */ NULL, NULL, "pfacc", NULL, | |
21435 | +/* B0 */ "pfcmpeq", NULL, NULL, NULL, | |
21436 | +/* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw", | |
21437 | +/* B8 */ NULL, NULL, NULL, "pswapd", | |
21438 | +/* BC */ NULL, NULL, NULL, "pavgusb", | |
21439 | +/* C0 */ NULL, NULL, NULL, NULL, | |
21440 | +/* C4 */ NULL, NULL, NULL, NULL, | |
21441 | +/* C8 */ NULL, NULL, NULL, NULL, | |
21442 | +/* CC */ NULL, NULL, NULL, NULL, | |
21443 | +/* D0 */ NULL, NULL, NULL, NULL, | |
21444 | +/* D4 */ NULL, NULL, NULL, NULL, | |
21445 | +/* D8 */ NULL, NULL, NULL, NULL, | |
21446 | +/* DC */ NULL, NULL, NULL, NULL, | |
21447 | +/* E0 */ NULL, NULL, NULL, NULL, | |
21448 | +/* E4 */ NULL, NULL, NULL, NULL, | |
21449 | +/* E8 */ NULL, NULL, NULL, NULL, | |
21450 | +/* EC */ NULL, NULL, NULL, NULL, | |
21451 | +/* F0 */ NULL, NULL, NULL, NULL, | |
21452 | +/* F4 */ NULL, NULL, NULL, NULL, | |
21453 | +/* F8 */ NULL, NULL, NULL, NULL, | |
21454 | +/* FC */ NULL, NULL, NULL, NULL, | |
21455 | +}; | |
21456 | + | |
21457 | +static void | |
21458 | +OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
21459 | +{ | |
21460 | + const char *mnemonic; | |
21461 | + | |
21462 | + FETCH_DATA (the_info, codep + 1); | |
21463 | + /* AMD 3DNow! instructions are specified by an opcode suffix in the | |
21464 | + place where an 8-bit immediate would normally go. ie. the last | |
21465 | + byte of the instruction. */ | |
21466 | + obufp = obuf + strlen (obuf); | |
21467 | + mnemonic = Suffix3DNow[*codep++ & 0xff]; | |
21468 | + if (mnemonic) | |
21469 | + oappend (mnemonic); | |
21470 | + else | |
21471 | + { | |
21472 | + /* Since a variable sized modrm/sib chunk is between the start | |
21473 | + of the opcode (0x0f0f) and the opcode suffix, we need to do | |
21474 | + all the modrm processing first, and don't know until now that | |
21475 | + we have a bad opcode. This necessitates some cleaning up. */ | |
21476 | + op1out[0] = '\0'; | |
21477 | + op2out[0] = '\0'; | |
21478 | + BadOp (); | |
21479 | + } | |
21480 | +} | |
21481 | + | |
21482 | +static const char *simd_cmp_op[] = { | |
21483 | + "eq", | |
21484 | + "lt", | |
21485 | + "le", | |
21486 | + "unord", | |
21487 | + "neq", | |
21488 | + "nlt", | |
21489 | + "nle", | |
21490 | + "ord" | |
21491 | +}; | |
21492 | + | |
21493 | +static void | |
21494 | +OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) | |
21495 | +{ | |
21496 | + unsigned int cmp_type; | |
21497 | + | |
21498 | + FETCH_DATA (the_info, codep + 1); | |
21499 | + obufp = obuf + strlen (obuf); | |
21500 | + cmp_type = *codep++ & 0xff; | |
21501 | + if (cmp_type < 8) | |
21502 | + { | |
21503 | + char suffix1 = 'p', suffix2 = 's'; | |
21504 | + used_prefixes |= (prefixes & PREFIX_REPZ); | |
21505 | + if (prefixes & PREFIX_REPZ) | |
21506 | + suffix1 = 's'; | |
21507 | + else | |
21508 | + { | |
21509 | + used_prefixes |= (prefixes & PREFIX_DATA); | |
21510 | + if (prefixes & PREFIX_DATA) | |
21511 | + suffix2 = 'd'; | |
21512 | + else | |
21513 | + { | |
21514 | + used_prefixes |= (prefixes & PREFIX_REPNZ); | |
21515 | + if (prefixes & PREFIX_REPNZ) | |
21516 | + suffix1 = 's', suffix2 = 'd'; | |
21517 | + } | |
21518 | + } | |
21519 | + sprintf (scratchbuf, "cmp%s%c%c", | |
21520 | + simd_cmp_op[cmp_type], suffix1, suffix2); | |
21521 | + used_prefixes |= (prefixes & PREFIX_REPZ); | |
21522 | + oappend (scratchbuf); | |
21523 | + } | |
21524 | + else | |
21525 | + { | |
21526 | + /* We have a bad extension byte. Clean up. */ | |
21527 | + op1out[0] = '\0'; | |
21528 | + op2out[0] = '\0'; | |
21529 | + BadOp (); | |
21530 | + } | |
21531 | +} | |
21532 | + | |
21533 | +static void | |
21534 | +SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED) | |
21535 | +{ | |
21536 | + /* Change movlps/movhps to movhlps/movlhps for 2 register operand | |
21537 | + forms of these instructions. */ | |
21538 | + if (mod == 3) | |
21539 | + { | |
21540 | + char *p = obuf + strlen (obuf); | |
21541 | + *(p + 1) = '\0'; | |
21542 | + *p = *(p - 1); | |
21543 | + *(p - 1) = *(p - 2); | |
21544 | + *(p - 2) = *(p - 3); | |
21545 | + *(p - 3) = extrachar; | |
21546 | + } | |
21547 | +} | |
21548 | + | |
21549 | +static void | |
21550 | +PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag) | |
21551 | +{ | |
21552 | + if (mod == 3 && reg == 1 && rm <= 1) | |
21553 | + { | |
21554 | + /* Override "sidt". */ | |
21555 | + char *p = obuf + strlen (obuf) - 4; | |
21556 | + | |
21557 | + /* We might have a suffix when disassembling with -Msuffix. */ | |
21558 | + if (*p == 'i') | |
21559 | + --p; | |
21560 | + | |
21561 | + if (rm) | |
21562 | + { | |
21563 | + /* mwait %eax,%ecx */ | |
21564 | + strcpy (p, "mwait"); | |
21565 | + if (!intel_syntax) | |
21566 | + strcpy (op1out, names32[0]); | |
21567 | + } | |
21568 | + else | |
21569 | + { | |
21570 | + /* monitor %eax,%ecx,%edx" */ | |
21571 | + strcpy (p, "monitor"); | |
21572 | + if (!intel_syntax) | |
21573 | + { | |
21574 | + if (!mode_64bit) | |
21575 | + strcpy (op1out, names32[0]); | |
21576 | + else if (!(prefixes & PREFIX_ADDR)) | |
21577 | + strcpy (op1out, names64[0]); | |
21578 | + else | |
21579 | + { | |
21580 | + strcpy (op1out, names32[0]); | |
21581 | + used_prefixes |= PREFIX_ADDR; | |
21582 | + } | |
21583 | + strcpy (op3out, names32[2]); | |
21584 | + } | |
21585 | + } | |
21586 | + if (!intel_syntax) | |
21587 | + { | |
21588 | + strcpy (op2out, names32[1]); | |
21589 | + two_source_ops = 1; | |
21590 | + } | |
21591 | + | |
21592 | + codep++; | |
21593 | + } | |
21594 | + else | |
21595 | + OP_M (0, sizeflag); | |
21596 | +} | |
21597 | + | |
21598 | +static void | |
21599 | +SVME_Fixup (int bytemode, int sizeflag) | |
21600 | +{ | |
21601 | + const char *alt; | |
21602 | + char *p; | |
21603 | + | |
21604 | + switch (*codep) | |
21605 | + { | |
21606 | + case 0xd8: | |
21607 | + alt = "vmrun"; | |
21608 | + break; | |
21609 | + case 0xd9: | |
21610 | + alt = "vmmcall"; | |
21611 | + break; | |
21612 | + case 0xda: | |
21613 | + alt = "vmload"; | |
21614 | + break; | |
21615 | + case 0xdb: | |
21616 | + alt = "vmsave"; | |
21617 | + break; | |
21618 | + case 0xdc: | |
21619 | + alt = "stgi"; | |
21620 | + break; | |
21621 | + case 0xdd: | |
21622 | + alt = "clgi"; | |
21623 | + break; | |
21624 | + case 0xde: | |
21625 | + alt = "skinit"; | |
21626 | + break; | |
21627 | + case 0xdf: | |
21628 | + alt = "invlpga"; | |
21629 | + break; | |
21630 | + default: | |
21631 | + OP_M (bytemode, sizeflag); | |
21632 | + return; | |
21633 | + } | |
21634 | + /* Override "lidt". */ | |
21635 | + p = obuf + strlen (obuf) - 4; | |
21636 | + /* We might have a suffix. */ | |
21637 | + if (*p == 'i') | |
21638 | + --p; | |
21639 | + strcpy (p, alt); | |
21640 | + if (!(prefixes & PREFIX_ADDR)) | |
21641 | + { | |
21642 | + ++codep; | |
21643 | + return; | |
21644 | + } | |
21645 | + used_prefixes |= PREFIX_ADDR; | |
21646 | + switch (*codep++) | |
21647 | + { | |
21648 | + case 0xdf: | |
21649 | + strcpy (op2out, names32[1]); | |
21650 | + two_source_ops = 1; | |
21651 | + /* Fall through. */ | |
21652 | + case 0xd8: | |
21653 | + case 0xda: | |
21654 | + case 0xdb: | |
21655 | + *obufp++ = open_char; | |
21656 | + if (mode_64bit || (sizeflag & AFLAG)) | |
21657 | + alt = names32[0]; | |
21658 | + else | |
21659 | + alt = names16[0]; | |
21660 | + strcpy (obufp, alt); | |
21661 | + obufp += strlen (alt); | |
21662 | + *obufp++ = close_char; | |
21663 | + *obufp = '\0'; | |
21664 | + break; | |
21665 | + } | |
21666 | +} | |
21667 | + | |
21668 | +static void | |
21669 | +INVLPG_Fixup (int bytemode, int sizeflag) | |
21670 | +{ | |
21671 | + const char *alt; | |
21672 | + | |
21673 | + switch (*codep) | |
21674 | + { | |
21675 | + case 0xf8: | |
21676 | + alt = "swapgs"; | |
21677 | + break; | |
21678 | + case 0xf9: | |
21679 | + alt = "rdtscp"; | |
21680 | + break; | |
21681 | + default: | |
21682 | + OP_M (bytemode, sizeflag); | |
21683 | + return; | |
21684 | + } | |
21685 | + /* Override "invlpg". */ | |
21686 | + strcpy (obuf + strlen (obuf) - 6, alt); | |
21687 | + codep++; | |
21688 | +} | |
21689 | + | |
21690 | +static void | |
21691 | +BadOp (void) | |
21692 | +{ | |
21693 | + /* Throw away prefixes and 1st. opcode byte. */ | |
21694 | + codep = insn_codep + 1; | |
21695 | + oappend ("(bad)"); | |
21696 | +} | |
21697 | + | |
21698 | +static void | |
21699 | +SEG_Fixup (int extrachar, int sizeflag) | |
21700 | +{ | |
21701 | + if (mod == 3) | |
21702 | + { | |
21703 | + /* We need to add a proper suffix with | |
21704 | + | |
21705 | + movw %ds,%ax | |
21706 | + movl %ds,%eax | |
21707 | + movq %ds,%rax | |
21708 | + movw %ax,%ds | |
21709 | + movl %eax,%ds | |
21710 | + movq %rax,%ds | |
21711 | + */ | |
21712 | + const char *suffix; | |
21713 | + | |
21714 | + if (prefixes & PREFIX_DATA) | |
21715 | + suffix = "w"; | |
21716 | + else | |
21717 | + { | |
21718 | + USED_REX (REX_MODE64); | |
21719 | + if (rex & REX_MODE64) | |
21720 | + suffix = "q"; | |
21721 | + else | |
21722 | + suffix = "l"; | |
21723 | + } | |
21724 | + strcat (obuf, suffix); | |
21725 | + } | |
21726 | + else | |
21727 | + { | |
21728 | + /* We need to fix the suffix for | |
21729 | + | |
21730 | + movw %ds,(%eax) | |
21731 | + movw %ds,(%rax) | |
21732 | + movw (%eax),%ds | |
21733 | + movw (%rax),%ds | |
21734 | + | |
21735 | + Override "mov[l|q]". */ | |
21736 | + char *p = obuf + strlen (obuf) - 1; | |
21737 | + | |
21738 | + /* We might not have a suffix. */ | |
21739 | + if (*p == 'v') | |
21740 | + ++p; | |
21741 | + *p = 'w'; | |
21742 | + } | |
21743 | + | |
21744 | + OP_E (extrachar, sizeflag); | |
21745 | +} | |
21746 | + | |
21747 | +static void | |
21748 | +VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag) | |
21749 | +{ | |
21750 | + if (mod == 3 && reg == 0 && rm >=1 && rm <= 4) | |
21751 | + { | |
21752 | + /* Override "sgdt". */ | |
21753 | + char *p = obuf + strlen (obuf) - 4; | |
21754 | + | |
21755 | + /* We might have a suffix when disassembling with -Msuffix. */ | |
21756 | + if (*p == 'g') | |
21757 | + --p; | |
21758 | + | |
21759 | + switch (rm) | |
21760 | + { | |
21761 | + case 1: | |
21762 | + strcpy (p, "vmcall"); | |
21763 | + break; | |
21764 | + case 2: | |
21765 | + strcpy (p, "vmlaunch"); | |
21766 | + break; | |
21767 | + case 3: | |
21768 | + strcpy (p, "vmresume"); | |
21769 | + break; | |
21770 | + case 4: | |
21771 | + strcpy (p, "vmxoff"); | |
21772 | + break; | |
21773 | + } | |
21774 | + | |
21775 | + codep++; | |
21776 | + } | |
21777 | + else | |
21778 | + OP_E (0, sizeflag); | |
21779 | +} | |
21780 | + | |
21781 | +static void | |
21782 | +OP_VMX (int bytemode, int sizeflag) | |
21783 | +{ | |
21784 | + used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ)); | |
21785 | + if (prefixes & PREFIX_DATA) | |
21786 | + strcpy (obuf, "vmclear"); | |
21787 | + else if (prefixes & PREFIX_REPZ) | |
21788 | + strcpy (obuf, "vmxon"); | |
21789 | + else | |
21790 | + strcpy (obuf, "vmptrld"); | |
21791 | + OP_E (bytemode, sizeflag); | |
21792 | +} | |
21793 | --- a/arch/x86/kernel/crash.c | |
21794 | +++ b/arch/x86/kernel/crash.c | |
21795 | @@ -35,13 +35,38 @@ static int crashing_cpu; | |
21796 | #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) | |
21797 | static atomic_t waiting_for_crash_ipi; | |
21798 | ||
21799 | +#ifdef CONFIG_KDB_KDUMP | |
21800 | +void halt_current_cpu(struct pt_regs *regs) | |
21801 | +{ | |
21802 | +#ifdef CONFIG_X86_32 | |
21803 | + struct pt_regs fixed_regs; | |
21804 | +#endif | |
21805 | + local_irq_disable(); | |
21806 | +#ifdef CONFIG_X86_32 | |
21807 | + if (!user_mode_vm(regs)) { | |
21808 | + crash_fixup_ss_esp(&fixed_regs, regs); | |
21809 | + regs = &fixed_regs; | |
21810 | + } | |
21811 | +#endif | |
21812 | + crash_save_cpu(regs, raw_smp_processor_id()); | |
21813 | + disable_local_APIC(); | |
21814 | + atomic_dec(&waiting_for_crash_ipi); | |
21815 | + /* Assume hlt works */ | |
21816 | + halt(); | |
21817 | + for(;;) | |
21818 | + cpu_relax(); | |
21819 | +} | |
21820 | +#endif /* CONFIG_KDB_KDUMP */ | |
21821 | + | |
21822 | static int crash_nmi_callback(struct notifier_block *self, | |
21823 | unsigned long val, void *data) | |
21824 | { | |
21825 | struct pt_regs *regs; | |
21826 | +#ifndef CONFIG_KDB_KDUMP | |
21827 | #ifdef CONFIG_X86_32 | |
21828 | struct pt_regs fixed_regs; | |
21829 | #endif | |
21830 | +#endif /* !CONFIG_KDB_KDUMP */ | |
21831 | int cpu; | |
21832 | ||
21833 | if (val != DIE_NMI_IPI) | |
21834 | @@ -56,6 +81,9 @@ static int crash_nmi_callback(struct not | |
21835 | */ | |
21836 | if (cpu == crashing_cpu) | |
21837 | return NOTIFY_STOP; | |
21838 | +#ifdef CONFIG_KDB_KDUMP | |
21839 | + halt_current_cpu(regs); | |
21840 | +#else | |
21841 | local_irq_disable(); | |
21842 | ||
21843 | #ifdef CONFIG_X86_32 | |
21844 | @@ -71,6 +99,7 @@ static int crash_nmi_callback(struct not | |
21845 | halt(); | |
21846 | for (;;) | |
21847 | cpu_relax(); | |
21848 | +#endif /* !CONFIG_KDB_KDUMP */ | |
21849 | ||
21850 | return 1; | |
21851 | } | |
21852 | @@ -84,6 +113,43 @@ static struct notifier_block crash_nmi_n | |
21853 | .notifier_call = crash_nmi_callback, | |
21854 | }; | |
21855 | ||
21856 | +#ifdef CONFIG_KDB_KDUMP | |
21857 | +static void wait_other_cpus(void) | |
21858 | +{ | |
21859 | + unsigned long msecs; | |
21860 | + | |
21861 | + msecs = 1000; /* Wait at most a second for the other cpus to stop */ | |
21862 | + while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) { | |
21863 | + udelay(1000); | |
21864 | + msecs--; | |
21865 | + } | |
21866 | +} | |
21867 | + | |
21868 | +static void nmi_shootdown_cpus_init(void) | |
21869 | +{ | |
21870 | + atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); | |
21871 | +} | |
21872 | + | |
21873 | +static void nmi_shootdown_cpus(void) | |
21874 | +{ | |
21875 | + nmi_shootdown_cpus_init(); | |
21876 | + | |
21877 | + /* Would it be better to replace the trap vector here? */ | |
21878 | + if (register_die_notifier(&crash_nmi_nb)) | |
21879 | + return; /* return what? */ | |
21880 | + /* Ensure the new callback function is set before sending | |
21881 | + * out the NMI | |
21882 | + */ | |
21883 | + wmb(); | |
21884 | + | |
21885 | + smp_send_nmi_allbutself(); | |
21886 | + | |
21887 | + wait_other_cpus(); | |
21888 | + /* Leave the nmi callback set */ | |
21889 | + | |
21890 | + disable_local_APIC(); | |
21891 | +} | |
21892 | +#else | |
21893 | static void nmi_shootdown_cpus(void) | |
21894 | { | |
21895 | unsigned long msecs; | |
21896 | @@ -108,12 +174,22 @@ static void nmi_shootdown_cpus(void) | |
21897 | /* Leave the nmi callback set */ | |
21898 | disable_local_APIC(); | |
21899 | } | |
21900 | -#else | |
21901 | +#endif /* !CONFIG_KDB_KDUMP */ | |
21902 | + | |
21903 | +#else /* defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) */ | |
21904 | + | |
21905 | static void nmi_shootdown_cpus(void) | |
21906 | { | |
21907 | /* There are no cpus to shootdown */ | |
21908 | } | |
21909 | -#endif | |
21910 | + | |
21911 | +#ifdef CONFIG_KDB_KDUMP | |
21912 | +static void nmi_shootdown_cpus_init(void) {}; | |
21913 | +static void wait_other_cpus() {} | |
21914 | +static void halt_current_cpu(struct pt_regs *regs) {}; | |
21915 | +#endif /* CONFIG_KDB_KDUMP */ | |
21916 | + | |
21917 | +#endif /* defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) */ | |
21918 | ||
21919 | void native_machine_crash_shutdown(struct pt_regs *regs) | |
21920 | { | |
21921 | @@ -140,3 +216,33 @@ void native_machine_crash_shutdown(struc | |
21922 | #endif | |
21923 | crash_save_cpu(regs, safe_smp_processor_id()); | |
21924 | } | |
21925 | + | |
21926 | +#ifdef CONFIG_KDB_KDUMP | |
21927 | +void machine_crash_shutdown_begin(void) | |
21928 | +{ | |
21929 | + local_irq_disable(); | |
21930 | + | |
21931 | + /* Make a note of crashing cpu. Will be used in NMI callback.*/ | |
21932 | + crashing_cpu = safe_smp_processor_id(); | |
21933 | +#ifndef CONFIG_XEN | |
21934 | + nmi_shootdown_cpus_init(); | |
21935 | +#endif /* CONFIG_XEN */ | |
21936 | +} | |
21937 | + | |
21938 | +void machine_crash_shutdown_end(struct pt_regs *regs) | |
21939 | +{ | |
21940 | +#ifndef CONFIG_XEN | |
21941 | + wait_other_cpus(); | |
21942 | + | |
21943 | + local_irq_disable(); | |
21944 | + lapic_shutdown(); | |
21945 | +#if defined(CONFIG_X86_IO_APIC) | |
21946 | + disable_IO_APIC(); | |
21947 | +#endif | |
21948 | +#ifdef CONFIG_HPET_TIMER | |
21949 | + hpet_disable(); | |
21950 | +#endif | |
21951 | +#endif /* CONFIG_XEN */ | |
21952 | + crash_save_cpu(regs,safe_smp_processor_id()); | |
21953 | +} | |
21954 | +#endif /* CONFIG_KDB_KDUMP */ | |
21955 | --- a/arch/x86/kernel/entry_32.S | |
21956 | +++ b/arch/x86/kernel/entry_32.S | |
21957 | @@ -1015,6 +1015,26 @@ ENTRY(alignment_check) | |
21958 | CFI_ENDPROC | |
21959 | END(alignment_check) | |
21960 | ||
21961 | +#ifdef CONFIG_KDB | |
21962 | + | |
21963 | +ENTRY(kdb_call) | |
21964 | + RING0_INT_FRAME | |
21965 | + pushl %eax # save orig EAX | |
21966 | + CFI_ADJUST_CFA_OFFSET 4 | |
21967 | + SAVE_ALL | |
21968 | + movl %esp,%ecx # struct pt_regs | |
21969 | + movl $0,%edx # error_code | |
21970 | + movl $1,%eax # KDB_REASON_ENTER | |
21971 | + call kdb | |
21972 | + jmp restore_all | |
21973 | + CFI_ENDPROC | |
21974 | + | |
21975 | +#ifdef CONFIG_SMP | |
21976 | +BUILD_INTERRUPT(kdb_interrupt,KDB_VECTOR) | |
21977 | +#endif /* CONFIG_SMP */ | |
21978 | + | |
21979 | +#endif /* CONFIG_KDB */ | |
21980 | + | |
21981 | ENTRY(divide_error) | |
21982 | RING0_INT_FRAME | |
21983 | pushl $0 # no error code | |
21984 | --- a/arch/x86/kernel/entry_64.S | |
21985 | +++ b/arch/x86/kernel/entry_64.S | |
21986 | @@ -1467,3 +1467,30 @@ ENTRY(xen_failsafe_callback) | |
21987 | END(xen_failsafe_callback) | |
21988 | ||
21989 | #endif /* CONFIG_XEN */ | |
21990 | + | |
21991 | +#ifdef CONFIG_KDB | |
21992 | + | |
21993 | +#ifdef CONFIG_SMP | |
21994 | +ENTRY(kdb_interrupt) | |
21995 | + apicinterrupt KDB_VECTOR,smp_kdb_interrupt | |
21996 | +END(kdb_interrupt) | |
21997 | +#endif /* CONFIG_SMP */ | |
21998 | + | |
21999 | +ENTRY(kdb_call) | |
22000 | + INTR_FRAME | |
22001 | + cld | |
22002 | + pushq $-1 # orig_eax | |
22003 | + CFI_ADJUST_CFA_OFFSET 8 | |
22004 | + SAVE_ALL | |
22005 | + movq $1,%rdi # KDB_REASON_ENTER | |
22006 | + movq $0,%rsi # error_code | |
22007 | + movq %rsp,%rdx # struct pt_regs | |
22008 | + call kdb | |
22009 | + RESTORE_ALL | |
22010 | + addq $8,%rsp # forget orig_eax | |
22011 | + CFI_ADJUST_CFA_OFFSET -8 | |
22012 | + iretq | |
22013 | + CFI_ENDPROC | |
22014 | +END(kdb_call) | |
22015 | + | |
22016 | +#endif /* CONFIG_KDB */ | |
22017 | --- a/arch/x86/kernel/io_apic_32.c | |
22018 | +++ b/arch/x86/kernel/io_apic_32.c | |
22019 | @@ -33,6 +33,10 @@ | |
22020 | #include <linux/sysdev.h> | |
22021 | #include <linux/pci.h> | |
22022 | #include <linux/msi.h> | |
22023 | + | |
22024 | +#ifdef CONFIG_KDB | |
22025 | +#include <linux/kdb.h> | |
22026 | +#endif /* CONFIG_KDB */ | |
22027 | #include <linux/htirq.h> | |
22028 | #include <linux/freezer.h> | |
22029 | #include <linux/kthread.h> | |
22030 | @@ -1189,6 +1193,10 @@ next: | |
22031 | return -ENOSPC; | |
22032 | if (test_and_set_bit(vector, used_vectors)) | |
22033 | goto next; | |
22034 | +#ifdef CONFIG_KDB | |
22035 | + if (vector == KDBENTER_VECTOR) | |
22036 | + goto next; | |
22037 | +#endif | |
22038 | ||
22039 | current_vector = vector; | |
22040 | current_offset = offset; | |
22041 | --- a/arch/x86/kernel/io_apic_64.c | |
22042 | +++ b/arch/x86/kernel/io_apic_64.c | |
22043 | @@ -39,6 +39,10 @@ | |
22044 | #include <linux/bootmem.h> | |
22045 | #include <linux/dmar.h> | |
22046 | ||
22047 | +#ifdef CONFIG_KDB | |
22048 | +#include <linux/kdb.h> | |
22049 | +#endif /* CONFIG_KDB */ | |
22050 | + | |
22051 | #include <asm/idle.h> | |
22052 | #include <asm/io.h> | |
22053 | #include <asm/smp.h> | |
22054 | @@ -853,6 +857,10 @@ next: | |
22055 | continue; | |
22056 | if (vector == IA32_SYSCALL_VECTOR) | |
22057 | goto next; | |
22058 | +#ifdef CONFIG_KDB | |
22059 | + if (vector == KDBENTER_VECTOR) | |
22060 | + goto next; | |
22061 | +#endif /* CONFIG_KDB */ | |
22062 | for_each_cpu_mask_and(new_cpu, tmp_mask, cpu_online_map) | |
22063 | if (per_cpu(vector_irq, new_cpu)[vector] != -1) | |
22064 | goto next; | |
22065 | --- a/arch/x86/kernel/reboot.c | |
22066 | +++ b/arch/x86/kernel/reboot.c | |
22067 | @@ -3,6 +3,9 @@ | |
22068 | #include <linux/init.h> | |
22069 | #include <linux/pm.h> | |
22070 | #include <linux/efi.h> | |
22071 | +#ifdef CONFIG_KDB | |
22072 | +#include <linux/kdb.h> | |
22073 | +#endif /* CONFIG_KDB */ | |
22074 | #include <acpi/reboot.h> | |
22075 | #include <asm/io.h> | |
22076 | #include <asm/apic.h> | |
22077 | @@ -455,6 +458,14 @@ void native_machine_shutdown(void) | |
22078 | /* Make certain I only run on the appropriate processor */ | |
22079 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(reboot_cpu_id)); | |
22080 | ||
22081 | +#if defined(CONFIG_X86_32) && defined(CONFIG_KDB) | |
22082 | + /* | |
22083 | + * If this restart is occuring while kdb is running (e.g. reboot | |
22084 | + * command), the other CPU's are already stopped. Don't try to | |
22085 | + * stop them yet again. | |
22086 | + */ | |
22087 | + if (!KDB_IS_RUNNING()) | |
22088 | +#endif /* defined(CONFIG_X86_32) && defined(CONFIG_KDB) */ | |
22089 | /* O.K Now that I'm on the appropriate processor, | |
22090 | * stop all of the others. | |
22091 | */ | |
22092 | --- a/arch/x86/kernel/traps_32.c | |
22093 | +++ b/arch/x86/kernel/traps_32.c | |
22094 | @@ -46,6 +46,10 @@ | |
22095 | #include <linux/edac.h> | |
22096 | #endif | |
22097 | ||
22098 | +#ifdef CONFIG_KDB | |
22099 | +#include <linux/kdb.h> | |
22100 | +#endif /* CONFIG_KDB */ | |
22101 | + | |
22102 | #include <asm/arch_hooks.h> | |
22103 | #include <asm/stacktrace.h> | |
22104 | #include <asm/processor.h> | |
22105 | @@ -395,6 +399,9 @@ void __kprobes oops_end(unsigned long fl | |
22106 | add_taint(TAINT_DIE); | |
22107 | __raw_spin_unlock(&die_lock); | |
22108 | raw_local_irq_restore(flags); | |
22109 | +#ifdef CONFIG_KDB | |
22110 | + kdb(KDB_REASON_OOPS, signr, regs); | |
22111 | +#endif /* CONFIG_KDB */ | |
22112 | ||
22113 | if (!regs) | |
22114 | return; | |
22115 | @@ -465,6 +472,9 @@ void die(const char *str, struct pt_regs | |
22116 | printk(KERN_EMERG "Recursive die() failure, output suppressed\n"); | |
22117 | } | |
22118 | ||
22119 | +#ifdef CONFIG_KDB | |
22120 | + kdb_diemsg = str; | |
22121 | +#endif /* CONFIG_KDB */ | |
22122 | oops_end(flags, regs, SIGSEGV); | |
22123 | } | |
22124 | ||
22125 | @@ -575,7 +585,7 @@ void do_##name(struct pt_regs *regs, lon | |
22126 | } | |
22127 | ||
22128 | DO_VM86_ERROR_INFO(0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip) | |
22129 | -#ifndef CONFIG_KPROBES | |
22130 | +#if !defined(CONFIG_KPROBES) && !defined(CONFIG_KDB) | |
22131 | DO_VM86_ERROR(3, SIGTRAP, "int3", int3) | |
22132 | #endif | |
22133 | DO_VM86_ERROR(4, SIGSEGV, "overflow", overflow) | |
22134 | @@ -718,6 +728,10 @@ io_check_error(unsigned char reason, str | |
22135 | static notrace __kprobes void | |
22136 | unknown_nmi_error(unsigned char reason, struct pt_regs *regs) | |
22137 | { | |
22138 | +#ifdef CONFIG_KDB | |
22139 | + (void)kdb(KDB_REASON_NMI, reason, regs); | |
22140 | +#endif /* CONFIG_KDB */ | |
22141 | + | |
22142 | if (notify_die(DIE_NMIUNKNOWN, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) | |
22143 | return; | |
22144 | #ifdef CONFIG_MCA | |
22145 | @@ -758,6 +772,9 @@ void notrace __kprobes die_nmi(char *str | |
22146 | printk(" on CPU%d, ip %08lx, registers:\n", | |
22147 | smp_processor_id(), regs->ip); | |
22148 | show_registers(regs); | |
22149 | +#ifdef CONFIG_KDB | |
22150 | + kdb(KDB_REASON_NMI, 0, regs); | |
22151 | +#endif /* CONFIG_KDB */ | |
22152 | if (do_panic) | |
22153 | panic("Non maskable interrupt"); | |
22154 | console_silent(); | |
22155 | @@ -787,6 +804,16 @@ static notrace __kprobes void default_do | |
22156 | if (!cpu) | |
22157 | reason = get_nmi_reason(); | |
22158 | ||
22159 | +#if defined(CONFIG_SMP) && defined(CONFIG_KDB) | |
22160 | + /* | |
22161 | + * Call the kernel debugger to see if this NMI is due | |
22162 | + * to an KDB requested IPI. If so, kdb will handle it. | |
22163 | + */ | |
22164 | + if (kdb_ipi(regs, NULL)) { | |
22165 | + return; | |
22166 | + } | |
22167 | +#endif /* defined(CONFIG_SMP) && defined(CONFIG_KDB) */ | |
22168 | + | |
22169 | if (!(reason & 0xc0)) { | |
22170 | if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT) | |
22171 | == NOTIFY_STOP) | |
22172 | @@ -854,6 +881,10 @@ void __kprobes do_int3(struct pt_regs *r | |
22173 | { | |
22174 | trace_hardirqs_fixup(); | |
22175 | ||
22176 | +#ifdef CONFIG_KDB | |
22177 | + if (kdb(KDB_REASON_BREAK, error_code, regs)) | |
22178 | + return; | |
22179 | +#endif | |
22180 | if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) | |
22181 | == NOTIFY_STOP) | |
22182 | return; | |
22183 | @@ -904,6 +935,11 @@ void __kprobes do_debug(struct pt_regs * | |
22184 | clear_tsk_thread_flag(tsk, TIF_DEBUGCTLMSR); | |
22185 | tsk->thread.debugctlmsr = 0; | |
22186 | ||
22187 | +#ifdef CONFIG_KDB | |
22188 | + if (kdb(KDB_REASON_DEBUG, error_code, regs)) | |
22189 | + return; | |
22190 | +#endif /* CONFIG_KDB */ | |
22191 | + | |
22192 | if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, | |
22193 | SIGTRAP) == NOTIFY_STOP) | |
22194 | return; | |
22195 | @@ -958,6 +994,16 @@ clear_TF_reenable: | |
22196 | return; | |
22197 | } | |
22198 | ||
22199 | +#if defined(CONFIG_KDB) && !defined(CONFIG_KPROBES) | |
22200 | +void do_int3(struct pt_regs * regs, long error_code) | |
22201 | +{ | |
22202 | + if (kdb(KDB_REASON_BREAK, error_code, regs)) | |
22203 | + return; | |
22204 | + do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL); | |
22205 | +} | |
22206 | +#endif /* CONFIG_KDB && !CONFIG_KPROBES */ | |
22207 | + | |
22208 | + | |
22209 | /* | |
22210 | * Note that we play around with the 'TS' bit in an attempt to get | |
22211 | * the correct behaviour even in the presence of the asynchronous | |
22212 | --- a/arch/x86/kernel/traps_64.c | |
22213 | +++ b/arch/x86/kernel/traps_64.c | |
22214 | @@ -583,6 +583,8 @@ die_nmi(char *str, struct pt_regs *regs, | |
22215 | printk(" on CPU%d, ip %08lx, registers:\n", | |
22216 | smp_processor_id(), regs->ip); | |
22217 | show_registers(regs); | |
22218 | + if (strncmp(str, "NMI Watchdog", 12) == 0) | |
22219 | + notify_die(DIE_NMIWATCHDOG, "nmi_watchdog", regs, 0, 2, SIGINT); | |
22220 | if (kexec_should_crash(current)) | |
22221 | crash_kexec(regs); | |
22222 | if (do_panic || panic_on_oops) | |
22223 | --- a/arch/x86/Makefile | |
22224 | +++ b/arch/x86/Makefile | |
22225 | @@ -171,6 +171,9 @@ ifeq ($(CONFIG_X86_32),y) | |
22226 | drivers-$(CONFIG_FB) += arch/x86/video/ | |
22227 | endif | |
22228 | ||
22229 | +# KDB support | |
22230 | +drivers-$(CONFIG_KDB) += arch/x86/kdb/ | |
22231 | + | |
22232 | #### | |
22233 | # boot loader support. Several targets are kept for legacy purposes | |
22234 | ||
22235 | --- /dev/null | |
22236 | +++ b/include/asm-x86/ansidecl_32.h | |
22237 | @@ -0,0 +1,383 @@ | |
22238 | +/* ANSI and traditional C compatability macros | |
22239 | + Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 | |
22240 | + Free Software Foundation, Inc. | |
22241 | + This file is part of the GNU C Library. | |
22242 | + | |
22243 | +This program is free software; you can redistribute it and/or modify | |
22244 | +it under the terms of the GNU General Public License as published by | |
22245 | +the Free Software Foundation; either version 2 of the License, or | |
22246 | +(at your option) any later version. | |
22247 | + | |
22248 | +This program is distributed in the hope that it will be useful, | |
22249 | +but WITHOUT ANY WARRANTY; without even the implied warranty of | |
22250 | +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22251 | +GNU General Public License for more details. | |
22252 | + | |
22253 | +You should have received a copy of the GNU General Public License | |
22254 | +along with this program; if not, write to the Free Software | |
22255 | +Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ | |
22256 | + | |
22257 | +/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use. | |
22258 | + * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as | |
22259 | + * required. | |
22260 | + * Keith Owens <kaos@sgi.com> 15 May 2006 | |
22261 | + */ | |
22262 | + | |
22263 | +/* ANSI and traditional C compatibility macros | |
22264 | + | |
22265 | + ANSI C is assumed if __STDC__ is #defined. | |
22266 | + | |
22267 | + Macro ANSI C definition Traditional C definition | |
22268 | + ----- ---- - ---------- ----------- - ---------- | |
22269 | + ANSI_PROTOTYPES 1 not defined | |
22270 | + PTR `void *' `char *' | |
22271 | + PTRCONST `void *const' `char *' | |
22272 | + LONG_DOUBLE `long double' `double' | |
22273 | + const not defined `' | |
22274 | + volatile not defined `' | |
22275 | + signed not defined `' | |
22276 | + VA_START(ap, var) va_start(ap, var) va_start(ap) | |
22277 | + | |
22278 | + Note that it is safe to write "void foo();" indicating a function | |
22279 | + with no return value, in all K+R compilers we have been able to test. | |
22280 | + | |
22281 | + For declaring functions with prototypes, we also provide these: | |
22282 | + | |
22283 | + PARAMS ((prototype)) | |
22284 | + -- for functions which take a fixed number of arguments. Use this | |
22285 | + when declaring the function. When defining the function, write a | |
22286 | + K+R style argument list. For example: | |
22287 | + | |
22288 | + char *strcpy PARAMS ((char *dest, char *source)); | |
22289 | + ... | |
22290 | + char * | |
22291 | + strcpy (dest, source) | |
22292 | + char *dest; | |
22293 | + char *source; | |
22294 | + { ... } | |
22295 | + | |
22296 | + | |
22297 | + VPARAMS ((prototype, ...)) | |
22298 | + -- for functions which take a variable number of arguments. Use | |
22299 | + PARAMS to declare the function, VPARAMS to define it. For example: | |
22300 | + | |
22301 | + int printf PARAMS ((const char *format, ...)); | |
22302 | + ... | |
22303 | + int | |
22304 | + printf VPARAMS ((const char *format, ...)) | |
22305 | + { | |
22306 | + ... | |
22307 | + } | |
22308 | + | |
22309 | + For writing functions which take variable numbers of arguments, we | |
22310 | + also provide the VA_OPEN, VA_CLOSE, and VA_FIXEDARG macros. These | |
22311 | + hide the differences between K+R <varargs.h> and C89 <stdarg.h> more | |
22312 | + thoroughly than the simple VA_START() macro mentioned above. | |
22313 | + | |
22314 | + VA_OPEN and VA_CLOSE are used *instead of* va_start and va_end. | |
22315 | + Immediately after VA_OPEN, put a sequence of VA_FIXEDARG calls | |
22316 | + corresponding to the list of fixed arguments. Then use va_arg | |
22317 | + normally to get the variable arguments, or pass your va_list object | |
22318 | + around. You do not declare the va_list yourself; VA_OPEN does it | |
22319 | + for you. | |
22320 | + | |
22321 | + Here is a complete example: | |
22322 | + | |
22323 | + int | |
22324 | + printf VPARAMS ((const char *format, ...)) | |
22325 | + { | |
22326 | + int result; | |
22327 | + | |
22328 | + VA_OPEN (ap, format); | |
22329 | + VA_FIXEDARG (ap, const char *, format); | |
22330 | + | |
22331 | + result = vfprintf (stdout, format, ap); | |
22332 | + VA_CLOSE (ap); | |
22333 | + | |
22334 | + return result; | |
22335 | + } | |
22336 | + | |
22337 | + | |
22338 | + You can declare variables either before or after the VA_OPEN, | |
22339 | + VA_FIXEDARG sequence. Also, VA_OPEN and VA_CLOSE are the beginning | |
22340 | + and end of a block. They must appear at the same nesting level, | |
22341 | + and any variables declared after VA_OPEN go out of scope at | |
22342 | + VA_CLOSE. Unfortunately, with a K+R compiler, that includes the | |
22343 | + argument list. You can have multiple instances of VA_OPEN/VA_CLOSE | |
22344 | + pairs in a single function in case you need to traverse the | |
22345 | + argument list more than once. | |
22346 | + | |
22347 | + For ease of writing code which uses GCC extensions but needs to be | |
22348 | + portable to other compilers, we provide the GCC_VERSION macro that | |
22349 | + simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various | |
22350 | + wrappers around __attribute__. Also, __extension__ will be #defined | |
22351 | + to nothing if it doesn't work. See below. | |
22352 | + | |
22353 | + This header also defines a lot of obsolete macros: | |
22354 | + CONST, VOLATILE, SIGNED, PROTO, EXFUN, DEFUN, DEFUN_VOID, | |
22355 | + AND, DOTS, NOARGS. Don't use them. */ | |
22356 | + | |
22357 | +#ifndef _ANSIDECL_H | |
22358 | +#define _ANSIDECL_H 1 | |
22359 | + | |
22360 | +/* Every source file includes this file, | |
22361 | + so they will all get the switch for lint. */ | |
22362 | +/* LINTLIBRARY */ | |
22363 | + | |
22364 | +/* Using MACRO(x,y) in cpp #if conditionals does not work with some | |
22365 | + older preprocessors. Thus we can't define something like this: | |
22366 | + | |
22367 | +#define HAVE_GCC_VERSION(MAJOR, MINOR) \ | |
22368 | + (__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR))) | |
22369 | + | |
22370 | +and then test "#if HAVE_GCC_VERSION(2,7)". | |
22371 | + | |
22372 | +So instead we use the macro below and test it against specific values. */ | |
22373 | + | |
22374 | +/* This macro simplifies testing whether we are using gcc, and if it | |
22375 | + is of a particular minimum version. (Both major & minor numbers are | |
22376 | + significant.) This macro will evaluate to 0 if we are not using | |
22377 | + gcc at all. */ | |
22378 | +#ifndef GCC_VERSION | |
22379 | +#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) | |
22380 | +#endif /* GCC_VERSION */ | |
22381 | + | |
22382 | +#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32) || (defined(__alpha) && defined(__cplusplus)) | |
22383 | +/* All known AIX compilers implement these things (but don't always | |
22384 | + define __STDC__). The RISC/OS MIPS compiler defines these things | |
22385 | + in SVR4 mode, but does not define __STDC__. */ | |
22386 | +/* eraxxon@alumni.rice.edu: The Compaq C++ compiler, unlike many other | |
22387 | + C++ compilers, does not define __STDC__, though it acts as if this | |
22388 | + was so. (Verified versions: 5.7, 6.2, 6.3, 6.5) */ | |
22389 | + | |
22390 | +#define ANSI_PROTOTYPES 1 | |
22391 | +#define PTR void * | |
22392 | +#define PTRCONST void *const | |
22393 | +#define LONG_DOUBLE long double | |
22394 | + | |
22395 | +/* PARAMS is often defined elsewhere (e.g. by libintl.h), so wrap it in | |
22396 | + a #ifndef. */ | |
22397 | +#ifndef PARAMS | |
22398 | +#define PARAMS(ARGS) ARGS | |
22399 | +#endif | |
22400 | + | |
22401 | +#define VPARAMS(ARGS) ARGS | |
22402 | +#define VA_START(VA_LIST, VAR) va_start(VA_LIST, VAR) | |
22403 | + | |
22404 | +/* variadic function helper macros */ | |
22405 | +/* "struct Qdmy" swallows the semicolon after VA_OPEN/VA_FIXEDARG's | |
22406 | + use without inhibiting further decls and without declaring an | |
22407 | + actual variable. */ | |
22408 | +#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP, VAR); { struct Qdmy | |
22409 | +#define VA_CLOSE(AP) } va_end(AP); } | |
22410 | +#define VA_FIXEDARG(AP, T, N) struct Qdmy | |
22411 | + | |
22412 | +#undef const | |
22413 | +#undef volatile | |
22414 | +#undef signed | |
22415 | + | |
22416 | +#ifdef __KERNEL__ | |
22417 | +#ifndef __STDC_VERSION__ | |
22418 | +#define __STDC_VERSION__ 0 | |
22419 | +#endif | |
22420 | +#endif /* __KERNEL__ */ | |
22421 | + | |
22422 | +/* inline requires special treatment; it's in C99, and GCC >=2.7 supports | |
22423 | + it too, but it's not in C89. */ | |
22424 | +#undef inline | |
22425 | +#if __STDC_VERSION__ > 199901L | |
22426 | +/* it's a keyword */ | |
22427 | +#else | |
22428 | +# if GCC_VERSION >= 2007 | |
22429 | +# define inline __inline__ /* __inline__ prevents -pedantic warnings */ | |
22430 | +# else | |
22431 | +# define inline /* nothing */ | |
22432 | +# endif | |
22433 | +#endif | |
22434 | + | |
22435 | +/* These are obsolete. Do not use. */ | |
22436 | +#ifndef IN_GCC | |
22437 | +#define CONST const | |
22438 | +#define VOLATILE volatile | |
22439 | +#define SIGNED signed | |
22440 | + | |
22441 | +#define PROTO(type, name, arglist) type name arglist | |
22442 | +#define EXFUN(name, proto) name proto | |
22443 | +#define DEFUN(name, arglist, args) name(args) | |
22444 | +#define DEFUN_VOID(name) name(void) | |
22445 | +#define AND , | |
22446 | +#define DOTS , ... | |
22447 | +#define NOARGS void | |
22448 | +#endif /* ! IN_GCC */ | |
22449 | + | |
22450 | +#else /* Not ANSI C. */ | |
22451 | + | |
22452 | +#undef ANSI_PROTOTYPES | |
22453 | +#define PTR char * | |
22454 | +#define PTRCONST PTR | |
22455 | +#define LONG_DOUBLE double | |
22456 | + | |
22457 | +#define PARAMS(args) () | |
22458 | +#define VPARAMS(args) (va_alist) va_dcl | |
22459 | +#define VA_START(va_list, var) va_start(va_list) | |
22460 | + | |
22461 | +#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP); { struct Qdmy | |
22462 | +#define VA_CLOSE(AP) } va_end(AP); } | |
22463 | +#define VA_FIXEDARG(AP, TYPE, NAME) TYPE NAME = va_arg(AP, TYPE) | |
22464 | + | |
22465 | +/* some systems define these in header files for non-ansi mode */ | |
22466 | +#undef const | |
22467 | +#undef volatile | |
22468 | +#undef signed | |
22469 | +#undef inline | |
22470 | +#define const | |
22471 | +#define volatile | |
22472 | +#define signed | |
22473 | +#define inline | |
22474 | + | |
22475 | +#ifndef IN_GCC | |
22476 | +#define CONST | |
22477 | +#define VOLATILE | |
22478 | +#define SIGNED | |
22479 | + | |
22480 | +#define PROTO(type, name, arglist) type name () | |
22481 | +#define EXFUN(name, proto) name() | |
22482 | +#define DEFUN(name, arglist, args) name arglist args; | |
22483 | +#define DEFUN_VOID(name) name() | |
22484 | +#define AND ; | |
22485 | +#define DOTS | |
22486 | +#define NOARGS | |
22487 | +#endif /* ! IN_GCC */ | |
22488 | + | |
22489 | +#endif /* ANSI C. */ | |
22490 | + | |
22491 | +/* Define macros for some gcc attributes. This permits us to use the | |
22492 | + macros freely, and know that they will come into play for the | |
22493 | + version of gcc in which they are supported. */ | |
22494 | + | |
22495 | +#if (GCC_VERSION < 2007) | |
22496 | +# define __attribute__(x) | |
22497 | +#endif | |
22498 | + | |
22499 | +/* Attribute __malloc__ on functions was valid as of gcc 2.96. */ | |
22500 | +#ifndef ATTRIBUTE_MALLOC | |
22501 | +# if (GCC_VERSION >= 2096) | |
22502 | +# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) | |
22503 | +# else | |
22504 | +# define ATTRIBUTE_MALLOC | |
22505 | +# endif /* GNUC >= 2.96 */ | |
22506 | +#endif /* ATTRIBUTE_MALLOC */ | |
22507 | + | |
22508 | +/* Attributes on labels were valid as of gcc 2.93. */ | |
22509 | +#ifndef ATTRIBUTE_UNUSED_LABEL | |
22510 | +# if (!defined (__cplusplus) && GCC_VERSION >= 2093) | |
22511 | +# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED | |
22512 | +# else | |
22513 | +# define ATTRIBUTE_UNUSED_LABEL | |
22514 | +# endif /* !__cplusplus && GNUC >= 2.93 */ | |
22515 | +#endif /* ATTRIBUTE_UNUSED_LABEL */ | |
22516 | + | |
22517 | +#ifndef ATTRIBUTE_UNUSED | |
22518 | +#define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) | |
22519 | +#endif /* ATTRIBUTE_UNUSED */ | |
22520 | + | |
22521 | +/* Before GCC 3.4, the C++ frontend couldn't parse attributes placed after the | |
22522 | + identifier name. */ | |
22523 | +#if ! defined(__cplusplus) || (GCC_VERSION >= 3004) | |
22524 | +# define ARG_UNUSED(NAME) NAME ATTRIBUTE_UNUSED | |
22525 | +#else /* !__cplusplus || GNUC >= 3.4 */ | |
22526 | +# define ARG_UNUSED(NAME) NAME | |
22527 | +#endif /* !__cplusplus || GNUC >= 3.4 */ | |
22528 | + | |
22529 | +#ifndef ATTRIBUTE_NORETURN | |
22530 | +#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) | |
22531 | +#endif /* ATTRIBUTE_NORETURN */ | |
22532 | + | |
22533 | +/* Attribute `nonnull' was valid as of gcc 3.3. */ | |
22534 | +#ifndef ATTRIBUTE_NONNULL | |
22535 | +# if (GCC_VERSION >= 3003) | |
22536 | +# define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m))) | |
22537 | +# else | |
22538 | +# define ATTRIBUTE_NONNULL(m) | |
22539 | +# endif /* GNUC >= 3.3 */ | |
22540 | +#endif /* ATTRIBUTE_NONNULL */ | |
22541 | + | |
22542 | +/* Attribute `pure' was valid as of gcc 3.0. */ | |
22543 | +#ifndef ATTRIBUTE_PURE | |
22544 | +# if (GCC_VERSION >= 3000) | |
22545 | +# define ATTRIBUTE_PURE __attribute__ ((__pure__)) | |
22546 | +# else | |
22547 | +# define ATTRIBUTE_PURE | |
22548 | +# endif /* GNUC >= 3.0 */ | |
22549 | +#endif /* ATTRIBUTE_PURE */ | |
22550 | + | |
22551 | +/* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL. | |
22552 | + This was the case for the `printf' format attribute by itself | |
22553 | + before GCC 3.3, but as of 3.3 we need to add the `nonnull' | |
22554 | + attribute to retain this behavior. */ | |
22555 | +#ifndef ATTRIBUTE_PRINTF | |
22556 | +#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m) | |
22557 | +#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2) | |
22558 | +#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3) | |
22559 | +#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4) | |
22560 | +#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5) | |
22561 | +#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6) | |
22562 | +#endif /* ATTRIBUTE_PRINTF */ | |
22563 | + | |
22564 | +/* Use ATTRIBUTE_FPTR_PRINTF when the format attribute is to be set on | |
22565 | + a function pointer. Format attributes were allowed on function | |
22566 | + pointers as of gcc 3.1. */ | |
22567 | +#ifndef ATTRIBUTE_FPTR_PRINTF | |
22568 | +# if (GCC_VERSION >= 3001) | |
22569 | +# define ATTRIBUTE_FPTR_PRINTF(m, n) ATTRIBUTE_PRINTF(m, n) | |
22570 | +# else | |
22571 | +# define ATTRIBUTE_FPTR_PRINTF(m, n) | |
22572 | +# endif /* GNUC >= 3.1 */ | |
22573 | +# define ATTRIBUTE_FPTR_PRINTF_1 ATTRIBUTE_FPTR_PRINTF(1, 2) | |
22574 | +# define ATTRIBUTE_FPTR_PRINTF_2 ATTRIBUTE_FPTR_PRINTF(2, 3) | |
22575 | +# define ATTRIBUTE_FPTR_PRINTF_3 ATTRIBUTE_FPTR_PRINTF(3, 4) | |
22576 | +# define ATTRIBUTE_FPTR_PRINTF_4 ATTRIBUTE_FPTR_PRINTF(4, 5) | |
22577 | +# define ATTRIBUTE_FPTR_PRINTF_5 ATTRIBUTE_FPTR_PRINTF(5, 6) | |
22578 | +#endif /* ATTRIBUTE_FPTR_PRINTF */ | |
22579 | + | |
22580 | +/* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL. A | |
22581 | + NULL format specifier was allowed as of gcc 3.3. */ | |
22582 | +#ifndef ATTRIBUTE_NULL_PRINTF | |
22583 | +# if (GCC_VERSION >= 3003) | |
22584 | +# define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) | |
22585 | +# else | |
22586 | +# define ATTRIBUTE_NULL_PRINTF(m, n) | |
22587 | +# endif /* GNUC >= 3.3 */ | |
22588 | +# define ATTRIBUTE_NULL_PRINTF_1 ATTRIBUTE_NULL_PRINTF(1, 2) | |
22589 | +# define ATTRIBUTE_NULL_PRINTF_2 ATTRIBUTE_NULL_PRINTF(2, 3) | |
22590 | +# define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4) | |
22591 | +# define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5) | |
22592 | +# define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6) | |
22593 | +#endif /* ATTRIBUTE_NULL_PRINTF */ | |
22594 | + | |
22595 | +/* Attribute `sentinel' was valid as of gcc 3.5. */ | |
22596 | +#ifndef ATTRIBUTE_SENTINEL | |
22597 | +# if (GCC_VERSION >= 3005) | |
22598 | +# define ATTRIBUTE_SENTINEL __attribute__ ((__sentinel__)) | |
22599 | +# else | |
22600 | +# define ATTRIBUTE_SENTINEL | |
22601 | +# endif /* GNUC >= 3.5 */ | |
22602 | +#endif /* ATTRIBUTE_SENTINEL */ | |
22603 | + | |
22604 | + | |
22605 | +#ifndef ATTRIBUTE_ALIGNED_ALIGNOF | |
22606 | +# if (GCC_VERSION >= 3000) | |
22607 | +# define ATTRIBUTE_ALIGNED_ALIGNOF(m) __attribute__ ((__aligned__ (__alignof__ (m)))) | |
22608 | +# else | |
22609 | +# define ATTRIBUTE_ALIGNED_ALIGNOF(m) | |
22610 | +# endif /* GNUC >= 3.0 */ | |
22611 | +#endif /* ATTRIBUTE_ALIGNED_ALIGNOF */ | |
22612 | + | |
22613 | +/* We use __extension__ in some places to suppress -pedantic warnings | |
22614 | + about GCC extensions. This feature didn't work properly before | |
22615 | + gcc 2.8. */ | |
22616 | +#if GCC_VERSION < 2008 | |
22617 | +#define __extension__ | |
22618 | +#endif | |
22619 | + | |
22620 | +#endif /* ansidecl.h */ | |
22621 | --- /dev/null | |
22622 | +++ b/include/asm-x86/ansidecl_64.h | |
22623 | @@ -0,0 +1,383 @@ | |
22624 | +/* ANSI and traditional C compatability macros | |
22625 | + Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 | |
22626 | + Free Software Foundation, Inc. | |
22627 | + This file is part of the GNU C Library. | |
22628 | + | |
22629 | +This program is free software; you can redistribute it and/or modify | |
22630 | +it under the terms of the GNU General Public License as published by | |
22631 | +the Free Software Foundation; either version 2 of the License, or | |
22632 | +(at your option) any later version. | |
22633 | + | |
22634 | +This program is distributed in the hope that it will be useful, | |
22635 | +but WITHOUT ANY WARRANTY; without even the implied warranty of | |
22636 | +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22637 | +GNU General Public License for more details. | |
22638 | + | |
22639 | +You should have received a copy of the GNU General Public License | |
22640 | +along with this program; if not, write to the Free Software | |
22641 | +Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ | |
22642 | + | |
22643 | +/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use. | |
22644 | + * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as | |
22645 | + * required. | |
22646 | + * Keith Owens <kaos@sgi.com> 15 May 2006 | |
22647 | + */ | |
22648 | + | |
22649 | +/* ANSI and traditional C compatibility macros | |
22650 | + | |
22651 | + ANSI C is assumed if __STDC__ is #defined. | |
22652 | + | |
22653 | + Macro ANSI C definition Traditional C definition | |
22654 | + ----- ---- - ---------- ----------- - ---------- | |
22655 | + ANSI_PROTOTYPES 1 not defined | |
22656 | + PTR `void *' `char *' | |
22657 | + PTRCONST `void *const' `char *' | |
22658 | + LONG_DOUBLE `long double' `double' | |
22659 | + const not defined `' | |
22660 | + volatile not defined `' | |
22661 | + signed not defined `' | |
22662 | + VA_START(ap, var) va_start(ap, var) va_start(ap) | |
22663 | + | |
22664 | + Note that it is safe to write "void foo();" indicating a function | |
22665 | + with no return value, in all K+R compilers we have been able to test. | |
22666 | + | |
22667 | + For declaring functions with prototypes, we also provide these: | |
22668 | + | |
22669 | + PARAMS ((prototype)) | |
22670 | + -- for functions which take a fixed number of arguments. Use this | |
22671 | + when declaring the function. When defining the function, write a | |
22672 | + K+R style argument list. For example: | |
22673 | + | |
22674 | + char *strcpy PARAMS ((char *dest, char *source)); | |
22675 | + ... | |
22676 | + char * | |
22677 | + strcpy (dest, source) | |
22678 | + char *dest; | |
22679 | + char *source; | |
22680 | + { ... } | |
22681 | + | |
22682 | + | |
22683 | + VPARAMS ((prototype, ...)) | |
22684 | + -- for functions which take a variable number of arguments. Use | |
22685 | + PARAMS to declare the function, VPARAMS to define it. For example: | |
22686 | + | |
22687 | + int printf PARAMS ((const char *format, ...)); | |
22688 | + ... | |
22689 | + int | |
22690 | + printf VPARAMS ((const char *format, ...)) | |
22691 | + { | |
22692 | + ... | |
22693 | + } | |
22694 | + | |
22695 | + For writing functions which take variable numbers of arguments, we | |
22696 | + also provide the VA_OPEN, VA_CLOSE, and VA_FIXEDARG macros. These | |
22697 | + hide the differences between K+R <varargs.h> and C89 <stdarg.h> more | |
22698 | + thoroughly than the simple VA_START() macro mentioned above. | |
22699 | + | |
22700 | + VA_OPEN and VA_CLOSE are used *instead of* va_start and va_end. | |
22701 | + Immediately after VA_OPEN, put a sequence of VA_FIXEDARG calls | |
22702 | + corresponding to the list of fixed arguments. Then use va_arg | |
22703 | + normally to get the variable arguments, or pass your va_list object | |
22704 | + around. You do not declare the va_list yourself; VA_OPEN does it | |
22705 | + for you. | |
22706 | + | |
22707 | + Here is a complete example: | |
22708 | + | |
22709 | + int | |
22710 | + printf VPARAMS ((const char *format, ...)) | |
22711 | + { | |
22712 | + int result; | |
22713 | + | |
22714 | + VA_OPEN (ap, format); | |
22715 | + VA_FIXEDARG (ap, const char *, format); | |
22716 | + | |
22717 | + result = vfprintf (stdout, format, ap); | |
22718 | + VA_CLOSE (ap); | |
22719 | + | |
22720 | + return result; | |
22721 | + } | |
22722 | + | |
22723 | + | |
22724 | + You can declare variables either before or after the VA_OPEN, | |
22725 | + VA_FIXEDARG sequence. Also, VA_OPEN and VA_CLOSE are the beginning | |
22726 | + and end of a block. They must appear at the same nesting level, | |
22727 | + and any variables declared after VA_OPEN go out of scope at | |
22728 | + VA_CLOSE. Unfortunately, with a K+R compiler, that includes the | |
22729 | + argument list. You can have multiple instances of VA_OPEN/VA_CLOSE | |
22730 | + pairs in a single function in case you need to traverse the | |
22731 | + argument list more than once. | |
22732 | + | |
22733 | + For ease of writing code which uses GCC extensions but needs to be | |
22734 | + portable to other compilers, we provide the GCC_VERSION macro that | |
22735 | + simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various | |
22736 | + wrappers around __attribute__. Also, __extension__ will be #defined | |
22737 | + to nothing if it doesn't work. See below. | |
22738 | + | |
22739 | + This header also defines a lot of obsolete macros: | |
22740 | + CONST, VOLATILE, SIGNED, PROTO, EXFUN, DEFUN, DEFUN_VOID, | |
22741 | + AND, DOTS, NOARGS. Don't use them. */ | |
22742 | + | |
22743 | +#ifndef _ANSIDECL_H | |
22744 | +#define _ANSIDECL_H 1 | |
22745 | + | |
22746 | +/* Every source file includes this file, | |
22747 | + so they will all get the switch for lint. */ | |
22748 | +/* LINTLIBRARY */ | |
22749 | + | |
22750 | +/* Using MACRO(x,y) in cpp #if conditionals does not work with some | |
22751 | + older preprocessors. Thus we can't define something like this: | |
22752 | + | |
22753 | +#define HAVE_GCC_VERSION(MAJOR, MINOR) \ | |
22754 | + (__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR))) | |
22755 | + | |
22756 | +and then test "#if HAVE_GCC_VERSION(2,7)". | |
22757 | + | |
22758 | +So instead we use the macro below and test it against specific values. */ | |
22759 | + | |
22760 | +/* This macro simplifies testing whether we are using gcc, and if it | |
22761 | + is of a particular minimum version. (Both major & minor numbers are | |
22762 | + significant.) This macro will evaluate to 0 if we are not using | |
22763 | + gcc at all. */ | |
22764 | +#ifndef GCC_VERSION | |
22765 | +#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) | |
22766 | +#endif /* GCC_VERSION */ | |
22767 | + | |
22768 | +#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32) || (defined(__alpha) && defined(__cplusplus)) | |
22769 | +/* All known AIX compilers implement these things (but don't always | |
22770 | + define __STDC__). The RISC/OS MIPS compiler defines these things | |
22771 | + in SVR4 mode, but does not define __STDC__. */ | |
22772 | +/* eraxxon@alumni.rice.edu: The Compaq C++ compiler, unlike many other | |
22773 | + C++ compilers, does not define __STDC__, though it acts as if this | |
22774 | + was so. (Verified versions: 5.7, 6.2, 6.3, 6.5) */ | |
22775 | + | |
22776 | +#define ANSI_PROTOTYPES 1 | |
22777 | +#define PTR void * | |
22778 | +#define PTRCONST void *const | |
22779 | +#define LONG_DOUBLE long double | |
22780 | + | |
22781 | +/* PARAMS is often defined elsewhere (e.g. by libintl.h), so wrap it in | |
22782 | + a #ifndef. */ | |
22783 | +#ifndef PARAMS | |
22784 | +#define PARAMS(ARGS) ARGS | |
22785 | +#endif | |
22786 | + | |
22787 | +#define VPARAMS(ARGS) ARGS | |
22788 | +#define VA_START(VA_LIST, VAR) va_start(VA_LIST, VAR) | |
22789 | + | |
22790 | +/* variadic function helper macros */ | |
22791 | +/* "struct Qdmy" swallows the semicolon after VA_OPEN/VA_FIXEDARG's | |
22792 | + use without inhibiting further decls and without declaring an | |
22793 | + actual variable. */ | |
22794 | +#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP, VAR); { struct Qdmy | |
22795 | +#define VA_CLOSE(AP) } va_end(AP); } | |
22796 | +#define VA_FIXEDARG(AP, T, N) struct Qdmy | |
22797 | + | |
22798 | +#undef const | |
22799 | +#undef volatile | |
22800 | +#undef signed | |
22801 | + | |
22802 | +#ifdef __KERNEL__ | |
22803 | +#ifndef __STDC_VERSION__ | |
22804 | +#define __STDC_VERSION__ 0 | |
22805 | +#endif | |
22806 | +#endif /* __KERNEL__ */ | |
22807 | + | |
22808 | +/* inline requires special treatment; it's in C99, and GCC >=2.7 supports | |
22809 | + it too, but it's not in C89. */ | |
22810 | +#undef inline | |
22811 | +#if __STDC_VERSION__ > 199901L | |
22812 | +/* it's a keyword */ | |
22813 | +#else | |
22814 | +# if GCC_VERSION >= 2007 | |
22815 | +# define inline __inline__ /* __inline__ prevents -pedantic warnings */ | |
22816 | +# else | |
22817 | +# define inline /* nothing */ | |
22818 | +# endif | |
22819 | +#endif | |
22820 | + | |
22821 | +/* These are obsolete. Do not use. */ | |
22822 | +#ifndef IN_GCC | |
22823 | +#define CONST const | |
22824 | +#define VOLATILE volatile | |
22825 | +#define SIGNED signed | |
22826 | + | |
22827 | +#define PROTO(type, name, arglist) type name arglist | |
22828 | +#define EXFUN(name, proto) name proto | |
22829 | +#define DEFUN(name, arglist, args) name(args) | |
22830 | +#define DEFUN_VOID(name) name(void) | |
22831 | +#define AND , | |
22832 | +#define DOTS , ... | |
22833 | +#define NOARGS void | |
22834 | +#endif /* ! IN_GCC */ | |
22835 | + | |
22836 | +#else /* Not ANSI C. */ | |
22837 | + | |
22838 | +#undef ANSI_PROTOTYPES | |
22839 | +#define PTR char * | |
22840 | +#define PTRCONST PTR | |
22841 | +#define LONG_DOUBLE double | |
22842 | + | |
22843 | +#define PARAMS(args) () | |
22844 | +#define VPARAMS(args) (va_alist) va_dcl | |
22845 | +#define VA_START(va_list, var) va_start(va_list) | |
22846 | + | |
22847 | +#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP); { struct Qdmy | |
22848 | +#define VA_CLOSE(AP) } va_end(AP); } | |
22849 | +#define VA_FIXEDARG(AP, TYPE, NAME) TYPE NAME = va_arg(AP, TYPE) | |
22850 | + | |
22851 | +/* some systems define these in header files for non-ansi mode */ | |
22852 | +#undef const | |
22853 | +#undef volatile | |
22854 | +#undef signed | |
22855 | +#undef inline | |
22856 | +#define const | |
22857 | +#define volatile | |
22858 | +#define signed | |
22859 | +#define inline | |
22860 | + | |
22861 | +#ifndef IN_GCC | |
22862 | +#define CONST | |
22863 | +#define VOLATILE | |
22864 | +#define SIGNED | |
22865 | + | |
22866 | +#define PROTO(type, name, arglist) type name () | |
22867 | +#define EXFUN(name, proto) name() | |
22868 | +#define DEFUN(name, arglist, args) name arglist args; | |
22869 | +#define DEFUN_VOID(name) name() | |
22870 | +#define AND ; | |
22871 | +#define DOTS | |
22872 | +#define NOARGS | |
22873 | +#endif /* ! IN_GCC */ | |
22874 | + | |
22875 | +#endif /* ANSI C. */ | |
22876 | + | |
22877 | +/* Define macros for some gcc attributes. This permits us to use the | |
22878 | + macros freely, and know that they will come into play for the | |
22879 | + version of gcc in which they are supported. */ | |
22880 | + | |
22881 | +#if (GCC_VERSION < 2007) | |
22882 | +# define __attribute__(x) | |
22883 | +#endif | |
22884 | + | |
22885 | +/* Attribute __malloc__ on functions was valid as of gcc 2.96. */ | |
22886 | +#ifndef ATTRIBUTE_MALLOC | |
22887 | +# if (GCC_VERSION >= 2096) | |
22888 | +# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) | |
22889 | +# else | |
22890 | +# define ATTRIBUTE_MALLOC | |
22891 | +# endif /* GNUC >= 2.96 */ | |
22892 | +#endif /* ATTRIBUTE_MALLOC */ | |
22893 | + | |
22894 | +/* Attributes on labels were valid as of gcc 2.93. */ | |
22895 | +#ifndef ATTRIBUTE_UNUSED_LABEL | |
22896 | +# if (!defined (__cplusplus) && GCC_VERSION >= 2093) | |
22897 | +# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED | |
22898 | +# else | |
22899 | +# define ATTRIBUTE_UNUSED_LABEL | |
22900 | +# endif /* !__cplusplus && GNUC >= 2.93 */ | |
22901 | +#endif /* ATTRIBUTE_UNUSED_LABEL */ | |
22902 | + | |
22903 | +#ifndef ATTRIBUTE_UNUSED | |
22904 | +#define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) | |
22905 | +#endif /* ATTRIBUTE_UNUSED */ | |
22906 | + | |
22907 | +/* Before GCC 3.4, the C++ frontend couldn't parse attributes placed after the | |
22908 | + identifier name. */ | |
22909 | +#if ! defined(__cplusplus) || (GCC_VERSION >= 3004) | |
22910 | +# define ARG_UNUSED(NAME) NAME ATTRIBUTE_UNUSED | |
22911 | +#else /* !__cplusplus || GNUC >= 3.4 */ | |
22912 | +# define ARG_UNUSED(NAME) NAME | |
22913 | +#endif /* !__cplusplus || GNUC >= 3.4 */ | |
22914 | + | |
22915 | +#ifndef ATTRIBUTE_NORETURN | |
22916 | +#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) | |
22917 | +#endif /* ATTRIBUTE_NORETURN */ | |
22918 | + | |
22919 | +/* Attribute `nonnull' was valid as of gcc 3.3. */ | |
22920 | +#ifndef ATTRIBUTE_NONNULL | |
22921 | +# if (GCC_VERSION >= 3003) | |
22922 | +# define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m))) | |
22923 | +# else | |
22924 | +# define ATTRIBUTE_NONNULL(m) | |
22925 | +# endif /* GNUC >= 3.3 */ | |
22926 | +#endif /* ATTRIBUTE_NONNULL */ | |
22927 | + | |
22928 | +/* Attribute `pure' was valid as of gcc 3.0. */ | |
22929 | +#ifndef ATTRIBUTE_PURE | |
22930 | +# if (GCC_VERSION >= 3000) | |
22931 | +# define ATTRIBUTE_PURE __attribute__ ((__pure__)) | |
22932 | +# else | |
22933 | +# define ATTRIBUTE_PURE | |
22934 | +# endif /* GNUC >= 3.0 */ | |
22935 | +#endif /* ATTRIBUTE_PURE */ | |
22936 | + | |
22937 | +/* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL. | |
22938 | + This was the case for the `printf' format attribute by itself | |
22939 | + before GCC 3.3, but as of 3.3 we need to add the `nonnull' | |
22940 | + attribute to retain this behavior. */ | |
22941 | +#ifndef ATTRIBUTE_PRINTF | |
22942 | +#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m) | |
22943 | +#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2) | |
22944 | +#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3) | |
22945 | +#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4) | |
22946 | +#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5) | |
22947 | +#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6) | |
22948 | +#endif /* ATTRIBUTE_PRINTF */ | |
22949 | + | |
22950 | +/* Use ATTRIBUTE_FPTR_PRINTF when the format attribute is to be set on | |
22951 | + a function pointer. Format attributes were allowed on function | |
22952 | + pointers as of gcc 3.1. */ | |
22953 | +#ifndef ATTRIBUTE_FPTR_PRINTF | |
22954 | +# if (GCC_VERSION >= 3001) | |
22955 | +# define ATTRIBUTE_FPTR_PRINTF(m, n) ATTRIBUTE_PRINTF(m, n) | |
22956 | +# else | |
22957 | +# define ATTRIBUTE_FPTR_PRINTF(m, n) | |
22958 | +# endif /* GNUC >= 3.1 */ | |
22959 | +# define ATTRIBUTE_FPTR_PRINTF_1 ATTRIBUTE_FPTR_PRINTF(1, 2) | |
22960 | +# define ATTRIBUTE_FPTR_PRINTF_2 ATTRIBUTE_FPTR_PRINTF(2, 3) | |
22961 | +# define ATTRIBUTE_FPTR_PRINTF_3 ATTRIBUTE_FPTR_PRINTF(3, 4) | |
22962 | +# define ATTRIBUTE_FPTR_PRINTF_4 ATTRIBUTE_FPTR_PRINTF(4, 5) | |
22963 | +# define ATTRIBUTE_FPTR_PRINTF_5 ATTRIBUTE_FPTR_PRINTF(5, 6) | |
22964 | +#endif /* ATTRIBUTE_FPTR_PRINTF */ | |
22965 | + | |
22966 | +/* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL. A | |
22967 | + NULL format specifier was allowed as of gcc 3.3. */ | |
22968 | +#ifndef ATTRIBUTE_NULL_PRINTF | |
22969 | +# if (GCC_VERSION >= 3003) | |
22970 | +# define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) | |
22971 | +# else | |
22972 | +# define ATTRIBUTE_NULL_PRINTF(m, n) | |
22973 | +# endif /* GNUC >= 3.3 */ | |
22974 | +# define ATTRIBUTE_NULL_PRINTF_1 ATTRIBUTE_NULL_PRINTF(1, 2) | |
22975 | +# define ATTRIBUTE_NULL_PRINTF_2 ATTRIBUTE_NULL_PRINTF(2, 3) | |
22976 | +# define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4) | |
22977 | +# define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5) | |
22978 | +# define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6) | |
22979 | +#endif /* ATTRIBUTE_NULL_PRINTF */ | |
22980 | + | |
22981 | +/* Attribute `sentinel' was valid as of gcc 3.5. */ | |
22982 | +#ifndef ATTRIBUTE_SENTINEL | |
22983 | +# if (GCC_VERSION >= 3005) | |
22984 | +# define ATTRIBUTE_SENTINEL __attribute__ ((__sentinel__)) | |
22985 | +# else | |
22986 | +# define ATTRIBUTE_SENTINEL | |
22987 | +# endif /* GNUC >= 3.5 */ | |
22988 | +#endif /* ATTRIBUTE_SENTINEL */ | |
22989 | + | |
22990 | + | |
22991 | +#ifndef ATTRIBUTE_ALIGNED_ALIGNOF | |
22992 | +# if (GCC_VERSION >= 3000) | |
22993 | +# define ATTRIBUTE_ALIGNED_ALIGNOF(m) __attribute__ ((__aligned__ (__alignof__ (m)))) | |
22994 | +# else | |
22995 | +# define ATTRIBUTE_ALIGNED_ALIGNOF(m) | |
22996 | +# endif /* GNUC >= 3.0 */ | |
22997 | +#endif /* ATTRIBUTE_ALIGNED_ALIGNOF */ | |
22998 | + | |
22999 | +/* We use __extension__ in some places to suppress -pedantic warnings | |
23000 | + about GCC extensions. This feature didn't work properly before | |
23001 | + gcc 2.8. */ | |
23002 | +#if GCC_VERSION < 2008 | |
23003 | +#define __extension__ | |
23004 | +#endif | |
23005 | + | |
23006 | +#endif /* ansidecl.h */ | |
23007 | --- /dev/null | |
23008 | +++ b/include/asm-x86/ansidecl.h | |
23009 | @@ -0,0 +1,5 @@ | |
23010 | +#ifdef CONFIG_X86_32 | |
23011 | +# include "ansidecl_32.h" | |
23012 | +#else | |
23013 | +# include "ansidecl_64.h" | |
23014 | +#endif | |
23015 | --- /dev/null | |
23016 | +++ b/include/asm-x86/bfd_32.h | |
23017 | @@ -0,0 +1,4921 @@ | |
23018 | +/* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically | |
23019 | + generated from "bfd-in.h", "init.c", "opncls.c", "libbfd.c", | |
23020 | + "bfdio.c", "bfdwin.c", "section.c", "archures.c", "reloc.c", | |
23021 | + "syms.c", "bfd.c", "archive.c", "corefile.c", "targets.c", "format.c", | |
23022 | + "linker.c" and "simple.c". | |
23023 | + Run "make headers" in your build bfd/ to regenerate. */ | |
23024 | + | |
23025 | +/* Main header file for the bfd library -- portable access to object files. | |
23026 | + | |
23027 | + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, | |
23028 | + 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. | |
23029 | + | |
23030 | + Contributed by Cygnus Support. | |
23031 | + | |
23032 | + This file is part of BFD, the Binary File Descriptor library. | |
23033 | + | |
23034 | + This program is free software; you can redistribute it and/or modify | |
23035 | + it under the terms of the GNU General Public License as published by | |
23036 | + the Free Software Foundation; either version 2 of the License, or | |
23037 | + (at your option) any later version. | |
23038 | + | |
23039 | + This program is distributed in the hope that it will be useful, | |
23040 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23041 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
23042 | + GNU General Public License for more details. | |
23043 | + | |
23044 | + You should have received a copy of the GNU General Public License | |
23045 | + along with this program; if not, write to the Free Software | |
23046 | + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ | |
23047 | + | |
23048 | +/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use. | |
23049 | + * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as | |
23050 | + * required. | |
23051 | + * Keith Owens <kaos@sgi.com> 15 May 2006 | |
23052 | + */ | |
23053 | + | |
23054 | +#ifndef __BFD_H_SEEN__ | |
23055 | +#define __BFD_H_SEEN__ | |
23056 | + | |
23057 | +#ifdef __cplusplus | |
23058 | +extern "C" { | |
23059 | +#endif | |
23060 | + | |
23061 | +#ifdef __KERNEL__ | |
23062 | +#include <asm/ansidecl.h> | |
23063 | +#else /* __KERNEL__ */ | |
23064 | +#include "ansidecl.h" | |
23065 | +#include "symcat.h" | |
23066 | +#endif /* __KERNEL__ */ | |
23067 | +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) | |
23068 | +#ifndef SABER | |
23069 | +/* This hack is to avoid a problem with some strict ANSI C preprocessors. | |
23070 | + The problem is, "32_" is not a valid preprocessing token, and we don't | |
23071 | + want extra underscores (e.g., "nlm_32_"). The XCONCAT2 macro will | |
23072 | + cause the inner CONCAT2 macros to be evaluated first, producing | |
23073 | + still-valid pp-tokens. Then the final concatenation can be done. */ | |
23074 | +#undef CONCAT4 | |
23075 | +#define CONCAT4(a,b,c,d) XCONCAT2(CONCAT2(a,b),CONCAT2(c,d)) | |
23076 | +#endif | |
23077 | +#endif | |
23078 | + | |
23079 | +/* The word size used by BFD on the host. This may be 64 with a 32 | |
23080 | + bit target if the host is 64 bit, or if other 64 bit targets have | |
23081 | + been selected with --enable-targets, or if --enable-64-bit-bfd. */ | |
23082 | +#ifdef __KERNEL__ | |
23083 | +#define BFD_ARCH_SIZE 32 | |
23084 | +#else /* __KERNEL__ */ | |
23085 | +#define BFD_ARCH_SIZE 64 | |
23086 | +#endif /* __KERNEL__ */ | |
23087 | + | |
23088 | +/* The word size of the default bfd target. */ | |
23089 | +#define BFD_DEFAULT_TARGET_SIZE 32 | |
23090 | + | |
23091 | +#define BFD_HOST_64BIT_LONG 0 | |
23092 | +#define BFD_HOST_LONG_LONG 1 | |
23093 | +#if 1 | |
23094 | +#define BFD_HOST_64_BIT long long | |
23095 | +#define BFD_HOST_U_64_BIT unsigned long long | |
23096 | +typedef BFD_HOST_64_BIT bfd_int64_t; | |
23097 | +typedef BFD_HOST_U_64_BIT bfd_uint64_t; | |
23098 | +#endif | |
23099 | + | |
23100 | +#if BFD_ARCH_SIZE >= 64 | |
23101 | +#define BFD64 | |
23102 | +#endif | |
23103 | + | |
23104 | +#ifndef INLINE | |
23105 | +#if __GNUC__ >= 2 | |
23106 | +#define INLINE __inline__ | |
23107 | +#else | |
23108 | +#define INLINE | |
23109 | +#endif | |
23110 | +#endif | |
23111 | + | |
23112 | +/* Forward declaration. */ | |
23113 | +typedef struct bfd bfd; | |
23114 | + | |
23115 | +/* Boolean type used in bfd. Too many systems define their own | |
23116 | + versions of "boolean" for us to safely typedef a "boolean" of | |
23117 | + our own. Using an enum for "bfd_boolean" has its own set of | |
23118 | + problems, with strange looking casts required to avoid warnings | |
23119 | + on some older compilers. Thus we just use an int. | |
23120 | + | |
23121 | + General rule: Functions which are bfd_boolean return TRUE on | |
23122 | + success and FALSE on failure (unless they're a predicate). */ | |
23123 | + | |
23124 | +typedef int bfd_boolean; | |
23125 | +#undef FALSE | |
23126 | +#undef TRUE | |
23127 | +#define FALSE 0 | |
23128 | +#define TRUE 1 | |
23129 | + | |
23130 | +#ifdef BFD64 | |
23131 | + | |
23132 | +#ifndef BFD_HOST_64_BIT | |
23133 | + #error No 64 bit integer type available | |
23134 | +#endif /* ! defined (BFD_HOST_64_BIT) */ | |
23135 | + | |
23136 | +typedef BFD_HOST_U_64_BIT bfd_vma; | |
23137 | +typedef BFD_HOST_64_BIT bfd_signed_vma; | |
23138 | +typedef BFD_HOST_U_64_BIT bfd_size_type; | |
23139 | +typedef BFD_HOST_U_64_BIT symvalue; | |
23140 | + | |
23141 | +#ifndef fprintf_vma | |
23142 | +#if BFD_HOST_64BIT_LONG | |
23143 | +#define sprintf_vma(s,x) sprintf (s, "%016lx", x) | |
23144 | +#define fprintf_vma(f,x) fprintf (f, "%016lx", x) | |
23145 | +#else | |
23146 | +#define _bfd_int64_low(x) ((unsigned long) (((x) & 0xffffffff))) | |
23147 | +#define _bfd_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff)) | |
23148 | +#define fprintf_vma(s,x) \ | |
23149 | + fprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x)) | |
23150 | +#define sprintf_vma(s,x) \ | |
23151 | + sprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x)) | |
23152 | +#endif | |
23153 | +#endif | |
23154 | + | |
23155 | +#else /* not BFD64 */ | |
23156 | + | |
23157 | +/* Represent a target address. Also used as a generic unsigned type | |
23158 | + which is guaranteed to be big enough to hold any arithmetic types | |
23159 | + we need to deal with. */ | |
23160 | +typedef unsigned long bfd_vma; | |
23161 | + | |
23162 | +/* A generic signed type which is guaranteed to be big enough to hold any | |
23163 | + arithmetic types we need to deal with. Can be assumed to be compatible | |
23164 | + with bfd_vma in the same way that signed and unsigned ints are compatible | |
23165 | + (as parameters, in assignment, etc). */ | |
23166 | +typedef long bfd_signed_vma; | |
23167 | + | |
23168 | +typedef unsigned long symvalue; | |
23169 | +typedef unsigned long bfd_size_type; | |
23170 | + | |
23171 | +/* Print a bfd_vma x on stream s. */ | |
23172 | +#define fprintf_vma(s,x) fprintf (s, "%08lx", x) | |
23173 | +#define sprintf_vma(s,x) sprintf (s, "%08lx", x) | |
23174 | + | |
23175 | +#endif /* not BFD64 */ | |
23176 | + | |
23177 | +#define HALF_BFD_SIZE_TYPE \ | |
23178 | + (((bfd_size_type) 1) << (8 * sizeof (bfd_size_type) / 2)) | |
23179 | + | |
23180 | +#ifndef BFD_HOST_64_BIT | |
23181 | +/* Fall back on a 32 bit type. The idea is to make these types always | |
23182 | + available for function return types, but in the case that | |
23183 | + BFD_HOST_64_BIT is undefined such a function should abort or | |
23184 | + otherwise signal an error. */ | |
23185 | +typedef bfd_signed_vma bfd_int64_t; | |
23186 | +typedef bfd_vma bfd_uint64_t; | |
23187 | +#endif | |
23188 | + | |
23189 | +/* An offset into a file. BFD always uses the largest possible offset | |
23190 | + based on the build time availability of fseek, fseeko, or fseeko64. */ | |
23191 | +typedef BFD_HOST_64_BIT file_ptr; | |
23192 | +typedef unsigned BFD_HOST_64_BIT ufile_ptr; | |
23193 | + | |
23194 | +extern void bfd_sprintf_vma (bfd *, char *, bfd_vma); | |
23195 | +extern void bfd_fprintf_vma (bfd *, void *, bfd_vma); | |
23196 | + | |
23197 | +#define printf_vma(x) fprintf_vma(stdout,x) | |
23198 | +#define bfd_printf_vma(abfd,x) bfd_fprintf_vma (abfd,stdout,x) | |
23199 | + | |
23200 | +typedef unsigned int flagword; /* 32 bits of flags */ | |
23201 | +typedef unsigned char bfd_byte; | |
23202 | +\f | |
23203 | +/* File formats. */ | |
23204 | + | |
23205 | +typedef enum bfd_format | |
23206 | +{ | |
23207 | + bfd_unknown = 0, /* File format is unknown. */ | |
23208 | + bfd_object, /* Linker/assembler/compiler output. */ | |
23209 | + bfd_archive, /* Object archive file. */ | |
23210 | + bfd_core, /* Core dump. */ | |
23211 | + bfd_type_end /* Marks the end; don't use it! */ | |
23212 | +} | |
23213 | +bfd_format; | |
23214 | + | |
23215 | +/* Values that may appear in the flags field of a BFD. These also | |
23216 | + appear in the object_flags field of the bfd_target structure, where | |
23217 | + they indicate the set of flags used by that backend (not all flags | |
23218 | + are meaningful for all object file formats) (FIXME: at the moment, | |
23219 | + the object_flags values have mostly just been copied from backend | |
23220 | + to another, and are not necessarily correct). */ | |
23221 | + | |
23222 | +/* No flags. */ | |
23223 | +#define BFD_NO_FLAGS 0x00 | |
23224 | + | |
23225 | +/* BFD contains relocation entries. */ | |
23226 | +#define HAS_RELOC 0x01 | |
23227 | + | |
23228 | +/* BFD is directly executable. */ | |
23229 | +#define EXEC_P 0x02 | |
23230 | + | |
23231 | +/* BFD has line number information (basically used for F_LNNO in a | |
23232 | + COFF header). */ | |
23233 | +#define HAS_LINENO 0x04 | |
23234 | + | |
23235 | +/* BFD has debugging information. */ | |
23236 | +#define HAS_DEBUG 0x08 | |
23237 | + | |
23238 | +/* BFD has symbols. */ | |
23239 | +#define HAS_SYMS 0x10 | |
23240 | + | |
23241 | +/* BFD has local symbols (basically used for F_LSYMS in a COFF | |
23242 | + header). */ | |
23243 | +#define HAS_LOCALS 0x20 | |
23244 | + | |
23245 | +/* BFD is a dynamic object. */ | |
23246 | +#define DYNAMIC 0x40 | |
23247 | + | |
23248 | +/* Text section is write protected (if D_PAGED is not set, this is | |
23249 | + like an a.out NMAGIC file) (the linker sets this by default, but | |
23250 | + clears it for -r or -N). */ | |
23251 | +#define WP_TEXT 0x80 | |
23252 | + | |
23253 | +/* BFD is dynamically paged (this is like an a.out ZMAGIC file) (the | |
23254 | + linker sets this by default, but clears it for -r or -n or -N). */ | |
23255 | +#define D_PAGED 0x100 | |
23256 | + | |
23257 | +/* BFD is relaxable (this means that bfd_relax_section may be able to | |
23258 | + do something) (sometimes bfd_relax_section can do something even if | |
23259 | + this is not set). */ | |
23260 | +#define BFD_IS_RELAXABLE 0x200 | |
23261 | + | |
23262 | +/* This may be set before writing out a BFD to request using a | |
23263 | + traditional format. For example, this is used to request that when | |
23264 | + writing out an a.out object the symbols not be hashed to eliminate | |
23265 | + duplicates. */ | |
23266 | +#define BFD_TRADITIONAL_FORMAT 0x400 | |
23267 | + | |
23268 | +/* This flag indicates that the BFD contents are actually cached in | |
23269 | + memory. If this is set, iostream points to a bfd_in_memory struct. */ | |
23270 | +#define BFD_IN_MEMORY 0x800 | |
23271 | + | |
23272 | +/* The sections in this BFD specify a memory page. */ | |
23273 | +#define HAS_LOAD_PAGE 0x1000 | |
23274 | + | |
23275 | +/* This BFD has been created by the linker and doesn't correspond | |
23276 | + to any input file. */ | |
23277 | +#define BFD_LINKER_CREATED 0x2000 | |
23278 | +\f | |
23279 | +/* Symbols and relocation. */ | |
23280 | + | |
23281 | +/* A count of carsyms (canonical archive symbols). */ | |
23282 | +typedef unsigned long symindex; | |
23283 | + | |
23284 | +/* How to perform a relocation. */ | |
23285 | +typedef const struct reloc_howto_struct reloc_howto_type; | |
23286 | + | |
23287 | +#define BFD_NO_MORE_SYMBOLS ((symindex) ~0) | |
23288 | + | |
23289 | +/* General purpose part of a symbol X; | |
23290 | + target specific parts are in libcoff.h, libaout.h, etc. */ | |
23291 | + | |
23292 | +#define bfd_get_section(x) ((x)->section) | |
23293 | +#define bfd_get_output_section(x) ((x)->section->output_section) | |
23294 | +#define bfd_set_section(x,y) ((x)->section) = (y) | |
23295 | +#define bfd_asymbol_base(x) ((x)->section->vma) | |
23296 | +#define bfd_asymbol_value(x) (bfd_asymbol_base(x) + (x)->value) | |
23297 | +#define bfd_asymbol_name(x) ((x)->name) | |
23298 | +/*Perhaps future: #define bfd_asymbol_bfd(x) ((x)->section->owner)*/ | |
23299 | +#define bfd_asymbol_bfd(x) ((x)->the_bfd) | |
23300 | +#define bfd_asymbol_flavour(x) (bfd_asymbol_bfd(x)->xvec->flavour) | |
23301 | + | |
23302 | +/* A canonical archive symbol. */ | |
23303 | +/* This is a type pun with struct ranlib on purpose! */ | |
23304 | +typedef struct carsym | |
23305 | +{ | |
23306 | + char *name; | |
23307 | + file_ptr file_offset; /* Look here to find the file. */ | |
23308 | +} | |
23309 | +carsym; /* To make these you call a carsymogen. */ | |
23310 | + | |
23311 | +/* Used in generating armaps (archive tables of contents). | |
23312 | + Perhaps just a forward definition would do? */ | |
23313 | +struct orl /* Output ranlib. */ | |
23314 | +{ | |
23315 | + char **name; /* Symbol name. */ | |
23316 | + union | |
23317 | + { | |
23318 | + file_ptr pos; | |
23319 | + bfd *abfd; | |
23320 | + } u; /* bfd* or file position. */ | |
23321 | + int namidx; /* Index into string table. */ | |
23322 | +}; | |
23323 | +\f | |
23324 | +/* Linenumber stuff. */ | |
23325 | +typedef struct lineno_cache_entry | |
23326 | +{ | |
23327 | + unsigned int line_number; /* Linenumber from start of function. */ | |
23328 | + union | |
23329 | + { | |
23330 | + struct bfd_symbol *sym; /* Function name. */ | |
23331 | + bfd_vma offset; /* Offset into section. */ | |
23332 | + } u; | |
23333 | +} | |
23334 | +alent; | |
23335 | +\f | |
23336 | +/* Object and core file sections. */ | |
23337 | + | |
23338 | +#define align_power(addr, align) \ | |
23339 | + (((addr) + ((bfd_vma) 1 << (align)) - 1) & ((bfd_vma) -1 << (align))) | |
23340 | + | |
23341 | +typedef struct bfd_section *sec_ptr; | |
23342 | + | |
23343 | +#define bfd_get_section_name(bfd, ptr) ((ptr)->name + 0) | |
23344 | +#define bfd_get_section_vma(bfd, ptr) ((ptr)->vma + 0) | |
23345 | +#define bfd_get_section_lma(bfd, ptr) ((ptr)->lma + 0) | |
23346 | +#define bfd_get_section_alignment(bfd, ptr) ((ptr)->alignment_power + 0) | |
23347 | +#define bfd_section_name(bfd, ptr) ((ptr)->name) | |
23348 | +#define bfd_section_size(bfd, ptr) ((ptr)->size) | |
23349 | +#define bfd_get_section_size(ptr) ((ptr)->size) | |
23350 | +#define bfd_section_vma(bfd, ptr) ((ptr)->vma) | |
23351 | +#define bfd_section_lma(bfd, ptr) ((ptr)->lma) | |
23352 | +#define bfd_section_alignment(bfd, ptr) ((ptr)->alignment_power) | |
23353 | +#define bfd_get_section_flags(bfd, ptr) ((ptr)->flags + 0) | |
23354 | +#define bfd_get_section_userdata(bfd, ptr) ((ptr)->userdata) | |
23355 | + | |
23356 | +#define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0) | |
23357 | + | |
23358 | +#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma = (val)), ((ptr)->user_set_vma = TRUE), TRUE) | |
23359 | +#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),TRUE) | |
23360 | +#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE) | |
23361 | +/* Find the address one past the end of SEC. */ | |
23362 | +#define bfd_get_section_limit(bfd, sec) \ | |
23363 | + (((sec)->rawsize ? (sec)->rawsize : (sec)->size) \ | |
23364 | + / bfd_octets_per_byte (bfd)) | |
23365 | + | |
23366 | +typedef struct stat stat_type; | |
23367 | +\f | |
23368 | +typedef enum bfd_print_symbol | |
23369 | +{ | |
23370 | + bfd_print_symbol_name, | |
23371 | + bfd_print_symbol_more, | |
23372 | + bfd_print_symbol_all | |
23373 | +} bfd_print_symbol_type; | |
23374 | + | |
23375 | +/* Information about a symbol that nm needs. */ | |
23376 | + | |
23377 | +typedef struct _symbol_info | |
23378 | +{ | |
23379 | + symvalue value; | |
23380 | + char type; | |
23381 | + const char *name; /* Symbol name. */ | |
23382 | + unsigned char stab_type; /* Stab type. */ | |
23383 | + char stab_other; /* Stab other. */ | |
23384 | + short stab_desc; /* Stab desc. */ | |
23385 | + const char *stab_name; /* String for stab type. */ | |
23386 | +} symbol_info; | |
23387 | + | |
23388 | +/* Get the name of a stabs type code. */ | |
23389 | + | |
23390 | +extern const char *bfd_get_stab_name (int); | |
23391 | +\f | |
23392 | +/* Hash table routines. There is no way to free up a hash table. */ | |
23393 | + | |
23394 | +/* An element in the hash table. Most uses will actually use a larger | |
23395 | + structure, and an instance of this will be the first field. */ | |
23396 | + | |
23397 | +struct bfd_hash_entry | |
23398 | +{ | |
23399 | + /* Next entry for this hash code. */ | |
23400 | + struct bfd_hash_entry *next; | |
23401 | + /* String being hashed. */ | |
23402 | + const char *string; | |
23403 | + /* Hash code. This is the full hash code, not the index into the | |
23404 | + table. */ | |
23405 | + unsigned long hash; | |
23406 | +}; | |
23407 | + | |
23408 | +/* A hash table. */ | |
23409 | + | |
23410 | +struct bfd_hash_table | |
23411 | +{ | |
23412 | + /* The hash array. */ | |
23413 | + struct bfd_hash_entry **table; | |
23414 | + /* The number of slots in the hash table. */ | |
23415 | + unsigned int size; | |
23416 | + /* A function used to create new elements in the hash table. The | |
23417 | + first entry is itself a pointer to an element. When this | |
23418 | + function is first invoked, this pointer will be NULL. However, | |
23419 | + having the pointer permits a hierarchy of method functions to be | |
23420 | + built each of which calls the function in the superclass. Thus | |
23421 | + each function should be written to allocate a new block of memory | |
23422 | + only if the argument is NULL. */ | |
23423 | + struct bfd_hash_entry *(*newfunc) | |
23424 | + (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); | |
23425 | + /* An objalloc for this hash table. This is a struct objalloc *, | |
23426 | + but we use void * to avoid requiring the inclusion of objalloc.h. */ | |
23427 | + void *memory; | |
23428 | +}; | |
23429 | + | |
23430 | +/* Initialize a hash table. */ | |
23431 | +extern bfd_boolean bfd_hash_table_init | |
23432 | + (struct bfd_hash_table *, | |
23433 | + struct bfd_hash_entry *(*) (struct bfd_hash_entry *, | |
23434 | + struct bfd_hash_table *, | |
23435 | + const char *)); | |
23436 | + | |
23437 | +/* Initialize a hash table specifying a size. */ | |
23438 | +extern bfd_boolean bfd_hash_table_init_n | |
23439 | + (struct bfd_hash_table *, | |
23440 | + struct bfd_hash_entry *(*) (struct bfd_hash_entry *, | |
23441 | + struct bfd_hash_table *, | |
23442 | + const char *), | |
23443 | + unsigned int size); | |
23444 | + | |
23445 | +/* Free up a hash table. */ | |
23446 | +extern void bfd_hash_table_free | |
23447 | + (struct bfd_hash_table *); | |
23448 | + | |
23449 | +/* Look up a string in a hash table. If CREATE is TRUE, a new entry | |
23450 | + will be created for this string if one does not already exist. The | |
23451 | + COPY argument must be TRUE if this routine should copy the string | |
23452 | + into newly allocated memory when adding an entry. */ | |
23453 | +extern struct bfd_hash_entry *bfd_hash_lookup | |
23454 | + (struct bfd_hash_table *, const char *, bfd_boolean create, | |
23455 | + bfd_boolean copy); | |
23456 | + | |
23457 | +/* Replace an entry in a hash table. */ | |
23458 | +extern void bfd_hash_replace | |
23459 | + (struct bfd_hash_table *, struct bfd_hash_entry *old, | |
23460 | + struct bfd_hash_entry *nw); | |
23461 | + | |
23462 | +/* Base method for creating a hash table entry. */ | |
23463 | +extern struct bfd_hash_entry *bfd_hash_newfunc | |
23464 | + (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); | |
23465 | + | |
23466 | +/* Grab some space for a hash table entry. */ | |
23467 | +extern void *bfd_hash_allocate | |
23468 | + (struct bfd_hash_table *, unsigned int); | |
23469 | + | |
23470 | +/* Traverse a hash table in a random order, calling a function on each | |
23471 | + element. If the function returns FALSE, the traversal stops. The | |
23472 | + INFO argument is passed to the function. */ | |
23473 | +extern void bfd_hash_traverse | |
23474 | + (struct bfd_hash_table *, | |
23475 | + bfd_boolean (*) (struct bfd_hash_entry *, void *), | |
23476 | + void *info); | |
23477 | + | |
23478 | +/* Allows the default size of a hash table to be configured. New hash | |
23479 | + tables allocated using bfd_hash_table_init will be created with | |
23480 | + this size. */ | |
23481 | +extern void bfd_hash_set_default_size (bfd_size_type); | |
23482 | + | |
23483 | +/* This structure is used to keep track of stabs in sections | |
23484 | + information while linking. */ | |
23485 | + | |
23486 | +struct stab_info | |
23487 | +{ | |
23488 | + /* A hash table used to hold stabs strings. */ | |
23489 | + struct bfd_strtab_hash *strings; | |
23490 | + /* The header file hash table. */ | |
23491 | + struct bfd_hash_table includes; | |
23492 | + /* The first .stabstr section. */ | |
23493 | + struct bfd_section *stabstr; | |
23494 | +}; | |
23495 | + | |
23496 | +#define COFF_SWAP_TABLE (void *) &bfd_coff_std_swap_table | |
23497 | + | |
23498 | +/* User program access to BFD facilities. */ | |
23499 | + | |
23500 | +/* Direct I/O routines, for programs which know more about the object | |
23501 | + file than BFD does. Use higher level routines if possible. */ | |
23502 | + | |
23503 | +extern bfd_size_type bfd_bread (void *, bfd_size_type, bfd *); | |
23504 | +extern bfd_size_type bfd_bwrite (const void *, bfd_size_type, bfd *); | |
23505 | +extern int bfd_seek (bfd *, file_ptr, int); | |
23506 | +extern file_ptr bfd_tell (bfd *); | |
23507 | +extern int bfd_flush (bfd *); | |
23508 | +extern int bfd_stat (bfd *, struct stat *); | |
23509 | + | |
23510 | +/* Deprecated old routines. */ | |
23511 | +#if __GNUC__ | |
23512 | +#define bfd_read(BUF, ELTSIZE, NITEMS, ABFD) \ | |
23513 | + (warn_deprecated ("bfd_read", __FILE__, __LINE__, __FUNCTION__), \ | |
23514 | + bfd_bread ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) | |
23515 | +#define bfd_write(BUF, ELTSIZE, NITEMS, ABFD) \ | |
23516 | + (warn_deprecated ("bfd_write", __FILE__, __LINE__, __FUNCTION__), \ | |
23517 | + bfd_bwrite ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) | |
23518 | +#else | |
23519 | +#define bfd_read(BUF, ELTSIZE, NITEMS, ABFD) \ | |
23520 | + (warn_deprecated ("bfd_read", (const char *) 0, 0, (const char *) 0), \ | |
23521 | + bfd_bread ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) | |
23522 | +#define bfd_write(BUF, ELTSIZE, NITEMS, ABFD) \ | |
23523 | + (warn_deprecated ("bfd_write", (const char *) 0, 0, (const char *) 0),\ | |
23524 | + bfd_bwrite ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) | |
23525 | +#endif | |
23526 | +extern void warn_deprecated (const char *, const char *, int, const char *); | |
23527 | + | |
23528 | +/* Cast from const char * to char * so that caller can assign to | |
23529 | + a char * without a warning. */ | |
23530 | +#define bfd_get_filename(abfd) ((char *) (abfd)->filename) | |
23531 | +#define bfd_get_cacheable(abfd) ((abfd)->cacheable) | |
23532 | +#define bfd_get_format(abfd) ((abfd)->format) | |
23533 | +#define bfd_get_target(abfd) ((abfd)->xvec->name) | |
23534 | +#define bfd_get_flavour(abfd) ((abfd)->xvec->flavour) | |
23535 | +#define bfd_family_coff(abfd) \ | |
23536 | + (bfd_get_flavour (abfd) == bfd_target_coff_flavour || \ | |
23537 | + bfd_get_flavour (abfd) == bfd_target_xcoff_flavour) | |
23538 | +#define bfd_big_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_BIG) | |
23539 | +#define bfd_little_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_LITTLE) | |
23540 | +#define bfd_header_big_endian(abfd) \ | |
23541 | + ((abfd)->xvec->header_byteorder == BFD_ENDIAN_BIG) | |
23542 | +#define bfd_header_little_endian(abfd) \ | |
23543 | + ((abfd)->xvec->header_byteorder == BFD_ENDIAN_LITTLE) | |
23544 | +#define bfd_get_file_flags(abfd) ((abfd)->flags) | |
23545 | +#define bfd_applicable_file_flags(abfd) ((abfd)->xvec->object_flags) | |
23546 | +#define bfd_applicable_section_flags(abfd) ((abfd)->xvec->section_flags) | |
23547 | +#define bfd_my_archive(abfd) ((abfd)->my_archive) | |
23548 | +#define bfd_has_map(abfd) ((abfd)->has_armap) | |
23549 | + | |
23550 | +#define bfd_valid_reloc_types(abfd) ((abfd)->xvec->valid_reloc_types) | |
23551 | +#define bfd_usrdata(abfd) ((abfd)->usrdata) | |
23552 | + | |
23553 | +#define bfd_get_start_address(abfd) ((abfd)->start_address) | |
23554 | +#define bfd_get_symcount(abfd) ((abfd)->symcount) | |
23555 | +#define bfd_get_outsymbols(abfd) ((abfd)->outsymbols) | |
23556 | +#define bfd_count_sections(abfd) ((abfd)->section_count) | |
23557 | + | |
23558 | +#define bfd_get_dynamic_symcount(abfd) ((abfd)->dynsymcount) | |
23559 | + | |
23560 | +#define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char) | |
23561 | + | |
23562 | +#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE) | |
23563 | + | |
23564 | +extern bfd_boolean bfd_cache_close | |
23565 | + (bfd *abfd); | |
23566 | +/* NB: This declaration should match the autogenerated one in libbfd.h. */ | |
23567 | + | |
23568 | +extern bfd_boolean bfd_cache_close_all (void); | |
23569 | + | |
23570 | +extern bfd_boolean bfd_record_phdr | |
23571 | + (bfd *, unsigned long, bfd_boolean, flagword, bfd_boolean, bfd_vma, | |
23572 | + bfd_boolean, bfd_boolean, unsigned int, struct bfd_section **); | |
23573 | + | |
23574 | +/* Byte swapping routines. */ | |
23575 | + | |
23576 | +bfd_uint64_t bfd_getb64 (const void *); | |
23577 | +bfd_uint64_t bfd_getl64 (const void *); | |
23578 | +bfd_int64_t bfd_getb_signed_64 (const void *); | |
23579 | +bfd_int64_t bfd_getl_signed_64 (const void *); | |
23580 | +bfd_vma bfd_getb32 (const void *); | |
23581 | +bfd_vma bfd_getl32 (const void *); | |
23582 | +bfd_signed_vma bfd_getb_signed_32 (const void *); | |
23583 | +bfd_signed_vma bfd_getl_signed_32 (const void *); | |
23584 | +bfd_vma bfd_getb16 (const void *); | |
23585 | +bfd_vma bfd_getl16 (const void *); | |
23586 | +bfd_signed_vma bfd_getb_signed_16 (const void *); | |
23587 | +bfd_signed_vma bfd_getl_signed_16 (const void *); | |
23588 | +void bfd_putb64 (bfd_uint64_t, void *); | |
23589 | +void bfd_putl64 (bfd_uint64_t, void *); | |
23590 | +void bfd_putb32 (bfd_vma, void *); | |
23591 | +void bfd_putl32 (bfd_vma, void *); | |
23592 | +void bfd_putb16 (bfd_vma, void *); | |
23593 | +void bfd_putl16 (bfd_vma, void *); | |
23594 | + | |
23595 | +/* Byte swapping routines which take size and endiannes as arguments. */ | |
23596 | + | |
23597 | +bfd_uint64_t bfd_get_bits (const void *, int, bfd_boolean); | |
23598 | +void bfd_put_bits (bfd_uint64_t, void *, int, bfd_boolean); | |
23599 | + | |
23600 | +extern bfd_boolean bfd_section_already_linked_table_init (void); | |
23601 | +extern void bfd_section_already_linked_table_free (void); | |
23602 | +\f | |
23603 | +/* Externally visible ECOFF routines. */ | |
23604 | + | |
23605 | +#if defined(__STDC__) || defined(ALMOST_STDC) | |
23606 | +struct ecoff_debug_info; | |
23607 | +struct ecoff_debug_swap; | |
23608 | +struct ecoff_extr; | |
23609 | +struct bfd_symbol; | |
23610 | +struct bfd_link_info; | |
23611 | +struct bfd_link_hash_entry; | |
23612 | +struct bfd_elf_version_tree; | |
23613 | +#endif | |
23614 | +extern bfd_vma bfd_ecoff_get_gp_value | |
23615 | + (bfd * abfd); | |
23616 | +extern bfd_boolean bfd_ecoff_set_gp_value | |
23617 | + (bfd *abfd, bfd_vma gp_value); | |
23618 | +extern bfd_boolean bfd_ecoff_set_regmasks | |
23619 | + (bfd *abfd, unsigned long gprmask, unsigned long fprmask, | |
23620 | + unsigned long *cprmask); | |
23621 | +extern void *bfd_ecoff_debug_init | |
23622 | + (bfd *output_bfd, struct ecoff_debug_info *output_debug, | |
23623 | + const struct ecoff_debug_swap *output_swap, struct bfd_link_info *); | |
23624 | +extern void bfd_ecoff_debug_free | |
23625 | + (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, | |
23626 | + const struct ecoff_debug_swap *output_swap, struct bfd_link_info *); | |
23627 | +extern bfd_boolean bfd_ecoff_debug_accumulate | |
23628 | + (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, | |
23629 | + const struct ecoff_debug_swap *output_swap, bfd *input_bfd, | |
23630 | + struct ecoff_debug_info *input_debug, | |
23631 | + const struct ecoff_debug_swap *input_swap, struct bfd_link_info *); | |
23632 | +extern bfd_boolean bfd_ecoff_debug_accumulate_other | |
23633 | + (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, | |
23634 | + const struct ecoff_debug_swap *output_swap, bfd *input_bfd, | |
23635 | + struct bfd_link_info *); | |
23636 | +extern bfd_boolean bfd_ecoff_debug_externals | |
23637 | + (bfd *abfd, struct ecoff_debug_info *debug, | |
23638 | + const struct ecoff_debug_swap *swap, bfd_boolean relocatable, | |
23639 | + bfd_boolean (*get_extr) (struct bfd_symbol *, struct ecoff_extr *), | |
23640 | + void (*set_index) (struct bfd_symbol *, bfd_size_type)); | |
23641 | +extern bfd_boolean bfd_ecoff_debug_one_external | |
23642 | + (bfd *abfd, struct ecoff_debug_info *debug, | |
23643 | + const struct ecoff_debug_swap *swap, const char *name, | |
23644 | + struct ecoff_extr *esym); | |
23645 | +extern bfd_size_type bfd_ecoff_debug_size | |
23646 | + (bfd *abfd, struct ecoff_debug_info *debug, | |
23647 | + const struct ecoff_debug_swap *swap); | |
23648 | +extern bfd_boolean bfd_ecoff_write_debug | |
23649 | + (bfd *abfd, struct ecoff_debug_info *debug, | |
23650 | + const struct ecoff_debug_swap *swap, file_ptr where); | |
23651 | +extern bfd_boolean bfd_ecoff_write_accumulated_debug | |
23652 | + (void *handle, bfd *abfd, struct ecoff_debug_info *debug, | |
23653 | + const struct ecoff_debug_swap *swap, | |
23654 | + struct bfd_link_info *info, file_ptr where); | |
23655 | + | |
23656 | +/* Externally visible ELF routines. */ | |
23657 | + | |
23658 | +struct bfd_link_needed_list | |
23659 | +{ | |
23660 | + struct bfd_link_needed_list *next; | |
23661 | + bfd *by; | |
23662 | + const char *name; | |
23663 | +}; | |
23664 | + | |
23665 | +enum dynamic_lib_link_class { | |
23666 | + DYN_NORMAL = 0, | |
23667 | + DYN_AS_NEEDED = 1, | |
23668 | + DYN_DT_NEEDED = 2, | |
23669 | + DYN_NO_ADD_NEEDED = 4, | |
23670 | + DYN_NO_NEEDED = 8 | |
23671 | +}; | |
23672 | + | |
23673 | +extern bfd_boolean bfd_elf_record_link_assignment | |
23674 | + (struct bfd_link_info *, const char *, bfd_boolean); | |
23675 | +extern struct bfd_link_needed_list *bfd_elf_get_needed_list | |
23676 | + (bfd *, struct bfd_link_info *); | |
23677 | +extern bfd_boolean bfd_elf_get_bfd_needed_list | |
23678 | + (bfd *, struct bfd_link_needed_list **); | |
23679 | +extern bfd_boolean bfd_elf_size_dynamic_sections | |
23680 | + (bfd *, const char *, const char *, const char *, const char * const *, | |
23681 | + struct bfd_link_info *, struct bfd_section **, | |
23682 | + struct bfd_elf_version_tree *); | |
23683 | +extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr | |
23684 | + (bfd *, struct bfd_link_info *); | |
23685 | +extern void bfd_elf_set_dt_needed_name | |
23686 | + (bfd *, const char *); | |
23687 | +extern const char *bfd_elf_get_dt_soname | |
23688 | + (bfd *); | |
23689 | +extern void bfd_elf_set_dyn_lib_class | |
23690 | + (bfd *, int); | |
23691 | +extern int bfd_elf_get_dyn_lib_class | |
23692 | + (bfd *); | |
23693 | +extern struct bfd_link_needed_list *bfd_elf_get_runpath_list | |
23694 | + (bfd *, struct bfd_link_info *); | |
23695 | +extern bfd_boolean bfd_elf_discard_info | |
23696 | + (bfd *, struct bfd_link_info *); | |
23697 | +extern unsigned int _bfd_elf_default_action_discarded | |
23698 | + (struct bfd_section *); | |
23699 | + | |
23700 | +/* Return an upper bound on the number of bytes required to store a | |
23701 | + copy of ABFD's program header table entries. Return -1 if an error | |
23702 | + occurs; bfd_get_error will return an appropriate code. */ | |
23703 | +extern long bfd_get_elf_phdr_upper_bound | |
23704 | + (bfd *abfd); | |
23705 | + | |
23706 | +/* Copy ABFD's program header table entries to *PHDRS. The entries | |
23707 | + will be stored as an array of Elf_Internal_Phdr structures, as | |
23708 | + defined in include/elf/internal.h. To find out how large the | |
23709 | + buffer needs to be, call bfd_get_elf_phdr_upper_bound. | |
23710 | + | |
23711 | + Return the number of program header table entries read, or -1 if an | |
23712 | + error occurs; bfd_get_error will return an appropriate code. */ | |
23713 | +extern int bfd_get_elf_phdrs | |
23714 | + (bfd *abfd, void *phdrs); | |
23715 | + | |
23716 | +/* Create a new BFD as if by bfd_openr. Rather than opening a file, | |
23717 | + reconstruct an ELF file by reading the segments out of remote memory | |
23718 | + based on the ELF file header at EHDR_VMA and the ELF program headers it | |
23719 | + points to. If not null, *LOADBASEP is filled in with the difference | |
23720 | + between the VMAs from which the segments were read, and the VMAs the | |
23721 | + file headers (and hence BFD's idea of each section's VMA) put them at. | |
23722 | + | |
23723 | + The function TARGET_READ_MEMORY is called to copy LEN bytes from the | |
23724 | + remote memory at target address VMA into the local buffer at MYADDR; it | |
23725 | + should return zero on success or an `errno' code on failure. TEMPL must | |
23726 | + be a BFD for an ELF target with the word size and byte order found in | |
23727 | + the remote memory. */ | |
23728 | +extern bfd *bfd_elf_bfd_from_remote_memory | |
23729 | + (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep, | |
23730 | + int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr, int len)); | |
23731 | + | |
23732 | +/* Return the arch_size field of an elf bfd, or -1 if not elf. */ | |
23733 | +extern int bfd_get_arch_size | |
23734 | + (bfd *); | |
23735 | + | |
23736 | +/* Return TRUE if address "naturally" sign extends, or -1 if not elf. */ | |
23737 | +extern int bfd_get_sign_extend_vma | |
23738 | + (bfd *); | |
23739 | + | |
23740 | +extern struct bfd_section *_bfd_elf_tls_setup | |
23741 | + (bfd *, struct bfd_link_info *); | |
23742 | + | |
23743 | +extern void _bfd_elf_provide_symbol | |
23744 | + (struct bfd_link_info *, const char *, bfd_vma, struct bfd_section *); | |
23745 | + | |
23746 | +extern void _bfd_elf_provide_section_bound_symbols | |
23747 | + (struct bfd_link_info *, struct bfd_section *, const char *, const char *); | |
23748 | + | |
23749 | +extern void _bfd_elf_fix_excluded_sec_syms | |
23750 | + (bfd *, struct bfd_link_info *); | |
23751 | + | |
23752 | +extern bfd_boolean bfd_m68k_elf32_create_embedded_relocs | |
23753 | + (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, | |
23754 | + char **); | |
23755 | + | |
23756 | +/* SunOS shared library support routines for the linker. */ | |
23757 | + | |
23758 | +extern struct bfd_link_needed_list *bfd_sunos_get_needed_list | |
23759 | + (bfd *, struct bfd_link_info *); | |
23760 | +extern bfd_boolean bfd_sunos_record_link_assignment | |
23761 | + (bfd *, struct bfd_link_info *, const char *); | |
23762 | +extern bfd_boolean bfd_sunos_size_dynamic_sections | |
23763 | + (bfd *, struct bfd_link_info *, struct bfd_section **, | |
23764 | + struct bfd_section **, struct bfd_section **); | |
23765 | + | |
23766 | +/* Linux shared library support routines for the linker. */ | |
23767 | + | |
23768 | +extern bfd_boolean bfd_i386linux_size_dynamic_sections | |
23769 | + (bfd *, struct bfd_link_info *); | |
23770 | +extern bfd_boolean bfd_m68klinux_size_dynamic_sections | |
23771 | + (bfd *, struct bfd_link_info *); | |
23772 | +extern bfd_boolean bfd_sparclinux_size_dynamic_sections | |
23773 | + (bfd *, struct bfd_link_info *); | |
23774 | + | |
23775 | +/* mmap hacks */ | |
23776 | + | |
23777 | +struct _bfd_window_internal; | |
23778 | +typedef struct _bfd_window_internal bfd_window_internal; | |
23779 | + | |
23780 | +typedef struct _bfd_window | |
23781 | +{ | |
23782 | + /* What the user asked for. */ | |
23783 | + void *data; | |
23784 | + bfd_size_type size; | |
23785 | + /* The actual window used by BFD. Small user-requested read-only | |
23786 | + regions sharing a page may share a single window into the object | |
23787 | + file. Read-write versions shouldn't until I've fixed things to | |
23788 | + keep track of which portions have been claimed by the | |
23789 | + application; don't want to give the same region back when the | |
23790 | + application wants two writable copies! */ | |
23791 | + struct _bfd_window_internal *i; | |
23792 | +} | |
23793 | +bfd_window; | |
23794 | + | |
23795 | +extern void bfd_init_window | |
23796 | + (bfd_window *); | |
23797 | +extern void bfd_free_window | |
23798 | + (bfd_window *); | |
23799 | +extern bfd_boolean bfd_get_file_window | |
23800 | + (bfd *, file_ptr, bfd_size_type, bfd_window *, bfd_boolean); | |
23801 | + | |
23802 | +/* XCOFF support routines for the linker. */ | |
23803 | + | |
23804 | +extern bfd_boolean bfd_xcoff_link_record_set | |
23805 | + (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, bfd_size_type); | |
23806 | +extern bfd_boolean bfd_xcoff_import_symbol | |
23807 | + (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, bfd_vma, | |
23808 | + const char *, const char *, const char *, unsigned int); | |
23809 | +extern bfd_boolean bfd_xcoff_export_symbol | |
23810 | + (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *); | |
23811 | +extern bfd_boolean bfd_xcoff_link_count_reloc | |
23812 | + (bfd *, struct bfd_link_info *, const char *); | |
23813 | +extern bfd_boolean bfd_xcoff_record_link_assignment | |
23814 | + (bfd *, struct bfd_link_info *, const char *); | |
23815 | +extern bfd_boolean bfd_xcoff_size_dynamic_sections | |
23816 | + (bfd *, struct bfd_link_info *, const char *, const char *, | |
23817 | + unsigned long, unsigned long, unsigned long, bfd_boolean, | |
23818 | + int, bfd_boolean, bfd_boolean, struct bfd_section **, bfd_boolean); | |
23819 | +extern bfd_boolean bfd_xcoff_link_generate_rtinit | |
23820 | + (bfd *, const char *, const char *, bfd_boolean); | |
23821 | + | |
23822 | +/* XCOFF support routines for ar. */ | |
23823 | +extern bfd_boolean bfd_xcoff_ar_archive_set_magic | |
23824 | + (bfd *, char *); | |
23825 | + | |
23826 | +/* Externally visible COFF routines. */ | |
23827 | + | |
23828 | +#if defined(__STDC__) || defined(ALMOST_STDC) | |
23829 | +struct internal_syment; | |
23830 | +union internal_auxent; | |
23831 | +#endif | |
23832 | + | |
23833 | +extern bfd_boolean bfd_coff_get_syment | |
23834 | + (bfd *, struct bfd_symbol *, struct internal_syment *); | |
23835 | + | |
23836 | +extern bfd_boolean bfd_coff_get_auxent | |
23837 | + (bfd *, struct bfd_symbol *, int, union internal_auxent *); | |
23838 | + | |
23839 | +extern bfd_boolean bfd_coff_set_symbol_class | |
23840 | + (bfd *, struct bfd_symbol *, unsigned int); | |
23841 | + | |
23842 | +extern bfd_boolean bfd_m68k_coff_create_embedded_relocs | |
23843 | + (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, char **); | |
23844 | + | |
23845 | +/* ARM Interworking support. Called from linker. */ | |
23846 | +extern bfd_boolean bfd_arm_allocate_interworking_sections | |
23847 | + (struct bfd_link_info *); | |
23848 | + | |
23849 | +extern bfd_boolean bfd_arm_process_before_allocation | |
23850 | + (bfd *, struct bfd_link_info *, int); | |
23851 | + | |
23852 | +extern bfd_boolean bfd_arm_get_bfd_for_interworking | |
23853 | + (bfd *, struct bfd_link_info *); | |
23854 | + | |
23855 | +/* PE ARM Interworking support. Called from linker. */ | |
23856 | +extern bfd_boolean bfd_arm_pe_allocate_interworking_sections | |
23857 | + (struct bfd_link_info *); | |
23858 | + | |
23859 | +extern bfd_boolean bfd_arm_pe_process_before_allocation | |
23860 | + (bfd *, struct bfd_link_info *, int); | |
23861 | + | |
23862 | +extern bfd_boolean bfd_arm_pe_get_bfd_for_interworking | |
23863 | + (bfd *, struct bfd_link_info *); | |
23864 | + | |
23865 | +/* ELF ARM Interworking support. Called from linker. */ | |
23866 | +extern bfd_boolean bfd_elf32_arm_allocate_interworking_sections | |
23867 | + (struct bfd_link_info *); | |
23868 | + | |
23869 | +extern bfd_boolean bfd_elf32_arm_process_before_allocation | |
23870 | + (bfd *, struct bfd_link_info *, int); | |
23871 | + | |
23872 | +void bfd_elf32_arm_set_target_relocs | |
23873 | + (struct bfd_link_info *, int, char *, int, int); | |
23874 | + | |
23875 | +extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking | |
23876 | + (bfd *, struct bfd_link_info *); | |
23877 | + | |
23878 | +extern bfd_boolean bfd_elf32_arm_add_glue_sections_to_bfd | |
23879 | + (bfd *, struct bfd_link_info *); | |
23880 | + | |
23881 | +/* ELF ARM mapping symbol support */ | |
23882 | +extern bfd_boolean bfd_is_arm_mapping_symbol_name | |
23883 | + (const char * name); | |
23884 | + | |
23885 | +/* ARM Note section processing. */ | |
23886 | +extern bfd_boolean bfd_arm_merge_machines | |
23887 | + (bfd *, bfd *); | |
23888 | + | |
23889 | +extern bfd_boolean bfd_arm_update_notes | |
23890 | + (bfd *, const char *); | |
23891 | + | |
23892 | +extern unsigned int bfd_arm_get_mach_from_notes | |
23893 | + (bfd *, const char *); | |
23894 | + | |
23895 | +/* TI COFF load page support. */ | |
23896 | +extern void bfd_ticoff_set_section_load_page | |
23897 | + (struct bfd_section *, int); | |
23898 | + | |
23899 | +extern int bfd_ticoff_get_section_load_page | |
23900 | + (struct bfd_section *); | |
23901 | + | |
23902 | +/* H8/300 functions. */ | |
23903 | +extern bfd_vma bfd_h8300_pad_address | |
23904 | + (bfd *, bfd_vma); | |
23905 | + | |
23906 | +/* IA64 Itanium code generation. Called from linker. */ | |
23907 | +extern void bfd_elf32_ia64_after_parse | |
23908 | + (int); | |
23909 | + | |
23910 | +extern void bfd_elf64_ia64_after_parse | |
23911 | + (int); | |
23912 | + | |
23913 | +/* This structure is used for a comdat section, as in PE. A comdat | |
23914 | + section is associated with a particular symbol. When the linker | |
23915 | + sees a comdat section, it keeps only one of the sections with a | |
23916 | + given name and associated with a given symbol. */ | |
23917 | + | |
23918 | +struct coff_comdat_info | |
23919 | +{ | |
23920 | + /* The name of the symbol associated with a comdat section. */ | |
23921 | + const char *name; | |
23922 | + | |
23923 | + /* The local symbol table index of the symbol associated with a | |
23924 | + comdat section. This is only meaningful to the object file format | |
23925 | + specific code; it is not an index into the list returned by | |
23926 | + bfd_canonicalize_symtab. */ | |
23927 | + long symbol; | |
23928 | +}; | |
23929 | + | |
23930 | +extern struct coff_comdat_info *bfd_coff_get_comdat_section | |
23931 | + (bfd *, struct bfd_section *); | |
23932 | + | |
23933 | +/* Extracted from init.c. */ | |
23934 | +void bfd_init (void); | |
23935 | + | |
23936 | +/* Extracted from opncls.c. */ | |
23937 | +bfd *bfd_fopen (const char *filename, const char *target, | |
23938 | + const char *mode, int fd); | |
23939 | + | |
23940 | +bfd *bfd_openr (const char *filename, const char *target); | |
23941 | + | |
23942 | +bfd *bfd_fdopenr (const char *filename, const char *target, int fd); | |
23943 | + | |
23944 | +bfd *bfd_openstreamr (const char *, const char *, void *); | |
23945 | + | |
23946 | +bfd *bfd_openr_iovec (const char *filename, const char *target, | |
23947 | + void *(*open) (struct bfd *nbfd, | |
23948 | + void *open_closure), | |
23949 | + void *open_closure, | |
23950 | + file_ptr (*pread) (struct bfd *nbfd, | |
23951 | + void *stream, | |
23952 | + void *buf, | |
23953 | + file_ptr nbytes, | |
23954 | + file_ptr offset), | |
23955 | + int (*close) (struct bfd *nbfd, | |
23956 | + void *stream)); | |
23957 | + | |
23958 | +bfd *bfd_openw (const char *filename, const char *target); | |
23959 | + | |
23960 | +bfd_boolean bfd_close (bfd *abfd); | |
23961 | + | |
23962 | +bfd_boolean bfd_close_all_done (bfd *); | |
23963 | + | |
23964 | +bfd *bfd_create (const char *filename, bfd *templ); | |
23965 | + | |
23966 | +bfd_boolean bfd_make_writable (bfd *abfd); | |
23967 | + | |
23968 | +bfd_boolean bfd_make_readable (bfd *abfd); | |
23969 | + | |
23970 | +unsigned long bfd_calc_gnu_debuglink_crc32 | |
23971 | + (unsigned long crc, const unsigned char *buf, bfd_size_type len); | |
23972 | + | |
23973 | +char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir); | |
23974 | + | |
23975 | +struct bfd_section *bfd_create_gnu_debuglink_section | |
23976 | + (bfd *abfd, const char *filename); | |
23977 | + | |
23978 | +bfd_boolean bfd_fill_in_gnu_debuglink_section | |
23979 | + (bfd *abfd, struct bfd_section *sect, const char *filename); | |
23980 | + | |
23981 | +/* Extracted from libbfd.c. */ | |
23982 | + | |
23983 | +/* Byte swapping macros for user section data. */ | |
23984 | + | |
23985 | +#define bfd_put_8(abfd, val, ptr) \ | |
23986 | + ((void) (*((unsigned char *) (ptr)) = (val) & 0xff)) | |
23987 | +#define bfd_put_signed_8 \ | |
23988 | + bfd_put_8 | |
23989 | +#define bfd_get_8(abfd, ptr) \ | |
23990 | + (*(unsigned char *) (ptr) & 0xff) | |
23991 | +#define bfd_get_signed_8(abfd, ptr) \ | |
23992 | + (((*(unsigned char *) (ptr) & 0xff) ^ 0x80) - 0x80) | |
23993 | + | |
23994 | +#define bfd_put_16(abfd, val, ptr) \ | |
23995 | + BFD_SEND (abfd, bfd_putx16, ((val),(ptr))) | |
23996 | +#define bfd_put_signed_16 \ | |
23997 | + bfd_put_16 | |
23998 | +#define bfd_get_16(abfd, ptr) \ | |
23999 | + BFD_SEND (abfd, bfd_getx16, (ptr)) | |
24000 | +#define bfd_get_signed_16(abfd, ptr) \ | |
24001 | + BFD_SEND (abfd, bfd_getx_signed_16, (ptr)) | |
24002 | + | |
24003 | +#define bfd_put_32(abfd, val, ptr) \ | |
24004 | + BFD_SEND (abfd, bfd_putx32, ((val),(ptr))) | |
24005 | +#define bfd_put_signed_32 \ | |
24006 | + bfd_put_32 | |
24007 | +#define bfd_get_32(abfd, ptr) \ | |
24008 | + BFD_SEND (abfd, bfd_getx32, (ptr)) | |
24009 | +#define bfd_get_signed_32(abfd, ptr) \ | |
24010 | + BFD_SEND (abfd, bfd_getx_signed_32, (ptr)) | |
24011 | + | |
24012 | +#define bfd_put_64(abfd, val, ptr) \ | |
24013 | + BFD_SEND (abfd, bfd_putx64, ((val), (ptr))) | |
24014 | +#define bfd_put_signed_64 \ | |
24015 | + bfd_put_64 | |
24016 | +#define bfd_get_64(abfd, ptr) \ | |
24017 | + BFD_SEND (abfd, bfd_getx64, (ptr)) | |
24018 | +#define bfd_get_signed_64(abfd, ptr) \ | |
24019 | + BFD_SEND (abfd, bfd_getx_signed_64, (ptr)) | |
24020 | + | |
24021 | +#define bfd_get(bits, abfd, ptr) \ | |
24022 | + ((bits) == 8 ? (bfd_vma) bfd_get_8 (abfd, ptr) \ | |
24023 | + : (bits) == 16 ? bfd_get_16 (abfd, ptr) \ | |
24024 | + : (bits) == 32 ? bfd_get_32 (abfd, ptr) \ | |
24025 | + : (bits) == 64 ? bfd_get_64 (abfd, ptr) \ | |
24026 | + : (abort (), (bfd_vma) - 1)) | |
24027 | + | |
24028 | +#define bfd_put(bits, abfd, val, ptr) \ | |
24029 | + ((bits) == 8 ? bfd_put_8 (abfd, val, ptr) \ | |
24030 | + : (bits) == 16 ? bfd_put_16 (abfd, val, ptr) \ | |
24031 | + : (bits) == 32 ? bfd_put_32 (abfd, val, ptr) \ | |
24032 | + : (bits) == 64 ? bfd_put_64 (abfd, val, ptr) \ | |
24033 | + : (abort (), (void) 0)) | |
24034 | + | |
24035 | + | |
24036 | +/* Byte swapping macros for file header data. */ | |
24037 | + | |
24038 | +#define bfd_h_put_8(abfd, val, ptr) \ | |
24039 | + bfd_put_8 (abfd, val, ptr) | |
24040 | +#define bfd_h_put_signed_8(abfd, val, ptr) \ | |
24041 | + bfd_put_8 (abfd, val, ptr) | |
24042 | +#define bfd_h_get_8(abfd, ptr) \ | |
24043 | + bfd_get_8 (abfd, ptr) | |
24044 | +#define bfd_h_get_signed_8(abfd, ptr) \ | |
24045 | + bfd_get_signed_8 (abfd, ptr) | |
24046 | + | |
24047 | +#define bfd_h_put_16(abfd, val, ptr) \ | |
24048 | + BFD_SEND (abfd, bfd_h_putx16, (val, ptr)) | |
24049 | +#define bfd_h_put_signed_16 \ | |
24050 | + bfd_h_put_16 | |
24051 | +#define bfd_h_get_16(abfd, ptr) \ | |
24052 | + BFD_SEND (abfd, bfd_h_getx16, (ptr)) | |
24053 | +#define bfd_h_get_signed_16(abfd, ptr) \ | |
24054 | + BFD_SEND (abfd, bfd_h_getx_signed_16, (ptr)) | |
24055 | + | |
24056 | +#define bfd_h_put_32(abfd, val, ptr) \ | |
24057 | + BFD_SEND (abfd, bfd_h_putx32, (val, ptr)) | |
24058 | +#define bfd_h_put_signed_32 \ | |
24059 | + bfd_h_put_32 | |
24060 | +#define bfd_h_get_32(abfd, ptr) \ | |
24061 | + BFD_SEND (abfd, bfd_h_getx32, (ptr)) | |
24062 | +#define bfd_h_get_signed_32(abfd, ptr) \ | |
24063 | + BFD_SEND (abfd, bfd_h_getx_signed_32, (ptr)) | |
24064 | + | |
24065 | +#define bfd_h_put_64(abfd, val, ptr) \ | |
24066 | + BFD_SEND (abfd, bfd_h_putx64, (val, ptr)) | |
24067 | +#define bfd_h_put_signed_64 \ | |
24068 | + bfd_h_put_64 | |
24069 | +#define bfd_h_get_64(abfd, ptr) \ | |
24070 | + BFD_SEND (abfd, bfd_h_getx64, (ptr)) | |
24071 | +#define bfd_h_get_signed_64(abfd, ptr) \ | |
24072 | + BFD_SEND (abfd, bfd_h_getx_signed_64, (ptr)) | |
24073 | + | |
24074 | +/* Aliases for the above, which should eventually go away. */ | |
24075 | + | |
24076 | +#define H_PUT_64 bfd_h_put_64 | |
24077 | +#define H_PUT_32 bfd_h_put_32 | |
24078 | +#define H_PUT_16 bfd_h_put_16 | |
24079 | +#define H_PUT_8 bfd_h_put_8 | |
24080 | +#define H_PUT_S64 bfd_h_put_signed_64 | |
24081 | +#define H_PUT_S32 bfd_h_put_signed_32 | |
24082 | +#define H_PUT_S16 bfd_h_put_signed_16 | |
24083 | +#define H_PUT_S8 bfd_h_put_signed_8 | |
24084 | +#define H_GET_64 bfd_h_get_64 | |
24085 | +#define H_GET_32 bfd_h_get_32 | |
24086 | +#define H_GET_16 bfd_h_get_16 | |
24087 | +#define H_GET_8 bfd_h_get_8 | |
24088 | +#define H_GET_S64 bfd_h_get_signed_64 | |
24089 | +#define H_GET_S32 bfd_h_get_signed_32 | |
24090 | +#define H_GET_S16 bfd_h_get_signed_16 | |
24091 | +#define H_GET_S8 bfd_h_get_signed_8 | |
24092 | + | |
24093 | + | |
24094 | +/* Extracted from bfdio.c. */ | |
24095 | +long bfd_get_mtime (bfd *abfd); | |
24096 | + | |
24097 | +long bfd_get_size (bfd *abfd); | |
24098 | + | |
24099 | +/* Extracted from bfdwin.c. */ | |
24100 | +/* Extracted from section.c. */ | |
24101 | +typedef struct bfd_section | |
24102 | +{ | |
24103 | + /* The name of the section; the name isn't a copy, the pointer is | |
24104 | + the same as that passed to bfd_make_section. */ | |
24105 | + const char *name; | |
24106 | + | |
24107 | + /* A unique sequence number. */ | |
24108 | + int id; | |
24109 | + | |
24110 | + /* Which section in the bfd; 0..n-1 as sections are created in a bfd. */ | |
24111 | + int index; | |
24112 | + | |
24113 | + /* The next section in the list belonging to the BFD, or NULL. */ | |
24114 | + struct bfd_section *next; | |
24115 | + | |
24116 | + /* The previous section in the list belonging to the BFD, or NULL. */ | |
24117 | + struct bfd_section *prev; | |
24118 | + | |
24119 | + /* The field flags contains attributes of the section. Some | |
24120 | + flags are read in from the object file, and some are | |
24121 | + synthesized from other information. */ | |
24122 | + flagword flags; | |
24123 | + | |
24124 | +#define SEC_NO_FLAGS 0x000 | |
24125 | + | |
24126 | + /* Tells the OS to allocate space for this section when loading. | |
24127 | + This is clear for a section containing debug information only. */ | |
24128 | +#define SEC_ALLOC 0x001 | |
24129 | + | |
24130 | + /* Tells the OS to load the section from the file when loading. | |
24131 | + This is clear for a .bss section. */ | |
24132 | +#define SEC_LOAD 0x002 | |
24133 | + | |
24134 | + /* The section contains data still to be relocated, so there is | |
24135 | + some relocation information too. */ | |
24136 | +#define SEC_RELOC 0x004 | |
24137 | + | |
24138 | + /* A signal to the OS that the section contains read only data. */ | |
24139 | +#define SEC_READONLY 0x008 | |
24140 | + | |
24141 | + /* The section contains code only. */ | |
24142 | +#define SEC_CODE 0x010 | |
24143 | + | |
24144 | + /* The section contains data only. */ | |
24145 | +#define SEC_DATA 0x020 | |
24146 | + | |
24147 | + /* The section will reside in ROM. */ | |
24148 | +#define SEC_ROM 0x040 | |
24149 | + | |
24150 | + /* The section contains constructor information. This section | |
24151 | + type is used by the linker to create lists of constructors and | |
24152 | + destructors used by <<g++>>. When a back end sees a symbol | |
24153 | + which should be used in a constructor list, it creates a new | |
24154 | + section for the type of name (e.g., <<__CTOR_LIST__>>), attaches | |
24155 | + the symbol to it, and builds a relocation. To build the lists | |
24156 | + of constructors, all the linker has to do is catenate all the | |
24157 | + sections called <<__CTOR_LIST__>> and relocate the data | |
24158 | + contained within - exactly the operations it would peform on | |
24159 | + standard data. */ | |
24160 | +#define SEC_CONSTRUCTOR 0x080 | |
24161 | + | |
24162 | + /* The section has contents - a data section could be | |
24163 | + <<SEC_ALLOC>> | <<SEC_HAS_CONTENTS>>; a debug section could be | |
24164 | + <<SEC_HAS_CONTENTS>> */ | |
24165 | +#define SEC_HAS_CONTENTS 0x100 | |
24166 | + | |
24167 | + /* An instruction to the linker to not output the section | |
24168 | + even if it has information which would normally be written. */ | |
24169 | +#define SEC_NEVER_LOAD 0x200 | |
24170 | + | |
24171 | + /* The section contains thread local data. */ | |
24172 | +#define SEC_THREAD_LOCAL 0x400 | |
24173 | + | |
24174 | + /* The section has GOT references. This flag is only for the | |
24175 | + linker, and is currently only used by the elf32-hppa back end. | |
24176 | + It will be set if global offset table references were detected | |
24177 | + in this section, which indicate to the linker that the section | |
24178 | + contains PIC code, and must be handled specially when doing a | |
24179 | + static link. */ | |
24180 | +#define SEC_HAS_GOT_REF 0x800 | |
24181 | + | |
24182 | + /* The section contains common symbols (symbols may be defined | |
24183 | + multiple times, the value of a symbol is the amount of | |
24184 | + space it requires, and the largest symbol value is the one | |
24185 | + used). Most targets have exactly one of these (which we | |
24186 | + translate to bfd_com_section_ptr), but ECOFF has two. */ | |
24187 | +#define SEC_IS_COMMON 0x1000 | |
24188 | + | |
24189 | + /* The section contains only debugging information. For | |
24190 | + example, this is set for ELF .debug and .stab sections. | |
24191 | + strip tests this flag to see if a section can be | |
24192 | + discarded. */ | |
24193 | +#define SEC_DEBUGGING 0x2000 | |
24194 | + | |
24195 | + /* The contents of this section are held in memory pointed to | |
24196 | + by the contents field. This is checked by bfd_get_section_contents, | |
24197 | + and the data is retrieved from memory if appropriate. */ | |
24198 | +#define SEC_IN_MEMORY 0x4000 | |
24199 | + | |
24200 | + /* The contents of this section are to be excluded by the | |
24201 | + linker for executable and shared objects unless those | |
24202 | + objects are to be further relocated. */ | |
24203 | +#define SEC_EXCLUDE 0x8000 | |
24204 | + | |
24205 | + /* The contents of this section are to be sorted based on the sum of | |
24206 | + the symbol and addend values specified by the associated relocation | |
24207 | + entries. Entries without associated relocation entries will be | |
24208 | + appended to the end of the section in an unspecified order. */ | |
24209 | +#define SEC_SORT_ENTRIES 0x10000 | |
24210 | + | |
24211 | + /* When linking, duplicate sections of the same name should be | |
24212 | + discarded, rather than being combined into a single section as | |
24213 | + is usually done. This is similar to how common symbols are | |
24214 | + handled. See SEC_LINK_DUPLICATES below. */ | |
24215 | +#define SEC_LINK_ONCE 0x20000 | |
24216 | + | |
24217 | + /* If SEC_LINK_ONCE is set, this bitfield describes how the linker | |
24218 | + should handle duplicate sections. */ | |
24219 | +#define SEC_LINK_DUPLICATES 0x40000 | |
24220 | + | |
24221 | + /* This value for SEC_LINK_DUPLICATES means that duplicate | |
24222 | + sections with the same name should simply be discarded. */ | |
24223 | +#define SEC_LINK_DUPLICATES_DISCARD 0x0 | |
24224 | + | |
24225 | + /* This value for SEC_LINK_DUPLICATES means that the linker | |
24226 | + should warn if there are any duplicate sections, although | |
24227 | + it should still only link one copy. */ | |
24228 | +#define SEC_LINK_DUPLICATES_ONE_ONLY 0x80000 | |
24229 | + | |
24230 | + /* This value for SEC_LINK_DUPLICATES means that the linker | |
24231 | + should warn if any duplicate sections are a different size. */ | |
24232 | +#define SEC_LINK_DUPLICATES_SAME_SIZE 0x100000 | |
24233 | + | |
24234 | + /* This value for SEC_LINK_DUPLICATES means that the linker | |
24235 | + should warn if any duplicate sections contain different | |
24236 | + contents. */ | |
24237 | +#define SEC_LINK_DUPLICATES_SAME_CONTENTS \ | |
24238 | + (SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE) | |
24239 | + | |
24240 | + /* This section was created by the linker as part of dynamic | |
24241 | + relocation or other arcane processing. It is skipped when | |
24242 | + going through the first-pass output, trusting that someone | |
24243 | + else up the line will take care of it later. */ | |
24244 | +#define SEC_LINKER_CREATED 0x200000 | |
24245 | + | |
24246 | + /* This section should not be subject to garbage collection. */ | |
24247 | +#define SEC_KEEP 0x400000 | |
24248 | + | |
24249 | + /* This section contains "short" data, and should be placed | |
24250 | + "near" the GP. */ | |
24251 | +#define SEC_SMALL_DATA 0x800000 | |
24252 | + | |
24253 | + /* Attempt to merge identical entities in the section. | |
24254 | + Entity size is given in the entsize field. */ | |
24255 | +#define SEC_MERGE 0x1000000 | |
24256 | + | |
24257 | + /* If given with SEC_MERGE, entities to merge are zero terminated | |
24258 | + strings where entsize specifies character size instead of fixed | |
24259 | + size entries. */ | |
24260 | +#define SEC_STRINGS 0x2000000 | |
24261 | + | |
24262 | + /* This section contains data about section groups. */ | |
24263 | +#define SEC_GROUP 0x4000000 | |
24264 | + | |
24265 | + /* The section is a COFF shared library section. This flag is | |
24266 | + only for the linker. If this type of section appears in | |
24267 | + the input file, the linker must copy it to the output file | |
24268 | + without changing the vma or size. FIXME: Although this | |
24269 | + was originally intended to be general, it really is COFF | |
24270 | + specific (and the flag was renamed to indicate this). It | |
24271 | + might be cleaner to have some more general mechanism to | |
24272 | + allow the back end to control what the linker does with | |
24273 | + sections. */ | |
24274 | +#define SEC_COFF_SHARED_LIBRARY 0x10000000 | |
24275 | + | |
24276 | + /* This section contains data which may be shared with other | |
24277 | + executables or shared objects. This is for COFF only. */ | |
24278 | +#define SEC_COFF_SHARED 0x20000000 | |
24279 | + | |
24280 | + /* When a section with this flag is being linked, then if the size of | |
24281 | + the input section is less than a page, it should not cross a page | |
24282 | + boundary. If the size of the input section is one page or more, | |
24283 | + it should be aligned on a page boundary. This is for TI | |
24284 | + TMS320C54X only. */ | |
24285 | +#define SEC_TIC54X_BLOCK 0x40000000 | |
24286 | + | |
24287 | + /* Conditionally link this section; do not link if there are no | |
24288 | + references found to any symbol in the section. This is for TI | |
24289 | + TMS320C54X only. */ | |
24290 | +#define SEC_TIC54X_CLINK 0x80000000 | |
24291 | + | |
24292 | + /* End of section flags. */ | |
24293 | + | |
24294 | + /* Some internal packed boolean fields. */ | |
24295 | + | |
24296 | + /* See the vma field. */ | |
24297 | + unsigned int user_set_vma : 1; | |
24298 | + | |
24299 | + /* A mark flag used by some of the linker backends. */ | |
24300 | + unsigned int linker_mark : 1; | |
24301 | + | |
24302 | + /* Another mark flag used by some of the linker backends. Set for | |
24303 | + output sections that have an input section. */ | |
24304 | + unsigned int linker_has_input : 1; | |
24305 | + | |
24306 | + /* Mark flags used by some linker backends for garbage collection. */ | |
24307 | + unsigned int gc_mark : 1; | |
24308 | + unsigned int gc_mark_from_eh : 1; | |
24309 | + | |
24310 | + /* The following flags are used by the ELF linker. */ | |
24311 | + | |
24312 | + /* Mark sections which have been allocated to segments. */ | |
24313 | + unsigned int segment_mark : 1; | |
24314 | + | |
24315 | + /* Type of sec_info information. */ | |
24316 | + unsigned int sec_info_type:3; | |
24317 | +#define ELF_INFO_TYPE_NONE 0 | |
24318 | +#define ELF_INFO_TYPE_STABS 1 | |
24319 | +#define ELF_INFO_TYPE_MERGE 2 | |
24320 | +#define ELF_INFO_TYPE_EH_FRAME 3 | |
24321 | +#define ELF_INFO_TYPE_JUST_SYMS 4 | |
24322 | + | |
24323 | + /* Nonzero if this section uses RELA relocations, rather than REL. */ | |
24324 | + unsigned int use_rela_p:1; | |
24325 | + | |
24326 | + /* Bits used by various backends. The generic code doesn't touch | |
24327 | + these fields. */ | |
24328 | + | |
24329 | + /* Nonzero if this section has TLS related relocations. */ | |
24330 | + unsigned int has_tls_reloc:1; | |
24331 | + | |
24332 | + /* Nonzero if this section has a gp reloc. */ | |
24333 | + unsigned int has_gp_reloc:1; | |
24334 | + | |
24335 | + /* Nonzero if this section needs the relax finalize pass. */ | |
24336 | + unsigned int need_finalize_relax:1; | |
24337 | + | |
24338 | + /* Whether relocations have been processed. */ | |
24339 | + unsigned int reloc_done : 1; | |
24340 | + | |
24341 | + /* End of internal packed boolean fields. */ | |
24342 | + | |
24343 | + /* The virtual memory address of the section - where it will be | |
24344 | + at run time. The symbols are relocated against this. The | |
24345 | + user_set_vma flag is maintained by bfd; if it's not set, the | |
24346 | + backend can assign addresses (for example, in <<a.out>>, where | |
24347 | + the default address for <<.data>> is dependent on the specific | |
24348 | + target and various flags). */ | |
24349 | + bfd_vma vma; | |
24350 | + | |
24351 | + /* The load address of the section - where it would be in a | |
24352 | + rom image; really only used for writing section header | |
24353 | + information. */ | |
24354 | + bfd_vma lma; | |
24355 | + | |
24356 | + /* The size of the section in octets, as it will be output. | |
24357 | + Contains a value even if the section has no contents (e.g., the | |
24358 | + size of <<.bss>>). */ | |
24359 | + bfd_size_type size; | |
24360 | + | |
24361 | + /* For input sections, the original size on disk of the section, in | |
24362 | + octets. This field is used by the linker relaxation code. It is | |
24363 | + currently only set for sections where the linker relaxation scheme | |
24364 | + doesn't cache altered section and reloc contents (stabs, eh_frame, | |
24365 | + SEC_MERGE, some coff relaxing targets), and thus the original size | |
24366 | + needs to be kept to read the section multiple times. | |
24367 | + For output sections, rawsize holds the section size calculated on | |
24368 | + a previous linker relaxation pass. */ | |
24369 | + bfd_size_type rawsize; | |
24370 | + | |
24371 | + /* If this section is going to be output, then this value is the | |
24372 | + offset in *bytes* into the output section of the first byte in the | |
24373 | + input section (byte ==> smallest addressable unit on the | |
24374 | + target). In most cases, if this was going to start at the | |
24375 | + 100th octet (8-bit quantity) in the output section, this value | |
24376 | + would be 100. However, if the target byte size is 16 bits | |
24377 | + (bfd_octets_per_byte is "2"), this value would be 50. */ | |
24378 | + bfd_vma output_offset; | |
24379 | + | |
24380 | + /* The output section through which to map on output. */ | |
24381 | + struct bfd_section *output_section; | |
24382 | + | |
24383 | + /* The alignment requirement of the section, as an exponent of 2 - | |
24384 | + e.g., 3 aligns to 2^3 (or 8). */ | |
24385 | + unsigned int alignment_power; | |
24386 | + | |
24387 | + /* If an input section, a pointer to a vector of relocation | |
24388 | + records for the data in this section. */ | |
24389 | + struct reloc_cache_entry *relocation; | |
24390 | + | |
24391 | + /* If an output section, a pointer to a vector of pointers to | |
24392 | + relocation records for the data in this section. */ | |
24393 | + struct reloc_cache_entry **orelocation; | |
24394 | + | |
24395 | + /* The number of relocation records in one of the above. */ | |
24396 | + unsigned reloc_count; | |
24397 | + | |
24398 | + /* Information below is back end specific - and not always used | |
24399 | + or updated. */ | |
24400 | + | |
24401 | + /* File position of section data. */ | |
24402 | + file_ptr filepos; | |
24403 | + | |
24404 | + /* File position of relocation info. */ | |
24405 | + file_ptr rel_filepos; | |
24406 | + | |
24407 | + /* File position of line data. */ | |
24408 | + file_ptr line_filepos; | |
24409 | + | |
24410 | + /* Pointer to data for applications. */ | |
24411 | + void *userdata; | |
24412 | + | |
24413 | + /* If the SEC_IN_MEMORY flag is set, this points to the actual | |
24414 | + contents. */ | |
24415 | + unsigned char *contents; | |
24416 | + | |
24417 | + /* Attached line number information. */ | |
24418 | + alent *lineno; | |
24419 | + | |
24420 | + /* Number of line number records. */ | |
24421 | + unsigned int lineno_count; | |
24422 | + | |
24423 | + /* Entity size for merging purposes. */ | |
24424 | + unsigned int entsize; | |
24425 | + | |
24426 | + /* Points to the kept section if this section is a link-once section, | |
24427 | + and is discarded. */ | |
24428 | + struct bfd_section *kept_section; | |
24429 | + | |
24430 | + /* When a section is being output, this value changes as more | |
24431 | + linenumbers are written out. */ | |
24432 | + file_ptr moving_line_filepos; | |
24433 | + | |
24434 | + /* What the section number is in the target world. */ | |
24435 | + int target_index; | |
24436 | + | |
24437 | + void *used_by_bfd; | |
24438 | + | |
24439 | + /* If this is a constructor section then here is a list of the | |
24440 | + relocations created to relocate items within it. */ | |
24441 | + struct relent_chain *constructor_chain; | |
24442 | + | |
24443 | + /* The BFD which owns the section. */ | |
24444 | + bfd *owner; | |
24445 | + | |
24446 | + /* A symbol which points at this section only. */ | |
24447 | + struct bfd_symbol *symbol; | |
24448 | + struct bfd_symbol **symbol_ptr_ptr; | |
24449 | + | |
24450 | + /* Early in the link process, map_head and map_tail are used to build | |
24451 | + a list of input sections attached to an output section. Later, | |
24452 | + output sections use these fields for a list of bfd_link_order | |
24453 | + structs. */ | |
24454 | + union { | |
24455 | + struct bfd_link_order *link_order; | |
24456 | + struct bfd_section *s; | |
24457 | + } map_head, map_tail; | |
24458 | +} asection; | |
24459 | + | |
24460 | +/* These sections are global, and are managed by BFD. The application | |
24461 | + and target back end are not permitted to change the values in | |
24462 | + these sections. New code should use the section_ptr macros rather | |
24463 | + than referring directly to the const sections. The const sections | |
24464 | + may eventually vanish. */ | |
24465 | +#define BFD_ABS_SECTION_NAME "*ABS*" | |
24466 | +#define BFD_UND_SECTION_NAME "*UND*" | |
24467 | +#define BFD_COM_SECTION_NAME "*COM*" | |
24468 | +#define BFD_IND_SECTION_NAME "*IND*" | |
24469 | + | |
24470 | +/* The absolute section. */ | |
24471 | +extern asection bfd_abs_section; | |
24472 | +#define bfd_abs_section_ptr ((asection *) &bfd_abs_section) | |
24473 | +#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr) | |
24474 | +/* Pointer to the undefined section. */ | |
24475 | +extern asection bfd_und_section; | |
24476 | +#define bfd_und_section_ptr ((asection *) &bfd_und_section) | |
24477 | +#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr) | |
24478 | +/* Pointer to the common section. */ | |
24479 | +extern asection bfd_com_section; | |
24480 | +#define bfd_com_section_ptr ((asection *) &bfd_com_section) | |
24481 | +/* Pointer to the indirect section. */ | |
24482 | +extern asection bfd_ind_section; | |
24483 | +#define bfd_ind_section_ptr ((asection *) &bfd_ind_section) | |
24484 | +#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr) | |
24485 | + | |
24486 | +#define bfd_is_const_section(SEC) \ | |
24487 | + ( ((SEC) == bfd_abs_section_ptr) \ | |
24488 | + || ((SEC) == bfd_und_section_ptr) \ | |
24489 | + || ((SEC) == bfd_com_section_ptr) \ | |
24490 | + || ((SEC) == bfd_ind_section_ptr)) | |
24491 | + | |
24492 | +extern const struct bfd_symbol * const bfd_abs_symbol; | |
24493 | +extern const struct bfd_symbol * const bfd_com_symbol; | |
24494 | +extern const struct bfd_symbol * const bfd_und_symbol; | |
24495 | +extern const struct bfd_symbol * const bfd_ind_symbol; | |
24496 | + | |
24497 | +/* Macros to handle insertion and deletion of a bfd's sections. These | |
24498 | + only handle the list pointers, ie. do not adjust section_count, | |
24499 | + target_index etc. */ | |
24500 | +#define bfd_section_list_remove(ABFD, S) \ | |
24501 | + do \ | |
24502 | + { \ | |
24503 | + asection *_s = S; \ | |
24504 | + asection *_next = _s->next; \ | |
24505 | + asection *_prev = _s->prev; \ | |
24506 | + if (_prev) \ | |
24507 | + _prev->next = _next; \ | |
24508 | + else \ | |
24509 | + (ABFD)->sections = _next; \ | |
24510 | + if (_next) \ | |
24511 | + _next->prev = _prev; \ | |
24512 | + else \ | |
24513 | + (ABFD)->section_last = _prev; \ | |
24514 | + } \ | |
24515 | + while (0) | |
24516 | +#define bfd_section_list_append(ABFD, S) \ | |
24517 | + do \ | |
24518 | + { \ | |
24519 | + asection *_s = S; \ | |
24520 | + bfd *_abfd = ABFD; \ | |
24521 | + _s->next = NULL; \ | |
24522 | + if (_abfd->section_last) \ | |
24523 | + { \ | |
24524 | + _s->prev = _abfd->section_last; \ | |
24525 | + _abfd->section_last->next = _s; \ | |
24526 | + } \ | |
24527 | + else \ | |
24528 | + { \ | |
24529 | + _s->prev = NULL; \ | |
24530 | + _abfd->sections = _s; \ | |
24531 | + } \ | |
24532 | + _abfd->section_last = _s; \ | |
24533 | + } \ | |
24534 | + while (0) | |
24535 | +#define bfd_section_list_prepend(ABFD, S) \ | |
24536 | + do \ | |
24537 | + { \ | |
24538 | + asection *_s = S; \ | |
24539 | + bfd *_abfd = ABFD; \ | |
24540 | + _s->prev = NULL; \ | |
24541 | + if (_abfd->sections) \ | |
24542 | + { \ | |
24543 | + _s->next = _abfd->sections; \ | |
24544 | + _abfd->sections->prev = _s; \ | |
24545 | + } \ | |
24546 | + else \ | |
24547 | + { \ | |
24548 | + _s->next = NULL; \ | |
24549 | + _abfd->section_last = _s; \ | |
24550 | + } \ | |
24551 | + _abfd->sections = _s; \ | |
24552 | + } \ | |
24553 | + while (0) | |
24554 | +#define bfd_section_list_insert_after(ABFD, A, S) \ | |
24555 | + do \ | |
24556 | + { \ | |
24557 | + asection *_a = A; \ | |
24558 | + asection *_s = S; \ | |
24559 | + asection *_next = _a->next; \ | |
24560 | + _s->next = _next; \ | |
24561 | + _s->prev = _a; \ | |
24562 | + _a->next = _s; \ | |
24563 | + if (_next) \ | |
24564 | + _next->prev = _s; \ | |
24565 | + else \ | |
24566 | + (ABFD)->section_last = _s; \ | |
24567 | + } \ | |
24568 | + while (0) | |
24569 | +#define bfd_section_list_insert_before(ABFD, B, S) \ | |
24570 | + do \ | |
24571 | + { \ | |
24572 | + asection *_b = B; \ | |
24573 | + asection *_s = S; \ | |
24574 | + asection *_prev = _b->prev; \ | |
24575 | + _s->prev = _prev; \ | |
24576 | + _s->next = _b; \ | |
24577 | + _b->prev = _s; \ | |
24578 | + if (_prev) \ | |
24579 | + _prev->next = _s; \ | |
24580 | + else \ | |
24581 | + (ABFD)->sections = _s; \ | |
24582 | + } \ | |
24583 | + while (0) | |
24584 | +#define bfd_section_removed_from_list(ABFD, S) \ | |
24585 | + ((S)->next == NULL ? (ABFD)->section_last != (S) : (S)->next->prev != (S)) | |
24586 | + | |
24587 | +void bfd_section_list_clear (bfd *); | |
24588 | + | |
24589 | +asection *bfd_get_section_by_name (bfd *abfd, const char *name); | |
24590 | + | |
24591 | +asection *bfd_get_section_by_name_if | |
24592 | + (bfd *abfd, | |
24593 | + const char *name, | |
24594 | + bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj), | |
24595 | + void *obj); | |
24596 | + | |
24597 | +char *bfd_get_unique_section_name | |
24598 | + (bfd *abfd, const char *templat, int *count); | |
24599 | + | |
24600 | +asection *bfd_make_section_old_way (bfd *abfd, const char *name); | |
24601 | + | |
24602 | +asection *bfd_make_section_anyway_with_flags | |
24603 | + (bfd *abfd, const char *name, flagword flags); | |
24604 | + | |
24605 | +asection *bfd_make_section_anyway (bfd *abfd, const char *name); | |
24606 | + | |
24607 | +asection *bfd_make_section_with_flags | |
24608 | + (bfd *, const char *name, flagword flags); | |
24609 | + | |
24610 | +asection *bfd_make_section (bfd *, const char *name); | |
24611 | + | |
24612 | +bfd_boolean bfd_set_section_flags | |
24613 | + (bfd *abfd, asection *sec, flagword flags); | |
24614 | + | |
24615 | +void bfd_map_over_sections | |
24616 | + (bfd *abfd, | |
24617 | + void (*func) (bfd *abfd, asection *sect, void *obj), | |
24618 | + void *obj); | |
24619 | + | |
24620 | +asection *bfd_sections_find_if | |
24621 | + (bfd *abfd, | |
24622 | + bfd_boolean (*operation) (bfd *abfd, asection *sect, void *obj), | |
24623 | + void *obj); | |
24624 | + | |
24625 | +bfd_boolean bfd_set_section_size | |
24626 | + (bfd *abfd, asection *sec, bfd_size_type val); | |
24627 | + | |
24628 | +bfd_boolean bfd_set_section_contents | |
24629 | + (bfd *abfd, asection *section, const void *data, | |
24630 | + file_ptr offset, bfd_size_type count); | |
24631 | + | |
24632 | +bfd_boolean bfd_get_section_contents | |
24633 | + (bfd *abfd, asection *section, void *location, file_ptr offset, | |
24634 | + bfd_size_type count); | |
24635 | + | |
24636 | +bfd_boolean bfd_malloc_and_get_section | |
24637 | + (bfd *abfd, asection *section, bfd_byte **buf); | |
24638 | + | |
24639 | +bfd_boolean bfd_copy_private_section_data | |
24640 | + (bfd *ibfd, asection *isec, bfd *obfd, asection *osec); | |
24641 | + | |
24642 | +#define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \ | |
24643 | + BFD_SEND (obfd, _bfd_copy_private_section_data, \ | |
24644 | + (ibfd, isection, obfd, osection)) | |
24645 | +bfd_boolean bfd_generic_is_group_section (bfd *, const asection *sec); | |
24646 | + | |
24647 | +bfd_boolean bfd_generic_discard_group (bfd *abfd, asection *group); | |
24648 | + | |
24649 | +/* Extracted from archures.c. */ | |
24650 | +enum bfd_architecture | |
24651 | +{ | |
24652 | + bfd_arch_unknown, /* File arch not known. */ | |
24653 | + bfd_arch_obscure, /* Arch known, not one of these. */ | |
24654 | + bfd_arch_m68k, /* Motorola 68xxx */ | |
24655 | +#define bfd_mach_m68000 1 | |
24656 | +#define bfd_mach_m68008 2 | |
24657 | +#define bfd_mach_m68010 3 | |
24658 | +#define bfd_mach_m68020 4 | |
24659 | +#define bfd_mach_m68030 5 | |
24660 | +#define bfd_mach_m68040 6 | |
24661 | +#define bfd_mach_m68060 7 | |
24662 | +#define bfd_mach_cpu32 8 | |
24663 | +#define bfd_mach_mcf5200 9 | |
24664 | +#define bfd_mach_mcf5206e 10 | |
24665 | +#define bfd_mach_mcf5307 11 | |
24666 | +#define bfd_mach_mcf5407 12 | |
24667 | +#define bfd_mach_mcf528x 13 | |
24668 | +#define bfd_mach_mcfv4e 14 | |
24669 | +#define bfd_mach_mcf521x 15 | |
24670 | +#define bfd_mach_mcf5249 16 | |
24671 | +#define bfd_mach_mcf547x 17 | |
24672 | +#define bfd_mach_mcf548x 18 | |
24673 | + bfd_arch_vax, /* DEC Vax */ | |
24674 | + bfd_arch_i960, /* Intel 960 */ | |
24675 | + /* The order of the following is important. | |
24676 | + lower number indicates a machine type that | |
24677 | + only accepts a subset of the instructions | |
24678 | + available to machines with higher numbers. | |
24679 | + The exception is the "ca", which is | |
24680 | + incompatible with all other machines except | |
24681 | + "core". */ | |
24682 | + | |
24683 | +#define bfd_mach_i960_core 1 | |
24684 | +#define bfd_mach_i960_ka_sa 2 | |
24685 | +#define bfd_mach_i960_kb_sb 3 | |
24686 | +#define bfd_mach_i960_mc 4 | |
24687 | +#define bfd_mach_i960_xa 5 | |
24688 | +#define bfd_mach_i960_ca 6 | |
24689 | +#define bfd_mach_i960_jx 7 | |
24690 | +#define bfd_mach_i960_hx 8 | |
24691 | + | |
24692 | + bfd_arch_or32, /* OpenRISC 32 */ | |
24693 | + | |
24694 | + bfd_arch_a29k, /* AMD 29000 */ | |
24695 | + bfd_arch_sparc, /* SPARC */ | |
24696 | +#define bfd_mach_sparc 1 | |
24697 | +/* The difference between v8plus and v9 is that v9 is a true 64 bit env. */ | |
24698 | +#define bfd_mach_sparc_sparclet 2 | |
24699 | +#define bfd_mach_sparc_sparclite 3 | |
24700 | +#define bfd_mach_sparc_v8plus 4 | |
24701 | +#define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns. */ | |
24702 | +#define bfd_mach_sparc_sparclite_le 6 | |
24703 | +#define bfd_mach_sparc_v9 7 | |
24704 | +#define bfd_mach_sparc_v9a 8 /* with ultrasparc add'ns. */ | |
24705 | +#define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */ | |
24706 | +#define bfd_mach_sparc_v9b 10 /* with cheetah add'ns. */ | |
24707 | +/* Nonzero if MACH has the v9 instruction set. */ | |
24708 | +#define bfd_mach_sparc_v9_p(mach) \ | |
24709 | + ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9b \ | |
24710 | + && (mach) != bfd_mach_sparc_sparclite_le) | |
24711 | +/* Nonzero if MACH is a 64 bit sparc architecture. */ | |
24712 | +#define bfd_mach_sparc_64bit_p(mach) \ | |
24713 | + ((mach) >= bfd_mach_sparc_v9 && (mach) != bfd_mach_sparc_v8plusb) | |
24714 | + bfd_arch_mips, /* MIPS Rxxxx */ | |
24715 | +#define bfd_mach_mips3000 3000 | |
24716 | +#define bfd_mach_mips3900 3900 | |
24717 | +#define bfd_mach_mips4000 4000 | |
24718 | +#define bfd_mach_mips4010 4010 | |
24719 | +#define bfd_mach_mips4100 4100 | |
24720 | +#define bfd_mach_mips4111 4111 | |
24721 | +#define bfd_mach_mips4120 4120 | |
24722 | +#define bfd_mach_mips4300 4300 | |
24723 | +#define bfd_mach_mips4400 4400 | |
24724 | +#define bfd_mach_mips4600 4600 | |
24725 | +#define bfd_mach_mips4650 4650 | |
24726 | +#define bfd_mach_mips5000 5000 | |
24727 | +#define bfd_mach_mips5400 5400 | |
24728 | +#define bfd_mach_mips5500 5500 | |
24729 | +#define bfd_mach_mips6000 6000 | |
24730 | +#define bfd_mach_mips7000 7000 | |
24731 | +#define bfd_mach_mips8000 8000 | |
24732 | +#define bfd_mach_mips9000 9000 | |
24733 | +#define bfd_mach_mips10000 10000 | |
24734 | +#define bfd_mach_mips12000 12000 | |
24735 | +#define bfd_mach_mips16 16 | |
24736 | +#define bfd_mach_mips5 5 | |
24737 | +#define bfd_mach_mips_sb1 12310201 /* octal 'SB', 01 */ | |
24738 | +#define bfd_mach_mipsisa32 32 | |
24739 | +#define bfd_mach_mipsisa32r2 33 | |
24740 | +#define bfd_mach_mipsisa64 64 | |
24741 | +#define bfd_mach_mipsisa64r2 65 | |
24742 | + bfd_arch_i386, /* Intel 386 */ | |
24743 | +#define bfd_mach_i386_i386 1 | |
24744 | +#define bfd_mach_i386_i8086 2 | |
24745 | +#define bfd_mach_i386_i386_intel_syntax 3 | |
24746 | +#define bfd_mach_x86_64 64 | |
24747 | +#define bfd_mach_x86_64_intel_syntax 65 | |
24748 | + bfd_arch_we32k, /* AT&T WE32xxx */ | |
24749 | + bfd_arch_tahoe, /* CCI/Harris Tahoe */ | |
24750 | + bfd_arch_i860, /* Intel 860 */ | |
24751 | + bfd_arch_i370, /* IBM 360/370 Mainframes */ | |
24752 | + bfd_arch_romp, /* IBM ROMP PC/RT */ | |
24753 | + bfd_arch_alliant, /* Alliant */ | |
24754 | + bfd_arch_convex, /* Convex */ | |
24755 | + bfd_arch_m88k, /* Motorola 88xxx */ | |
24756 | + bfd_arch_m98k, /* Motorola 98xxx */ | |
24757 | + bfd_arch_pyramid, /* Pyramid Technology */ | |
24758 | + bfd_arch_h8300, /* Renesas H8/300 (formerly Hitachi H8/300) */ | |
24759 | +#define bfd_mach_h8300 1 | |
24760 | +#define bfd_mach_h8300h 2 | |
24761 | +#define bfd_mach_h8300s 3 | |
24762 | +#define bfd_mach_h8300hn 4 | |
24763 | +#define bfd_mach_h8300sn 5 | |
24764 | +#define bfd_mach_h8300sx 6 | |
24765 | +#define bfd_mach_h8300sxn 7 | |
24766 | + bfd_arch_pdp11, /* DEC PDP-11 */ | |
24767 | + bfd_arch_powerpc, /* PowerPC */ | |
24768 | +#define bfd_mach_ppc 32 | |
24769 | +#define bfd_mach_ppc64 64 | |
24770 | +#define bfd_mach_ppc_403 403 | |
24771 | +#define bfd_mach_ppc_403gc 4030 | |
24772 | +#define bfd_mach_ppc_505 505 | |
24773 | +#define bfd_mach_ppc_601 601 | |
24774 | +#define bfd_mach_ppc_602 602 | |
24775 | +#define bfd_mach_ppc_603 603 | |
24776 | +#define bfd_mach_ppc_ec603e 6031 | |
24777 | +#define bfd_mach_ppc_604 604 | |
24778 | +#define bfd_mach_ppc_620 620 | |
24779 | +#define bfd_mach_ppc_630 630 | |
24780 | +#define bfd_mach_ppc_750 750 | |
24781 | +#define bfd_mach_ppc_860 860 | |
24782 | +#define bfd_mach_ppc_a35 35 | |
24783 | +#define bfd_mach_ppc_rs64ii 642 | |
24784 | +#define bfd_mach_ppc_rs64iii 643 | |
24785 | +#define bfd_mach_ppc_7400 7400 | |
24786 | +#define bfd_mach_ppc_e500 500 | |
24787 | + bfd_arch_rs6000, /* IBM RS/6000 */ | |
24788 | +#define bfd_mach_rs6k 6000 | |
24789 | +#define bfd_mach_rs6k_rs1 6001 | |
24790 | +#define bfd_mach_rs6k_rsc 6003 | |
24791 | +#define bfd_mach_rs6k_rs2 6002 | |
24792 | + bfd_arch_hppa, /* HP PA RISC */ | |
24793 | +#define bfd_mach_hppa10 10 | |
24794 | +#define bfd_mach_hppa11 11 | |
24795 | +#define bfd_mach_hppa20 20 | |
24796 | +#define bfd_mach_hppa20w 25 | |
24797 | + bfd_arch_d10v, /* Mitsubishi D10V */ | |
24798 | +#define bfd_mach_d10v 1 | |
24799 | +#define bfd_mach_d10v_ts2 2 | |
24800 | +#define bfd_mach_d10v_ts3 3 | |
24801 | + bfd_arch_d30v, /* Mitsubishi D30V */ | |
24802 | + bfd_arch_dlx, /* DLX */ | |
24803 | + bfd_arch_m68hc11, /* Motorola 68HC11 */ | |
24804 | + bfd_arch_m68hc12, /* Motorola 68HC12 */ | |
24805 | +#define bfd_mach_m6812_default 0 | |
24806 | +#define bfd_mach_m6812 1 | |
24807 | +#define bfd_mach_m6812s 2 | |
24808 | + bfd_arch_z8k, /* Zilog Z8000 */ | |
24809 | +#define bfd_mach_z8001 1 | |
24810 | +#define bfd_mach_z8002 2 | |
24811 | + bfd_arch_h8500, /* Renesas H8/500 (formerly Hitachi H8/500) */ | |
24812 | + bfd_arch_sh, /* Renesas / SuperH SH (formerly Hitachi SH) */ | |
24813 | +#define bfd_mach_sh 1 | |
24814 | +#define bfd_mach_sh2 0x20 | |
24815 | +#define bfd_mach_sh_dsp 0x2d | |
24816 | +#define bfd_mach_sh2a 0x2a | |
24817 | +#define bfd_mach_sh2a_nofpu 0x2b | |
24818 | +#define bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu 0x2a1 | |
24819 | +#define bfd_mach_sh2a_nofpu_or_sh3_nommu 0x2a2 | |
24820 | +#define bfd_mach_sh2a_or_sh4 0x2a3 | |
24821 | +#define bfd_mach_sh2a_or_sh3e 0x2a4 | |
24822 | +#define bfd_mach_sh2e 0x2e | |
24823 | +#define bfd_mach_sh3 0x30 | |
24824 | +#define bfd_mach_sh3_nommu 0x31 | |
24825 | +#define bfd_mach_sh3_dsp 0x3d | |
24826 | +#define bfd_mach_sh3e 0x3e | |
24827 | +#define bfd_mach_sh4 0x40 | |
24828 | +#define bfd_mach_sh4_nofpu 0x41 | |
24829 | +#define bfd_mach_sh4_nommu_nofpu 0x42 | |
24830 | +#define bfd_mach_sh4a 0x4a | |
24831 | +#define bfd_mach_sh4a_nofpu 0x4b | |
24832 | +#define bfd_mach_sh4al_dsp 0x4d | |
24833 | +#define bfd_mach_sh5 0x50 | |
24834 | + bfd_arch_alpha, /* Dec Alpha */ | |
24835 | +#define bfd_mach_alpha_ev4 0x10 | |
24836 | +#define bfd_mach_alpha_ev5 0x20 | |
24837 | +#define bfd_mach_alpha_ev6 0x30 | |
24838 | + bfd_arch_arm, /* Advanced Risc Machines ARM. */ | |
24839 | +#define bfd_mach_arm_unknown 0 | |
24840 | +#define bfd_mach_arm_2 1 | |
24841 | +#define bfd_mach_arm_2a 2 | |
24842 | +#define bfd_mach_arm_3 3 | |
24843 | +#define bfd_mach_arm_3M 4 | |
24844 | +#define bfd_mach_arm_4 5 | |
24845 | +#define bfd_mach_arm_4T 6 | |
24846 | +#define bfd_mach_arm_5 7 | |
24847 | +#define bfd_mach_arm_5T 8 | |
24848 | +#define bfd_mach_arm_5TE 9 | |
24849 | +#define bfd_mach_arm_XScale 10 | |
24850 | +#define bfd_mach_arm_ep9312 11 | |
24851 | +#define bfd_mach_arm_iWMMXt 12 | |
24852 | + bfd_arch_ns32k, /* National Semiconductors ns32000 */ | |
24853 | + bfd_arch_w65, /* WDC 65816 */ | |
24854 | + bfd_arch_tic30, /* Texas Instruments TMS320C30 */ | |
24855 | + bfd_arch_tic4x, /* Texas Instruments TMS320C3X/4X */ | |
24856 | +#define bfd_mach_tic3x 30 | |
24857 | +#define bfd_mach_tic4x 40 | |
24858 | + bfd_arch_tic54x, /* Texas Instruments TMS320C54X */ | |
24859 | + bfd_arch_tic80, /* TI TMS320c80 (MVP) */ | |
24860 | + bfd_arch_v850, /* NEC V850 */ | |
24861 | +#define bfd_mach_v850 1 | |
24862 | +#define bfd_mach_v850e 'E' | |
24863 | +#define bfd_mach_v850e1 '1' | |
24864 | + bfd_arch_arc, /* ARC Cores */ | |
24865 | +#define bfd_mach_arc_5 5 | |
24866 | +#define bfd_mach_arc_6 6 | |
24867 | +#define bfd_mach_arc_7 7 | |
24868 | +#define bfd_mach_arc_8 8 | |
24869 | + bfd_arch_m32c, /* Renesas M16C/M32C. */ | |
24870 | +#define bfd_mach_m16c 0x75 | |
24871 | +#define bfd_mach_m32c 0x78 | |
24872 | + bfd_arch_m32r, /* Renesas M32R (formerly Mitsubishi M32R/D) */ | |
24873 | +#define bfd_mach_m32r 1 /* For backwards compatibility. */ | |
24874 | +#define bfd_mach_m32rx 'x' | |
24875 | +#define bfd_mach_m32r2 '2' | |
24876 | + bfd_arch_mn10200, /* Matsushita MN10200 */ | |
24877 | + bfd_arch_mn10300, /* Matsushita MN10300 */ | |
24878 | +#define bfd_mach_mn10300 300 | |
24879 | +#define bfd_mach_am33 330 | |
24880 | +#define bfd_mach_am33_2 332 | |
24881 | + bfd_arch_fr30, | |
24882 | +#define bfd_mach_fr30 0x46523330 | |
24883 | + bfd_arch_frv, | |
24884 | +#define bfd_mach_frv 1 | |
24885 | +#define bfd_mach_frvsimple 2 | |
24886 | +#define bfd_mach_fr300 300 | |
24887 | +#define bfd_mach_fr400 400 | |
24888 | +#define bfd_mach_fr450 450 | |
24889 | +#define bfd_mach_frvtomcat 499 /* fr500 prototype */ | |
24890 | +#define bfd_mach_fr500 500 | |
24891 | +#define bfd_mach_fr550 550 | |
24892 | + bfd_arch_mcore, | |
24893 | + bfd_arch_ia64, /* HP/Intel ia64 */ | |
24894 | +#define bfd_mach_ia64_elf64 64 | |
24895 | +#define bfd_mach_ia64_elf32 32 | |
24896 | + bfd_arch_ip2k, /* Ubicom IP2K microcontrollers. */ | |
24897 | +#define bfd_mach_ip2022 1 | |
24898 | +#define bfd_mach_ip2022ext 2 | |
24899 | + bfd_arch_iq2000, /* Vitesse IQ2000. */ | |
24900 | +#define bfd_mach_iq2000 1 | |
24901 | +#define bfd_mach_iq10 2 | |
24902 | + bfd_arch_ms1, | |
24903 | +#define bfd_mach_ms1 1 | |
24904 | +#define bfd_mach_mrisc2 2 | |
24905 | + bfd_arch_pj, | |
24906 | + bfd_arch_avr, /* Atmel AVR microcontrollers. */ | |
24907 | +#define bfd_mach_avr1 1 | |
24908 | +#define bfd_mach_avr2 2 | |
24909 | +#define bfd_mach_avr3 3 | |
24910 | +#define bfd_mach_avr4 4 | |
24911 | +#define bfd_mach_avr5 5 | |
24912 | + bfd_arch_cr16c, /* National Semiconductor CompactRISC. */ | |
24913 | +#define bfd_mach_cr16c 1 | |
24914 | + bfd_arch_crx, /* National Semiconductor CRX. */ | |
24915 | +#define bfd_mach_crx 1 | |
24916 | + bfd_arch_cris, /* Axis CRIS */ | |
24917 | +#define bfd_mach_cris_v0_v10 255 | |
24918 | +#define bfd_mach_cris_v32 32 | |
24919 | +#define bfd_mach_cris_v10_v32 1032 | |
24920 | + bfd_arch_s390, /* IBM s390 */ | |
24921 | +#define bfd_mach_s390_31 31 | |
24922 | +#define bfd_mach_s390_64 64 | |
24923 | + bfd_arch_openrisc, /* OpenRISC */ | |
24924 | + bfd_arch_mmix, /* Donald Knuth's educational processor. */ | |
24925 | + bfd_arch_xstormy16, | |
24926 | +#define bfd_mach_xstormy16 1 | |
24927 | + bfd_arch_msp430, /* Texas Instruments MSP430 architecture. */ | |
24928 | +#define bfd_mach_msp11 11 | |
24929 | +#define bfd_mach_msp110 110 | |
24930 | +#define bfd_mach_msp12 12 | |
24931 | +#define bfd_mach_msp13 13 | |
24932 | +#define bfd_mach_msp14 14 | |
24933 | +#define bfd_mach_msp15 15 | |
24934 | +#define bfd_mach_msp16 16 | |
24935 | +#define bfd_mach_msp31 31 | |
24936 | +#define bfd_mach_msp32 32 | |
24937 | +#define bfd_mach_msp33 33 | |
24938 | +#define bfd_mach_msp41 41 | |
24939 | +#define bfd_mach_msp42 42 | |
24940 | +#define bfd_mach_msp43 43 | |
24941 | +#define bfd_mach_msp44 44 | |
24942 | + bfd_arch_xtensa, /* Tensilica's Xtensa cores. */ | |
24943 | +#define bfd_mach_xtensa 1 | |
24944 | + bfd_arch_maxq, /* Dallas MAXQ 10/20 */ | |
24945 | +#define bfd_mach_maxq10 10 | |
24946 | +#define bfd_mach_maxq20 20 | |
24947 | + bfd_arch_last | |
24948 | + }; | |
24949 | + | |
24950 | +typedef struct bfd_arch_info | |
24951 | +{ | |
24952 | + int bits_per_word; | |
24953 | + int bits_per_address; | |
24954 | + int bits_per_byte; | |
24955 | + enum bfd_architecture arch; | |
24956 | + unsigned long mach; | |
24957 | + const char *arch_name; | |
24958 | + const char *printable_name; | |
24959 | + unsigned int section_align_power; | |
24960 | + /* TRUE if this is the default machine for the architecture. | |
24961 | + The default arch should be the first entry for an arch so that | |
24962 | + all the entries for that arch can be accessed via <<next>>. */ | |
24963 | + bfd_boolean the_default; | |
24964 | + const struct bfd_arch_info * (*compatible) | |
24965 | + (const struct bfd_arch_info *a, const struct bfd_arch_info *b); | |
24966 | + | |
24967 | + bfd_boolean (*scan) (const struct bfd_arch_info *, const char *); | |
24968 | + | |
24969 | + const struct bfd_arch_info *next; | |
24970 | +} | |
24971 | +bfd_arch_info_type; | |
24972 | + | |
24973 | +const char *bfd_printable_name (bfd *abfd); | |
24974 | + | |
24975 | +const bfd_arch_info_type *bfd_scan_arch (const char *string); | |
24976 | + | |
24977 | +const char **bfd_arch_list (void); | |
24978 | + | |
24979 | +const bfd_arch_info_type *bfd_arch_get_compatible | |
24980 | + (const bfd *abfd, const bfd *bbfd, bfd_boolean accept_unknowns); | |
24981 | + | |
24982 | +void bfd_set_arch_info (bfd *abfd, const bfd_arch_info_type *arg); | |
24983 | + | |
24984 | +enum bfd_architecture bfd_get_arch (bfd *abfd); | |
24985 | + | |
24986 | +unsigned long bfd_get_mach (bfd *abfd); | |
24987 | + | |
24988 | +unsigned int bfd_arch_bits_per_byte (bfd *abfd); | |
24989 | + | |
24990 | +unsigned int bfd_arch_bits_per_address (bfd *abfd); | |
24991 | + | |
24992 | +const bfd_arch_info_type *bfd_get_arch_info (bfd *abfd); | |
24993 | + | |
24994 | +const bfd_arch_info_type *bfd_lookup_arch | |
24995 | + (enum bfd_architecture arch, unsigned long machine); | |
24996 | + | |
24997 | +const char *bfd_printable_arch_mach | |
24998 | + (enum bfd_architecture arch, unsigned long machine); | |
24999 | + | |
25000 | +unsigned int bfd_octets_per_byte (bfd *abfd); | |
25001 | + | |
25002 | +unsigned int bfd_arch_mach_octets_per_byte | |
25003 | + (enum bfd_architecture arch, unsigned long machine); | |
25004 | + | |
25005 | +/* Extracted from reloc.c. */ | |
25006 | +typedef enum bfd_reloc_status | |
25007 | +{ | |
25008 | + /* No errors detected. */ | |
25009 | + bfd_reloc_ok, | |
25010 | + | |
25011 | + /* The relocation was performed, but there was an overflow. */ | |
25012 | + bfd_reloc_overflow, | |
25013 | + | |
25014 | + /* The address to relocate was not within the section supplied. */ | |
25015 | + bfd_reloc_outofrange, | |
25016 | + | |
25017 | + /* Used by special functions. */ | |
25018 | + bfd_reloc_continue, | |
25019 | + | |
25020 | + /* Unsupported relocation size requested. */ | |
25021 | + bfd_reloc_notsupported, | |
25022 | + | |
25023 | + /* Unused. */ | |
25024 | + bfd_reloc_other, | |
25025 | + | |
25026 | + /* The symbol to relocate against was undefined. */ | |
25027 | + bfd_reloc_undefined, | |
25028 | + | |
25029 | + /* The relocation was performed, but may not be ok - presently | |
25030 | + generated only when linking i960 coff files with i960 b.out | |
25031 | + symbols. If this type is returned, the error_message argument | |
25032 | + to bfd_perform_relocation will be set. */ | |
25033 | + bfd_reloc_dangerous | |
25034 | + } | |
25035 | + bfd_reloc_status_type; | |
25036 | + | |
25037 | + | |
25038 | +typedef struct reloc_cache_entry | |
25039 | +{ | |
25040 | + /* A pointer into the canonical table of pointers. */ | |
25041 | + struct bfd_symbol **sym_ptr_ptr; | |
25042 | + | |
25043 | + /* offset in section. */ | |
25044 | + bfd_size_type address; | |
25045 | + | |
25046 | + /* addend for relocation value. */ | |
25047 | + bfd_vma addend; | |
25048 | + | |
25049 | + /* Pointer to how to perform the required relocation. */ | |
25050 | + reloc_howto_type *howto; | |
25051 | + | |
25052 | +} | |
25053 | +arelent; | |
25054 | + | |
25055 | +enum complain_overflow | |
25056 | +{ | |
25057 | + /* Do not complain on overflow. */ | |
25058 | + complain_overflow_dont, | |
25059 | + | |
25060 | + /* Complain if the bitfield overflows, whether it is considered | |
25061 | + as signed or unsigned. */ | |
25062 | + complain_overflow_bitfield, | |
25063 | + | |
25064 | + /* Complain if the value overflows when considered as signed | |
25065 | + number. */ | |
25066 | + complain_overflow_signed, | |
25067 | + | |
25068 | + /* Complain if the value overflows when considered as an | |
25069 | + unsigned number. */ | |
25070 | + complain_overflow_unsigned | |
25071 | +}; | |
25072 | + | |
25073 | +struct reloc_howto_struct | |
25074 | +{ | |
25075 | + /* The type field has mainly a documentary use - the back end can | |
25076 | + do what it wants with it, though normally the back end's | |
25077 | + external idea of what a reloc number is stored | |
25078 | + in this field. For example, a PC relative word relocation | |
25079 | + in a coff environment has the type 023 - because that's | |
25080 | + what the outside world calls a R_PCRWORD reloc. */ | |
25081 | + unsigned int type; | |
25082 | + | |
25083 | + /* The value the final relocation is shifted right by. This drops | |
25084 | + unwanted data from the relocation. */ | |
25085 | + unsigned int rightshift; | |
25086 | + | |
25087 | + /* The size of the item to be relocated. This is *not* a | |
25088 | + power-of-two measure. To get the number of bytes operated | |
25089 | + on by a type of relocation, use bfd_get_reloc_size. */ | |
25090 | + int size; | |
25091 | + | |
25092 | + /* The number of bits in the item to be relocated. This is used | |
25093 | + when doing overflow checking. */ | |
25094 | + unsigned int bitsize; | |
25095 | + | |
25096 | + /* Notes that the relocation is relative to the location in the | |
25097 | + data section of the addend. The relocation function will | |
25098 | + subtract from the relocation value the address of the location | |
25099 | + being relocated. */ | |
25100 | + bfd_boolean pc_relative; | |
25101 | + | |
25102 | + /* The bit position of the reloc value in the destination. | |
25103 | + The relocated value is left shifted by this amount. */ | |
25104 | + unsigned int bitpos; | |
25105 | + | |
25106 | + /* What type of overflow error should be checked for when | |
25107 | + relocating. */ | |
25108 | + enum complain_overflow complain_on_overflow; | |
25109 | + | |
25110 | + /* If this field is non null, then the supplied function is | |
25111 | + called rather than the normal function. This allows really | |
25112 | + strange relocation methods to be accommodated (e.g., i960 callj | |
25113 | + instructions). */ | |
25114 | + bfd_reloc_status_type (*special_function) | |
25115 | + (bfd *, arelent *, struct bfd_symbol *, void *, asection *, | |
25116 | + bfd *, char **); | |
25117 | + | |
25118 | + /* The textual name of the relocation type. */ | |
25119 | + char *name; | |
25120 | + | |
25121 | + /* Some formats record a relocation addend in the section contents | |
25122 | + rather than with the relocation. For ELF formats this is the | |
25123 | + distinction between USE_REL and USE_RELA (though the code checks | |
25124 | + for USE_REL == 1/0). The value of this field is TRUE if the | |
25125 | + addend is recorded with the section contents; when performing a | |
25126 | + partial link (ld -r) the section contents (the data) will be | |
25127 | + modified. The value of this field is FALSE if addends are | |
25128 | + recorded with the relocation (in arelent.addend); when performing | |
25129 | + a partial link the relocation will be modified. | |
25130 | + All relocations for all ELF USE_RELA targets should set this field | |
25131 | + to FALSE (values of TRUE should be looked on with suspicion). | |
25132 | + However, the converse is not true: not all relocations of all ELF | |
25133 | + USE_REL targets set this field to TRUE. Why this is so is peculiar | |
25134 | + to each particular target. For relocs that aren't used in partial | |
25135 | + links (e.g. GOT stuff) it doesn't matter what this is set to. */ | |
25136 | + bfd_boolean partial_inplace; | |
25137 | + | |
25138 | + /* src_mask selects the part of the instruction (or data) to be used | |
25139 | + in the relocation sum. If the target relocations don't have an | |
25140 | + addend in the reloc, eg. ELF USE_REL, src_mask will normally equal | |
25141 | + dst_mask to extract the addend from the section contents. If | |
25142 | + relocations do have an addend in the reloc, eg. ELF USE_RELA, this | |
25143 | + field should be zero. Non-zero values for ELF USE_RELA targets are | |
25144 | + bogus as in those cases the value in the dst_mask part of the | |
25145 | + section contents should be treated as garbage. */ | |
25146 | + bfd_vma src_mask; | |
25147 | + | |
25148 | + /* dst_mask selects which parts of the instruction (or data) are | |
25149 | + replaced with a relocated value. */ | |
25150 | + bfd_vma dst_mask; | |
25151 | + | |
25152 | + /* When some formats create PC relative instructions, they leave | |
25153 | + the value of the pc of the place being relocated in the offset | |
25154 | + slot of the instruction, so that a PC relative relocation can | |
25155 | + be made just by adding in an ordinary offset (e.g., sun3 a.out). | |
25156 | + Some formats leave the displacement part of an instruction | |
25157 | + empty (e.g., m88k bcs); this flag signals the fact. */ | |
25158 | + bfd_boolean pcrel_offset; | |
25159 | +}; | |
25160 | + | |
25161 | +#define HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \ | |
25162 | + { (unsigned) C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC } | |
25163 | +#define NEWHOWTO(FUNCTION, NAME, SIZE, REL, IN) \ | |
25164 | + HOWTO (0, 0, SIZE, 0, REL, 0, complain_overflow_dont, FUNCTION, \ | |
25165 | + NAME, FALSE, 0, 0, IN) | |
25166 | + | |
25167 | +#define EMPTY_HOWTO(C) \ | |
25168 | + HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \ | |
25169 | + NULL, FALSE, 0, 0, FALSE) | |
25170 | + | |
25171 | +#define HOWTO_PREPARE(relocation, symbol) \ | |
25172 | + { \ | |
25173 | + if (symbol != NULL) \ | |
25174 | + { \ | |
25175 | + if (bfd_is_com_section (symbol->section)) \ | |
25176 | + { \ | |
25177 | + relocation = 0; \ | |
25178 | + } \ | |
25179 | + else \ | |
25180 | + { \ | |
25181 | + relocation = symbol->value; \ | |
25182 | + } \ | |
25183 | + } \ | |
25184 | + } | |
25185 | + | |
25186 | +unsigned int bfd_get_reloc_size (reloc_howto_type *); | |
25187 | + | |
25188 | +typedef struct relent_chain | |
25189 | +{ | |
25190 | + arelent relent; | |
25191 | + struct relent_chain *next; | |
25192 | +} | |
25193 | +arelent_chain; | |
25194 | + | |
25195 | +bfd_reloc_status_type bfd_check_overflow | |
25196 | + (enum complain_overflow how, | |
25197 | + unsigned int bitsize, | |
25198 | + unsigned int rightshift, | |
25199 | + unsigned int addrsize, | |
25200 | + bfd_vma relocation); | |
25201 | + | |
25202 | +bfd_reloc_status_type bfd_perform_relocation | |
25203 | + (bfd *abfd, | |
25204 | + arelent *reloc_entry, | |
25205 | + void *data, | |
25206 | + asection *input_section, | |
25207 | + bfd *output_bfd, | |
25208 | + char **error_message); | |
25209 | + | |
25210 | +bfd_reloc_status_type bfd_install_relocation | |
25211 | + (bfd *abfd, | |
25212 | + arelent *reloc_entry, | |
25213 | + void *data, bfd_vma data_start, | |
25214 | + asection *input_section, | |
25215 | + char **error_message); | |
25216 | + | |
25217 | +enum bfd_reloc_code_real { | |
25218 | + _dummy_first_bfd_reloc_code_real, | |
25219 | + | |
25220 | + | |
25221 | +/* Basic absolute relocations of N bits. */ | |
25222 | + BFD_RELOC_64, | |
25223 | + BFD_RELOC_32, | |
25224 | + BFD_RELOC_26, | |
25225 | + BFD_RELOC_24, | |
25226 | + BFD_RELOC_16, | |
25227 | + BFD_RELOC_14, | |
25228 | + BFD_RELOC_8, | |
25229 | + | |
25230 | +/* PC-relative relocations. Sometimes these are relative to the address | |
25231 | +of the relocation itself; sometimes they are relative to the start of | |
25232 | +the section containing the relocation. It depends on the specific target. | |
25233 | + | |
25234 | +The 24-bit relocation is used in some Intel 960 configurations. */ | |
25235 | + BFD_RELOC_64_PCREL, | |
25236 | + BFD_RELOC_32_PCREL, | |
25237 | + BFD_RELOC_24_PCREL, | |
25238 | + BFD_RELOC_16_PCREL, | |
25239 | + BFD_RELOC_12_PCREL, | |
25240 | + BFD_RELOC_8_PCREL, | |
25241 | + | |
25242 | +/* Section relative relocations. Some targets need this for DWARF2. */ | |
25243 | + BFD_RELOC_32_SECREL, | |
25244 | + | |
25245 | +/* For ELF. */ | |
25246 | + BFD_RELOC_32_GOT_PCREL, | |
25247 | + BFD_RELOC_16_GOT_PCREL, | |
25248 | + BFD_RELOC_8_GOT_PCREL, | |
25249 | + BFD_RELOC_32_GOTOFF, | |
25250 | + BFD_RELOC_16_GOTOFF, | |
25251 | + BFD_RELOC_LO16_GOTOFF, | |
25252 | + BFD_RELOC_HI16_GOTOFF, | |
25253 | + BFD_RELOC_HI16_S_GOTOFF, | |
25254 | + BFD_RELOC_8_GOTOFF, | |
25255 | + BFD_RELOC_64_PLT_PCREL, | |
25256 | + BFD_RELOC_32_PLT_PCREL, | |
25257 | + BFD_RELOC_24_PLT_PCREL, | |
25258 | + BFD_RELOC_16_PLT_PCREL, | |
25259 | + BFD_RELOC_8_PLT_PCREL, | |
25260 | + BFD_RELOC_64_PLTOFF, | |
25261 | + BFD_RELOC_32_PLTOFF, | |
25262 | + BFD_RELOC_16_PLTOFF, | |
25263 | + BFD_RELOC_LO16_PLTOFF, | |
25264 | + BFD_RELOC_HI16_PLTOFF, | |
25265 | + BFD_RELOC_HI16_S_PLTOFF, | |
25266 | + BFD_RELOC_8_PLTOFF, | |
25267 | + | |
25268 | +/* Relocations used by 68K ELF. */ | |
25269 | + BFD_RELOC_68K_GLOB_DAT, | |
25270 | + BFD_RELOC_68K_JMP_SLOT, | |
25271 | + BFD_RELOC_68K_RELATIVE, | |
25272 | + | |
25273 | +/* Linkage-table relative. */ | |
25274 | + BFD_RELOC_32_BASEREL, | |
25275 | + BFD_RELOC_16_BASEREL, | |
25276 | + BFD_RELOC_LO16_BASEREL, | |
25277 | + BFD_RELOC_HI16_BASEREL, | |
25278 | + BFD_RELOC_HI16_S_BASEREL, | |
25279 | + BFD_RELOC_8_BASEREL, | |
25280 | + BFD_RELOC_RVA, | |
25281 | + | |
25282 | +/* Absolute 8-bit relocation, but used to form an address like 0xFFnn. */ | |
25283 | + BFD_RELOC_8_FFnn, | |
25284 | + | |
25285 | +/* These PC-relative relocations are stored as word displacements -- | |
25286 | +i.e., byte displacements shifted right two bits. The 30-bit word | |
25287 | +displacement (<<32_PCREL_S2>> -- 32 bits, shifted 2) is used on the | |
25288 | +SPARC. (SPARC tools generally refer to this as <<WDISP30>>.) The | |
25289 | +signed 16-bit displacement is used on the MIPS, and the 23-bit | |
25290 | +displacement is used on the Alpha. */ | |
25291 | + BFD_RELOC_32_PCREL_S2, | |
25292 | + BFD_RELOC_16_PCREL_S2, | |
25293 | + BFD_RELOC_23_PCREL_S2, | |
25294 | + | |
25295 | +/* High 22 bits and low 10 bits of 32-bit value, placed into lower bits of | |
25296 | +the target word. These are used on the SPARC. */ | |
25297 | + BFD_RELOC_HI22, | |
25298 | + BFD_RELOC_LO10, | |
25299 | + | |
25300 | +/* For systems that allocate a Global Pointer register, these are | |
25301 | +displacements off that register. These relocation types are | |
25302 | +handled specially, because the value the register will have is | |
25303 | +decided relatively late. */ | |
25304 | + BFD_RELOC_GPREL16, | |
25305 | + BFD_RELOC_GPREL32, | |
25306 | + | |
25307 | +/* Reloc types used for i960/b.out. */ | |
25308 | + BFD_RELOC_I960_CALLJ, | |
25309 | + | |
25310 | +/* SPARC ELF relocations. There is probably some overlap with other | |
25311 | +relocation types already defined. */ | |
25312 | + BFD_RELOC_NONE, | |
25313 | + BFD_RELOC_SPARC_WDISP22, | |
25314 | + BFD_RELOC_SPARC22, | |
25315 | + BFD_RELOC_SPARC13, | |
25316 | + BFD_RELOC_SPARC_GOT10, | |
25317 | + BFD_RELOC_SPARC_GOT13, | |
25318 | + BFD_RELOC_SPARC_GOT22, | |
25319 | + BFD_RELOC_SPARC_PC10, | |
25320 | + BFD_RELOC_SPARC_PC22, | |
25321 | + BFD_RELOC_SPARC_WPLT30, | |
25322 | + BFD_RELOC_SPARC_COPY, | |
25323 | + BFD_RELOC_SPARC_GLOB_DAT, | |
25324 | + BFD_RELOC_SPARC_JMP_SLOT, | |
25325 | + BFD_RELOC_SPARC_RELATIVE, | |
25326 | + BFD_RELOC_SPARC_UA16, | |
25327 | + BFD_RELOC_SPARC_UA32, | |
25328 | + BFD_RELOC_SPARC_UA64, | |
25329 | + | |
25330 | +/* I think these are specific to SPARC a.out (e.g., Sun 4). */ | |
25331 | + BFD_RELOC_SPARC_BASE13, | |
25332 | + BFD_RELOC_SPARC_BASE22, | |
25333 | + | |
25334 | +/* SPARC64 relocations */ | |
25335 | +#define BFD_RELOC_SPARC_64 BFD_RELOC_64 | |
25336 | + BFD_RELOC_SPARC_10, | |
25337 | + BFD_RELOC_SPARC_11, | |
25338 | + BFD_RELOC_SPARC_OLO10, | |
25339 | + BFD_RELOC_SPARC_HH22, | |
25340 | + BFD_RELOC_SPARC_HM10, | |
25341 | + BFD_RELOC_SPARC_LM22, | |
25342 | + BFD_RELOC_SPARC_PC_HH22, | |
25343 | + BFD_RELOC_SPARC_PC_HM10, | |
25344 | + BFD_RELOC_SPARC_PC_LM22, | |
25345 | + BFD_RELOC_SPARC_WDISP16, | |
25346 | + BFD_RELOC_SPARC_WDISP19, | |
25347 | + BFD_RELOC_SPARC_7, | |
25348 | + BFD_RELOC_SPARC_6, | |
25349 | + BFD_RELOC_SPARC_5, | |
25350 | +#define BFD_RELOC_SPARC_DISP64 BFD_RELOC_64_PCREL | |
25351 | + BFD_RELOC_SPARC_PLT32, | |
25352 | + BFD_RELOC_SPARC_PLT64, | |
25353 | + BFD_RELOC_SPARC_HIX22, | |
25354 | + BFD_RELOC_SPARC_LOX10, | |
25355 | + BFD_RELOC_SPARC_H44, | |
25356 | + BFD_RELOC_SPARC_M44, | |
25357 | + BFD_RELOC_SPARC_L44, | |
25358 | + BFD_RELOC_SPARC_REGISTER, | |
25359 | + | |
25360 | +/* SPARC little endian relocation */ | |
25361 | + BFD_RELOC_SPARC_REV32, | |
25362 | + | |
25363 | +/* SPARC TLS relocations */ | |
25364 | + BFD_RELOC_SPARC_TLS_GD_HI22, | |
25365 | + BFD_RELOC_SPARC_TLS_GD_LO10, | |
25366 | + BFD_RELOC_SPARC_TLS_GD_ADD, | |
25367 | + BFD_RELOC_SPARC_TLS_GD_CALL, | |
25368 | + BFD_RELOC_SPARC_TLS_LDM_HI22, | |
25369 | + BFD_RELOC_SPARC_TLS_LDM_LO10, | |
25370 | + BFD_RELOC_SPARC_TLS_LDM_ADD, | |
25371 | + BFD_RELOC_SPARC_TLS_LDM_CALL, | |
25372 | + BFD_RELOC_SPARC_TLS_LDO_HIX22, | |
25373 | + BFD_RELOC_SPARC_TLS_LDO_LOX10, | |
25374 | + BFD_RELOC_SPARC_TLS_LDO_ADD, | |
25375 | + BFD_RELOC_SPARC_TLS_IE_HI22, | |
25376 | + BFD_RELOC_SPARC_TLS_IE_LO10, | |
25377 | + BFD_RELOC_SPARC_TLS_IE_LD, | |
25378 | + BFD_RELOC_SPARC_TLS_IE_LDX, | |
25379 | + BFD_RELOC_SPARC_TLS_IE_ADD, | |
25380 | + BFD_RELOC_SPARC_TLS_LE_HIX22, | |
25381 | + BFD_RELOC_SPARC_TLS_LE_LOX10, | |
25382 | + BFD_RELOC_SPARC_TLS_DTPMOD32, | |
25383 | + BFD_RELOC_SPARC_TLS_DTPMOD64, | |
25384 | + BFD_RELOC_SPARC_TLS_DTPOFF32, | |
25385 | + BFD_RELOC_SPARC_TLS_DTPOFF64, | |
25386 | + BFD_RELOC_SPARC_TLS_TPOFF32, | |
25387 | + BFD_RELOC_SPARC_TLS_TPOFF64, | |
25388 | + | |
25389 | +/* Alpha ECOFF and ELF relocations. Some of these treat the symbol or | |
25390 | +"addend" in some special way. | |
25391 | +For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when | |
25392 | +writing; when reading, it will be the absolute section symbol. The | |
25393 | +addend is the displacement in bytes of the "lda" instruction from | |
25394 | +the "ldah" instruction (which is at the address of this reloc). */ | |
25395 | + BFD_RELOC_ALPHA_GPDISP_HI16, | |
25396 | + | |
25397 | +/* For GPDISP_LO16 ("ignore") relocations, the symbol is handled as | |
25398 | +with GPDISP_HI16 relocs. The addend is ignored when writing the | |
25399 | +relocations out, and is filled in with the file's GP value on | |
25400 | +reading, for convenience. */ | |
25401 | + BFD_RELOC_ALPHA_GPDISP_LO16, | |
25402 | + | |
25403 | +/* The ELF GPDISP relocation is exactly the same as the GPDISP_HI16 | |
25404 | +relocation except that there is no accompanying GPDISP_LO16 | |
25405 | +relocation. */ | |
25406 | + BFD_RELOC_ALPHA_GPDISP, | |
25407 | + | |
25408 | +/* The Alpha LITERAL/LITUSE relocs are produced by a symbol reference; | |
25409 | +the assembler turns it into a LDQ instruction to load the address of | |
25410 | +the symbol, and then fills in a register in the real instruction. | |
25411 | + | |
25412 | +The LITERAL reloc, at the LDQ instruction, refers to the .lita | |
25413 | +section symbol. The addend is ignored when writing, but is filled | |
25414 | +in with the file's GP value on reading, for convenience, as with the | |
25415 | +GPDISP_LO16 reloc. | |
25416 | + | |
25417 | +The ELF_LITERAL reloc is somewhere between 16_GOTOFF and GPDISP_LO16. | |
25418 | +It should refer to the symbol to be referenced, as with 16_GOTOFF, | |
25419 | +but it generates output not based on the position within the .got | |
25420 | +section, but relative to the GP value chosen for the file during the | |
25421 | +final link stage. | |
25422 | + | |
25423 | +The LITUSE reloc, on the instruction using the loaded address, gives | |
25424 | +information to the linker that it might be able to use to optimize | |
25425 | +away some literal section references. The symbol is ignored (read | |
25426 | +as the absolute section symbol), and the "addend" indicates the type | |
25427 | +of instruction using the register: | |
25428 | +1 - "memory" fmt insn | |
25429 | +2 - byte-manipulation (byte offset reg) | |
25430 | +3 - jsr (target of branch) */ | |
25431 | + BFD_RELOC_ALPHA_LITERAL, | |
25432 | + BFD_RELOC_ALPHA_ELF_LITERAL, | |
25433 | + BFD_RELOC_ALPHA_LITUSE, | |
25434 | + | |
25435 | +/* The HINT relocation indicates a value that should be filled into the | |
25436 | +"hint" field of a jmp/jsr/ret instruction, for possible branch- | |
25437 | +prediction logic which may be provided on some processors. */ | |
25438 | + BFD_RELOC_ALPHA_HINT, | |
25439 | + | |
25440 | +/* The LINKAGE relocation outputs a linkage pair in the object file, | |
25441 | +which is filled by the linker. */ | |
25442 | + BFD_RELOC_ALPHA_LINKAGE, | |
25443 | + | |
25444 | +/* The CODEADDR relocation outputs a STO_CA in the object file, | |
25445 | +which is filled by the linker. */ | |
25446 | + BFD_RELOC_ALPHA_CODEADDR, | |
25447 | + | |
25448 | +/* The GPREL_HI/LO relocations together form a 32-bit offset from the | |
25449 | +GP register. */ | |
25450 | + BFD_RELOC_ALPHA_GPREL_HI16, | |
25451 | + BFD_RELOC_ALPHA_GPREL_LO16, | |
25452 | + | |
25453 | +/* Like BFD_RELOC_23_PCREL_S2, except that the source and target must | |
25454 | +share a common GP, and the target address is adjusted for | |
25455 | +STO_ALPHA_STD_GPLOAD. */ | |
25456 | + BFD_RELOC_ALPHA_BRSGP, | |
25457 | + | |
25458 | +/* Alpha thread-local storage relocations. */ | |
25459 | + BFD_RELOC_ALPHA_TLSGD, | |
25460 | + BFD_RELOC_ALPHA_TLSLDM, | |
25461 | + BFD_RELOC_ALPHA_DTPMOD64, | |
25462 | + BFD_RELOC_ALPHA_GOTDTPREL16, | |
25463 | + BFD_RELOC_ALPHA_DTPREL64, | |
25464 | + BFD_RELOC_ALPHA_DTPREL_HI16, | |
25465 | + BFD_RELOC_ALPHA_DTPREL_LO16, | |
25466 | + BFD_RELOC_ALPHA_DTPREL16, | |
25467 | + BFD_RELOC_ALPHA_GOTTPREL16, | |
25468 | + BFD_RELOC_ALPHA_TPREL64, | |
25469 | + BFD_RELOC_ALPHA_TPREL_HI16, | |
25470 | + BFD_RELOC_ALPHA_TPREL_LO16, | |
25471 | + BFD_RELOC_ALPHA_TPREL16, | |
25472 | + | |
25473 | +/* Bits 27..2 of the relocation address shifted right 2 bits; | |
25474 | +simple reloc otherwise. */ | |
25475 | + BFD_RELOC_MIPS_JMP, | |
25476 | + | |
25477 | +/* The MIPS16 jump instruction. */ | |
25478 | + BFD_RELOC_MIPS16_JMP, | |
25479 | + | |
25480 | +/* MIPS16 GP relative reloc. */ | |
25481 | + BFD_RELOC_MIPS16_GPREL, | |
25482 | + | |
25483 | +/* High 16 bits of 32-bit value; simple reloc. */ | |
25484 | + BFD_RELOC_HI16, | |
25485 | + | |
25486 | +/* High 16 bits of 32-bit value but the low 16 bits will be sign | |
25487 | +extended and added to form the final result. If the low 16 | |
25488 | +bits form a negative number, we need to add one to the high value | |
25489 | +to compensate for the borrow when the low bits are added. */ | |
25490 | + BFD_RELOC_HI16_S, | |
25491 | + | |
25492 | +/* Low 16 bits. */ | |
25493 | + BFD_RELOC_LO16, | |
25494 | + | |
25495 | +/* High 16 bits of 32-bit pc-relative value */ | |
25496 | + BFD_RELOC_HI16_PCREL, | |
25497 | + | |
25498 | +/* High 16 bits of 32-bit pc-relative value, adjusted */ | |
25499 | + BFD_RELOC_HI16_S_PCREL, | |
25500 | + | |
25501 | +/* Low 16 bits of pc-relative value */ | |
25502 | + BFD_RELOC_LO16_PCREL, | |
25503 | + | |
25504 | +/* MIPS16 high 16 bits of 32-bit value. */ | |
25505 | + BFD_RELOC_MIPS16_HI16, | |
25506 | + | |
25507 | +/* MIPS16 high 16 bits of 32-bit value but the low 16 bits will be sign | |
25508 | +extended and added to form the final result. If the low 16 | |
25509 | +bits form a negative number, we need to add one to the high value | |
25510 | +to compensate for the borrow when the low bits are added. */ | |
25511 | + BFD_RELOC_MIPS16_HI16_S, | |
25512 | + | |
25513 | +/* MIPS16 low 16 bits. */ | |
25514 | + BFD_RELOC_MIPS16_LO16, | |
25515 | + | |
25516 | +/* Relocation against a MIPS literal section. */ | |
25517 | + BFD_RELOC_MIPS_LITERAL, | |
25518 | + | |
25519 | +/* MIPS ELF relocations. */ | |
25520 | + BFD_RELOC_MIPS_GOT16, | |
25521 | + BFD_RELOC_MIPS_CALL16, | |
25522 | + BFD_RELOC_MIPS_GOT_HI16, | |
25523 | + BFD_RELOC_MIPS_GOT_LO16, | |
25524 | + BFD_RELOC_MIPS_CALL_HI16, | |
25525 | + BFD_RELOC_MIPS_CALL_LO16, | |
25526 | + BFD_RELOC_MIPS_SUB, | |
25527 | + BFD_RELOC_MIPS_GOT_PAGE, | |
25528 | + BFD_RELOC_MIPS_GOT_OFST, | |
25529 | + BFD_RELOC_MIPS_GOT_DISP, | |
25530 | + BFD_RELOC_MIPS_SHIFT5, | |
25531 | + BFD_RELOC_MIPS_SHIFT6, | |
25532 | + BFD_RELOC_MIPS_INSERT_A, | |
25533 | + BFD_RELOC_MIPS_INSERT_B, | |
25534 | + BFD_RELOC_MIPS_DELETE, | |
25535 | + BFD_RELOC_MIPS_HIGHEST, | |
25536 | + BFD_RELOC_MIPS_HIGHER, | |
25537 | + BFD_RELOC_MIPS_SCN_DISP, | |
25538 | + BFD_RELOC_MIPS_REL16, | |
25539 | + BFD_RELOC_MIPS_RELGOT, | |
25540 | + BFD_RELOC_MIPS_JALR, | |
25541 | + BFD_RELOC_MIPS_TLS_DTPMOD32, | |
25542 | + BFD_RELOC_MIPS_TLS_DTPREL32, | |
25543 | + BFD_RELOC_MIPS_TLS_DTPMOD64, | |
25544 | + BFD_RELOC_MIPS_TLS_DTPREL64, | |
25545 | + BFD_RELOC_MIPS_TLS_GD, | |
25546 | + BFD_RELOC_MIPS_TLS_LDM, | |
25547 | + BFD_RELOC_MIPS_TLS_DTPREL_HI16, | |
25548 | + BFD_RELOC_MIPS_TLS_DTPREL_LO16, | |
25549 | + BFD_RELOC_MIPS_TLS_GOTTPREL, | |
25550 | + BFD_RELOC_MIPS_TLS_TPREL32, | |
25551 | + BFD_RELOC_MIPS_TLS_TPREL64, | |
25552 | + BFD_RELOC_MIPS_TLS_TPREL_HI16, | |
25553 | + BFD_RELOC_MIPS_TLS_TPREL_LO16, | |
25554 | + | |
25555 | + | |
25556 | +/* Fujitsu Frv Relocations. */ | |
25557 | + BFD_RELOC_FRV_LABEL16, | |
25558 | + BFD_RELOC_FRV_LABEL24, | |
25559 | + BFD_RELOC_FRV_LO16, | |
25560 | + BFD_RELOC_FRV_HI16, | |
25561 | + BFD_RELOC_FRV_GPREL12, | |
25562 | + BFD_RELOC_FRV_GPRELU12, | |
25563 | + BFD_RELOC_FRV_GPREL32, | |
25564 | + BFD_RELOC_FRV_GPRELHI, | |
25565 | + BFD_RELOC_FRV_GPRELLO, | |
25566 | + BFD_RELOC_FRV_GOT12, | |
25567 | + BFD_RELOC_FRV_GOTHI, | |
25568 | + BFD_RELOC_FRV_GOTLO, | |
25569 | + BFD_RELOC_FRV_FUNCDESC, | |
25570 | + BFD_RELOC_FRV_FUNCDESC_GOT12, | |
25571 | + BFD_RELOC_FRV_FUNCDESC_GOTHI, | |
25572 | + BFD_RELOC_FRV_FUNCDESC_GOTLO, | |
25573 | + BFD_RELOC_FRV_FUNCDESC_VALUE, | |
25574 | + BFD_RELOC_FRV_FUNCDESC_GOTOFF12, | |
25575 | + BFD_RELOC_FRV_FUNCDESC_GOTOFFHI, | |
25576 | + BFD_RELOC_FRV_FUNCDESC_GOTOFFLO, | |
25577 | + BFD_RELOC_FRV_GOTOFF12, | |
25578 | + BFD_RELOC_FRV_GOTOFFHI, | |
25579 | + BFD_RELOC_FRV_GOTOFFLO, | |
25580 | + BFD_RELOC_FRV_GETTLSOFF, | |
25581 | + BFD_RELOC_FRV_TLSDESC_VALUE, | |
25582 | + BFD_RELOC_FRV_GOTTLSDESC12, | |
25583 | + BFD_RELOC_FRV_GOTTLSDESCHI, | |
25584 | + BFD_RELOC_FRV_GOTTLSDESCLO, | |
25585 | + BFD_RELOC_FRV_TLSMOFF12, | |
25586 | + BFD_RELOC_FRV_TLSMOFFHI, | |
25587 | + BFD_RELOC_FRV_TLSMOFFLO, | |
25588 | + BFD_RELOC_FRV_GOTTLSOFF12, | |
25589 | + BFD_RELOC_FRV_GOTTLSOFFHI, | |
25590 | + BFD_RELOC_FRV_GOTTLSOFFLO, | |
25591 | + BFD_RELOC_FRV_TLSOFF, | |
25592 | + BFD_RELOC_FRV_TLSDESC_RELAX, | |
25593 | + BFD_RELOC_FRV_GETTLSOFF_RELAX, | |
25594 | + BFD_RELOC_FRV_TLSOFF_RELAX, | |
25595 | + BFD_RELOC_FRV_TLSMOFF, | |
25596 | + | |
25597 | + | |
25598 | +/* This is a 24bit GOT-relative reloc for the mn10300. */ | |
25599 | + BFD_RELOC_MN10300_GOTOFF24, | |
25600 | + | |
25601 | +/* This is a 32bit GOT-relative reloc for the mn10300, offset by two bytes | |
25602 | +in the instruction. */ | |
25603 | + BFD_RELOC_MN10300_GOT32, | |
25604 | + | |
25605 | +/* This is a 24bit GOT-relative reloc for the mn10300, offset by two bytes | |
25606 | +in the instruction. */ | |
25607 | + BFD_RELOC_MN10300_GOT24, | |
25608 | + | |
25609 | +/* This is a 16bit GOT-relative reloc for the mn10300, offset by two bytes | |
25610 | +in the instruction. */ | |
25611 | + BFD_RELOC_MN10300_GOT16, | |
25612 | + | |
25613 | +/* Copy symbol at runtime. */ | |
25614 | + BFD_RELOC_MN10300_COPY, | |
25615 | + | |
25616 | +/* Create GOT entry. */ | |
25617 | + BFD_RELOC_MN10300_GLOB_DAT, | |
25618 | + | |
25619 | +/* Create PLT entry. */ | |
25620 | + BFD_RELOC_MN10300_JMP_SLOT, | |
25621 | + | |
25622 | +/* Adjust by program base. */ | |
25623 | + BFD_RELOC_MN10300_RELATIVE, | |
25624 | + | |
25625 | + | |
25626 | +/* i386/elf relocations */ | |
25627 | + BFD_RELOC_386_GOT32, | |
25628 | + BFD_RELOC_386_PLT32, | |
25629 | + BFD_RELOC_386_COPY, | |
25630 | + BFD_RELOC_386_GLOB_DAT, | |
25631 | + BFD_RELOC_386_JUMP_SLOT, | |
25632 | + BFD_RELOC_386_RELATIVE, | |
25633 | + BFD_RELOC_386_GOTOFF, | |
25634 | + BFD_RELOC_386_GOTPC, | |
25635 | + BFD_RELOC_386_TLS_TPOFF, | |
25636 | + BFD_RELOC_386_TLS_IE, | |
25637 | + BFD_RELOC_386_TLS_GOTIE, | |
25638 | + BFD_RELOC_386_TLS_LE, | |
25639 | + BFD_RELOC_386_TLS_GD, | |
25640 | + BFD_RELOC_386_TLS_LDM, | |
25641 | + BFD_RELOC_386_TLS_LDO_32, | |
25642 | + BFD_RELOC_386_TLS_IE_32, | |
25643 | + BFD_RELOC_386_TLS_LE_32, | |
25644 | + BFD_RELOC_386_TLS_DTPMOD32, | |
25645 | + BFD_RELOC_386_TLS_DTPOFF32, | |
25646 | + BFD_RELOC_386_TLS_TPOFF32, | |
25647 | + | |
25648 | +/* x86-64/elf relocations */ | |
25649 | + BFD_RELOC_X86_64_GOT32, | |
25650 | + BFD_RELOC_X86_64_PLT32, | |
25651 | + BFD_RELOC_X86_64_COPY, | |
25652 | + BFD_RELOC_X86_64_GLOB_DAT, | |
25653 | + BFD_RELOC_X86_64_JUMP_SLOT, | |
25654 | + BFD_RELOC_X86_64_RELATIVE, | |
25655 | + BFD_RELOC_X86_64_GOTPCREL, | |
25656 | + BFD_RELOC_X86_64_32S, | |
25657 | + BFD_RELOC_X86_64_DTPMOD64, | |
25658 | + BFD_RELOC_X86_64_DTPOFF64, | |
25659 | + BFD_RELOC_X86_64_TPOFF64, | |
25660 | + BFD_RELOC_X86_64_TLSGD, | |
25661 | + BFD_RELOC_X86_64_TLSLD, | |
25662 | + BFD_RELOC_X86_64_DTPOFF32, | |
25663 | + BFD_RELOC_X86_64_GOTTPOFF, | |
25664 | + BFD_RELOC_X86_64_TPOFF32, | |
25665 | + BFD_RELOC_X86_64_GOTOFF64, | |
25666 | + BFD_RELOC_X86_64_GOTPC32, | |
25667 | + | |
25668 | +/* ns32k relocations */ | |
25669 | + BFD_RELOC_NS32K_IMM_8, | |
25670 | + BFD_RELOC_NS32K_IMM_16, | |
25671 | + BFD_RELOC_NS32K_IMM_32, | |
25672 | + BFD_RELOC_NS32K_IMM_8_PCREL, | |
25673 | + BFD_RELOC_NS32K_IMM_16_PCREL, | |
25674 | + BFD_RELOC_NS32K_IMM_32_PCREL, | |
25675 | + BFD_RELOC_NS32K_DISP_8, | |
25676 | + BFD_RELOC_NS32K_DISP_16, | |
25677 | + BFD_RELOC_NS32K_DISP_32, | |
25678 | + BFD_RELOC_NS32K_DISP_8_PCREL, | |
25679 | + BFD_RELOC_NS32K_DISP_16_PCREL, | |
25680 | + BFD_RELOC_NS32K_DISP_32_PCREL, | |
25681 | + | |
25682 | +/* PDP11 relocations */ | |
25683 | + BFD_RELOC_PDP11_DISP_8_PCREL, | |
25684 | + BFD_RELOC_PDP11_DISP_6_PCREL, | |
25685 | + | |
25686 | +/* Picojava relocs. Not all of these appear in object files. */ | |
25687 | + BFD_RELOC_PJ_CODE_HI16, | |
25688 | + BFD_RELOC_PJ_CODE_LO16, | |
25689 | + BFD_RELOC_PJ_CODE_DIR16, | |
25690 | + BFD_RELOC_PJ_CODE_DIR32, | |
25691 | + BFD_RELOC_PJ_CODE_REL16, | |
25692 | + BFD_RELOC_PJ_CODE_REL32, | |
25693 | + | |
25694 | +/* Power(rs6000) and PowerPC relocations. */ | |
25695 | + BFD_RELOC_PPC_B26, | |
25696 | + BFD_RELOC_PPC_BA26, | |
25697 | + BFD_RELOC_PPC_TOC16, | |
25698 | + BFD_RELOC_PPC_B16, | |
25699 | + BFD_RELOC_PPC_B16_BRTAKEN, | |
25700 | + BFD_RELOC_PPC_B16_BRNTAKEN, | |
25701 | + BFD_RELOC_PPC_BA16, | |
25702 | + BFD_RELOC_PPC_BA16_BRTAKEN, | |
25703 | + BFD_RELOC_PPC_BA16_BRNTAKEN, | |
25704 | + BFD_RELOC_PPC_COPY, | |
25705 | + BFD_RELOC_PPC_GLOB_DAT, | |
25706 | + BFD_RELOC_PPC_JMP_SLOT, | |
25707 | + BFD_RELOC_PPC_RELATIVE, | |
25708 | + BFD_RELOC_PPC_LOCAL24PC, | |
25709 | + BFD_RELOC_PPC_EMB_NADDR32, | |
25710 | + BFD_RELOC_PPC_EMB_NADDR16, | |
25711 | + BFD_RELOC_PPC_EMB_NADDR16_LO, | |
25712 | + BFD_RELOC_PPC_EMB_NADDR16_HI, | |
25713 | + BFD_RELOC_PPC_EMB_NADDR16_HA, | |
25714 | + BFD_RELOC_PPC_EMB_SDAI16, | |
25715 | + BFD_RELOC_PPC_EMB_SDA2I16, | |
25716 | + BFD_RELOC_PPC_EMB_SDA2REL, | |
25717 | + BFD_RELOC_PPC_EMB_SDA21, | |
25718 | + BFD_RELOC_PPC_EMB_MRKREF, | |
25719 | + BFD_RELOC_PPC_EMB_RELSEC16, | |
25720 | + BFD_RELOC_PPC_EMB_RELST_LO, | |
25721 | + BFD_RELOC_PPC_EMB_RELST_HI, | |
25722 | + BFD_RELOC_PPC_EMB_RELST_HA, | |
25723 | + BFD_RELOC_PPC_EMB_BIT_FLD, | |
25724 | + BFD_RELOC_PPC_EMB_RELSDA, | |
25725 | + BFD_RELOC_PPC64_HIGHER, | |
25726 | + BFD_RELOC_PPC64_HIGHER_S, | |
25727 | + BFD_RELOC_PPC64_HIGHEST, | |
25728 | + BFD_RELOC_PPC64_HIGHEST_S, | |
25729 | + BFD_RELOC_PPC64_TOC16_LO, | |
25730 | + BFD_RELOC_PPC64_TOC16_HI, | |
25731 | + BFD_RELOC_PPC64_TOC16_HA, | |
25732 | + BFD_RELOC_PPC64_TOC, | |
25733 | + BFD_RELOC_PPC64_PLTGOT16, | |
25734 | + BFD_RELOC_PPC64_PLTGOT16_LO, | |
25735 | + BFD_RELOC_PPC64_PLTGOT16_HI, | |
25736 | + BFD_RELOC_PPC64_PLTGOT16_HA, | |
25737 | + BFD_RELOC_PPC64_ADDR16_DS, | |
25738 | + BFD_RELOC_PPC64_ADDR16_LO_DS, | |
25739 | + BFD_RELOC_PPC64_GOT16_DS, | |
25740 | + BFD_RELOC_PPC64_GOT16_LO_DS, | |
25741 | + BFD_RELOC_PPC64_PLT16_LO_DS, | |
25742 | + BFD_RELOC_PPC64_SECTOFF_DS, | |
25743 | + BFD_RELOC_PPC64_SECTOFF_LO_DS, | |
25744 | + BFD_RELOC_PPC64_TOC16_DS, | |
25745 | + BFD_RELOC_PPC64_TOC16_LO_DS, | |
25746 | + BFD_RELOC_PPC64_PLTGOT16_DS, | |
25747 | + BFD_RELOC_PPC64_PLTGOT16_LO_DS, | |
25748 | + | |
25749 | +/* PowerPC and PowerPC64 thread-local storage relocations. */ | |
25750 | + BFD_RELOC_PPC_TLS, | |
25751 | + BFD_RELOC_PPC_DTPMOD, | |
25752 | + BFD_RELOC_PPC_TPREL16, | |
25753 | + BFD_RELOC_PPC_TPREL16_LO, | |
25754 | + BFD_RELOC_PPC_TPREL16_HI, | |
25755 | + BFD_RELOC_PPC_TPREL16_HA, | |
25756 | + BFD_RELOC_PPC_TPREL, | |
25757 | + BFD_RELOC_PPC_DTPREL16, | |
25758 | + BFD_RELOC_PPC_DTPREL16_LO, | |
25759 | + BFD_RELOC_PPC_DTPREL16_HI, | |
25760 | + BFD_RELOC_PPC_DTPREL16_HA, | |
25761 | + BFD_RELOC_PPC_DTPREL, | |
25762 | + BFD_RELOC_PPC_GOT_TLSGD16, | |
25763 | + BFD_RELOC_PPC_GOT_TLSGD16_LO, | |
25764 | + BFD_RELOC_PPC_GOT_TLSGD16_HI, | |
25765 | + BFD_RELOC_PPC_GOT_TLSGD16_HA, | |
25766 | + BFD_RELOC_PPC_GOT_TLSLD16, | |
25767 | + BFD_RELOC_PPC_GOT_TLSLD16_LO, | |
25768 | + BFD_RELOC_PPC_GOT_TLSLD16_HI, | |
25769 | + BFD_RELOC_PPC_GOT_TLSLD16_HA, | |
25770 | + BFD_RELOC_PPC_GOT_TPREL16, | |
25771 | + BFD_RELOC_PPC_GOT_TPREL16_LO, | |
25772 | + BFD_RELOC_PPC_GOT_TPREL16_HI, | |
25773 | + BFD_RELOC_PPC_GOT_TPREL16_HA, | |
25774 | + BFD_RELOC_PPC_GOT_DTPREL16, | |
25775 | + BFD_RELOC_PPC_GOT_DTPREL16_LO, | |
25776 | + BFD_RELOC_PPC_GOT_DTPREL16_HI, | |
25777 | + BFD_RELOC_PPC_GOT_DTPREL16_HA, | |
25778 | + BFD_RELOC_PPC64_TPREL16_DS, | |
25779 | + BFD_RELOC_PPC64_TPREL16_LO_DS, | |
25780 | + BFD_RELOC_PPC64_TPREL16_HIGHER, | |
25781 | + BFD_RELOC_PPC64_TPREL16_HIGHERA, | |
25782 | + BFD_RELOC_PPC64_TPREL16_HIGHEST, | |
25783 | + BFD_RELOC_PPC64_TPREL16_HIGHESTA, | |
25784 | + BFD_RELOC_PPC64_DTPREL16_DS, | |
25785 | + BFD_RELOC_PPC64_DTPREL16_LO_DS, | |
25786 | + BFD_RELOC_PPC64_DTPREL16_HIGHER, | |
25787 | + BFD_RELOC_PPC64_DTPREL16_HIGHERA, | |
25788 | + BFD_RELOC_PPC64_DTPREL16_HIGHEST, | |
25789 | + BFD_RELOC_PPC64_DTPREL16_HIGHESTA, | |
25790 | + | |
25791 | +/* IBM 370/390 relocations */ | |
25792 | + BFD_RELOC_I370_D12, | |
25793 | + | |
25794 | +/* The type of reloc used to build a constructor table - at the moment | |
25795 | +probably a 32 bit wide absolute relocation, but the target can choose. | |
25796 | +It generally does map to one of the other relocation types. */ | |
25797 | + BFD_RELOC_CTOR, | |
25798 | + | |
25799 | +/* ARM 26 bit pc-relative branch. The lowest two bits must be zero and are | |
25800 | +not stored in the instruction. */ | |
25801 | + BFD_RELOC_ARM_PCREL_BRANCH, | |
25802 | + | |
25803 | +/* ARM 26 bit pc-relative branch. The lowest bit must be zero and is | |
25804 | +not stored in the instruction. The 2nd lowest bit comes from a 1 bit | |
25805 | +field in the instruction. */ | |
25806 | + BFD_RELOC_ARM_PCREL_BLX, | |
25807 | + | |
25808 | +/* Thumb 22 bit pc-relative branch. The lowest bit must be zero and is | |
25809 | +not stored in the instruction. The 2nd lowest bit comes from a 1 bit | |
25810 | +field in the instruction. */ | |
25811 | + BFD_RELOC_THUMB_PCREL_BLX, | |
25812 | + | |
25813 | +/* Thumb 7-, 9-, 12-, 20-, 23-, and 25-bit pc-relative branches. | |
25814 | +The lowest bit must be zero and is not stored in the instruction. | |
25815 | +Note that the corresponding ELF R_ARM_THM_JUMPnn constant has an | |
25816 | +"nn" one smaller in all cases. Note further that BRANCH23 | |
25817 | +corresponds to R_ARM_THM_CALL. */ | |
25818 | + BFD_RELOC_THUMB_PCREL_BRANCH7, | |
25819 | + BFD_RELOC_THUMB_PCREL_BRANCH9, | |
25820 | + BFD_RELOC_THUMB_PCREL_BRANCH12, | |
25821 | + BFD_RELOC_THUMB_PCREL_BRANCH20, | |
25822 | + BFD_RELOC_THUMB_PCREL_BRANCH23, | |
25823 | + BFD_RELOC_THUMB_PCREL_BRANCH25, | |
25824 | + | |
25825 | +/* 12-bit immediate offset, used in ARM-format ldr and str instructions. */ | |
25826 | + BFD_RELOC_ARM_OFFSET_IMM, | |
25827 | + | |
25828 | +/* 5-bit immediate offset, used in Thumb-format ldr and str instructions. */ | |
25829 | + BFD_RELOC_ARM_THUMB_OFFSET, | |
25830 | + | |
25831 | +/* Pc-relative or absolute relocation depending on target. Used for | |
25832 | +entries in .init_array sections. */ | |
25833 | + BFD_RELOC_ARM_TARGET1, | |
25834 | + | |
25835 | +/* Read-only segment base relative address. */ | |
25836 | + BFD_RELOC_ARM_ROSEGREL32, | |
25837 | + | |
25838 | +/* Data segment base relative address. */ | |
25839 | + BFD_RELOC_ARM_SBREL32, | |
25840 | + | |
25841 | +/* This reloc is used for references to RTTI data from exception handling | |
25842 | +tables. The actual definition depends on the target. It may be a | |
25843 | +pc-relative or some form of GOT-indirect relocation. */ | |
25844 | + BFD_RELOC_ARM_TARGET2, | |
25845 | + | |
25846 | +/* 31-bit PC relative address. */ | |
25847 | + BFD_RELOC_ARM_PREL31, | |
25848 | + | |
25849 | +/* Relocations for setting up GOTs and PLTs for shared libraries. */ | |
25850 | + BFD_RELOC_ARM_JUMP_SLOT, | |
25851 | + BFD_RELOC_ARM_GLOB_DAT, | |
25852 | + BFD_RELOC_ARM_GOT32, | |
25853 | + BFD_RELOC_ARM_PLT32, | |
25854 | + BFD_RELOC_ARM_RELATIVE, | |
25855 | + BFD_RELOC_ARM_GOTOFF, | |
25856 | + BFD_RELOC_ARM_GOTPC, | |
25857 | + | |
25858 | +/* ARM thread-local storage relocations. */ | |
25859 | + BFD_RELOC_ARM_TLS_GD32, | |
25860 | + BFD_RELOC_ARM_TLS_LDO32, | |
25861 | + BFD_RELOC_ARM_TLS_LDM32, | |
25862 | + BFD_RELOC_ARM_TLS_DTPOFF32, | |
25863 | + BFD_RELOC_ARM_TLS_DTPMOD32, | |
25864 | + BFD_RELOC_ARM_TLS_TPOFF32, | |
25865 | + BFD_RELOC_ARM_TLS_IE32, | |
25866 | + BFD_RELOC_ARM_TLS_LE32, | |
25867 | + | |
25868 | +/* These relocs are only used within the ARM assembler. They are not | |
25869 | +(at present) written to any object files. */ | |
25870 | + BFD_RELOC_ARM_IMMEDIATE, | |
25871 | + BFD_RELOC_ARM_ADRL_IMMEDIATE, | |
25872 | + BFD_RELOC_ARM_T32_IMMEDIATE, | |
25873 | + BFD_RELOC_ARM_SHIFT_IMM, | |
25874 | + BFD_RELOC_ARM_SMI, | |
25875 | + BFD_RELOC_ARM_SWI, | |
25876 | + BFD_RELOC_ARM_MULTI, | |
25877 | + BFD_RELOC_ARM_CP_OFF_IMM, | |
25878 | + BFD_RELOC_ARM_CP_OFF_IMM_S2, | |
25879 | + BFD_RELOC_ARM_ADR_IMM, | |
25880 | + BFD_RELOC_ARM_LDR_IMM, | |
25881 | + BFD_RELOC_ARM_LITERAL, | |
25882 | + BFD_RELOC_ARM_IN_POOL, | |
25883 | + BFD_RELOC_ARM_OFFSET_IMM8, | |
25884 | + BFD_RELOC_ARM_T32_OFFSET_U8, | |
25885 | + BFD_RELOC_ARM_T32_OFFSET_IMM, | |
25886 | + BFD_RELOC_ARM_HWLITERAL, | |
25887 | + BFD_RELOC_ARM_THUMB_ADD, | |
25888 | + BFD_RELOC_ARM_THUMB_IMM, | |
25889 | + BFD_RELOC_ARM_THUMB_SHIFT, | |
25890 | + | |
25891 | +/* Renesas / SuperH SH relocs. Not all of these appear in object files. */ | |
25892 | + BFD_RELOC_SH_PCDISP8BY2, | |
25893 | + BFD_RELOC_SH_PCDISP12BY2, | |
25894 | + BFD_RELOC_SH_IMM3, | |
25895 | + BFD_RELOC_SH_IMM3U, | |
25896 | + BFD_RELOC_SH_DISP12, | |
25897 | + BFD_RELOC_SH_DISP12BY2, | |
25898 | + BFD_RELOC_SH_DISP12BY4, | |
25899 | + BFD_RELOC_SH_DISP12BY8, | |
25900 | + BFD_RELOC_SH_DISP20, | |
25901 | + BFD_RELOC_SH_DISP20BY8, | |
25902 | + BFD_RELOC_SH_IMM4, | |
25903 | + BFD_RELOC_SH_IMM4BY2, | |
25904 | + BFD_RELOC_SH_IMM4BY4, | |
25905 | + BFD_RELOC_SH_IMM8, | |
25906 | + BFD_RELOC_SH_IMM8BY2, | |
25907 | + BFD_RELOC_SH_IMM8BY4, | |
25908 | + BFD_RELOC_SH_PCRELIMM8BY2, | |
25909 | + BFD_RELOC_SH_PCRELIMM8BY4, | |
25910 | + BFD_RELOC_SH_SWITCH16, | |
25911 | + BFD_RELOC_SH_SWITCH32, | |
25912 | + BFD_RELOC_SH_USES, | |
25913 | + BFD_RELOC_SH_COUNT, | |
25914 | + BFD_RELOC_SH_ALIGN, | |
25915 | + BFD_RELOC_SH_CODE, | |
25916 | + BFD_RELOC_SH_DATA, | |
25917 | + BFD_RELOC_SH_LABEL, | |
25918 | + BFD_RELOC_SH_LOOP_START, | |
25919 | + BFD_RELOC_SH_LOOP_END, | |
25920 | + BFD_RELOC_SH_COPY, | |
25921 | + BFD_RELOC_SH_GLOB_DAT, | |
25922 | + BFD_RELOC_SH_JMP_SLOT, | |
25923 | + BFD_RELOC_SH_RELATIVE, | |
25924 | + BFD_RELOC_SH_GOTPC, | |
25925 | + BFD_RELOC_SH_GOT_LOW16, | |
25926 | + BFD_RELOC_SH_GOT_MEDLOW16, | |
25927 | + BFD_RELOC_SH_GOT_MEDHI16, | |
25928 | + BFD_RELOC_SH_GOT_HI16, | |
25929 | + BFD_RELOC_SH_GOTPLT_LOW16, | |
25930 | + BFD_RELOC_SH_GOTPLT_MEDLOW16, | |
25931 | + BFD_RELOC_SH_GOTPLT_MEDHI16, | |
25932 | + BFD_RELOC_SH_GOTPLT_HI16, | |
25933 | + BFD_RELOC_SH_PLT_LOW16, | |
25934 | + BFD_RELOC_SH_PLT_MEDLOW16, | |
25935 | + BFD_RELOC_SH_PLT_MEDHI16, | |
25936 | + BFD_RELOC_SH_PLT_HI16, | |
25937 | + BFD_RELOC_SH_GOTOFF_LOW16, | |
25938 | + BFD_RELOC_SH_GOTOFF_MEDLOW16, | |
25939 | + BFD_RELOC_SH_GOTOFF_MEDHI16, | |
25940 | + BFD_RELOC_SH_GOTOFF_HI16, | |
25941 | + BFD_RELOC_SH_GOTPC_LOW16, | |
25942 | + BFD_RELOC_SH_GOTPC_MEDLOW16, | |
25943 | + BFD_RELOC_SH_GOTPC_MEDHI16, | |
25944 | + BFD_RELOC_SH_GOTPC_HI16, | |
25945 | + BFD_RELOC_SH_COPY64, | |
25946 | + BFD_RELOC_SH_GLOB_DAT64, | |
25947 | + BFD_RELOC_SH_JMP_SLOT64, | |
25948 | + BFD_RELOC_SH_RELATIVE64, | |
25949 | + BFD_RELOC_SH_GOT10BY4, | |
25950 | + BFD_RELOC_SH_GOT10BY8, | |
25951 | + BFD_RELOC_SH_GOTPLT10BY4, | |
25952 | + BFD_RELOC_SH_GOTPLT10BY8, | |
25953 | + BFD_RELOC_SH_GOTPLT32, | |
25954 | + BFD_RELOC_SH_SHMEDIA_CODE, | |
25955 | + BFD_RELOC_SH_IMMU5, | |
25956 | + BFD_RELOC_SH_IMMS6, | |
25957 | + BFD_RELOC_SH_IMMS6BY32, | |
25958 | + BFD_RELOC_SH_IMMU6, | |
25959 | + BFD_RELOC_SH_IMMS10, | |
25960 | + BFD_RELOC_SH_IMMS10BY2, | |
25961 | + BFD_RELOC_SH_IMMS10BY4, | |
25962 | + BFD_RELOC_SH_IMMS10BY8, | |
25963 | + BFD_RELOC_SH_IMMS16, | |
25964 | + BFD_RELOC_SH_IMMU16, | |
25965 | + BFD_RELOC_SH_IMM_LOW16, | |
25966 | + BFD_RELOC_SH_IMM_LOW16_PCREL, | |
25967 | + BFD_RELOC_SH_IMM_MEDLOW16, | |
25968 | + BFD_RELOC_SH_IMM_MEDLOW16_PCREL, | |
25969 | + BFD_RELOC_SH_IMM_MEDHI16, | |
25970 | + BFD_RELOC_SH_IMM_MEDHI16_PCREL, | |
25971 | + BFD_RELOC_SH_IMM_HI16, | |
25972 | + BFD_RELOC_SH_IMM_HI16_PCREL, | |
25973 | + BFD_RELOC_SH_PT_16, | |
25974 | + BFD_RELOC_SH_TLS_GD_32, | |
25975 | + BFD_RELOC_SH_TLS_LD_32, | |
25976 | + BFD_RELOC_SH_TLS_LDO_32, | |
25977 | + BFD_RELOC_SH_TLS_IE_32, | |
25978 | + BFD_RELOC_SH_TLS_LE_32, | |
25979 | + BFD_RELOC_SH_TLS_DTPMOD32, | |
25980 | + BFD_RELOC_SH_TLS_DTPOFF32, | |
25981 | + BFD_RELOC_SH_TLS_TPOFF32, | |
25982 | + | |
25983 | +/* ARC Cores relocs. | |
25984 | +ARC 22 bit pc-relative branch. The lowest two bits must be zero and are | |
25985 | +not stored in the instruction. The high 20 bits are installed in bits 26 | |
25986 | +through 7 of the instruction. */ | |
25987 | + BFD_RELOC_ARC_B22_PCREL, | |
25988 | + | |
25989 | +/* ARC 26 bit absolute branch. The lowest two bits must be zero and are not | |
25990 | +stored in the instruction. The high 24 bits are installed in bits 23 | |
25991 | +through 0. */ | |
25992 | + BFD_RELOC_ARC_B26, | |
25993 | + | |
25994 | +/* Mitsubishi D10V relocs. | |
25995 | +This is a 10-bit reloc with the right 2 bits | |
25996 | +assumed to be 0. */ | |
25997 | + BFD_RELOC_D10V_10_PCREL_R, | |
25998 | + | |
25999 | +/* Mitsubishi D10V relocs. | |
26000 | +This is a 10-bit reloc with the right 2 bits | |
26001 | +assumed to be 0. This is the same as the previous reloc | |
26002 | +except it is in the left container, i.e., | |
26003 | +shifted left 15 bits. */ | |
26004 | + BFD_RELOC_D10V_10_PCREL_L, | |
26005 | + | |
26006 | +/* This is an 18-bit reloc with the right 2 bits | |
26007 | +assumed to be 0. */ | |
26008 | + BFD_RELOC_D10V_18, | |
26009 | + | |
26010 | +/* This is an 18-bit reloc with the right 2 bits | |
26011 | +assumed to be 0. */ | |
26012 | + BFD_RELOC_D10V_18_PCREL, | |
26013 | + | |
26014 | +/* Mitsubishi D30V relocs. | |
26015 | +This is a 6-bit absolute reloc. */ | |
26016 | + BFD_RELOC_D30V_6, | |
26017 | + | |
26018 | +/* This is a 6-bit pc-relative reloc with | |
26019 | +the right 3 bits assumed to be 0. */ | |
26020 | + BFD_RELOC_D30V_9_PCREL, | |
26021 | + | |
26022 | +/* This is a 6-bit pc-relative reloc with | |
26023 | +the right 3 bits assumed to be 0. Same | |
26024 | +as the previous reloc but on the right side | |
26025 | +of the container. */ | |
26026 | + BFD_RELOC_D30V_9_PCREL_R, | |
26027 | + | |
26028 | +/* This is a 12-bit absolute reloc with the | |
26029 | +right 3 bitsassumed to be 0. */ | |
26030 | + BFD_RELOC_D30V_15, | |
26031 | + | |
26032 | +/* This is a 12-bit pc-relative reloc with | |
26033 | +the right 3 bits assumed to be 0. */ | |
26034 | + BFD_RELOC_D30V_15_PCREL, | |
26035 | + | |
26036 | +/* This is a 12-bit pc-relative reloc with | |
26037 | +the right 3 bits assumed to be 0. Same | |
26038 | +as the previous reloc but on the right side | |
26039 | +of the container. */ | |
26040 | + BFD_RELOC_D30V_15_PCREL_R, | |
26041 | + | |
26042 | +/* This is an 18-bit absolute reloc with | |
26043 | +the right 3 bits assumed to be 0. */ | |
26044 | + BFD_RELOC_D30V_21, | |
26045 | + | |
26046 | +/* This is an 18-bit pc-relative reloc with | |
26047 | +the right 3 bits assumed to be 0. */ | |
26048 | + BFD_RELOC_D30V_21_PCREL, | |
26049 | + | |
26050 | +/* This is an 18-bit pc-relative reloc with | |
26051 | +the right 3 bits assumed to be 0. Same | |
26052 | +as the previous reloc but on the right side | |
26053 | +of the container. */ | |
26054 | + BFD_RELOC_D30V_21_PCREL_R, | |
26055 | + | |
26056 | +/* This is a 32-bit absolute reloc. */ | |
26057 | + BFD_RELOC_D30V_32, | |
26058 | + | |
26059 | +/* This is a 32-bit pc-relative reloc. */ | |
26060 | + BFD_RELOC_D30V_32_PCREL, | |
26061 | + | |
26062 | +/* DLX relocs */ | |
26063 | + BFD_RELOC_DLX_HI16_S, | |
26064 | + | |
26065 | +/* DLX relocs */ | |
26066 | + BFD_RELOC_DLX_LO16, | |
26067 | + | |
26068 | +/* DLX relocs */ | |
26069 | + BFD_RELOC_DLX_JMP26, | |
26070 | + | |
26071 | +/* Renesas M16C/M32C Relocations. */ | |
26072 | + BFD_RELOC_M16C_8_PCREL8, | |
26073 | + BFD_RELOC_M16C_16_PCREL8, | |
26074 | + BFD_RELOC_M16C_8_PCREL16, | |
26075 | + BFD_RELOC_M16C_8_ELABEL24, | |
26076 | + BFD_RELOC_M16C_8_ABS16, | |
26077 | + BFD_RELOC_M16C_16_ABS16, | |
26078 | + BFD_RELOC_M16C_16_ABS24, | |
26079 | + BFD_RELOC_M16C_16_ABS32, | |
26080 | + BFD_RELOC_M16C_24_ABS16, | |
26081 | + BFD_RELOC_M16C_24_ABS24, | |
26082 | + BFD_RELOC_M16C_24_ABS32, | |
26083 | + BFD_RELOC_M16C_32_ABS16, | |
26084 | + BFD_RELOC_M16C_32_ABS24, | |
26085 | + BFD_RELOC_M16C_32_ABS32, | |
26086 | + BFD_RELOC_M16C_40_ABS16, | |
26087 | + BFD_RELOC_M16C_40_ABS24, | |
26088 | + BFD_RELOC_M16C_40_ABS32, | |
26089 | + | |
26090 | +/* Renesas M32R (formerly Mitsubishi M32R) relocs. | |
26091 | +This is a 24 bit absolute address. */ | |
26092 | + BFD_RELOC_M32R_24, | |
26093 | + | |
26094 | +/* This is a 10-bit pc-relative reloc with the right 2 bits assumed to be 0. */ | |
26095 | + BFD_RELOC_M32R_10_PCREL, | |
26096 | + | |
26097 | +/* This is an 18-bit reloc with the right 2 bits assumed to be 0. */ | |
26098 | + BFD_RELOC_M32R_18_PCREL, | |
26099 | + | |
26100 | +/* This is a 26-bit reloc with the right 2 bits assumed to be 0. */ | |
26101 | + BFD_RELOC_M32R_26_PCREL, | |
26102 | + | |
26103 | +/* This is a 16-bit reloc containing the high 16 bits of an address | |
26104 | +used when the lower 16 bits are treated as unsigned. */ | |
26105 | + BFD_RELOC_M32R_HI16_ULO, | |
26106 | + | |
26107 | +/* This is a 16-bit reloc containing the high 16 bits of an address | |
26108 | +used when the lower 16 bits are treated as signed. */ | |
26109 | + BFD_RELOC_M32R_HI16_SLO, | |
26110 | + | |
26111 | +/* This is a 16-bit reloc containing the lower 16 bits of an address. */ | |
26112 | + BFD_RELOC_M32R_LO16, | |
26113 | + | |
26114 | +/* This is a 16-bit reloc containing the small data area offset for use in | |
26115 | +add3, load, and store instructions. */ | |
26116 | + BFD_RELOC_M32R_SDA16, | |
26117 | + | |
26118 | +/* For PIC. */ | |
26119 | + BFD_RELOC_M32R_GOT24, | |
26120 | + BFD_RELOC_M32R_26_PLTREL, | |
26121 | + BFD_RELOC_M32R_COPY, | |
26122 | + BFD_RELOC_M32R_GLOB_DAT, | |
26123 | + BFD_RELOC_M32R_JMP_SLOT, | |
26124 | + BFD_RELOC_M32R_RELATIVE, | |
26125 | + BFD_RELOC_M32R_GOTOFF, | |
26126 | + BFD_RELOC_M32R_GOTOFF_HI_ULO, | |
26127 | + BFD_RELOC_M32R_GOTOFF_HI_SLO, | |
26128 | + BFD_RELOC_M32R_GOTOFF_LO, | |
26129 | + BFD_RELOC_M32R_GOTPC24, | |
26130 | + BFD_RELOC_M32R_GOT16_HI_ULO, | |
26131 | + BFD_RELOC_M32R_GOT16_HI_SLO, | |
26132 | + BFD_RELOC_M32R_GOT16_LO, | |
26133 | + BFD_RELOC_M32R_GOTPC_HI_ULO, | |
26134 | + BFD_RELOC_M32R_GOTPC_HI_SLO, | |
26135 | + BFD_RELOC_M32R_GOTPC_LO, | |
26136 | + | |
26137 | +/* This is a 9-bit reloc */ | |
26138 | + BFD_RELOC_V850_9_PCREL, | |
26139 | + | |
26140 | +/* This is a 22-bit reloc */ | |
26141 | + BFD_RELOC_V850_22_PCREL, | |
26142 | + | |
26143 | +/* This is a 16 bit offset from the short data area pointer. */ | |
26144 | + BFD_RELOC_V850_SDA_16_16_OFFSET, | |
26145 | + | |
26146 | +/* This is a 16 bit offset (of which only 15 bits are used) from the | |
26147 | +short data area pointer. */ | |
26148 | + BFD_RELOC_V850_SDA_15_16_OFFSET, | |
26149 | + | |
26150 | +/* This is a 16 bit offset from the zero data area pointer. */ | |
26151 | + BFD_RELOC_V850_ZDA_16_16_OFFSET, | |
26152 | + | |
26153 | +/* This is a 16 bit offset (of which only 15 bits are used) from the | |
26154 | +zero data area pointer. */ | |
26155 | + BFD_RELOC_V850_ZDA_15_16_OFFSET, | |
26156 | + | |
26157 | +/* This is an 8 bit offset (of which only 6 bits are used) from the | |
26158 | +tiny data area pointer. */ | |
26159 | + BFD_RELOC_V850_TDA_6_8_OFFSET, | |
26160 | + | |
26161 | +/* This is an 8bit offset (of which only 7 bits are used) from the tiny | |
26162 | +data area pointer. */ | |
26163 | + BFD_RELOC_V850_TDA_7_8_OFFSET, | |
26164 | + | |
26165 | +/* This is a 7 bit offset from the tiny data area pointer. */ | |
26166 | + BFD_RELOC_V850_TDA_7_7_OFFSET, | |
26167 | + | |
26168 | +/* This is a 16 bit offset from the tiny data area pointer. */ | |
26169 | + BFD_RELOC_V850_TDA_16_16_OFFSET, | |
26170 | + | |
26171 | +/* This is a 5 bit offset (of which only 4 bits are used) from the tiny | |
26172 | +data area pointer. */ | |
26173 | + BFD_RELOC_V850_TDA_4_5_OFFSET, | |
26174 | + | |
26175 | +/* This is a 4 bit offset from the tiny data area pointer. */ | |
26176 | + BFD_RELOC_V850_TDA_4_4_OFFSET, | |
26177 | + | |
26178 | +/* This is a 16 bit offset from the short data area pointer, with the | |
26179 | +bits placed non-contiguously in the instruction. */ | |
26180 | + BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, | |
26181 | + | |
26182 | +/* This is a 16 bit offset from the zero data area pointer, with the | |
26183 | +bits placed non-contiguously in the instruction. */ | |
26184 | + BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, | |
26185 | + | |
26186 | +/* This is a 6 bit offset from the call table base pointer. */ | |
26187 | + BFD_RELOC_V850_CALLT_6_7_OFFSET, | |
26188 | + | |
26189 | +/* This is a 16 bit offset from the call table base pointer. */ | |
26190 | + BFD_RELOC_V850_CALLT_16_16_OFFSET, | |
26191 | + | |
26192 | +/* Used for relaxing indirect function calls. */ | |
26193 | + BFD_RELOC_V850_LONGCALL, | |
26194 | + | |
26195 | +/* Used for relaxing indirect jumps. */ | |
26196 | + BFD_RELOC_V850_LONGJUMP, | |
26197 | + | |
26198 | +/* Used to maintain alignment whilst relaxing. */ | |
26199 | + BFD_RELOC_V850_ALIGN, | |
26200 | + | |
26201 | +/* This is a variation of BFD_RELOC_LO16 that can be used in v850e ld.bu | |
26202 | +instructions. */ | |
26203 | + BFD_RELOC_V850_LO16_SPLIT_OFFSET, | |
26204 | + | |
26205 | +/* This is a 32bit pcrel reloc for the mn10300, offset by two bytes in the | |
26206 | +instruction. */ | |
26207 | + BFD_RELOC_MN10300_32_PCREL, | |
26208 | + | |
26209 | +/* This is a 16bit pcrel reloc for the mn10300, offset by two bytes in the | |
26210 | +instruction. */ | |
26211 | + BFD_RELOC_MN10300_16_PCREL, | |
26212 | + | |
26213 | +/* This is a 8bit DP reloc for the tms320c30, where the most | |
26214 | +significant 8 bits of a 24 bit word are placed into the least | |
26215 | +significant 8 bits of the opcode. */ | |
26216 | + BFD_RELOC_TIC30_LDP, | |
26217 | + | |
26218 | +/* This is a 7bit reloc for the tms320c54x, where the least | |
26219 | +significant 7 bits of a 16 bit word are placed into the least | |
26220 | +significant 7 bits of the opcode. */ | |
26221 | + BFD_RELOC_TIC54X_PARTLS7, | |
26222 | + | |
26223 | +/* This is a 9bit DP reloc for the tms320c54x, where the most | |
26224 | +significant 9 bits of a 16 bit word are placed into the least | |
26225 | +significant 9 bits of the opcode. */ | |
26226 | + BFD_RELOC_TIC54X_PARTMS9, | |
26227 | + | |
26228 | +/* This is an extended address 23-bit reloc for the tms320c54x. */ | |
26229 | + BFD_RELOC_TIC54X_23, | |
26230 | + | |
26231 | +/* This is a 16-bit reloc for the tms320c54x, where the least | |
26232 | +significant 16 bits of a 23-bit extended address are placed into | |
26233 | +the opcode. */ | |
26234 | + BFD_RELOC_TIC54X_16_OF_23, | |
26235 | + | |
26236 | +/* This is a reloc for the tms320c54x, where the most | |
26237 | +significant 7 bits of a 23-bit extended address are placed into | |
26238 | +the opcode. */ | |
26239 | + BFD_RELOC_TIC54X_MS7_OF_23, | |
26240 | + | |
26241 | +/* This is a 48 bit reloc for the FR30 that stores 32 bits. */ | |
26242 | + BFD_RELOC_FR30_48, | |
26243 | + | |
26244 | +/* This is a 32 bit reloc for the FR30 that stores 20 bits split up into | |
26245 | +two sections. */ | |
26246 | + BFD_RELOC_FR30_20, | |
26247 | + | |
26248 | +/* This is a 16 bit reloc for the FR30 that stores a 6 bit word offset in | |
26249 | +4 bits. */ | |
26250 | + BFD_RELOC_FR30_6_IN_4, | |
26251 | + | |
26252 | +/* This is a 16 bit reloc for the FR30 that stores an 8 bit byte offset | |
26253 | +into 8 bits. */ | |
26254 | + BFD_RELOC_FR30_8_IN_8, | |
26255 | + | |
26256 | +/* This is a 16 bit reloc for the FR30 that stores a 9 bit short offset | |
26257 | +into 8 bits. */ | |
26258 | + BFD_RELOC_FR30_9_IN_8, | |
26259 | + | |
26260 | +/* This is a 16 bit reloc for the FR30 that stores a 10 bit word offset | |
26261 | +into 8 bits. */ | |
26262 | + BFD_RELOC_FR30_10_IN_8, | |
26263 | + | |
26264 | +/* This is a 16 bit reloc for the FR30 that stores a 9 bit pc relative | |
26265 | +short offset into 8 bits. */ | |
26266 | + BFD_RELOC_FR30_9_PCREL, | |
26267 | + | |
26268 | +/* This is a 16 bit reloc for the FR30 that stores a 12 bit pc relative | |
26269 | +short offset into 11 bits. */ | |
26270 | + BFD_RELOC_FR30_12_PCREL, | |
26271 | + | |
26272 | +/* Motorola Mcore relocations. */ | |
26273 | + BFD_RELOC_MCORE_PCREL_IMM8BY4, | |
26274 | + BFD_RELOC_MCORE_PCREL_IMM11BY2, | |
26275 | + BFD_RELOC_MCORE_PCREL_IMM4BY2, | |
26276 | + BFD_RELOC_MCORE_PCREL_32, | |
26277 | + BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2, | |
26278 | + BFD_RELOC_MCORE_RVA, | |
26279 | + | |
26280 | +/* These are relocations for the GETA instruction. */ | |
26281 | + BFD_RELOC_MMIX_GETA, | |
26282 | + BFD_RELOC_MMIX_GETA_1, | |
26283 | + BFD_RELOC_MMIX_GETA_2, | |
26284 | + BFD_RELOC_MMIX_GETA_3, | |
26285 | + | |
26286 | +/* These are relocations for a conditional branch instruction. */ | |
26287 | + BFD_RELOC_MMIX_CBRANCH, | |
26288 | + BFD_RELOC_MMIX_CBRANCH_J, | |
26289 | + BFD_RELOC_MMIX_CBRANCH_1, | |
26290 | + BFD_RELOC_MMIX_CBRANCH_2, | |
26291 | + BFD_RELOC_MMIX_CBRANCH_3, | |
26292 | + | |
26293 | +/* These are relocations for the PUSHJ instruction. */ | |
26294 | + BFD_RELOC_MMIX_PUSHJ, | |
26295 | + BFD_RELOC_MMIX_PUSHJ_1, | |
26296 | + BFD_RELOC_MMIX_PUSHJ_2, | |
26297 | + BFD_RELOC_MMIX_PUSHJ_3, | |
26298 | + BFD_RELOC_MMIX_PUSHJ_STUBBABLE, | |
26299 | + | |
26300 | +/* These are relocations for the JMP instruction. */ | |
26301 | + BFD_RELOC_MMIX_JMP, | |
26302 | + BFD_RELOC_MMIX_JMP_1, | |
26303 | + BFD_RELOC_MMIX_JMP_2, | |
26304 | + BFD_RELOC_MMIX_JMP_3, | |
26305 | + | |
26306 | +/* This is a relocation for a relative address as in a GETA instruction or | |
26307 | +a branch. */ | |
26308 | + BFD_RELOC_MMIX_ADDR19, | |
26309 | + | |
26310 | +/* This is a relocation for a relative address as in a JMP instruction. */ | |
26311 | + BFD_RELOC_MMIX_ADDR27, | |
26312 | + | |
26313 | +/* This is a relocation for an instruction field that may be a general | |
26314 | +register or a value 0..255. */ | |
26315 | + BFD_RELOC_MMIX_REG_OR_BYTE, | |
26316 | + | |
26317 | +/* This is a relocation for an instruction field that may be a general | |
26318 | +register. */ | |
26319 | + BFD_RELOC_MMIX_REG, | |
26320 | + | |
26321 | +/* This is a relocation for two instruction fields holding a register and | |
26322 | +an offset, the equivalent of the relocation. */ | |
26323 | + BFD_RELOC_MMIX_BASE_PLUS_OFFSET, | |
26324 | + | |
26325 | +/* This relocation is an assertion that the expression is not allocated as | |
26326 | +a global register. It does not modify contents. */ | |
26327 | + BFD_RELOC_MMIX_LOCAL, | |
26328 | + | |
26329 | +/* This is a 16 bit reloc for the AVR that stores 8 bit pc relative | |
26330 | +short offset into 7 bits. */ | |
26331 | + BFD_RELOC_AVR_7_PCREL, | |
26332 | + | |
26333 | +/* This is a 16 bit reloc for the AVR that stores 13 bit pc relative | |
26334 | +short offset into 12 bits. */ | |
26335 | + BFD_RELOC_AVR_13_PCREL, | |
26336 | + | |
26337 | +/* This is a 16 bit reloc for the AVR that stores 17 bit value (usually | |
26338 | +program memory address) into 16 bits. */ | |
26339 | + BFD_RELOC_AVR_16_PM, | |
26340 | + | |
26341 | +/* This is a 16 bit reloc for the AVR that stores 8 bit value (usually | |
26342 | +data memory address) into 8 bit immediate value of LDI insn. */ | |
26343 | + BFD_RELOC_AVR_LO8_LDI, | |
26344 | + | |
26345 | +/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit | |
26346 | +of data memory address) into 8 bit immediate value of LDI insn. */ | |
26347 | + BFD_RELOC_AVR_HI8_LDI, | |
26348 | + | |
26349 | +/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit | |
26350 | +of program memory address) into 8 bit immediate value of LDI insn. */ | |
26351 | + BFD_RELOC_AVR_HH8_LDI, | |
26352 | + | |
26353 | +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value | |
26354 | +(usually data memory address) into 8 bit immediate value of SUBI insn. */ | |
26355 | + BFD_RELOC_AVR_LO8_LDI_NEG, | |
26356 | + | |
26357 | +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value | |
26358 | +(high 8 bit of data memory address) into 8 bit immediate value of | |
26359 | +SUBI insn. */ | |
26360 | + BFD_RELOC_AVR_HI8_LDI_NEG, | |
26361 | + | |
26362 | +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value | |
26363 | +(most high 8 bit of program memory address) into 8 bit immediate value | |
26364 | +of LDI or SUBI insn. */ | |
26365 | + BFD_RELOC_AVR_HH8_LDI_NEG, | |
26366 | + | |
26367 | +/* This is a 16 bit reloc for the AVR that stores 8 bit value (usually | |
26368 | +command address) into 8 bit immediate value of LDI insn. */ | |
26369 | + BFD_RELOC_AVR_LO8_LDI_PM, | |
26370 | + | |
26371 | +/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit | |
26372 | +of command address) into 8 bit immediate value of LDI insn. */ | |
26373 | + BFD_RELOC_AVR_HI8_LDI_PM, | |
26374 | + | |
26375 | +/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit | |
26376 | +of command address) into 8 bit immediate value of LDI insn. */ | |
26377 | + BFD_RELOC_AVR_HH8_LDI_PM, | |
26378 | + | |
26379 | +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value | |
26380 | +(usually command address) into 8 bit immediate value of SUBI insn. */ | |
26381 | + BFD_RELOC_AVR_LO8_LDI_PM_NEG, | |
26382 | + | |
26383 | +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value | |
26384 | +(high 8 bit of 16 bit command address) into 8 bit immediate value | |
26385 | +of SUBI insn. */ | |
26386 | + BFD_RELOC_AVR_HI8_LDI_PM_NEG, | |
26387 | + | |
26388 | +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value | |
26389 | +(high 6 bit of 22 bit command address) into 8 bit immediate | |
26390 | +value of SUBI insn. */ | |
26391 | + BFD_RELOC_AVR_HH8_LDI_PM_NEG, | |
26392 | + | |
26393 | +/* This is a 32 bit reloc for the AVR that stores 23 bit value | |
26394 | +into 22 bits. */ | |
26395 | + BFD_RELOC_AVR_CALL, | |
26396 | + | |
26397 | +/* This is a 16 bit reloc for the AVR that stores all needed bits | |
26398 | +for absolute addressing with ldi with overflow check to linktime */ | |
26399 | + BFD_RELOC_AVR_LDI, | |
26400 | + | |
26401 | +/* This is a 6 bit reloc for the AVR that stores offset for ldd/std | |
26402 | +instructions */ | |
26403 | + BFD_RELOC_AVR_6, | |
26404 | + | |
26405 | +/* This is a 6 bit reloc for the AVR that stores offset for adiw/sbiw | |
26406 | +instructions */ | |
26407 | + BFD_RELOC_AVR_6_ADIW, | |
26408 | + | |
26409 | +/* Direct 12 bit. */ | |
26410 | + BFD_RELOC_390_12, | |
26411 | + | |
26412 | +/* 12 bit GOT offset. */ | |
26413 | + BFD_RELOC_390_GOT12, | |
26414 | + | |
26415 | +/* 32 bit PC relative PLT address. */ | |
26416 | + BFD_RELOC_390_PLT32, | |
26417 | + | |
26418 | +/* Copy symbol at runtime. */ | |
26419 | + BFD_RELOC_390_COPY, | |
26420 | + | |
26421 | +/* Create GOT entry. */ | |
26422 | + BFD_RELOC_390_GLOB_DAT, | |
26423 | + | |
26424 | +/* Create PLT entry. */ | |
26425 | + BFD_RELOC_390_JMP_SLOT, | |
26426 | + | |
26427 | +/* Adjust by program base. */ | |
26428 | + BFD_RELOC_390_RELATIVE, | |
26429 | + | |
26430 | +/* 32 bit PC relative offset to GOT. */ | |
26431 | + BFD_RELOC_390_GOTPC, | |
26432 | + | |
26433 | +/* 16 bit GOT offset. */ | |
26434 | + BFD_RELOC_390_GOT16, | |
26435 | + | |
26436 | +/* PC relative 16 bit shifted by 1. */ | |
26437 | + BFD_RELOC_390_PC16DBL, | |
26438 | + | |
26439 | +/* 16 bit PC rel. PLT shifted by 1. */ | |
26440 | + BFD_RELOC_390_PLT16DBL, | |
26441 | + | |
26442 | +/* PC relative 32 bit shifted by 1. */ | |
26443 | + BFD_RELOC_390_PC32DBL, | |
26444 | + | |
26445 | +/* 32 bit PC rel. PLT shifted by 1. */ | |
26446 | + BFD_RELOC_390_PLT32DBL, | |
26447 | + | |
26448 | +/* 32 bit PC rel. GOT shifted by 1. */ | |
26449 | + BFD_RELOC_390_GOTPCDBL, | |
26450 | + | |
26451 | +/* 64 bit GOT offset. */ | |
26452 | + BFD_RELOC_390_GOT64, | |
26453 | + | |
26454 | +/* 64 bit PC relative PLT address. */ | |
26455 | + BFD_RELOC_390_PLT64, | |
26456 | + | |
26457 | +/* 32 bit rel. offset to GOT entry. */ | |
26458 | + BFD_RELOC_390_GOTENT, | |
26459 | + | |
26460 | +/* 64 bit offset to GOT. */ | |
26461 | + BFD_RELOC_390_GOTOFF64, | |
26462 | + | |
26463 | +/* 12-bit offset to symbol-entry within GOT, with PLT handling. */ | |
26464 | + BFD_RELOC_390_GOTPLT12, | |
26465 | + | |
26466 | +/* 16-bit offset to symbol-entry within GOT, with PLT handling. */ | |
26467 | + BFD_RELOC_390_GOTPLT16, | |
26468 | + | |
26469 | +/* 32-bit offset to symbol-entry within GOT, with PLT handling. */ | |
26470 | + BFD_RELOC_390_GOTPLT32, | |
26471 | + | |
26472 | +/* 64-bit offset to symbol-entry within GOT, with PLT handling. */ | |
26473 | + BFD_RELOC_390_GOTPLT64, | |
26474 | + | |
26475 | +/* 32-bit rel. offset to symbol-entry within GOT, with PLT handling. */ | |
26476 | + BFD_RELOC_390_GOTPLTENT, | |
26477 | + | |
26478 | +/* 16-bit rel. offset from the GOT to a PLT entry. */ | |
26479 | + BFD_RELOC_390_PLTOFF16, | |
26480 | + | |
26481 | +/* 32-bit rel. offset from the GOT to a PLT entry. */ | |
26482 | + BFD_RELOC_390_PLTOFF32, | |
26483 | + | |
26484 | +/* 64-bit rel. offset from the GOT to a PLT entry. */ | |
26485 | + BFD_RELOC_390_PLTOFF64, | |
26486 | + | |
26487 | +/* s390 tls relocations. */ | |
26488 | + BFD_RELOC_390_TLS_LOAD, | |
26489 | + BFD_RELOC_390_TLS_GDCALL, | |
26490 | + BFD_RELOC_390_TLS_LDCALL, | |
26491 | + BFD_RELOC_390_TLS_GD32, | |
26492 | + BFD_RELOC_390_TLS_GD64, | |
26493 | + BFD_RELOC_390_TLS_GOTIE12, | |
26494 | + BFD_RELOC_390_TLS_GOTIE32, | |
26495 | + BFD_RELOC_390_TLS_GOTIE64, | |
26496 | + BFD_RELOC_390_TLS_LDM32, | |
26497 | + BFD_RELOC_390_TLS_LDM64, | |
26498 | + BFD_RELOC_390_TLS_IE32, | |
26499 | + BFD_RELOC_390_TLS_IE64, | |
26500 | + BFD_RELOC_390_TLS_IEENT, | |
26501 | + BFD_RELOC_390_TLS_LE32, | |
26502 | + BFD_RELOC_390_TLS_LE64, | |
26503 | + BFD_RELOC_390_TLS_LDO32, | |
26504 | + BFD_RELOC_390_TLS_LDO64, | |
26505 | + BFD_RELOC_390_TLS_DTPMOD, | |
26506 | + BFD_RELOC_390_TLS_DTPOFF, | |
26507 | + BFD_RELOC_390_TLS_TPOFF, | |
26508 | + | |
26509 | +/* Long displacement extension. */ | |
26510 | + BFD_RELOC_390_20, | |
26511 | + BFD_RELOC_390_GOT20, | |
26512 | + BFD_RELOC_390_GOTPLT20, | |
26513 | + BFD_RELOC_390_TLS_GOTIE20, | |
26514 | + | |
26515 | +/* Scenix IP2K - 9-bit register number / data address */ | |
26516 | + BFD_RELOC_IP2K_FR9, | |
26517 | + | |
26518 | +/* Scenix IP2K - 4-bit register/data bank number */ | |
26519 | + BFD_RELOC_IP2K_BANK, | |
26520 | + | |
26521 | +/* Scenix IP2K - low 13 bits of instruction word address */ | |
26522 | + BFD_RELOC_IP2K_ADDR16CJP, | |
26523 | + | |
26524 | +/* Scenix IP2K - high 3 bits of instruction word address */ | |
26525 | + BFD_RELOC_IP2K_PAGE3, | |
26526 | + | |
26527 | +/* Scenix IP2K - ext/low/high 8 bits of data address */ | |
26528 | + BFD_RELOC_IP2K_LO8DATA, | |
26529 | + BFD_RELOC_IP2K_HI8DATA, | |
26530 | + BFD_RELOC_IP2K_EX8DATA, | |
26531 | + | |
26532 | +/* Scenix IP2K - low/high 8 bits of instruction word address */ | |
26533 | + BFD_RELOC_IP2K_LO8INSN, | |
26534 | + BFD_RELOC_IP2K_HI8INSN, | |
26535 | + | |
26536 | +/* Scenix IP2K - even/odd PC modifier to modify snb pcl.0 */ | |
26537 | + BFD_RELOC_IP2K_PC_SKIP, | |
26538 | + | |
26539 | +/* Scenix IP2K - 16 bit word address in text section. */ | |
26540 | + BFD_RELOC_IP2K_TEXT, | |
26541 | + | |
26542 | +/* Scenix IP2K - 7-bit sp or dp offset */ | |
26543 | + BFD_RELOC_IP2K_FR_OFFSET, | |
26544 | + | |
26545 | +/* Scenix VPE4K coprocessor - data/insn-space addressing */ | |
26546 | + BFD_RELOC_VPE4KMATH_DATA, | |
26547 | + BFD_RELOC_VPE4KMATH_INSN, | |
26548 | + | |
26549 | +/* These two relocations are used by the linker to determine which of | |
26550 | +the entries in a C++ virtual function table are actually used. When | |
26551 | +the --gc-sections option is given, the linker will zero out the entries | |
26552 | +that are not used, so that the code for those functions need not be | |
26553 | +included in the output. | |
26554 | + | |
26555 | +VTABLE_INHERIT is a zero-space relocation used to describe to the | |
26556 | +linker the inheritance tree of a C++ virtual function table. The | |
26557 | +relocation's symbol should be the parent class' vtable, and the | |
26558 | +relocation should be located at the child vtable. | |
26559 | + | |
26560 | +VTABLE_ENTRY is a zero-space relocation that describes the use of a | |
26561 | +virtual function table entry. The reloc's symbol should refer to the | |
26562 | +table of the class mentioned in the code. Off of that base, an offset | |
26563 | +describes the entry that is being used. For Rela hosts, this offset | |
26564 | +is stored in the reloc's addend. For Rel hosts, we are forced to put | |
26565 | +this offset in the reloc's section offset. */ | |
26566 | + BFD_RELOC_VTABLE_INHERIT, | |
26567 | + BFD_RELOC_VTABLE_ENTRY, | |
26568 | + | |
26569 | +/* Intel IA64 Relocations. */ | |
26570 | + BFD_RELOC_IA64_IMM14, | |
26571 | + BFD_RELOC_IA64_IMM22, | |
26572 | + BFD_RELOC_IA64_IMM64, | |
26573 | + BFD_RELOC_IA64_DIR32MSB, | |
26574 | + BFD_RELOC_IA64_DIR32LSB, | |
26575 | + BFD_RELOC_IA64_DIR64MSB, | |
26576 | + BFD_RELOC_IA64_DIR64LSB, | |
26577 | + BFD_RELOC_IA64_GPREL22, | |
26578 | + BFD_RELOC_IA64_GPREL64I, | |
26579 | + BFD_RELOC_IA64_GPREL32MSB, | |
26580 | + BFD_RELOC_IA64_GPREL32LSB, | |
26581 | + BFD_RELOC_IA64_GPREL64MSB, | |
26582 | + BFD_RELOC_IA64_GPREL64LSB, | |
26583 | + BFD_RELOC_IA64_LTOFF22, | |
26584 | + BFD_RELOC_IA64_LTOFF64I, | |
26585 | + BFD_RELOC_IA64_PLTOFF22, | |
26586 | + BFD_RELOC_IA64_PLTOFF64I, | |
26587 | + BFD_RELOC_IA64_PLTOFF64MSB, | |
26588 | + BFD_RELOC_IA64_PLTOFF64LSB, | |
26589 | + BFD_RELOC_IA64_FPTR64I, | |
26590 | + BFD_RELOC_IA64_FPTR32MSB, | |
26591 | + BFD_RELOC_IA64_FPTR32LSB, | |
26592 | + BFD_RELOC_IA64_FPTR64MSB, | |
26593 | + BFD_RELOC_IA64_FPTR64LSB, | |
26594 | + BFD_RELOC_IA64_PCREL21B, | |
26595 | + BFD_RELOC_IA64_PCREL21BI, | |
26596 | + BFD_RELOC_IA64_PCREL21M, | |
26597 | + BFD_RELOC_IA64_PCREL21F, | |
26598 | + BFD_RELOC_IA64_PCREL22, | |
26599 | + BFD_RELOC_IA64_PCREL60B, | |
26600 | + BFD_RELOC_IA64_PCREL64I, | |
26601 | + BFD_RELOC_IA64_PCREL32MSB, | |
26602 | + BFD_RELOC_IA64_PCREL32LSB, | |
26603 | + BFD_RELOC_IA64_PCREL64MSB, | |
26604 | + BFD_RELOC_IA64_PCREL64LSB, | |
26605 | + BFD_RELOC_IA64_LTOFF_FPTR22, | |
26606 | + BFD_RELOC_IA64_LTOFF_FPTR64I, | |
26607 | + BFD_RELOC_IA64_LTOFF_FPTR32MSB, | |
26608 | + BFD_RELOC_IA64_LTOFF_FPTR32LSB, | |
26609 | + BFD_RELOC_IA64_LTOFF_FPTR64MSB, | |
26610 | + BFD_RELOC_IA64_LTOFF_FPTR64LSB, | |
26611 | + BFD_RELOC_IA64_SEGREL32MSB, | |
26612 | + BFD_RELOC_IA64_SEGREL32LSB, | |
26613 | + BFD_RELOC_IA64_SEGREL64MSB, | |
26614 | + BFD_RELOC_IA64_SEGREL64LSB, | |
26615 | + BFD_RELOC_IA64_SECREL32MSB, | |
26616 | + BFD_RELOC_IA64_SECREL32LSB, | |
26617 | + BFD_RELOC_IA64_SECREL64MSB, | |
26618 | + BFD_RELOC_IA64_SECREL64LSB, | |
26619 | + BFD_RELOC_IA64_REL32MSB, | |
26620 | + BFD_RELOC_IA64_REL32LSB, | |
26621 | + BFD_RELOC_IA64_REL64MSB, | |
26622 | + BFD_RELOC_IA64_REL64LSB, | |
26623 | + BFD_RELOC_IA64_LTV32MSB, | |
26624 | + BFD_RELOC_IA64_LTV32LSB, | |
26625 | + BFD_RELOC_IA64_LTV64MSB, | |
26626 | + BFD_RELOC_IA64_LTV64LSB, | |
26627 | + BFD_RELOC_IA64_IPLTMSB, | |
26628 | + BFD_RELOC_IA64_IPLTLSB, | |
26629 | + BFD_RELOC_IA64_COPY, | |
26630 | + BFD_RELOC_IA64_LTOFF22X, | |
26631 | + BFD_RELOC_IA64_LDXMOV, | |
26632 | + BFD_RELOC_IA64_TPREL14, | |
26633 | + BFD_RELOC_IA64_TPREL22, | |
26634 | + BFD_RELOC_IA64_TPREL64I, | |
26635 | + BFD_RELOC_IA64_TPREL64MSB, | |
26636 | + BFD_RELOC_IA64_TPREL64LSB, | |
26637 | + BFD_RELOC_IA64_LTOFF_TPREL22, | |
26638 | + BFD_RELOC_IA64_DTPMOD64MSB, | |
26639 | + BFD_RELOC_IA64_DTPMOD64LSB, | |
26640 | + BFD_RELOC_IA64_LTOFF_DTPMOD22, | |
26641 | + BFD_RELOC_IA64_DTPREL14, | |
26642 | + BFD_RELOC_IA64_DTPREL22, | |
26643 | + BFD_RELOC_IA64_DTPREL64I, | |
26644 | + BFD_RELOC_IA64_DTPREL32MSB, | |
26645 | + BFD_RELOC_IA64_DTPREL32LSB, | |
26646 | + BFD_RELOC_IA64_DTPREL64MSB, | |
26647 | + BFD_RELOC_IA64_DTPREL64LSB, | |
26648 | + BFD_RELOC_IA64_LTOFF_DTPREL22, | |
26649 | + | |
26650 | +/* Motorola 68HC11 reloc. | |
26651 | +This is the 8 bit high part of an absolute address. */ | |
26652 | + BFD_RELOC_M68HC11_HI8, | |
26653 | + | |
26654 | +/* Motorola 68HC11 reloc. | |
26655 | +This is the 8 bit low part of an absolute address. */ | |
26656 | + BFD_RELOC_M68HC11_LO8, | |
26657 | + | |
26658 | +/* Motorola 68HC11 reloc. | |
26659 | +This is the 3 bit of a value. */ | |
26660 | + BFD_RELOC_M68HC11_3B, | |
26661 | + | |
26662 | +/* Motorola 68HC11 reloc. | |
26663 | +This reloc marks the beginning of a jump/call instruction. | |
26664 | +It is used for linker relaxation to correctly identify beginning | |
26665 | +of instruction and change some branches to use PC-relative | |
26666 | +addressing mode. */ | |
26667 | + BFD_RELOC_M68HC11_RL_JUMP, | |
26668 | + | |
26669 | +/* Motorola 68HC11 reloc. | |
26670 | +This reloc marks a group of several instructions that gcc generates | |
26671 | +and for which the linker relaxation pass can modify and/or remove | |
26672 | +some of them. */ | |
26673 | + BFD_RELOC_M68HC11_RL_GROUP, | |
26674 | + | |
26675 | +/* Motorola 68HC11 reloc. | |
26676 | +This is the 16-bit lower part of an address. It is used for 'call' | |
26677 | +instruction to specify the symbol address without any special | |
26678 | +transformation (due to memory bank window). */ | |
26679 | + BFD_RELOC_M68HC11_LO16, | |
26680 | + | |
26681 | +/* Motorola 68HC11 reloc. | |
26682 | +This is a 8-bit reloc that specifies the page number of an address. | |
26683 | +It is used by 'call' instruction to specify the page number of | |
26684 | +the symbol. */ | |
26685 | + BFD_RELOC_M68HC11_PAGE, | |
26686 | + | |
26687 | +/* Motorola 68HC11 reloc. | |
26688 | +This is a 24-bit reloc that represents the address with a 16-bit | |
26689 | +value and a 8-bit page number. The symbol address is transformed | |
26690 | +to follow the 16K memory bank of 68HC12 (seen as mapped in the window). */ | |
26691 | + BFD_RELOC_M68HC11_24, | |
26692 | + | |
26693 | +/* Motorola 68HC12 reloc. | |
26694 | +This is the 5 bits of a value. */ | |
26695 | + BFD_RELOC_M68HC12_5B, | |
26696 | + | |
26697 | +/* NS CR16C Relocations. */ | |
26698 | + BFD_RELOC_16C_NUM08, | |
26699 | + BFD_RELOC_16C_NUM08_C, | |
26700 | + BFD_RELOC_16C_NUM16, | |
26701 | + BFD_RELOC_16C_NUM16_C, | |
26702 | + BFD_RELOC_16C_NUM32, | |
26703 | + BFD_RELOC_16C_NUM32_C, | |
26704 | + BFD_RELOC_16C_DISP04, | |
26705 | + BFD_RELOC_16C_DISP04_C, | |
26706 | + BFD_RELOC_16C_DISP08, | |
26707 | + BFD_RELOC_16C_DISP08_C, | |
26708 | + BFD_RELOC_16C_DISP16, | |
26709 | + BFD_RELOC_16C_DISP16_C, | |
26710 | + BFD_RELOC_16C_DISP24, | |
26711 | + BFD_RELOC_16C_DISP24_C, | |
26712 | + BFD_RELOC_16C_DISP24a, | |
26713 | + BFD_RELOC_16C_DISP24a_C, | |
26714 | + BFD_RELOC_16C_REG04, | |
26715 | + BFD_RELOC_16C_REG04_C, | |
26716 | + BFD_RELOC_16C_REG04a, | |
26717 | + BFD_RELOC_16C_REG04a_C, | |
26718 | + BFD_RELOC_16C_REG14, | |
26719 | + BFD_RELOC_16C_REG14_C, | |
26720 | + BFD_RELOC_16C_REG16, | |
26721 | + BFD_RELOC_16C_REG16_C, | |
26722 | + BFD_RELOC_16C_REG20, | |
26723 | + BFD_RELOC_16C_REG20_C, | |
26724 | + BFD_RELOC_16C_ABS20, | |
26725 | + BFD_RELOC_16C_ABS20_C, | |
26726 | + BFD_RELOC_16C_ABS24, | |
26727 | + BFD_RELOC_16C_ABS24_C, | |
26728 | + BFD_RELOC_16C_IMM04, | |
26729 | + BFD_RELOC_16C_IMM04_C, | |
26730 | + BFD_RELOC_16C_IMM16, | |
26731 | + BFD_RELOC_16C_IMM16_C, | |
26732 | + BFD_RELOC_16C_IMM20, | |
26733 | + BFD_RELOC_16C_IMM20_C, | |
26734 | + BFD_RELOC_16C_IMM24, | |
26735 | + BFD_RELOC_16C_IMM24_C, | |
26736 | + BFD_RELOC_16C_IMM32, | |
26737 | + BFD_RELOC_16C_IMM32_C, | |
26738 | + | |
26739 | +/* NS CRX Relocations. */ | |
26740 | + BFD_RELOC_CRX_REL4, | |
26741 | + BFD_RELOC_CRX_REL8, | |
26742 | + BFD_RELOC_CRX_REL8_CMP, | |
26743 | + BFD_RELOC_CRX_REL16, | |
26744 | + BFD_RELOC_CRX_REL24, | |
26745 | + BFD_RELOC_CRX_REL32, | |
26746 | + BFD_RELOC_CRX_REGREL12, | |
26747 | + BFD_RELOC_CRX_REGREL22, | |
26748 | + BFD_RELOC_CRX_REGREL28, | |
26749 | + BFD_RELOC_CRX_REGREL32, | |
26750 | + BFD_RELOC_CRX_ABS16, | |
26751 | + BFD_RELOC_CRX_ABS32, | |
26752 | + BFD_RELOC_CRX_NUM8, | |
26753 | + BFD_RELOC_CRX_NUM16, | |
26754 | + BFD_RELOC_CRX_NUM32, | |
26755 | + BFD_RELOC_CRX_IMM16, | |
26756 | + BFD_RELOC_CRX_IMM32, | |
26757 | + BFD_RELOC_CRX_SWITCH8, | |
26758 | + BFD_RELOC_CRX_SWITCH16, | |
26759 | + BFD_RELOC_CRX_SWITCH32, | |
26760 | + | |
26761 | +/* These relocs are only used within the CRIS assembler. They are not | |
26762 | +(at present) written to any object files. */ | |
26763 | + BFD_RELOC_CRIS_BDISP8, | |
26764 | + BFD_RELOC_CRIS_UNSIGNED_5, | |
26765 | + BFD_RELOC_CRIS_SIGNED_6, | |
26766 | + BFD_RELOC_CRIS_UNSIGNED_6, | |
26767 | + BFD_RELOC_CRIS_SIGNED_8, | |
26768 | + BFD_RELOC_CRIS_UNSIGNED_8, | |
26769 | + BFD_RELOC_CRIS_SIGNED_16, | |
26770 | + BFD_RELOC_CRIS_UNSIGNED_16, | |
26771 | + BFD_RELOC_CRIS_LAPCQ_OFFSET, | |
26772 | + BFD_RELOC_CRIS_UNSIGNED_4, | |
26773 | + | |
26774 | +/* Relocs used in ELF shared libraries for CRIS. */ | |
26775 | + BFD_RELOC_CRIS_COPY, | |
26776 | + BFD_RELOC_CRIS_GLOB_DAT, | |
26777 | + BFD_RELOC_CRIS_JUMP_SLOT, | |
26778 | + BFD_RELOC_CRIS_RELATIVE, | |
26779 | + | |
26780 | +/* 32-bit offset to symbol-entry within GOT. */ | |
26781 | + BFD_RELOC_CRIS_32_GOT, | |
26782 | + | |
26783 | +/* 16-bit offset to symbol-entry within GOT. */ | |
26784 | + BFD_RELOC_CRIS_16_GOT, | |
26785 | + | |
26786 | +/* 32-bit offset to symbol-entry within GOT, with PLT handling. */ | |
26787 | + BFD_RELOC_CRIS_32_GOTPLT, | |
26788 | + | |
26789 | +/* 16-bit offset to symbol-entry within GOT, with PLT handling. */ | |
26790 | + BFD_RELOC_CRIS_16_GOTPLT, | |
26791 | + | |
26792 | +/* 32-bit offset to symbol, relative to GOT. */ | |
26793 | + BFD_RELOC_CRIS_32_GOTREL, | |
26794 | + | |
26795 | +/* 32-bit offset to symbol with PLT entry, relative to GOT. */ | |
26796 | + BFD_RELOC_CRIS_32_PLT_GOTREL, | |
26797 | + | |
26798 | +/* 32-bit offset to symbol with PLT entry, relative to this relocation. */ | |
26799 | + BFD_RELOC_CRIS_32_PLT_PCREL, | |
26800 | + | |
26801 | +/* Intel i860 Relocations. */ | |
26802 | + BFD_RELOC_860_COPY, | |
26803 | + BFD_RELOC_860_GLOB_DAT, | |
26804 | + BFD_RELOC_860_JUMP_SLOT, | |
26805 | + BFD_RELOC_860_RELATIVE, | |
26806 | + BFD_RELOC_860_PC26, | |
26807 | + BFD_RELOC_860_PLT26, | |
26808 | + BFD_RELOC_860_PC16, | |
26809 | + BFD_RELOC_860_LOW0, | |
26810 | + BFD_RELOC_860_SPLIT0, | |
26811 | + BFD_RELOC_860_LOW1, | |
26812 | + BFD_RELOC_860_SPLIT1, | |
26813 | + BFD_RELOC_860_LOW2, | |
26814 | + BFD_RELOC_860_SPLIT2, | |
26815 | + BFD_RELOC_860_LOW3, | |
26816 | + BFD_RELOC_860_LOGOT0, | |
26817 | + BFD_RELOC_860_SPGOT0, | |
26818 | + BFD_RELOC_860_LOGOT1, | |
26819 | + BFD_RELOC_860_SPGOT1, | |
26820 | + BFD_RELOC_860_LOGOTOFF0, | |
26821 | + BFD_RELOC_860_SPGOTOFF0, | |
26822 | + BFD_RELOC_860_LOGOTOFF1, | |
26823 | + BFD_RELOC_860_SPGOTOFF1, | |
26824 | + BFD_RELOC_860_LOGOTOFF2, | |
26825 | + BFD_RELOC_860_LOGOTOFF3, | |
26826 | + BFD_RELOC_860_LOPC, | |
26827 | + BFD_RELOC_860_HIGHADJ, | |
26828 | + BFD_RELOC_860_HAGOT, | |
26829 | + BFD_RELOC_860_HAGOTOFF, | |
26830 | + BFD_RELOC_860_HAPC, | |
26831 | + BFD_RELOC_860_HIGH, | |
26832 | + BFD_RELOC_860_HIGOT, | |
26833 | + BFD_RELOC_860_HIGOTOFF, | |
26834 | + | |
26835 | +/* OpenRISC Relocations. */ | |
26836 | + BFD_RELOC_OPENRISC_ABS_26, | |
26837 | + BFD_RELOC_OPENRISC_REL_26, | |
26838 | + | |
26839 | +/* H8 elf Relocations. */ | |
26840 | + BFD_RELOC_H8_DIR16A8, | |
26841 | + BFD_RELOC_H8_DIR16R8, | |
26842 | + BFD_RELOC_H8_DIR24A8, | |
26843 | + BFD_RELOC_H8_DIR24R8, | |
26844 | + BFD_RELOC_H8_DIR32A16, | |
26845 | + | |
26846 | +/* Sony Xstormy16 Relocations. */ | |
26847 | + BFD_RELOC_XSTORMY16_REL_12, | |
26848 | + BFD_RELOC_XSTORMY16_12, | |
26849 | + BFD_RELOC_XSTORMY16_24, | |
26850 | + BFD_RELOC_XSTORMY16_FPTR16, | |
26851 | + | |
26852 | +/* Relocations used by VAX ELF. */ | |
26853 | + BFD_RELOC_VAX_GLOB_DAT, | |
26854 | + BFD_RELOC_VAX_JMP_SLOT, | |
26855 | + BFD_RELOC_VAX_RELATIVE, | |
26856 | + | |
26857 | +/* Morpho MS1 - 16 bit immediate relocation. */ | |
26858 | + BFD_RELOC_MS1_PC16, | |
26859 | + | |
26860 | +/* Morpho MS1 - Hi 16 bits of an address. */ | |
26861 | + BFD_RELOC_MS1_HI16, | |
26862 | + | |
26863 | +/* Morpho MS1 - Low 16 bits of an address. */ | |
26864 | + BFD_RELOC_MS1_LO16, | |
26865 | + | |
26866 | +/* Morpho MS1 - Used to tell the linker which vtable entries are used. */ | |
26867 | + BFD_RELOC_MS1_GNU_VTINHERIT, | |
26868 | + | |
26869 | +/* Morpho MS1 - Used to tell the linker which vtable entries are used. */ | |
26870 | + BFD_RELOC_MS1_GNU_VTENTRY, | |
26871 | + | |
26872 | +/* msp430 specific relocation codes */ | |
26873 | + BFD_RELOC_MSP430_10_PCREL, | |
26874 | + BFD_RELOC_MSP430_16_PCREL, | |
26875 | + BFD_RELOC_MSP430_16, | |
26876 | + BFD_RELOC_MSP430_16_PCREL_BYTE, | |
26877 | + BFD_RELOC_MSP430_16_BYTE, | |
26878 | + BFD_RELOC_MSP430_2X_PCREL, | |
26879 | + BFD_RELOC_MSP430_RL_PCREL, | |
26880 | + | |
26881 | +/* IQ2000 Relocations. */ | |
26882 | + BFD_RELOC_IQ2000_OFFSET_16, | |
26883 | + BFD_RELOC_IQ2000_OFFSET_21, | |
26884 | + BFD_RELOC_IQ2000_UHI16, | |
26885 | + | |
26886 | +/* Special Xtensa relocation used only by PLT entries in ELF shared | |
26887 | +objects to indicate that the runtime linker should set the value | |
26888 | +to one of its own internal functions or data structures. */ | |
26889 | + BFD_RELOC_XTENSA_RTLD, | |
26890 | + | |
26891 | +/* Xtensa relocations for ELF shared objects. */ | |
26892 | + BFD_RELOC_XTENSA_GLOB_DAT, | |
26893 | + BFD_RELOC_XTENSA_JMP_SLOT, | |
26894 | + BFD_RELOC_XTENSA_RELATIVE, | |
26895 | + | |
26896 | +/* Xtensa relocation used in ELF object files for symbols that may require | |
26897 | +PLT entries. Otherwise, this is just a generic 32-bit relocation. */ | |
26898 | + BFD_RELOC_XTENSA_PLT, | |
26899 | + | |
26900 | +/* Xtensa relocations to mark the difference of two local symbols. | |
26901 | +These are only needed to support linker relaxation and can be ignored | |
26902 | +when not relaxing. The field is set to the value of the difference | |
26903 | +assuming no relaxation. The relocation encodes the position of the | |
26904 | +first symbol so the linker can determine whether to adjust the field | |
26905 | +value. */ | |
26906 | + BFD_RELOC_XTENSA_DIFF8, | |
26907 | + BFD_RELOC_XTENSA_DIFF16, | |
26908 | + BFD_RELOC_XTENSA_DIFF32, | |
26909 | + | |
26910 | +/* Generic Xtensa relocations for instruction operands. Only the slot | |
26911 | +number is encoded in the relocation. The relocation applies to the | |
26912 | +last PC-relative immediate operand, or if there are no PC-relative | |
26913 | +immediates, to the last immediate operand. */ | |
26914 | + BFD_RELOC_XTENSA_SLOT0_OP, | |
26915 | + BFD_RELOC_XTENSA_SLOT1_OP, | |
26916 | + BFD_RELOC_XTENSA_SLOT2_OP, | |
26917 | + BFD_RELOC_XTENSA_SLOT3_OP, | |
26918 | + BFD_RELOC_XTENSA_SLOT4_OP, | |
26919 | + BFD_RELOC_XTENSA_SLOT5_OP, | |
26920 | + BFD_RELOC_XTENSA_SLOT6_OP, | |
26921 | + BFD_RELOC_XTENSA_SLOT7_OP, | |
26922 | + BFD_RELOC_XTENSA_SLOT8_OP, | |
26923 | + BFD_RELOC_XTENSA_SLOT9_OP, | |
26924 | + BFD_RELOC_XTENSA_SLOT10_OP, | |
26925 | + BFD_RELOC_XTENSA_SLOT11_OP, | |
26926 | + BFD_RELOC_XTENSA_SLOT12_OP, | |
26927 | + BFD_RELOC_XTENSA_SLOT13_OP, | |
26928 | + BFD_RELOC_XTENSA_SLOT14_OP, | |
26929 | + | |
26930 | +/* Alternate Xtensa relocations. Only the slot is encoded in the | |
26931 | +relocation. The meaning of these relocations is opcode-specific. */ | |
26932 | + BFD_RELOC_XTENSA_SLOT0_ALT, | |
26933 | + BFD_RELOC_XTENSA_SLOT1_ALT, | |
26934 | + BFD_RELOC_XTENSA_SLOT2_ALT, | |
26935 | + BFD_RELOC_XTENSA_SLOT3_ALT, | |
26936 | + BFD_RELOC_XTENSA_SLOT4_ALT, | |
26937 | + BFD_RELOC_XTENSA_SLOT5_ALT, | |
26938 | + BFD_RELOC_XTENSA_SLOT6_ALT, | |
26939 | + BFD_RELOC_XTENSA_SLOT7_ALT, | |
26940 | + BFD_RELOC_XTENSA_SLOT8_ALT, | |
26941 | + BFD_RELOC_XTENSA_SLOT9_ALT, | |
26942 | + BFD_RELOC_XTENSA_SLOT10_ALT, | |
26943 | + BFD_RELOC_XTENSA_SLOT11_ALT, | |
26944 | + BFD_RELOC_XTENSA_SLOT12_ALT, | |
26945 | + BFD_RELOC_XTENSA_SLOT13_ALT, | |
26946 | + BFD_RELOC_XTENSA_SLOT14_ALT, | |
26947 | + | |
26948 | +/* Xtensa relocations for backward compatibility. These have all been | |
26949 | +replaced by BFD_RELOC_XTENSA_SLOT0_OP. */ | |
26950 | + BFD_RELOC_XTENSA_OP0, | |
26951 | + BFD_RELOC_XTENSA_OP1, | |
26952 | + BFD_RELOC_XTENSA_OP2, | |
26953 | + | |
26954 | +/* Xtensa relocation to mark that the assembler expanded the | |
26955 | +instructions from an original target. The expansion size is | |
26956 | +encoded in the reloc size. */ | |
26957 | + BFD_RELOC_XTENSA_ASM_EXPAND, | |
26958 | + | |
26959 | +/* Xtensa relocation to mark that the linker should simplify | |
26960 | +assembler-expanded instructions. This is commonly used | |
26961 | +internally by the linker after analysis of a | |
26962 | +BFD_RELOC_XTENSA_ASM_EXPAND. */ | |
26963 | + BFD_RELOC_XTENSA_ASM_SIMPLIFY, | |
26964 | + BFD_RELOC_UNUSED }; | |
26965 | +typedef enum bfd_reloc_code_real bfd_reloc_code_real_type; | |
26966 | +reloc_howto_type *bfd_reloc_type_lookup | |
26967 | + (bfd *abfd, bfd_reloc_code_real_type code); | |
26968 | + | |
26969 | +const char *bfd_get_reloc_code_name (bfd_reloc_code_real_type code); | |
26970 | + | |
26971 | +/* Extracted from syms.c. */ | |
26972 | + | |
26973 | +typedef struct bfd_symbol | |
26974 | +{ | |
26975 | + /* A pointer to the BFD which owns the symbol. This information | |
26976 | + is necessary so that a back end can work out what additional | |
26977 | + information (invisible to the application writer) is carried | |
26978 | + with the symbol. | |
26979 | + | |
26980 | + This field is *almost* redundant, since you can use section->owner | |
26981 | + instead, except that some symbols point to the global sections | |
26982 | + bfd_{abs,com,und}_section. This could be fixed by making | |
26983 | + these globals be per-bfd (or per-target-flavor). FIXME. */ | |
26984 | + struct bfd *the_bfd; /* Use bfd_asymbol_bfd(sym) to access this field. */ | |
26985 | + | |
26986 | + /* The text of the symbol. The name is left alone, and not copied; the | |
26987 | + application may not alter it. */ | |
26988 | + const char *name; | |
26989 | + | |
26990 | + /* The value of the symbol. This really should be a union of a | |
26991 | + numeric value with a pointer, since some flags indicate that | |
26992 | + a pointer to another symbol is stored here. */ | |
26993 | + symvalue value; | |
26994 | + | |
26995 | + /* Attributes of a symbol. */ | |
26996 | +#define BSF_NO_FLAGS 0x00 | |
26997 | + | |
26998 | + /* The symbol has local scope; <<static>> in <<C>>. The value | |
26999 | + is the offset into the section of the data. */ | |
27000 | +#define BSF_LOCAL 0x01 | |
27001 | + | |
27002 | + /* The symbol has global scope; initialized data in <<C>>. The | |
27003 | + value is the offset into the section of the data. */ | |
27004 | +#define BSF_GLOBAL 0x02 | |
27005 | + | |
27006 | + /* The symbol has global scope and is exported. The value is | |
27007 | + the offset into the section of the data. */ | |
27008 | +#define BSF_EXPORT BSF_GLOBAL /* No real difference. */ | |
27009 | + | |
27010 | + /* A normal C symbol would be one of: | |
27011 | + <<BSF_LOCAL>>, <<BSF_FORT_COMM>>, <<BSF_UNDEFINED>> or | |
27012 | + <<BSF_GLOBAL>>. */ | |
27013 | + | |
27014 | + /* The symbol is a debugging record. The value has an arbitrary | |
27015 | + meaning, unless BSF_DEBUGGING_RELOC is also set. */ | |
27016 | +#define BSF_DEBUGGING 0x08 | |
27017 | + | |
27018 | + /* The symbol denotes a function entry point. Used in ELF, | |
27019 | + perhaps others someday. */ | |
27020 | +#define BSF_FUNCTION 0x10 | |
27021 | + | |
27022 | + /* Used by the linker. */ | |
27023 | +#define BSF_KEEP 0x20 | |
27024 | +#define BSF_KEEP_G 0x40 | |
27025 | + | |
27026 | + /* A weak global symbol, overridable without warnings by | |
27027 | + a regular global symbol of the same name. */ | |
27028 | +#define BSF_WEAK 0x80 | |
27029 | + | |
27030 | + /* This symbol was created to point to a section, e.g. ELF's | |
27031 | + STT_SECTION symbols. */ | |
27032 | +#define BSF_SECTION_SYM 0x100 | |
27033 | + | |
27034 | + /* The symbol used to be a common symbol, but now it is | |
27035 | + allocated. */ | |
27036 | +#define BSF_OLD_COMMON 0x200 | |
27037 | + | |
27038 | + /* The default value for common data. */ | |
27039 | +#define BFD_FORT_COMM_DEFAULT_VALUE 0 | |
27040 | + | |
27041 | + /* In some files the type of a symbol sometimes alters its | |
27042 | + location in an output file - ie in coff a <<ISFCN>> symbol | |
27043 | + which is also <<C_EXT>> symbol appears where it was | |
27044 | + declared and not at the end of a section. This bit is set | |
27045 | + by the target BFD part to convey this information. */ | |
27046 | +#define BSF_NOT_AT_END 0x400 | |
27047 | + | |
27048 | + /* Signal that the symbol is the label of constructor section. */ | |
27049 | +#define BSF_CONSTRUCTOR 0x800 | |
27050 | + | |
27051 | + /* Signal that the symbol is a warning symbol. The name is a | |
27052 | + warning. The name of the next symbol is the one to warn about; | |
27053 | + if a reference is made to a symbol with the same name as the next | |
27054 | + symbol, a warning is issued by the linker. */ | |
27055 | +#define BSF_WARNING 0x1000 | |
27056 | + | |
27057 | + /* Signal that the symbol is indirect. This symbol is an indirect | |
27058 | + pointer to the symbol with the same name as the next symbol. */ | |
27059 | +#define BSF_INDIRECT 0x2000 | |
27060 | + | |
27061 | + /* BSF_FILE marks symbols that contain a file name. This is used | |
27062 | + for ELF STT_FILE symbols. */ | |
27063 | +#define BSF_FILE 0x4000 | |
27064 | + | |
27065 | + /* Symbol is from dynamic linking information. */ | |
27066 | +#define BSF_DYNAMIC 0x8000 | |
27067 | + | |
27068 | + /* The symbol denotes a data object. Used in ELF, and perhaps | |
27069 | + others someday. */ | |
27070 | +#define BSF_OBJECT 0x10000 | |
27071 | + | |
27072 | + /* This symbol is a debugging symbol. The value is the offset | |
27073 | + into the section of the data. BSF_DEBUGGING should be set | |
27074 | + as well. */ | |
27075 | +#define BSF_DEBUGGING_RELOC 0x20000 | |
27076 | + | |
27077 | + /* This symbol is thread local. Used in ELF. */ | |
27078 | +#define BSF_THREAD_LOCAL 0x40000 | |
27079 | + | |
27080 | + flagword flags; | |
27081 | + | |
27082 | + /* A pointer to the section to which this symbol is | |
27083 | + relative. This will always be non NULL, there are special | |
27084 | + sections for undefined and absolute symbols. */ | |
27085 | + struct bfd_section *section; | |
27086 | + | |
27087 | + /* Back end special data. */ | |
27088 | + union | |
27089 | + { | |
27090 | + void *p; | |
27091 | + bfd_vma i; | |
27092 | + } | |
27093 | + udata; | |
27094 | +} | |
27095 | +asymbol; | |
27096 | + | |
27097 | +#define bfd_get_symtab_upper_bound(abfd) \ | |
27098 | + BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd)) | |
27099 | + | |
27100 | +bfd_boolean bfd_is_local_label (bfd *abfd, asymbol *sym); | |
27101 | + | |
27102 | +bfd_boolean bfd_is_local_label_name (bfd *abfd, const char *name); | |
27103 | + | |
27104 | +#define bfd_is_local_label_name(abfd, name) \ | |
27105 | + BFD_SEND (abfd, _bfd_is_local_label_name, (abfd, name)) | |
27106 | + | |
27107 | +bfd_boolean bfd_is_target_special_symbol (bfd *abfd, asymbol *sym); | |
27108 | + | |
27109 | +#define bfd_is_target_special_symbol(abfd, sym) \ | |
27110 | + BFD_SEND (abfd, _bfd_is_target_special_symbol, (abfd, sym)) | |
27111 | + | |
27112 | +#define bfd_canonicalize_symtab(abfd, location) \ | |
27113 | + BFD_SEND (abfd, _bfd_canonicalize_symtab, (abfd, location)) | |
27114 | + | |
27115 | +bfd_boolean bfd_set_symtab | |
27116 | + (bfd *abfd, asymbol **location, unsigned int count); | |
27117 | + | |
27118 | +void bfd_print_symbol_vandf (bfd *abfd, void *file, asymbol *symbol); | |
27119 | + | |
27120 | +#define bfd_make_empty_symbol(abfd) \ | |
27121 | + BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd)) | |
27122 | + | |
27123 | +asymbol *_bfd_generic_make_empty_symbol (bfd *); | |
27124 | + | |
27125 | +#define bfd_make_debug_symbol(abfd,ptr,size) \ | |
27126 | + BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size)) | |
27127 | + | |
27128 | +int bfd_decode_symclass (asymbol *symbol); | |
27129 | + | |
27130 | +bfd_boolean bfd_is_undefined_symclass (int symclass); | |
27131 | + | |
27132 | +void bfd_symbol_info (asymbol *symbol, symbol_info *ret); | |
27133 | + | |
27134 | +bfd_boolean bfd_copy_private_symbol_data | |
27135 | + (bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym); | |
27136 | + | |
27137 | +#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \ | |
27138 | + BFD_SEND (obfd, _bfd_copy_private_symbol_data, \ | |
27139 | + (ibfd, isymbol, obfd, osymbol)) | |
27140 | + | |
27141 | +/* Extracted from bfd.c. */ | |
27142 | +struct bfd | |
27143 | +{ | |
27144 | + /* A unique identifier of the BFD */ | |
27145 | + unsigned int id; | |
27146 | + | |
27147 | + /* The filename the application opened the BFD with. */ | |
27148 | + const char *filename; | |
27149 | + | |
27150 | + /* A pointer to the target jump table. */ | |
27151 | + const struct bfd_target *xvec; | |
27152 | + | |
27153 | + /* The IOSTREAM, and corresponding IO vector that provide access | |
27154 | + to the file backing the BFD. */ | |
27155 | + void *iostream; | |
27156 | + const struct bfd_iovec *iovec; | |
27157 | + | |
27158 | + /* Is the file descriptor being cached? That is, can it be closed as | |
27159 | + needed, and re-opened when accessed later? */ | |
27160 | + bfd_boolean cacheable; | |
27161 | + | |
27162 | + /* Marks whether there was a default target specified when the | |
27163 | + BFD was opened. This is used to select which matching algorithm | |
27164 | + to use to choose the back end. */ | |
27165 | + bfd_boolean target_defaulted; | |
27166 | + | |
27167 | + /* The caching routines use these to maintain a | |
27168 | + least-recently-used list of BFDs. */ | |
27169 | + struct bfd *lru_prev, *lru_next; | |
27170 | + | |
27171 | + /* When a file is closed by the caching routines, BFD retains | |
27172 | + state information on the file here... */ | |
27173 | + ufile_ptr where; | |
27174 | + | |
27175 | + /* ... and here: (``once'' means at least once). */ | |
27176 | + bfd_boolean opened_once; | |
27177 | + | |
27178 | + /* Set if we have a locally maintained mtime value, rather than | |
27179 | + getting it from the file each time. */ | |
27180 | + bfd_boolean mtime_set; | |
27181 | + | |
27182 | + /* File modified time, if mtime_set is TRUE. */ | |
27183 | + long mtime; | |
27184 | + | |
27185 | + /* Reserved for an unimplemented file locking extension. */ | |
27186 | + int ifd; | |
27187 | + | |
27188 | + /* The format which belongs to the BFD. (object, core, etc.) */ | |
27189 | + bfd_format format; | |
27190 | + | |
27191 | + /* The direction with which the BFD was opened. */ | |
27192 | + enum bfd_direction | |
27193 | + { | |
27194 | + no_direction = 0, | |
27195 | + read_direction = 1, | |
27196 | + write_direction = 2, | |
27197 | + both_direction = 3 | |
27198 | + } | |
27199 | + direction; | |
27200 | + | |
27201 | + /* Format_specific flags. */ | |
27202 | + flagword flags; | |
27203 | + | |
27204 | + /* Currently my_archive is tested before adding origin to | |
27205 | + anything. I believe that this can become always an add of | |
27206 | + origin, with origin set to 0 for non archive files. */ | |
27207 | + ufile_ptr origin; | |
27208 | + | |
27209 | + /* Remember when output has begun, to stop strange things | |
27210 | + from happening. */ | |
27211 | + bfd_boolean output_has_begun; | |
27212 | + | |
27213 | + /* A hash table for section names. */ | |
27214 | + struct bfd_hash_table section_htab; | |
27215 | + | |
27216 | + /* Pointer to linked list of sections. */ | |
27217 | + struct bfd_section *sections; | |
27218 | + | |
27219 | + /* The last section on the section list. */ | |
27220 | + struct bfd_section *section_last; | |
27221 | + | |
27222 | + /* The number of sections. */ | |
27223 | + unsigned int section_count; | |
27224 | + | |
27225 | + /* Stuff only useful for object files: | |
27226 | + The start address. */ | |
27227 | + bfd_vma start_address; | |
27228 | + | |
27229 | + /* Used for input and output. */ | |
27230 | + unsigned int symcount; | |
27231 | + | |
27232 | + /* Symbol table for output BFD (with symcount entries). */ | |
27233 | + struct bfd_symbol **outsymbols; | |
27234 | + | |
27235 | + /* Used for slurped dynamic symbol tables. */ | |
27236 | + unsigned int dynsymcount; | |
27237 | + | |
27238 | + /* Pointer to structure which contains architecture information. */ | |
27239 | + const struct bfd_arch_info *arch_info; | |
27240 | + | |
27241 | + /* Flag set if symbols from this BFD should not be exported. */ | |
27242 | + bfd_boolean no_export; | |
27243 | + | |
27244 | + /* Stuff only useful for archives. */ | |
27245 | + void *arelt_data; | |
27246 | + struct bfd *my_archive; /* The containing archive BFD. */ | |
27247 | + struct bfd *next; /* The next BFD in the archive. */ | |
27248 | + struct bfd *archive_head; /* The first BFD in the archive. */ | |
27249 | + bfd_boolean has_armap; | |
27250 | + | |
27251 | + /* A chain of BFD structures involved in a link. */ | |
27252 | + struct bfd *link_next; | |
27253 | + | |
27254 | + /* A field used by _bfd_generic_link_add_archive_symbols. This will | |
27255 | + be used only for archive elements. */ | |
27256 | + int archive_pass; | |
27257 | + | |
27258 | + /* Used by the back end to hold private data. */ | |
27259 | + union | |
27260 | + { | |
27261 | + struct aout_data_struct *aout_data; | |
27262 | + struct artdata *aout_ar_data; | |
27263 | + struct _oasys_data *oasys_obj_data; | |
27264 | + struct _oasys_ar_data *oasys_ar_data; | |
27265 | + struct coff_tdata *coff_obj_data; | |
27266 | + struct pe_tdata *pe_obj_data; | |
27267 | + struct xcoff_tdata *xcoff_obj_data; | |
27268 | + struct ecoff_tdata *ecoff_obj_data; | |
27269 | + struct ieee_data_struct *ieee_data; | |
27270 | + struct ieee_ar_data_struct *ieee_ar_data; | |
27271 | + struct srec_data_struct *srec_data; | |
27272 | + struct ihex_data_struct *ihex_data; | |
27273 | + struct tekhex_data_struct *tekhex_data; | |
27274 | + struct elf_obj_tdata *elf_obj_data; | |
27275 | + struct nlm_obj_tdata *nlm_obj_data; | |
27276 | + struct bout_data_struct *bout_data; | |
27277 | + struct mmo_data_struct *mmo_data; | |
27278 | + struct sun_core_struct *sun_core_data; | |
27279 | + struct sco5_core_struct *sco5_core_data; | |
27280 | + struct trad_core_struct *trad_core_data; | |
27281 | + struct som_data_struct *som_data; | |
27282 | + struct hpux_core_struct *hpux_core_data; | |
27283 | + struct hppabsd_core_struct *hppabsd_core_data; | |
27284 | + struct sgi_core_struct *sgi_core_data; | |
27285 | + struct lynx_core_struct *lynx_core_data; | |
27286 | + struct osf_core_struct *osf_core_data; | |
27287 | + struct cisco_core_struct *cisco_core_data; | |
27288 | + struct versados_data_struct *versados_data; | |
27289 | + struct netbsd_core_struct *netbsd_core_data; | |
27290 | + struct mach_o_data_struct *mach_o_data; | |
27291 | + struct mach_o_fat_data_struct *mach_o_fat_data; | |
27292 | + struct bfd_pef_data_struct *pef_data; | |
27293 | + struct bfd_pef_xlib_data_struct *pef_xlib_data; | |
27294 | + struct bfd_sym_data_struct *sym_data; | |
27295 | + void *any; | |
27296 | + } | |
27297 | + tdata; | |
27298 | + | |
27299 | + /* Used by the application to hold private data. */ | |
27300 | + void *usrdata; | |
27301 | + | |
27302 | + /* Where all the allocated stuff under this BFD goes. This is a | |
27303 | + struct objalloc *, but we use void * to avoid requiring the inclusion | |
27304 | + of objalloc.h. */ | |
27305 | + void *memory; | |
27306 | +}; | |
27307 | + | |
27308 | +typedef enum bfd_error | |
27309 | +{ | |
27310 | + bfd_error_no_error = 0, | |
27311 | + bfd_error_system_call, | |
27312 | + bfd_error_invalid_target, | |
27313 | + bfd_error_wrong_format, | |
27314 | + bfd_error_wrong_object_format, | |
27315 | + bfd_error_invalid_operation, | |
27316 | + bfd_error_no_memory, | |
27317 | + bfd_error_no_symbols, | |
27318 | + bfd_error_no_armap, | |
27319 | + bfd_error_no_more_archived_files, | |
27320 | + bfd_error_malformed_archive, | |
27321 | + bfd_error_file_not_recognized, | |
27322 | + bfd_error_file_ambiguously_recognized, | |
27323 | + bfd_error_no_contents, | |
27324 | + bfd_error_nonrepresentable_section, | |
27325 | + bfd_error_no_debug_section, | |
27326 | + bfd_error_bad_value, | |
27327 | + bfd_error_file_truncated, | |
27328 | + bfd_error_file_too_big, | |
27329 | + bfd_error_invalid_error_code | |
27330 | +} | |
27331 | +bfd_error_type; | |
27332 | + | |
27333 | +bfd_error_type bfd_get_error (void); | |
27334 | + | |
27335 | +void bfd_set_error (bfd_error_type error_tag); | |
27336 | + | |
27337 | +const char *bfd_errmsg (bfd_error_type error_tag); | |
27338 | + | |
27339 | +void bfd_perror (const char *message); | |
27340 | + | |
27341 | +typedef void (*bfd_error_handler_type) (const char *, ...); | |
27342 | + | |
27343 | +bfd_error_handler_type bfd_set_error_handler (bfd_error_handler_type); | |
27344 | + | |
27345 | +void bfd_set_error_program_name (const char *); | |
27346 | + | |
27347 | +bfd_error_handler_type bfd_get_error_handler (void); | |
27348 | + | |
27349 | +long bfd_get_reloc_upper_bound (bfd *abfd, asection *sect); | |
27350 | + | |
27351 | +long bfd_canonicalize_reloc | |
27352 | + (bfd *abfd, asection *sec, arelent **loc, asymbol **syms); | |
27353 | + | |
27354 | +void bfd_set_reloc | |
27355 | + (bfd *abfd, asection *sec, arelent **rel, unsigned int count); | |
27356 | + | |
27357 | +bfd_boolean bfd_set_file_flags (bfd *abfd, flagword flags); | |
27358 | + | |
27359 | +int bfd_get_arch_size (bfd *abfd); | |
27360 | + | |
27361 | +int bfd_get_sign_extend_vma (bfd *abfd); | |
27362 | + | |
27363 | +bfd_boolean bfd_set_start_address (bfd *abfd, bfd_vma vma); | |
27364 | + | |
27365 | +unsigned int bfd_get_gp_size (bfd *abfd); | |
27366 | + | |
27367 | +void bfd_set_gp_size (bfd *abfd, unsigned int i); | |
27368 | + | |
27369 | +bfd_vma bfd_scan_vma (const char *string, const char **end, int base); | |
27370 | + | |
27371 | +bfd_boolean bfd_copy_private_header_data (bfd *ibfd, bfd *obfd); | |
27372 | + | |
27373 | +#define bfd_copy_private_header_data(ibfd, obfd) \ | |
27374 | + BFD_SEND (obfd, _bfd_copy_private_header_data, \ | |
27375 | + (ibfd, obfd)) | |
27376 | +bfd_boolean bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd); | |
27377 | + | |
27378 | +#define bfd_copy_private_bfd_data(ibfd, obfd) \ | |
27379 | + BFD_SEND (obfd, _bfd_copy_private_bfd_data, \ | |
27380 | + (ibfd, obfd)) | |
27381 | +bfd_boolean bfd_merge_private_bfd_data (bfd *ibfd, bfd *obfd); | |
27382 | + | |
27383 | +#define bfd_merge_private_bfd_data(ibfd, obfd) \ | |
27384 | + BFD_SEND (obfd, _bfd_merge_private_bfd_data, \ | |
27385 | + (ibfd, obfd)) | |
27386 | +bfd_boolean bfd_set_private_flags (bfd *abfd, flagword flags); | |
27387 | + | |
27388 | +#define bfd_set_private_flags(abfd, flags) \ | |
27389 | + BFD_SEND (abfd, _bfd_set_private_flags, (abfd, flags)) | |
27390 | +#define bfd_sizeof_headers(abfd, reloc) \ | |
27391 | + BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc)) | |
27392 | + | |
27393 | +#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \ | |
27394 | + BFD_SEND (abfd, _bfd_find_nearest_line, \ | |
27395 | + (abfd, sec, syms, off, file, func, line)) | |
27396 | + | |
27397 | +#define bfd_find_line(abfd, syms, sym, file, line) \ | |
27398 | + BFD_SEND (abfd, _bfd_find_line, \ | |
27399 | + (abfd, syms, sym, file, line)) | |
27400 | + | |
27401 | +#define bfd_find_inliner_info(abfd, file, func, line) \ | |
27402 | + BFD_SEND (abfd, _bfd_find_inliner_info, \ | |
27403 | + (abfd, file, func, line)) | |
27404 | + | |
27405 | +#define bfd_debug_info_start(abfd) \ | |
27406 | + BFD_SEND (abfd, _bfd_debug_info_start, (abfd)) | |
27407 | + | |
27408 | +#define bfd_debug_info_end(abfd) \ | |
27409 | + BFD_SEND (abfd, _bfd_debug_info_end, (abfd)) | |
27410 | + | |
27411 | +#define bfd_debug_info_accumulate(abfd, section) \ | |
27412 | + BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section)) | |
27413 | + | |
27414 | +#define bfd_stat_arch_elt(abfd, stat) \ | |
27415 | + BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat)) | |
27416 | + | |
27417 | +#define bfd_update_armap_timestamp(abfd) \ | |
27418 | + BFD_SEND (abfd, _bfd_update_armap_timestamp, (abfd)) | |
27419 | + | |
27420 | +#define bfd_set_arch_mach(abfd, arch, mach)\ | |
27421 | + BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach)) | |
27422 | + | |
27423 | +#define bfd_relax_section(abfd, section, link_info, again) \ | |
27424 | + BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again)) | |
27425 | + | |
27426 | +#define bfd_gc_sections(abfd, link_info) \ | |
27427 | + BFD_SEND (abfd, _bfd_gc_sections, (abfd, link_info)) | |
27428 | + | |
27429 | +#define bfd_merge_sections(abfd, link_info) \ | |
27430 | + BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info)) | |
27431 | + | |
27432 | +#define bfd_is_group_section(abfd, sec) \ | |
27433 | + BFD_SEND (abfd, _bfd_is_group_section, (abfd, sec)) | |
27434 | + | |
27435 | +#define bfd_discard_group(abfd, sec) \ | |
27436 | + BFD_SEND (abfd, _bfd_discard_group, (abfd, sec)) | |
27437 | + | |
27438 | +#define bfd_link_hash_table_create(abfd) \ | |
27439 | + BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd)) | |
27440 | + | |
27441 | +#define bfd_link_hash_table_free(abfd, hash) \ | |
27442 | + BFD_SEND (abfd, _bfd_link_hash_table_free, (hash)) | |
27443 | + | |
27444 | +#define bfd_link_add_symbols(abfd, info) \ | |
27445 | + BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info)) | |
27446 | + | |
27447 | +#define bfd_link_just_syms(abfd, sec, info) \ | |
27448 | + BFD_SEND (abfd, _bfd_link_just_syms, (sec, info)) | |
27449 | + | |
27450 | +#define bfd_final_link(abfd, info) \ | |
27451 | + BFD_SEND (abfd, _bfd_final_link, (abfd, info)) | |
27452 | + | |
27453 | +#define bfd_free_cached_info(abfd) \ | |
27454 | + BFD_SEND (abfd, _bfd_free_cached_info, (abfd)) | |
27455 | + | |
27456 | +#define bfd_get_dynamic_symtab_upper_bound(abfd) \ | |
27457 | + BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd)) | |
27458 | + | |
27459 | +#define bfd_print_private_bfd_data(abfd, file)\ | |
27460 | + BFD_SEND (abfd, _bfd_print_private_bfd_data, (abfd, file)) | |
27461 | + | |
27462 | +#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \ | |
27463 | + BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols)) | |
27464 | + | |
27465 | +#define bfd_get_synthetic_symtab(abfd, count, syms, dyncount, dynsyms, ret) \ | |
27466 | + BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, count, syms, \ | |
27467 | + dyncount, dynsyms, ret)) | |
27468 | + | |
27469 | +#define bfd_get_dynamic_reloc_upper_bound(abfd) \ | |
27470 | + BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd)) | |
27471 | + | |
27472 | +#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \ | |
27473 | + BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms)) | |
27474 | + | |
27475 | +extern bfd_byte *bfd_get_relocated_section_contents | |
27476 | + (bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *, | |
27477 | + bfd_boolean, asymbol **); | |
27478 | + | |
27479 | +bfd_boolean bfd_alt_mach_code (bfd *abfd, int alternative); | |
27480 | + | |
27481 | +struct bfd_preserve | |
27482 | +{ | |
27483 | + void *marker; | |
27484 | + void *tdata; | |
27485 | + flagword flags; | |
27486 | + const struct bfd_arch_info *arch_info; | |
27487 | + struct bfd_section *sections; | |
27488 | + struct bfd_section *section_last; | |
27489 | + unsigned int section_count; | |
27490 | + struct bfd_hash_table section_htab; | |
27491 | +}; | |
27492 | + | |
27493 | +bfd_boolean bfd_preserve_save (bfd *, struct bfd_preserve *); | |
27494 | + | |
27495 | +void bfd_preserve_restore (bfd *, struct bfd_preserve *); | |
27496 | + | |
27497 | +void bfd_preserve_finish (bfd *, struct bfd_preserve *); | |
27498 | + | |
27499 | +/* Extracted from archive.c. */ | |
27500 | +symindex bfd_get_next_mapent | |
27501 | + (bfd *abfd, symindex previous, carsym **sym); | |
27502 | + | |
27503 | +bfd_boolean bfd_set_archive_head (bfd *output, bfd *new_head); | |
27504 | + | |
27505 | +bfd *bfd_openr_next_archived_file (bfd *archive, bfd *previous); | |
27506 | + | |
27507 | +/* Extracted from corefile.c. */ | |
27508 | +const char *bfd_core_file_failing_command (bfd *abfd); | |
27509 | + | |
27510 | +int bfd_core_file_failing_signal (bfd *abfd); | |
27511 | + | |
27512 | +bfd_boolean core_file_matches_executable_p | |
27513 | + (bfd *core_bfd, bfd *exec_bfd); | |
27514 | + | |
27515 | +/* Extracted from targets.c. */ | |
27516 | +#define BFD_SEND(bfd, message, arglist) \ | |
27517 | + ((*((bfd)->xvec->message)) arglist) | |
27518 | + | |
27519 | +#ifdef DEBUG_BFD_SEND | |
27520 | +#undef BFD_SEND | |
27521 | +#define BFD_SEND(bfd, message, arglist) \ | |
27522 | + (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ | |
27523 | + ((*((bfd)->xvec->message)) arglist) : \ | |
27524 | + (bfd_assert (__FILE__,__LINE__), NULL)) | |
27525 | +#endif | |
27526 | +#define BFD_SEND_FMT(bfd, message, arglist) \ | |
27527 | + (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist) | |
27528 | + | |
27529 | +#ifdef DEBUG_BFD_SEND | |
27530 | +#undef BFD_SEND_FMT | |
27531 | +#define BFD_SEND_FMT(bfd, message, arglist) \ | |
27532 | + (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ | |
27533 | + (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist) : \ | |
27534 | + (bfd_assert (__FILE__,__LINE__), NULL)) | |
27535 | +#endif | |
27536 | + | |
27537 | +enum bfd_flavour | |
27538 | +{ | |
27539 | + bfd_target_unknown_flavour, | |
27540 | + bfd_target_aout_flavour, | |
27541 | + bfd_target_coff_flavour, | |
27542 | + bfd_target_ecoff_flavour, | |
27543 | + bfd_target_xcoff_flavour, | |
27544 | + bfd_target_elf_flavour, | |
27545 | + bfd_target_ieee_flavour, | |
27546 | + bfd_target_nlm_flavour, | |
27547 | + bfd_target_oasys_flavour, | |
27548 | + bfd_target_tekhex_flavour, | |
27549 | + bfd_target_srec_flavour, | |
27550 | + bfd_target_ihex_flavour, | |
27551 | + bfd_target_som_flavour, | |
27552 | + bfd_target_os9k_flavour, | |
27553 | + bfd_target_versados_flavour, | |
27554 | + bfd_target_msdos_flavour, | |
27555 | + bfd_target_ovax_flavour, | |
27556 | + bfd_target_evax_flavour, | |
27557 | + bfd_target_mmo_flavour, | |
27558 | + bfd_target_mach_o_flavour, | |
27559 | + bfd_target_pef_flavour, | |
27560 | + bfd_target_pef_xlib_flavour, | |
27561 | + bfd_target_sym_flavour | |
27562 | +}; | |
27563 | + | |
27564 | +enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN }; | |
27565 | + | |
27566 | +/* Forward declaration. */ | |
27567 | +typedef struct bfd_link_info _bfd_link_info; | |
27568 | + | |
27569 | +typedef struct bfd_target | |
27570 | +{ | |
27571 | + /* Identifies the kind of target, e.g., SunOS4, Ultrix, etc. */ | |
27572 | + char *name; | |
27573 | + | |
27574 | + /* The "flavour" of a back end is a general indication about | |
27575 | + the contents of a file. */ | |
27576 | + enum bfd_flavour flavour; | |
27577 | + | |
27578 | + /* The order of bytes within the data area of a file. */ | |
27579 | + enum bfd_endian byteorder; | |
27580 | + | |
27581 | + /* The order of bytes within the header parts of a file. */ | |
27582 | + enum bfd_endian header_byteorder; | |
27583 | + | |
27584 | + /* A mask of all the flags which an executable may have set - | |
27585 | + from the set <<BFD_NO_FLAGS>>, <<HAS_RELOC>>, ...<<D_PAGED>>. */ | |
27586 | + flagword object_flags; | |
27587 | + | |
27588 | + /* A mask of all the flags which a section may have set - from | |
27589 | + the set <<SEC_NO_FLAGS>>, <<SEC_ALLOC>>, ...<<SET_NEVER_LOAD>>. */ | |
27590 | + flagword section_flags; | |
27591 | + | |
27592 | + /* The character normally found at the front of a symbol. | |
27593 | + (if any), perhaps `_'. */ | |
27594 | + char symbol_leading_char; | |
27595 | + | |
27596 | + /* The pad character for file names within an archive header. */ | |
27597 | + char ar_pad_char; | |
27598 | + | |
27599 | + /* The maximum number of characters in an archive header. */ | |
27600 | + unsigned short ar_max_namelen; | |
27601 | + | |
27602 | + /* Entries for byte swapping for data. These are different from the | |
27603 | + other entry points, since they don't take a BFD as the first argument. | |
27604 | + Certain other handlers could do the same. */ | |
27605 | + bfd_uint64_t (*bfd_getx64) (const void *); | |
27606 | + bfd_int64_t (*bfd_getx_signed_64) (const void *); | |
27607 | + void (*bfd_putx64) (bfd_uint64_t, void *); | |
27608 | + bfd_vma (*bfd_getx32) (const void *); | |
27609 | + bfd_signed_vma (*bfd_getx_signed_32) (const void *); | |
27610 | + void (*bfd_putx32) (bfd_vma, void *); | |
27611 | + bfd_vma (*bfd_getx16) (const void *); | |
27612 | + bfd_signed_vma (*bfd_getx_signed_16) (const void *); | |
27613 | + void (*bfd_putx16) (bfd_vma, void *); | |
27614 | + | |
27615 | + /* Byte swapping for the headers. */ | |
27616 | + bfd_uint64_t (*bfd_h_getx64) (const void *); | |
27617 | + bfd_int64_t (*bfd_h_getx_signed_64) (const void *); | |
27618 | + void (*bfd_h_putx64) (bfd_uint64_t, void *); | |
27619 | + bfd_vma (*bfd_h_getx32) (const void *); | |
27620 | + bfd_signed_vma (*bfd_h_getx_signed_32) (const void *); | |
27621 | + void (*bfd_h_putx32) (bfd_vma, void *); | |
27622 | + bfd_vma (*bfd_h_getx16) (const void *); | |
27623 | + bfd_signed_vma (*bfd_h_getx_signed_16) (const void *); | |
27624 | + void (*bfd_h_putx16) (bfd_vma, void *); | |
27625 | + | |
27626 | + /* Format dependent routines: these are vectors of entry points | |
27627 | + within the target vector structure, one for each format to check. */ | |
27628 | + | |
27629 | + /* Check the format of a file being read. Return a <<bfd_target *>> or zero. */ | |
27630 | + const struct bfd_target *(*_bfd_check_format[bfd_type_end]) (bfd *); | |
27631 | + | |
27632 | + /* Set the format of a file being written. */ | |
27633 | + bfd_boolean (*_bfd_set_format[bfd_type_end]) (bfd *); | |
27634 | + | |
27635 | + /* Write cached information into a file being written, at <<bfd_close>>. */ | |
27636 | + bfd_boolean (*_bfd_write_contents[bfd_type_end]) (bfd *); | |
27637 | + | |
27638 | + | |
27639 | + /* Generic entry points. */ | |
27640 | +#define BFD_JUMP_TABLE_GENERIC(NAME) \ | |
27641 | + NAME##_close_and_cleanup, \ | |
27642 | + NAME##_bfd_free_cached_info, \ | |
27643 | + NAME##_new_section_hook, \ | |
27644 | + NAME##_get_section_contents, \ | |
27645 | + NAME##_get_section_contents_in_window | |
27646 | + | |
27647 | + /* Called when the BFD is being closed to do any necessary cleanup. */ | |
27648 | + bfd_boolean (*_close_and_cleanup) (bfd *); | |
27649 | + /* Ask the BFD to free all cached information. */ | |
27650 | + bfd_boolean (*_bfd_free_cached_info) (bfd *); | |
27651 | + /* Called when a new section is created. */ | |
27652 | + bfd_boolean (*_new_section_hook) (bfd *, sec_ptr); | |
27653 | + /* Read the contents of a section. */ | |
27654 | + bfd_boolean (*_bfd_get_section_contents) | |
27655 | + (bfd *, sec_ptr, void *, file_ptr, bfd_size_type); | |
27656 | + bfd_boolean (*_bfd_get_section_contents_in_window) | |
27657 | + (bfd *, sec_ptr, bfd_window *, file_ptr, bfd_size_type); | |
27658 | + | |
27659 | + /* Entry points to copy private data. */ | |
27660 | +#define BFD_JUMP_TABLE_COPY(NAME) \ | |
27661 | + NAME##_bfd_copy_private_bfd_data, \ | |
27662 | + NAME##_bfd_merge_private_bfd_data, \ | |
27663 | + NAME##_bfd_copy_private_section_data, \ | |
27664 | + NAME##_bfd_copy_private_symbol_data, \ | |
27665 | + NAME##_bfd_copy_private_header_data, \ | |
27666 | + NAME##_bfd_set_private_flags, \ | |
27667 | + NAME##_bfd_print_private_bfd_data | |
27668 | + | |
27669 | + /* Called to copy BFD general private data from one object file | |
27670 | + to another. */ | |
27671 | + bfd_boolean (*_bfd_copy_private_bfd_data) (bfd *, bfd *); | |
27672 | + /* Called to merge BFD general private data from one object file | |
27673 | + to a common output file when linking. */ | |
27674 | + bfd_boolean (*_bfd_merge_private_bfd_data) (bfd *, bfd *); | |
27675 | + /* Called to copy BFD private section data from one object file | |
27676 | + to another. */ | |
27677 | + bfd_boolean (*_bfd_copy_private_section_data) | |
27678 | + (bfd *, sec_ptr, bfd *, sec_ptr); | |
27679 | + /* Called to copy BFD private symbol data from one symbol | |
27680 | + to another. */ | |
27681 | + bfd_boolean (*_bfd_copy_private_symbol_data) | |
27682 | + (bfd *, asymbol *, bfd *, asymbol *); | |
27683 | + /* Called to copy BFD private header data from one object file | |
27684 | + to another. */ | |
27685 | + bfd_boolean (*_bfd_copy_private_header_data) | |
27686 | + (bfd *, bfd *); | |
27687 | + /* Called to set private backend flags. */ | |
27688 | + bfd_boolean (*_bfd_set_private_flags) (bfd *, flagword); | |
27689 | + | |
27690 | + /* Called to print private BFD data. */ | |
27691 | + bfd_boolean (*_bfd_print_private_bfd_data) (bfd *, void *); | |
27692 | + | |
27693 | + /* Core file entry points. */ | |
27694 | +#define BFD_JUMP_TABLE_CORE(NAME) \ | |
27695 | + NAME##_core_file_failing_command, \ | |
27696 | + NAME##_core_file_failing_signal, \ | |
27697 | + NAME##_core_file_matches_executable_p | |
27698 | + | |
27699 | + char * (*_core_file_failing_command) (bfd *); | |
27700 | + int (*_core_file_failing_signal) (bfd *); | |
27701 | + bfd_boolean (*_core_file_matches_executable_p) (bfd *, bfd *); | |
27702 | + | |
27703 | + /* Archive entry points. */ | |
27704 | +#define BFD_JUMP_TABLE_ARCHIVE(NAME) \ | |
27705 | + NAME##_slurp_armap, \ | |
27706 | + NAME##_slurp_extended_name_table, \ | |
27707 | + NAME##_construct_extended_name_table, \ | |
27708 | + NAME##_truncate_arname, \ | |
27709 | + NAME##_write_armap, \ | |
27710 | + NAME##_read_ar_hdr, \ | |
27711 | + NAME##_openr_next_archived_file, \ | |
27712 | + NAME##_get_elt_at_index, \ | |
27713 | + NAME##_generic_stat_arch_elt, \ | |
27714 | + NAME##_update_armap_timestamp | |
27715 | + | |
27716 | + bfd_boolean (*_bfd_slurp_armap) (bfd *); | |
27717 | + bfd_boolean (*_bfd_slurp_extended_name_table) (bfd *); | |
27718 | + bfd_boolean (*_bfd_construct_extended_name_table) | |
27719 | + (bfd *, char **, bfd_size_type *, const char **); | |
27720 | + void (*_bfd_truncate_arname) (bfd *, const char *, char *); | |
27721 | + bfd_boolean (*write_armap) | |
27722 | + (bfd *, unsigned int, struct orl *, unsigned int, int); | |
27723 | + void * (*_bfd_read_ar_hdr_fn) (bfd *); | |
27724 | + bfd * (*openr_next_archived_file) (bfd *, bfd *); | |
27725 | +#define bfd_get_elt_at_index(b,i) BFD_SEND (b, _bfd_get_elt_at_index, (b,i)) | |
27726 | + bfd * (*_bfd_get_elt_at_index) (bfd *, symindex); | |
27727 | + int (*_bfd_stat_arch_elt) (bfd *, struct stat *); | |
27728 | + bfd_boolean (*_bfd_update_armap_timestamp) (bfd *); | |
27729 | + | |
27730 | + /* Entry points used for symbols. */ | |
27731 | +#define BFD_JUMP_TABLE_SYMBOLS(NAME) \ | |
27732 | + NAME##_get_symtab_upper_bound, \ | |
27733 | + NAME##_canonicalize_symtab, \ | |
27734 | + NAME##_make_empty_symbol, \ | |
27735 | + NAME##_print_symbol, \ | |
27736 | + NAME##_get_symbol_info, \ | |
27737 | + NAME##_bfd_is_local_label_name, \ | |
27738 | + NAME##_bfd_is_target_special_symbol, \ | |
27739 | + NAME##_get_lineno, \ | |
27740 | + NAME##_find_nearest_line, \ | |
27741 | + _bfd_generic_find_line, \ | |
27742 | + NAME##_find_inliner_info, \ | |
27743 | + NAME##_bfd_make_debug_symbol, \ | |
27744 | + NAME##_read_minisymbols, \ | |
27745 | + NAME##_minisymbol_to_symbol | |
27746 | + | |
27747 | + long (*_bfd_get_symtab_upper_bound) (bfd *); | |
27748 | + long (*_bfd_canonicalize_symtab) | |
27749 | + (bfd *, struct bfd_symbol **); | |
27750 | + struct bfd_symbol * | |
27751 | + (*_bfd_make_empty_symbol) (bfd *); | |
27752 | + void (*_bfd_print_symbol) | |
27753 | + (bfd *, void *, struct bfd_symbol *, bfd_print_symbol_type); | |
27754 | +#define bfd_print_symbol(b,p,s,e) BFD_SEND (b, _bfd_print_symbol, (b,p,s,e)) | |
27755 | + void (*_bfd_get_symbol_info) | |
27756 | + (bfd *, struct bfd_symbol *, symbol_info *); | |
27757 | +#define bfd_get_symbol_info(b,p,e) BFD_SEND (b, _bfd_get_symbol_info, (b,p,e)) | |
27758 | + bfd_boolean (*_bfd_is_local_label_name) (bfd *, const char *); | |
27759 | + bfd_boolean (*_bfd_is_target_special_symbol) (bfd *, asymbol *); | |
27760 | + alent * (*_get_lineno) (bfd *, struct bfd_symbol *); | |
27761 | + bfd_boolean (*_bfd_find_nearest_line) | |
27762 | + (bfd *, struct bfd_section *, struct bfd_symbol **, bfd_vma, | |
27763 | + const char **, const char **, unsigned int *); | |
27764 | + bfd_boolean (*_bfd_find_line) | |
27765 | + (bfd *, struct bfd_symbol **, struct bfd_symbol *, | |
27766 | + const char **, unsigned int *); | |
27767 | + bfd_boolean (*_bfd_find_inliner_info) | |
27768 | + (bfd *, const char **, const char **, unsigned int *); | |
27769 | + /* Back-door to allow format-aware applications to create debug symbols | |
27770 | + while using BFD for everything else. Currently used by the assembler | |
27771 | + when creating COFF files. */ | |
27772 | + asymbol * (*_bfd_make_debug_symbol) | |
27773 | + (bfd *, void *, unsigned long size); | |
27774 | +#define bfd_read_minisymbols(b, d, m, s) \ | |
27775 | + BFD_SEND (b, _read_minisymbols, (b, d, m, s)) | |
27776 | + long (*_read_minisymbols) | |
27777 | + (bfd *, bfd_boolean, void **, unsigned int *); | |
27778 | +#define bfd_minisymbol_to_symbol(b, d, m, f) \ | |
27779 | + BFD_SEND (b, _minisymbol_to_symbol, (b, d, m, f)) | |
27780 | + asymbol * (*_minisymbol_to_symbol) | |
27781 | + (bfd *, bfd_boolean, const void *, asymbol *); | |
27782 | + | |
27783 | + /* Routines for relocs. */ | |
27784 | +#define BFD_JUMP_TABLE_RELOCS(NAME) \ | |
27785 | + NAME##_get_reloc_upper_bound, \ | |
27786 | + NAME##_canonicalize_reloc, \ | |
27787 | + NAME##_bfd_reloc_type_lookup | |
27788 | + | |
27789 | + long (*_get_reloc_upper_bound) (bfd *, sec_ptr); | |
27790 | + long (*_bfd_canonicalize_reloc) | |
27791 | + (bfd *, sec_ptr, arelent **, struct bfd_symbol **); | |
27792 | + /* See documentation on reloc types. */ | |
27793 | + reloc_howto_type * | |
27794 | + (*reloc_type_lookup) (bfd *, bfd_reloc_code_real_type); | |
27795 | + | |
27796 | + /* Routines used when writing an object file. */ | |
27797 | +#define BFD_JUMP_TABLE_WRITE(NAME) \ | |
27798 | + NAME##_set_arch_mach, \ | |
27799 | + NAME##_set_section_contents | |
27800 | + | |
27801 | + bfd_boolean (*_bfd_set_arch_mach) | |
27802 | + (bfd *, enum bfd_architecture, unsigned long); | |
27803 | + bfd_boolean (*_bfd_set_section_contents) | |
27804 | + (bfd *, sec_ptr, const void *, file_ptr, bfd_size_type); | |
27805 | + | |
27806 | + /* Routines used by the linker. */ | |
27807 | +#define BFD_JUMP_TABLE_LINK(NAME) \ | |
27808 | + NAME##_sizeof_headers, \ | |
27809 | + NAME##_bfd_get_relocated_section_contents, \ | |
27810 | + NAME##_bfd_relax_section, \ | |
27811 | + NAME##_bfd_link_hash_table_create, \ | |
27812 | + NAME##_bfd_link_hash_table_free, \ | |
27813 | + NAME##_bfd_link_add_symbols, \ | |
27814 | + NAME##_bfd_link_just_syms, \ | |
27815 | + NAME##_bfd_final_link, \ | |
27816 | + NAME##_bfd_link_split_section, \ | |
27817 | + NAME##_bfd_gc_sections, \ | |
27818 | + NAME##_bfd_merge_sections, \ | |
27819 | + NAME##_bfd_is_group_section, \ | |
27820 | + NAME##_bfd_discard_group, \ | |
27821 | + NAME##_section_already_linked \ | |
27822 | + | |
27823 | + int (*_bfd_sizeof_headers) (bfd *, bfd_boolean); | |
27824 | + bfd_byte * (*_bfd_get_relocated_section_contents) | |
27825 | + (bfd *, struct bfd_link_info *, struct bfd_link_order *, | |
27826 | + bfd_byte *, bfd_boolean, struct bfd_symbol **); | |
27827 | + | |
27828 | + bfd_boolean (*_bfd_relax_section) | |
27829 | + (bfd *, struct bfd_section *, struct bfd_link_info *, bfd_boolean *); | |
27830 | + | |
27831 | + /* Create a hash table for the linker. Different backends store | |
27832 | + different information in this table. */ | |
27833 | + struct bfd_link_hash_table * | |
27834 | + (*_bfd_link_hash_table_create) (bfd *); | |
27835 | + | |
27836 | + /* Release the memory associated with the linker hash table. */ | |
27837 | + void (*_bfd_link_hash_table_free) (struct bfd_link_hash_table *); | |
27838 | + | |
27839 | + /* Add symbols from this object file into the hash table. */ | |
27840 | + bfd_boolean (*_bfd_link_add_symbols) (bfd *, struct bfd_link_info *); | |
27841 | + | |
27842 | + /* Indicate that we are only retrieving symbol values from this section. */ | |
27843 | + void (*_bfd_link_just_syms) (asection *, struct bfd_link_info *); | |
27844 | + | |
27845 | + /* Do a link based on the link_order structures attached to each | |
27846 | + section of the BFD. */ | |
27847 | + bfd_boolean (*_bfd_final_link) (bfd *, struct bfd_link_info *); | |
27848 | + | |
27849 | + /* Should this section be split up into smaller pieces during linking. */ | |
27850 | + bfd_boolean (*_bfd_link_split_section) (bfd *, struct bfd_section *); | |
27851 | + | |
27852 | + /* Remove sections that are not referenced from the output. */ | |
27853 | + bfd_boolean (*_bfd_gc_sections) (bfd *, struct bfd_link_info *); | |
27854 | + | |
27855 | + /* Attempt to merge SEC_MERGE sections. */ | |
27856 | + bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *); | |
27857 | + | |
27858 | + /* Is this section a member of a group? */ | |
27859 | + bfd_boolean (*_bfd_is_group_section) (bfd *, const struct bfd_section *); | |
27860 | + | |
27861 | + /* Discard members of a group. */ | |
27862 | + bfd_boolean (*_bfd_discard_group) (bfd *, struct bfd_section *); | |
27863 | + | |
27864 | + /* Check if SEC has been already linked during a reloceatable or | |
27865 | + final link. */ | |
27866 | + void (*_section_already_linked) (bfd *, struct bfd_section *); | |
27867 | + | |
27868 | + /* Routines to handle dynamic symbols and relocs. */ | |
27869 | +#define BFD_JUMP_TABLE_DYNAMIC(NAME) \ | |
27870 | + NAME##_get_dynamic_symtab_upper_bound, \ | |
27871 | + NAME##_canonicalize_dynamic_symtab, \ | |
27872 | + NAME##_get_synthetic_symtab, \ | |
27873 | + NAME##_get_dynamic_reloc_upper_bound, \ | |
27874 | + NAME##_canonicalize_dynamic_reloc | |
27875 | + | |
27876 | + /* Get the amount of memory required to hold the dynamic symbols. */ | |
27877 | + long (*_bfd_get_dynamic_symtab_upper_bound) (bfd *); | |
27878 | + /* Read in the dynamic symbols. */ | |
27879 | + long (*_bfd_canonicalize_dynamic_symtab) | |
27880 | + (bfd *, struct bfd_symbol **); | |
27881 | + /* Create synthetized symbols. */ | |
27882 | + long (*_bfd_get_synthetic_symtab) | |
27883 | + (bfd *, long, struct bfd_symbol **, long, struct bfd_symbol **, | |
27884 | + struct bfd_symbol **); | |
27885 | + /* Get the amount of memory required to hold the dynamic relocs. */ | |
27886 | + long (*_bfd_get_dynamic_reloc_upper_bound) (bfd *); | |
27887 | + /* Read in the dynamic relocs. */ | |
27888 | + long (*_bfd_canonicalize_dynamic_reloc) | |
27889 | + (bfd *, arelent **, struct bfd_symbol **); | |
27890 | + | |
27891 | + /* Opposite endian version of this target. */ | |
27892 | + const struct bfd_target * alternative_target; | |
27893 | + | |
27894 | + /* Data for use by back-end routines, which isn't | |
27895 | + generic enough to belong in this structure. */ | |
27896 | + const void *backend_data; | |
27897 | + | |
27898 | +} bfd_target; | |
27899 | + | |
27900 | +bfd_boolean bfd_set_default_target (const char *name); | |
27901 | + | |
27902 | +const bfd_target *bfd_find_target (const char *target_name, bfd *abfd); | |
27903 | + | |
27904 | +const char ** bfd_target_list (void); | |
27905 | + | |
27906 | +const bfd_target *bfd_search_for_target | |
27907 | + (int (*search_func) (const bfd_target *, void *), | |
27908 | + void *); | |
27909 | + | |
27910 | +/* Extracted from format.c. */ | |
27911 | +bfd_boolean bfd_check_format (bfd *abfd, bfd_format format); | |
27912 | + | |
27913 | +bfd_boolean bfd_check_format_matches | |
27914 | + (bfd *abfd, bfd_format format, char ***matching); | |
27915 | + | |
27916 | +bfd_boolean bfd_set_format (bfd *abfd, bfd_format format); | |
27917 | + | |
27918 | +const char *bfd_format_string (bfd_format format); | |
27919 | + | |
27920 | +/* Extracted from linker.c. */ | |
27921 | +bfd_boolean bfd_link_split_section (bfd *abfd, asection *sec); | |
27922 | + | |
27923 | +#define bfd_link_split_section(abfd, sec) \ | |
27924 | + BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec)) | |
27925 | + | |
27926 | +void bfd_section_already_linked (bfd *abfd, asection *sec); | |
27927 | + | |
27928 | +#define bfd_section_already_linked(abfd, sec) \ | |
27929 | + BFD_SEND (abfd, _section_already_linked, (abfd, sec)) | |
27930 | + | |
27931 | +/* Extracted from simple.c. */ | |
27932 | +bfd_byte *bfd_simple_get_relocated_section_contents | |
27933 | + (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table); | |
27934 | + | |
27935 | +#ifdef __cplusplus | |
27936 | +} | |
27937 | +#endif | |
27938 | +#endif | |
27939 | --- /dev/null | |
27940 | +++ b/include/asm-x86/bfd_64.h | |
27941 | @@ -0,0 +1,4917 @@ | |
27942 | +/* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically | |
27943 | + generated from "bfd-in.h", "init.c", "opncls.c", "libbfd.c", | |
27944 | + "bfdio.c", "bfdwin.c", "section.c", "archures.c", "reloc.c", | |
27945 | + "syms.c", "bfd.c", "archive.c", "corefile.c", "targets.c", "format.c", | |
27946 | + "linker.c" and "simple.c". | |
27947 | + Run "make headers" in your build bfd/ to regenerate. */ | |
27948 | + | |
27949 | +/* Main header file for the bfd library -- portable access to object files. | |
27950 | + | |
27951 | + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, | |
27952 | + 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. | |
27953 | + | |
27954 | + Contributed by Cygnus Support. | |
27955 | + | |
27956 | + This file is part of BFD, the Binary File Descriptor library. | |
27957 | + | |
27958 | + This program is free software; you can redistribute it and/or modify | |
27959 | + it under the terms of the GNU General Public License as published by | |
27960 | + the Free Software Foundation; either version 2 of the License, or | |
27961 | + (at your option) any later version. | |
27962 | + | |
27963 | + This program is distributed in the hope that it will be useful, | |
27964 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
27965 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
27966 | + GNU General Public License for more details. | |
27967 | + | |
27968 | + You should have received a copy of the GNU General Public License | |
27969 | + along with this program; if not, write to the Free Software | |
27970 | + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ | |
27971 | + | |
27972 | +/* Extracted from binutils 2.16.91.0.2 (OpenSUSE 10.0) and modified for kdb use. | |
27973 | + * Any trailing whitespace was removed and #ifdef/ifndef __KERNEL__ added as | |
27974 | + * required. | |
27975 | + * Keith Owens <kaos@sgi.com> 15 May 2006 | |
27976 | + */ | |
27977 | + | |
27978 | +#ifndef __BFD_H_SEEN__ | |
27979 | +#define __BFD_H_SEEN__ | |
27980 | + | |
27981 | +#ifdef __cplusplus | |
27982 | +extern "C" { | |
27983 | +#endif | |
27984 | + | |
27985 | +#ifdef __KERNEL__ | |
27986 | +#include <asm/ansidecl.h> | |
27987 | +#else /* __KERNEL__ */ | |
27988 | +#include "ansidecl.h" | |
27989 | +#include "symcat.h" | |
27990 | +#endif /* __KERNEL__ */ | |
27991 | +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) | |
27992 | +#ifndef SABER | |
27993 | +/* This hack is to avoid a problem with some strict ANSI C preprocessors. | |
27994 | + The problem is, "32_" is not a valid preprocessing token, and we don't | |
27995 | + want extra underscores (e.g., "nlm_32_"). The XCONCAT2 macro will | |
27996 | + cause the inner CONCAT2 macros to be evaluated first, producing | |
27997 | + still-valid pp-tokens. Then the final concatenation can be done. */ | |
27998 | +#undef CONCAT4 | |
27999 | +#define CONCAT4(a,b,c,d) XCONCAT2(CONCAT2(a,b),CONCAT2(c,d)) | |
28000 | +#endif | |
28001 | +#endif | |
28002 | + | |
28003 | +/* The word size used by BFD on the host. This may be 64 with a 32 | |
28004 | + bit target if the host is 64 bit, or if other 64 bit targets have | |
28005 | + been selected with --enable-targets, or if --enable-64-bit-bfd. */ | |
28006 | +#define BFD_ARCH_SIZE 64 | |
28007 | + | |
28008 | +/* The word size of the default bfd target. */ | |
28009 | +#define BFD_DEFAULT_TARGET_SIZE 64 | |
28010 | + | |
28011 | +#define BFD_HOST_64BIT_LONG 1 | |
28012 | +#define BFD_HOST_LONG_LONG 1 | |
28013 | +#if 1 | |
28014 | +#define BFD_HOST_64_BIT long | |
28015 | +#define BFD_HOST_U_64_BIT unsigned long | |
28016 | +typedef BFD_HOST_64_BIT bfd_int64_t; | |
28017 | +typedef BFD_HOST_U_64_BIT bfd_uint64_t; | |
28018 | +#endif | |
28019 | + | |
28020 | +#if BFD_ARCH_SIZE >= 64 | |
28021 | +#define BFD64 | |
28022 | +#endif | |
28023 | + | |
28024 | +#ifndef INLINE | |
28025 | +#if __GNUC__ >= 2 | |
28026 | +#define INLINE __inline__ | |
28027 | +#else | |
28028 | +#define INLINE | |
28029 | +#endif | |
28030 | +#endif | |
28031 | + | |
28032 | +/* Forward declaration. */ | |
28033 | +typedef struct bfd bfd; | |
28034 | + | |
28035 | +/* Boolean type used in bfd. Too many systems define their own | |
28036 | + versions of "boolean" for us to safely typedef a "boolean" of | |
28037 | + our own. Using an enum for "bfd_boolean" has its own set of | |
28038 | + problems, with strange looking casts required to avoid warnings | |
28039 | + on some older compilers. Thus we just use an int. | |
28040 | + | |
28041 | + General rule: Functions which are bfd_boolean return TRUE on | |
28042 | + success and FALSE on failure (unless they're a predicate). */ | |
28043 | + | |
28044 | +typedef int bfd_boolean; | |
28045 | +#undef FALSE | |
28046 | +#undef TRUE | |
28047 | +#define FALSE 0 | |
28048 | +#define TRUE 1 | |
28049 | + | |
28050 | +#ifdef BFD64 | |
28051 | + | |
28052 | +#ifndef BFD_HOST_64_BIT | |
28053 | + #error No 64 bit integer type available | |
28054 | +#endif /* ! defined (BFD_HOST_64_BIT) */ | |
28055 | + | |
28056 | +typedef BFD_HOST_U_64_BIT bfd_vma; | |
28057 | +typedef BFD_HOST_64_BIT bfd_signed_vma; | |
28058 | +typedef BFD_HOST_U_64_BIT bfd_size_type; | |
28059 | +typedef BFD_HOST_U_64_BIT symvalue; | |
28060 | + | |
28061 | +#ifndef fprintf_vma | |
28062 | +#if BFD_HOST_64BIT_LONG | |
28063 | +#define sprintf_vma(s,x) sprintf (s, "%016lx", x) | |
28064 | +#define fprintf_vma(f,x) fprintf (f, "%016lx", x) | |
28065 | +#else | |
28066 | +#define _bfd_int64_low(x) ((unsigned long) (((x) & 0xffffffff))) | |
28067 | +#define _bfd_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff)) | |
28068 | +#define fprintf_vma(s,x) \ | |
28069 | + fprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x)) | |
28070 | +#define sprintf_vma(s,x) \ | |
28071 | + sprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x)) | |
28072 | +#endif | |
28073 | +#endif | |
28074 | + | |
28075 | +#else /* not BFD64 */ | |
28076 | + | |
28077 | +/* Represent a target address. Also used as a generic unsigned type | |
28078 | + which is guaranteed to be big enough to hold any arithmetic types | |
28079 | + we need to deal with. */ | |
28080 | +typedef unsigned long bfd_vma; | |
28081 | + | |
28082 | +/* A generic signed type which is guaranteed to be big enough to hold any | |
28083 | + arithmetic types we need to deal with. Can be assumed to be compatible | |
28084 | + with bfd_vma in the same way that signed and unsigned ints are compatible | |
28085 | + (as parameters, in assignment, etc). */ | |
28086 | +typedef long bfd_signed_vma; | |
28087 | + | |
28088 | +typedef unsigned long symvalue; | |
28089 | +typedef unsigned long bfd_size_type; | |
28090 | + | |
28091 | +/* Print a bfd_vma x on stream s. */ | |
28092 | +#define fprintf_vma(s,x) fprintf (s, "%08lx", x) | |
28093 | +#define sprintf_vma(s,x) sprintf (s, "%08lx", x) | |
28094 | + | |
28095 | +#endif /* not BFD64 */ | |
28096 | + | |
28097 | +#define HALF_BFD_SIZE_TYPE \ | |
28098 | + (((bfd_size_type) 1) << (8 * sizeof (bfd_size_type) / 2)) | |
28099 | + | |
28100 | +#ifndef BFD_HOST_64_BIT | |
28101 | +/* Fall back on a 32 bit type. The idea is to make these types always | |
28102 | + available for function return types, but in the case that | |
28103 | + BFD_HOST_64_BIT is undefined such a function should abort or | |
28104 | + otherwise signal an error. */ | |
28105 | +typedef bfd_signed_vma bfd_int64_t; | |
28106 | +typedef bfd_vma bfd_uint64_t; | |
28107 | +#endif | |
28108 | + | |
28109 | +/* An offset into a file. BFD always uses the largest possible offset | |
28110 | + based on the build time availability of fseek, fseeko, or fseeko64. */ | |
28111 | +typedef BFD_HOST_64_BIT file_ptr; | |
28112 | +typedef unsigned BFD_HOST_64_BIT ufile_ptr; | |
28113 | + | |
28114 | +extern void bfd_sprintf_vma (bfd *, char *, bfd_vma); | |
28115 | +extern void bfd_fprintf_vma (bfd *, void *, bfd_vma); | |
28116 | + | |
28117 | +#define printf_vma(x) fprintf_vma(stdout,x) | |
28118 | +#define bfd_printf_vma(abfd,x) bfd_fprintf_vma (abfd,stdout,x) | |
28119 | + | |
28120 | +typedef unsigned int flagword; /* 32 bits of flags */ | |
28121 | +typedef unsigned char bfd_byte; | |
28122 | +\f | |
28123 | +/* File formats. */ | |
28124 | + | |
28125 | +typedef enum bfd_format | |
28126 | +{ | |
28127 | + bfd_unknown = 0, /* File format is unknown. */ | |
28128 | + bfd_object, /* Linker/assembler/compiler output. */ | |
28129 | + bfd_archive, /* Object archive file. */ | |
28130 | + bfd_core, /* Core dump. */ | |
28131 | + bfd_type_end /* Marks the end; don't use it! */ | |
28132 | +} | |
28133 | +bfd_format; | |
28134 | + | |
28135 | +/* Values that may appear in the flags field of a BFD. These also | |
28136 | + appear in the object_flags field of the bfd_target structure, where | |
28137 | + they indicate the set of flags used by that backend (not all flags | |
28138 | + are meaningful for all object file formats) (FIXME: at the moment, | |
28139 | + the object_flags values have mostly just been copied from backend | |
28140 | + to another, and are not necessarily correct). */ | |
28141 | + | |
28142 | +/* No flags. */ | |
28143 | +#define BFD_NO_FLAGS 0x00 | |
28144 | + | |
28145 | +/* BFD contains relocation entries. */ | |
28146 | +#define HAS_RELOC 0x01 | |
28147 | + | |
28148 | +/* BFD is directly executable. */ | |
28149 | +#define EXEC_P 0x02 | |
28150 | + | |
28151 | +/* BFD has line number information (basically used for F_LNNO in a | |
28152 | + COFF header). */ | |
28153 | +#define HAS_LINENO 0x04 | |
28154 | + | |
28155 | +/* BFD has debugging information. */ | |
28156 | +#define HAS_DEBUG 0x08 | |
28157 | + | |
28158 | +/* BFD has symbols. */ | |
28159 | +#define HAS_SYMS 0x10 | |
28160 | + | |
28161 | +/* BFD has local symbols (basically used for F_LSYMS in a COFF | |
28162 | + header). */ | |
28163 | +#define HAS_LOCALS 0x20 | |
28164 | + | |
28165 | +/* BFD is a dynamic object. */ | |
28166 | +#define DYNAMIC 0x40 | |
28167 | + | |
28168 | +/* Text section is write protected (if D_PAGED is not set, this is | |
28169 | + like an a.out NMAGIC file) (the linker sets this by default, but | |
28170 | + clears it for -r or -N). */ | |
28171 | +#define WP_TEXT 0x80 | |
28172 | + | |
28173 | +/* BFD is dynamically paged (this is like an a.out ZMAGIC file) (the | |
28174 | + linker sets this by default, but clears it for -r or -n or -N). */ | |
28175 | +#define D_PAGED 0x100 | |
28176 | + | |
28177 | +/* BFD is relaxable (this means that bfd_relax_section may be able to | |
28178 | + do something) (sometimes bfd_relax_section can do something even if | |
28179 | + this is not set). */ | |
28180 | +#define BFD_IS_RELAXABLE 0x200 | |
28181 | + | |
28182 | +/* This may be set before writing out a BFD to request using a | |
28183 | + traditional format. For example, this is used to request that when | |
28184 | + writing out an a.out object the symbols not be hashed to eliminate | |
28185 | + duplicates. */ | |
28186 | +#define BFD_TRADITIONAL_FORMAT 0x400 | |
28187 | + | |
28188 | +/* This flag indicates that the BFD contents are actually cached in | |
28189 | + memory. If this is set, iostream points to a bfd_in_memory struct. */ | |
28190 | +#define BFD_IN_MEMORY 0x800 | |
28191 | + | |
28192 | +/* The sections in this BFD specify a memory page. */ | |
28193 | +#define HAS_LOAD_PAGE 0x1000 | |
28194 | + | |
28195 | +/* This BFD has been created by the linker and doesn't correspond | |
28196 | + to any input file. */ | |
28197 | +#define BFD_LINKER_CREATED 0x2000 | |
28198 | +\f | |
28199 | +/* Symbols and relocation. */ | |
28200 | + | |
28201 | +/* A count of carsyms (canonical archive symbols). */ | |
28202 | +typedef unsigned long symindex; | |
28203 | + | |
28204 | +/* How to perform a relocation. */ | |
28205 | +typedef const struct reloc_howto_struct reloc_howto_type; | |
28206 | + | |
28207 | +#define BFD_NO_MORE_SYMBOLS ((symindex) ~0) | |
28208 | + | |
28209 | +/* General purpose part of a symbol X; | |
28210 | + target specific parts are in libcoff.h, libaout.h, etc. */ | |
28211 | + | |
28212 | +#define bfd_get_section(x) ((x)->section) | |
28213 | +#define bfd_get_output_section(x) ((x)->section->output_section) | |
28214 | +#define bfd_set_section(x,y) ((x)->section) = (y) | |
28215 | +#define bfd_asymbol_base(x) ((x)->section->vma) | |
28216 | +#define bfd_asymbol_value(x) (bfd_asymbol_base(x) + (x)->value) | |
28217 | +#define bfd_asymbol_name(x) ((x)->name) | |
28218 | +/*Perhaps future: #define bfd_asymbol_bfd(x) ((x)->section->owner)*/ | |
28219 | +#define bfd_asymbol_bfd(x) ((x)->the_bfd) | |
28220 | +#define bfd_asymbol_flavour(x) (bfd_asymbol_bfd(x)->xvec->flavour) | |
28221 | + | |
28222 | +/* A canonical archive symbol. */ | |
28223 | +/* This is a type pun with struct ranlib on purpose! */ | |
28224 | +typedef struct carsym | |
28225 | +{ | |
28226 | + char *name; | |
28227 | + file_ptr file_offset; /* Look here to find the file. */ | |
28228 | +} | |
28229 | +carsym; /* To make these you call a carsymogen. */ | |
28230 | + | |
28231 | +/* Used in generating armaps (archive tables of contents). | |
28232 | + Perhaps just a forward definition would do? */ | |
28233 | +struct orl /* Output ranlib. */ | |
28234 | +{ | |
28235 | + char **name; /* Symbol name. */ | |
28236 | + union | |
28237 | + { | |
28238 | + file_ptr pos; | |
28239 | + bfd *abfd; | |
28240 | + } u; /* bfd* or file position. */ | |
28241 | + int namidx; /* Index into string table. */ | |
28242 | +}; | |
28243 | +\f | |
28244 | +/* Linenumber stuff. */ | |
28245 | +typedef struct lineno_cache_entry | |
28246 | +{ | |
28247 | + unsigned int line_number; /* Linenumber from start of function. */ | |
28248 | + union | |
28249 | + { | |
28250 | + struct bfd_symbol *sym; /* Function name. */ | |
28251 | + bfd_vma offset; /* Offset into section. */ | |
28252 | + } u; | |
28253 | +} | |
28254 | +alent; | |
28255 | +\f | |
28256 | +/* Object and core file sections. */ | |
28257 | + | |
28258 | +#define align_power(addr, align) \ | |
28259 | + (((addr) + ((bfd_vma) 1 << (align)) - 1) & ((bfd_vma) -1 << (align))) | |
28260 | + | |
28261 | +typedef struct bfd_section *sec_ptr; | |
28262 | + | |
28263 | +#define bfd_get_section_name(bfd, ptr) ((ptr)->name + 0) | |
28264 | +#define bfd_get_section_vma(bfd, ptr) ((ptr)->vma + 0) | |
28265 | +#define bfd_get_section_lma(bfd, ptr) ((ptr)->lma + 0) | |
28266 | +#define bfd_get_section_alignment(bfd, ptr) ((ptr)->alignment_power + 0) | |
28267 | +#define bfd_section_name(bfd, ptr) ((ptr)->name) | |
28268 | +#define bfd_section_size(bfd, ptr) ((ptr)->size) | |
28269 | +#define bfd_get_section_size(ptr) ((ptr)->size) | |
28270 | +#define bfd_section_vma(bfd, ptr) ((ptr)->vma) | |
28271 | +#define bfd_section_lma(bfd, ptr) ((ptr)->lma) | |
28272 | +#define bfd_section_alignment(bfd, ptr) ((ptr)->alignment_power) | |
28273 | +#define bfd_get_section_flags(bfd, ptr) ((ptr)->flags + 0) | |
28274 | +#define bfd_get_section_userdata(bfd, ptr) ((ptr)->userdata) | |
28275 | + | |
28276 | +#define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0) | |
28277 | + | |
28278 | +#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma = (val)), ((ptr)->user_set_vma = TRUE), TRUE) | |
28279 | +#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),TRUE) | |
28280 | +#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE) | |
28281 | +/* Find the address one past the end of SEC. */ | |
28282 | +#define bfd_get_section_limit(bfd, sec) \ | |
28283 | + (((sec)->rawsize ? (sec)->rawsize : (sec)->size) \ | |
28284 | + / bfd_octets_per_byte (bfd)) | |
28285 | + | |
28286 | +typedef struct stat stat_type; | |
28287 | +\f | |
28288 | +typedef enum bfd_print_symbol | |
28289 | +{ | |
28290 | + bfd_print_symbol_name, | |
28291 | + bfd_print_symbol_more, | |
28292 | + bfd_print_symbol_all | |
28293 | +} bfd_print_symbol_type; | |
28294 | + | |
28295 | +/* Information about a symbol that nm needs. */ | |
28296 | + | |
28297 | +typedef struct _symbol_info | |
28298 | +{ | |
28299 | + symvalue value; | |
28300 | + char type; | |
28301 | + const char *name; /* Symbol name. */ | |
28302 | + unsigned char stab_type; /* Stab type. */ | |
28303 | + char stab_other; /* Stab other. */ | |
28304 | + short stab_desc; /* Stab desc. */ | |
28305 | + const char *stab_name; /* String for stab type. */ | |
28306 | +} symbol_info; | |
28307 | + | |
28308 | +/* Get the name of a stabs type code. */ | |
28309 | + | |
28310 | +extern const char *bfd_get_stab_name (int); | |
28311 | +\f | |
28312 | +/* Hash table routines. There is no way to free up a hash table. */ | |
28313 | + | |
28314 | +/* An element in the hash table. Most uses will actually use a larger | |
28315 | + structure, and an instance of this will be the first field. */ | |
28316 | + | |
28317 | +struct bfd_hash_entry | |
28318 | +{ | |
28319 | + /* Next entry for this hash code. */ | |
28320 | + struct bfd_hash_entry *next; | |
28321 | + /* String being hashed. */ | |
28322 | + const char *string; | |
28323 | + /* Hash code. This is the full hash code, not the index into the | |
28324 | + table. */ | |
28325 | + unsigned long hash; | |
28326 | +}; | |
28327 | + | |
28328 | +/* A hash table. */ | |
28329 | + | |
28330 | +struct bfd_hash_table | |
28331 | +{ | |
28332 | + /* The hash array. */ | |
28333 | + struct bfd_hash_entry **table; | |
28334 | + /* The number of slots in the hash table. */ | |
28335 | + unsigned int size; | |
28336 | + /* A function used to create new elements in the hash table. The | |
28337 | + first entry is itself a pointer to an element. When this | |
28338 | + function is first invoked, this pointer will be NULL. However, | |
28339 | + having the pointer permits a hierarchy of method functions to be | |
28340 | + built each of which calls the function in the superclass. Thus | |
28341 | + each function should be written to allocate a new block of memory | |
28342 | + only if the argument is NULL. */ | |
28343 | + struct bfd_hash_entry *(*newfunc) | |
28344 | + (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); | |
28345 | + /* An objalloc for this hash table. This is a struct objalloc *, | |
28346 | + but we use void * to avoid requiring the inclusion of objalloc.h. */ | |
28347 | + void *memory; | |
28348 | +}; | |
28349 | + | |
28350 | +/* Initialize a hash table. */ | |
28351 | +extern bfd_boolean bfd_hash_table_init | |
28352 | + (struct bfd_hash_table *, | |
28353 | + struct bfd_hash_entry *(*) (struct bfd_hash_entry *, | |
28354 | + struct bfd_hash_table *, | |
28355 | + const char *)); | |
28356 | + | |
28357 | +/* Initialize a hash table specifying a size. */ | |
28358 | +extern bfd_boolean bfd_hash_table_init_n | |
28359 | + (struct bfd_hash_table *, | |
28360 | + struct bfd_hash_entry *(*) (struct bfd_hash_entry *, | |
28361 | + struct bfd_hash_table *, | |
28362 | + const char *), | |
28363 | + unsigned int size); | |
28364 | + | |
28365 | +/* Free up a hash table. */ | |
28366 | +extern void bfd_hash_table_free | |
28367 | + (struct bfd_hash_table *); | |
28368 | + | |
28369 | +/* Look up a string in a hash table. If CREATE is TRUE, a new entry | |
28370 | + will be created for this string if one does not already exist. The | |
28371 | + COPY argument must be TRUE if this routine should copy the string | |
28372 | + into newly allocated memory when adding an entry. */ | |
28373 | +extern struct bfd_hash_entry *bfd_hash_lookup | |
28374 | + (struct bfd_hash_table *, const char *, bfd_boolean create, | |
28375 | + bfd_boolean copy); | |
28376 | + | |
28377 | +/* Replace an entry in a hash table. */ | |
28378 | +extern void bfd_hash_replace | |
28379 | + (struct bfd_hash_table *, struct bfd_hash_entry *old, | |
28380 | + struct bfd_hash_entry *nw); | |
28381 | + | |
28382 | +/* Base method for creating a hash table entry. */ | |
28383 | +extern struct bfd_hash_entry *bfd_hash_newfunc | |
28384 | + (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); | |
28385 | + | |
28386 | +/* Grab some space for a hash table entry. */ | |
28387 | +extern void *bfd_hash_allocate | |
28388 | + (struct bfd_hash_table *, unsigned int); | |
28389 | + | |
28390 | +/* Traverse a hash table in a random order, calling a function on each | |
28391 | + element. If the function returns FALSE, the traversal stops. The | |
28392 | + INFO argument is passed to the function. */ | |
28393 | +extern void bfd_hash_traverse | |
28394 | + (struct bfd_hash_table *, | |
28395 | + bfd_boolean (*) (struct bfd_hash_entry *, void *), | |
28396 | + void *info); | |
28397 | + | |
28398 | +/* Allows the default size of a hash table to be configured. New hash | |
28399 | + tables allocated using bfd_hash_table_init will be created with | |
28400 | + this size. */ | |
28401 | +extern void bfd_hash_set_default_size (bfd_size_type); | |
28402 | + | |
28403 | +/* This structure is used to keep track of stabs in sections | |
28404 | + information while linking. */ | |
28405 | + | |
28406 | +struct stab_info | |
28407 | +{ | |
28408 | + /* A hash table used to hold stabs strings. */ | |
28409 | + struct bfd_strtab_hash *strings; | |
28410 | + /* The header file hash table. */ | |
28411 | + struct bfd_hash_table includes; | |
28412 | + /* The first .stabstr section. */ | |
28413 | + struct bfd_section *stabstr; | |
28414 | +}; | |
28415 | + | |
28416 | +#define COFF_SWAP_TABLE (void *) &bfd_coff_std_swap_table | |
28417 | + | |
28418 | +/* User program access to BFD facilities. */ | |
28419 | + | |
28420 | +/* Direct I/O routines, for programs which know more about the object | |
28421 | + file than BFD does. Use higher level routines if possible. */ | |
28422 | + | |
28423 | +extern bfd_size_type bfd_bread (void *, bfd_size_type, bfd *); | |
28424 | +extern bfd_size_type bfd_bwrite (const void *, bfd_size_type, bfd *); | |
28425 | +extern int bfd_seek (bfd *, file_ptr, int); | |
28426 | +extern file_ptr bfd_tell (bfd *); | |
28427 | +extern int bfd_flush (bfd *); | |
28428 | +extern int bfd_stat (bfd *, struct stat *); | |
28429 | + | |
28430 | +/* Deprecated old routines. */ | |
28431 | +#if __GNUC__ | |
28432 | +#define bfd_read(BUF, ELTSIZE, NITEMS, ABFD) \ | |
28433 | + (warn_deprecated ("bfd_read", __FILE__, __LINE__, __FUNCTION__), \ | |
28434 | + bfd_bread ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) | |
28435 | +#define bfd_write(BUF, ELTSIZE, NITEMS, ABFD) \ | |
28436 | + (warn_deprecated ("bfd_write", __FILE__, __LINE__, __FUNCTION__), \ | |
28437 | + bfd_bwrite ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) | |
28438 | +#else | |
28439 | +#define bfd_read(BUF, ELTSIZE, NITEMS, ABFD) \ | |
28440 | + (warn_deprecated ("bfd_read", (const char *) 0, 0, (const char *) 0), \ | |
28441 | + bfd_bread ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) | |
28442 | +#define bfd_write(BUF, ELTSIZE, NITEMS, ABFD) \ | |
28443 | + (warn_deprecated ("bfd_write", (const char *) 0, 0, (const char *) 0),\ | |
28444 | + bfd_bwrite ((BUF), (ELTSIZE) * (NITEMS), (ABFD))) | |
28445 | +#endif | |
28446 | +extern void warn_deprecated (const char *, const char *, int, const char *); | |
28447 | + | |
28448 | +/* Cast from const char * to char * so that caller can assign to | |
28449 | + a char * without a warning. */ | |
28450 | +#define bfd_get_filename(abfd) ((char *) (abfd)->filename) | |
28451 | +#define bfd_get_cacheable(abfd) ((abfd)->cacheable) | |
28452 | +#define bfd_get_format(abfd) ((abfd)->format) | |
28453 | +#define bfd_get_target(abfd) ((abfd)->xvec->name) | |
28454 | +#define bfd_get_flavour(abfd) ((abfd)->xvec->flavour) | |
28455 | +#define bfd_family_coff(abfd) \ | |
28456 | + (bfd_get_flavour (abfd) == bfd_target_coff_flavour || \ | |
28457 | + bfd_get_flavour (abfd) == bfd_target_xcoff_flavour) | |
28458 | +#define bfd_big_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_BIG) | |
28459 | +#define bfd_little_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_LITTLE) | |
28460 | +#define bfd_header_big_endian(abfd) \ | |
28461 | + ((abfd)->xvec->header_byteorder == BFD_ENDIAN_BIG) | |
28462 | +#define bfd_header_little_endian(abfd) \ | |
28463 | + ((abfd)->xvec->header_byteorder == BFD_ENDIAN_LITTLE) | |
28464 | +#define bfd_get_file_flags(abfd) ((abfd)->flags) | |
28465 | +#define bfd_applicable_file_flags(abfd) ((abfd)->xvec->object_flags) | |
28466 | +#define bfd_applicable_section_flags(abfd) ((abfd)->xvec->section_flags) | |
28467 | +#define bfd_my_archive(abfd) ((abfd)->my_archive) | |
28468 | +#define bfd_has_map(abfd) ((abfd)->has_armap) | |
28469 | + | |
28470 | +#define bfd_valid_reloc_types(abfd) ((abfd)->xvec->valid_reloc_types) | |
28471 | +#define bfd_usrdata(abfd) ((abfd)->usrdata) | |
28472 | + | |
28473 | +#define bfd_get_start_address(abfd) ((abfd)->start_address) | |
28474 | +#define bfd_get_symcount(abfd) ((abfd)->symcount) | |
28475 | +#define bfd_get_outsymbols(abfd) ((abfd)->outsymbols) | |
28476 | +#define bfd_count_sections(abfd) ((abfd)->section_count) | |
28477 | + | |
28478 | +#define bfd_get_dynamic_symcount(abfd) ((abfd)->dynsymcount) | |
28479 | + | |
28480 | +#define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char) | |
28481 | + | |
28482 | +#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE) | |
28483 | + | |
28484 | +extern bfd_boolean bfd_cache_close | |
28485 | + (bfd *abfd); | |
28486 | +/* NB: This declaration should match the autogenerated one in libbfd.h. */ | |
28487 | + | |
28488 | +extern bfd_boolean bfd_cache_close_all (void); | |
28489 | + | |
28490 | +extern bfd_boolean bfd_record_phdr | |
28491 | + (bfd *, unsigned long, bfd_boolean, flagword, bfd_boolean, bfd_vma, | |
28492 | + bfd_boolean, bfd_boolean, unsigned int, struct bfd_section **); | |
28493 | + | |
28494 | +/* Byte swapping routines. */ | |
28495 | + | |
28496 | +bfd_uint64_t bfd_getb64 (const void *); | |
28497 | +bfd_uint64_t bfd_getl64 (const void *); | |
28498 | +bfd_int64_t bfd_getb_signed_64 (const void *); | |
28499 | +bfd_int64_t bfd_getl_signed_64 (const void *); | |
28500 | +bfd_vma bfd_getb32 (const void *); | |
28501 | +bfd_vma bfd_getl32 (const void *); | |
28502 | +bfd_signed_vma bfd_getb_signed_32 (const void *); | |
28503 | +bfd_signed_vma bfd_getl_signed_32 (const void *); | |
28504 | +bfd_vma bfd_getb16 (const void *); | |
28505 | +bfd_vma bfd_getl16 (const void *); | |
28506 | +bfd_signed_vma bfd_getb_signed_16 (const void *); | |
28507 | +bfd_signed_vma bfd_getl_signed_16 (const void *); | |
28508 | +void bfd_putb64 (bfd_uint64_t, void *); | |
28509 | +void bfd_putl64 (bfd_uint64_t, void *); | |
28510 | +void bfd_putb32 (bfd_vma, void *); | |
28511 | +void bfd_putl32 (bfd_vma, void *); | |
28512 | +void bfd_putb16 (bfd_vma, void *); | |
28513 | +void bfd_putl16 (bfd_vma, void *); | |
28514 | + | |
28515 | +/* Byte swapping routines which take size and endiannes as arguments. */ | |
28516 | + | |
28517 | +bfd_uint64_t bfd_get_bits (const void *, int, bfd_boolean); | |
28518 | +void bfd_put_bits (bfd_uint64_t, void *, int, bfd_boolean); | |
28519 | + | |
28520 | +extern bfd_boolean bfd_section_already_linked_table_init (void); | |
28521 | +extern void bfd_section_already_linked_table_free (void); | |
28522 | +\f | |
28523 | +/* Externally visible ECOFF routines. */ | |
28524 | + | |
28525 | +#if defined(__STDC__) || defined(ALMOST_STDC) | |
28526 | +struct ecoff_debug_info; | |
28527 | +struct ecoff_debug_swap; | |
28528 | +struct ecoff_extr; | |
28529 | +struct bfd_symbol; | |
28530 | +struct bfd_link_info; | |
28531 | +struct bfd_link_hash_entry; | |
28532 | +struct bfd_elf_version_tree; | |
28533 | +#endif | |
28534 | +extern bfd_vma bfd_ecoff_get_gp_value | |
28535 | + (bfd * abfd); | |
28536 | +extern bfd_boolean bfd_ecoff_set_gp_value | |
28537 | + (bfd *abfd, bfd_vma gp_value); | |
28538 | +extern bfd_boolean bfd_ecoff_set_regmasks | |
28539 | + (bfd *abfd, unsigned long gprmask, unsigned long fprmask, | |
28540 | + unsigned long *cprmask); | |
28541 | +extern void *bfd_ecoff_debug_init | |
28542 | + (bfd *output_bfd, struct ecoff_debug_info *output_debug, | |
28543 | + const struct ecoff_debug_swap *output_swap, struct bfd_link_info *); | |
28544 | +extern void bfd_ecoff_debug_free | |
28545 | + (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, | |
28546 | + const struct ecoff_debug_swap *output_swap, struct bfd_link_info *); | |
28547 | +extern bfd_boolean bfd_ecoff_debug_accumulate | |
28548 | + (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, | |
28549 | + const struct ecoff_debug_swap *output_swap, bfd *input_bfd, | |
28550 | + struct ecoff_debug_info *input_debug, | |
28551 | + const struct ecoff_debug_swap *input_swap, struct bfd_link_info *); | |
28552 | +extern bfd_boolean bfd_ecoff_debug_accumulate_other | |
28553 | + (void *handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, | |
28554 | + const struct ecoff_debug_swap *output_swap, bfd *input_bfd, | |
28555 | + struct bfd_link_info *); | |
28556 | +extern bfd_boolean bfd_ecoff_debug_externals | |
28557 | + (bfd *abfd, struct ecoff_debug_info *debug, | |
28558 | + const struct ecoff_debug_swap *swap, bfd_boolean relocatable, | |
28559 | + bfd_boolean (*get_extr) (struct bfd_symbol *, struct ecoff_extr *), | |
28560 | + void (*set_index) (struct bfd_symbol *, bfd_size_type)); | |
28561 | +extern bfd_boolean bfd_ecoff_debug_one_external | |
28562 | + (bfd *abfd, struct ecoff_debug_info *debug, | |
28563 | + const struct ecoff_debug_swap *swap, const char *name, | |
28564 | + struct ecoff_extr *esym); | |
28565 | +extern bfd_size_type bfd_ecoff_debug_size | |
28566 | + (bfd *abfd, struct ecoff_debug_info *debug, | |
28567 | + const struct ecoff_debug_swap *swap); | |
28568 | +extern bfd_boolean bfd_ecoff_write_debug | |
28569 | + (bfd *abfd, struct ecoff_debug_info *debug, | |
28570 | + const struct ecoff_debug_swap *swap, file_ptr where); | |
28571 | +extern bfd_boolean bfd_ecoff_write_accumulated_debug | |
28572 | + (void *handle, bfd *abfd, struct ecoff_debug_info *debug, | |
28573 | + const struct ecoff_debug_swap *swap, | |
28574 | + struct bfd_link_info *info, file_ptr where); | |
28575 | + | |
28576 | +/* Externally visible ELF routines. */ | |
28577 | + | |
28578 | +struct bfd_link_needed_list | |
28579 | +{ | |
28580 | + struct bfd_link_needed_list *next; | |
28581 | + bfd *by; | |
28582 | + const char *name; | |
28583 | +}; | |
28584 | + | |
28585 | +enum dynamic_lib_link_class { | |
28586 | + DYN_NORMAL = 0, | |
28587 | + DYN_AS_NEEDED = 1, | |
28588 | + DYN_DT_NEEDED = 2, | |
28589 | + DYN_NO_ADD_NEEDED = 4, | |
28590 | + DYN_NO_NEEDED = 8 | |
28591 | +}; | |
28592 | + | |
28593 | +extern bfd_boolean bfd_elf_record_link_assignment | |
28594 | + (struct bfd_link_info *, const char *, bfd_boolean); | |
28595 | +extern struct bfd_link_needed_list *bfd_elf_get_needed_list | |
28596 | + (bfd *, struct bfd_link_info *); | |
28597 | +extern bfd_boolean bfd_elf_get_bfd_needed_list | |
28598 | + (bfd *, struct bfd_link_needed_list **); | |
28599 | +extern bfd_boolean bfd_elf_size_dynamic_sections | |
28600 | + (bfd *, const char *, const char *, const char *, const char * const *, | |
28601 | + struct bfd_link_info *, struct bfd_section **, | |
28602 | + struct bfd_elf_version_tree *); | |
28603 | +extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr | |
28604 | + (bfd *, struct bfd_link_info *); | |
28605 | +extern void bfd_elf_set_dt_needed_name | |
28606 | + (bfd *, const char *); | |
28607 | +extern const char *bfd_elf_get_dt_soname | |
28608 | + (bfd *); | |
28609 | +extern void bfd_elf_set_dyn_lib_class | |
28610 | + (bfd *, int); | |
28611 | +extern int bfd_elf_get_dyn_lib_class | |
28612 | + (bfd *); | |
28613 | +extern struct bfd_link_needed_list *bfd_elf_get_runpath_list | |
28614 | + (bfd *, struct bfd_link_info *); | |
28615 | +extern bfd_boolean bfd_elf_discard_info | |
28616 | + (bfd *, struct bfd_link_info *); | |
28617 | +extern unsigned int _bfd_elf_default_action_discarded | |
28618 | + (struct bfd_section *); | |
28619 | + | |
28620 | +/* Return an upper bound on the number of bytes required to store a | |
28621 | + copy of ABFD's program header table entries. Return -1 if an error | |
28622 | + occurs; bfd_get_error will return an appropriate code. */ | |
28623 | +extern long bfd_get_elf_phdr_upper_bound | |
28624 | + (bfd *abfd); | |
28625 | + | |
28626 | +/* Copy ABFD's program header table entries to *PHDRS. The entries | |
28627 | + will be stored as an array of Elf_Internal_Phdr structures, as | |
28628 | + defined in include/elf/internal.h. To find out how large the | |
28629 | + buffer needs to be, call bfd_get_elf_phdr_upper_bound. | |
28630 | + | |
28631 | + Return the number of program header table entries read, or -1 if an | |
28632 | + error occurs; bfd_get_error will return an appropriate code. */ | |
28633 | +extern int bfd_get_elf_phdrs | |
28634 | + (bfd *abfd, void *phdrs); | |
28635 | + | |
28636 | +/* Create a new BFD as if by bfd_openr. Rather than opening a file, | |
28637 | + reconstruct an ELF file by reading the segments out of remote memory | |
28638 | + based on the ELF file header at EHDR_VMA and the ELF program headers it | |
28639 | + points to. If not null, *LOADBASEP is filled in with the difference | |
28640 | + between the VMAs from which the segments were read, and the VMAs the | |
28641 | + file headers (and hence BFD's idea of each section's VMA) put them at. | |
28642 | + | |
28643 | + The function TARGET_READ_MEMORY is called to copy LEN bytes from the | |
28644 | + remote memory at target address VMA into the local buffer at MYADDR; it | |
28645 | + should return zero on success or an `errno' code on failure. TEMPL must | |
28646 | + be a BFD for an ELF target with the word size and byte order found in | |
28647 | + the remote memory. */ | |
28648 | +extern bfd *bfd_elf_bfd_from_remote_memory | |
28649 | + (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep, | |
28650 | + int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr, int len)); | |
28651 | + | |
28652 | +/* Return the arch_size field of an elf bfd, or -1 if not elf. */ | |
28653 | +extern int bfd_get_arch_size | |
28654 | + (bfd *); | |
28655 | + | |
28656 | +/* Return TRUE if address "naturally" sign extends, or -1 if not elf. */ | |
28657 | +extern int bfd_get_sign_extend_vma | |
28658 | + (bfd *); | |
28659 | + | |
28660 | +extern struct bfd_section *_bfd_elf_tls_setup | |
28661 | + (bfd *, struct bfd_link_info *); | |
28662 | + | |
28663 | +extern void _bfd_elf_provide_symbol | |
28664 | + (struct bfd_link_info *, const char *, bfd_vma, struct bfd_section *); | |
28665 | + | |
28666 | +extern void _bfd_elf_provide_section_bound_symbols | |
28667 | + (struct bfd_link_info *, struct bfd_section *, const char *, const char *); | |
28668 | + | |
28669 | +extern void _bfd_elf_fix_excluded_sec_syms | |
28670 | + (bfd *, struct bfd_link_info *); | |
28671 | + | |
28672 | +extern bfd_boolean bfd_m68k_elf32_create_embedded_relocs | |
28673 | + (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, | |
28674 | + char **); | |
28675 | + | |
28676 | +/* SunOS shared library support routines for the linker. */ | |
28677 | + | |
28678 | +extern struct bfd_link_needed_list *bfd_sunos_get_needed_list | |
28679 | + (bfd *, struct bfd_link_info *); | |
28680 | +extern bfd_boolean bfd_sunos_record_link_assignment | |
28681 | + (bfd *, struct bfd_link_info *, const char *); | |
28682 | +extern bfd_boolean bfd_sunos_size_dynamic_sections | |
28683 | + (bfd *, struct bfd_link_info *, struct bfd_section **, | |
28684 | + struct bfd_section **, struct bfd_section **); | |
28685 | + | |
28686 | +/* Linux shared library support routines for the linker. */ | |
28687 | + | |
28688 | +extern bfd_boolean bfd_i386linux_size_dynamic_sections | |
28689 | + (bfd *, struct bfd_link_info *); | |
28690 | +extern bfd_boolean bfd_m68klinux_size_dynamic_sections | |
28691 | + (bfd *, struct bfd_link_info *); | |
28692 | +extern bfd_boolean bfd_sparclinux_size_dynamic_sections | |
28693 | + (bfd *, struct bfd_link_info *); | |
28694 | + | |
28695 | +/* mmap hacks */ | |
28696 | + | |
28697 | +struct _bfd_window_internal; | |
28698 | +typedef struct _bfd_window_internal bfd_window_internal; | |
28699 | + | |
28700 | +typedef struct _bfd_window | |
28701 | +{ | |
28702 | + /* What the user asked for. */ | |
28703 | + void *data; | |
28704 | + bfd_size_type size; | |
28705 | + /* The actual window used by BFD. Small user-requested read-only | |
28706 | + regions sharing a page may share a single window into the object | |
28707 | + file. Read-write versions shouldn't until I've fixed things to | |
28708 | + keep track of which portions have been claimed by the | |
28709 | + application; don't want to give the same region back when the | |
28710 | + application wants two writable copies! */ | |
28711 | + struct _bfd_window_internal *i; | |
28712 | +} | |
28713 | +bfd_window; | |
28714 | + | |
28715 | +extern void bfd_init_window | |
28716 | + (bfd_window *); | |
28717 | +extern void bfd_free_window | |
28718 | + (bfd_window *); | |
28719 | +extern bfd_boolean bfd_get_file_window | |
28720 | + (bfd *, file_ptr, bfd_size_type, bfd_window *, bfd_boolean); | |
28721 | + | |
28722 | +/* XCOFF support routines for the linker. */ | |
28723 | + | |
28724 | +extern bfd_boolean bfd_xcoff_link_record_set | |
28725 | + (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, bfd_size_type); | |
28726 | +extern bfd_boolean bfd_xcoff_import_symbol | |
28727 | + (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, bfd_vma, | |
28728 | + const char *, const char *, const char *, unsigned int); | |
28729 | +extern bfd_boolean bfd_xcoff_export_symbol | |
28730 | + (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *); | |
28731 | +extern bfd_boolean bfd_xcoff_link_count_reloc | |
28732 | + (bfd *, struct bfd_link_info *, const char *); | |
28733 | +extern bfd_boolean bfd_xcoff_record_link_assignment | |
28734 | + (bfd *, struct bfd_link_info *, const char *); | |
28735 | +extern bfd_boolean bfd_xcoff_size_dynamic_sections | |
28736 | + (bfd *, struct bfd_link_info *, const char *, const char *, | |
28737 | + unsigned long, unsigned long, unsigned long, bfd_boolean, | |
28738 | + int, bfd_boolean, bfd_boolean, struct bfd_section **, bfd_boolean); | |
28739 | +extern bfd_boolean bfd_xcoff_link_generate_rtinit | |
28740 | + (bfd *, const char *, const char *, bfd_boolean); | |
28741 | + | |
28742 | +/* XCOFF support routines for ar. */ | |
28743 | +extern bfd_boolean bfd_xcoff_ar_archive_set_magic | |
28744 | + (bfd *, char *); | |
28745 | + | |
28746 | +/* Externally visible COFF routines. */ | |
28747 | + | |
28748 | +#if defined(__STDC__) || defined(ALMOST_STDC) | |
28749 | +struct internal_syment; | |
28750 | +union internal_auxent; | |
28751 | +#endif | |
28752 | + | |
28753 | +extern bfd_boolean bfd_coff_get_syment | |
28754 | + (bfd *, struct bfd_symbol *, struct internal_syment *); | |
28755 | + | |
28756 | +extern bfd_boolean bfd_coff_get_auxent | |
28757 | + (bfd *, struct bfd_symbol *, int, union internal_auxent *); | |
28758 | + | |
28759 | +extern bfd_boolean bfd_coff_set_symbol_class | |
28760 | + (bfd *, struct bfd_symbol *, unsigned int); | |
28761 | + | |
28762 | +extern bfd_boolean bfd_m68k_coff_create_embedded_relocs | |
28763 | + (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, char **); | |
28764 | + | |
28765 | +/* ARM Interworking support. Called from linker. */ | |
28766 | +extern bfd_boolean bfd_arm_allocate_interworking_sections | |
28767 | + (struct bfd_link_info *); | |
28768 | + | |
28769 | +extern bfd_boolean bfd_arm_process_before_allocation | |
28770 | + (bfd *, struct bfd_link_info *, int); | |
28771 | + | |
28772 | +extern bfd_boolean bfd_arm_get_bfd_for_interworking | |
28773 | + (bfd *, struct bfd_link_info *); | |
28774 | + | |
28775 | +/* PE ARM Interworking support. Called from linker. */ | |
28776 | +extern bfd_boolean bfd_arm_pe_allocate_interworking_sections | |
28777 | + (struct bfd_link_info *); | |
28778 | + | |
28779 | +extern bfd_boolean bfd_arm_pe_process_before_allocation | |
28780 | + (bfd *, struct bfd_link_info *, int); | |
28781 | + | |
28782 | +extern bfd_boolean bfd_arm_pe_get_bfd_for_interworking | |
28783 | + (bfd *, struct bfd_link_info *); | |
28784 | + | |
28785 | +/* ELF ARM Interworking support. Called from linker. */ | |
28786 | +extern bfd_boolean bfd_elf32_arm_allocate_interworking_sections | |
28787 | + (struct bfd_link_info *); | |
28788 | + | |
28789 | +extern bfd_boolean bfd_elf32_arm_process_before_allocation | |
28790 | + (bfd *, struct bfd_link_info *, int); | |
28791 | + | |
28792 | +void bfd_elf32_arm_set_target_relocs | |
28793 | + (struct bfd_link_info *, int, char *, int, int); | |
28794 | + | |
28795 | +extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking | |
28796 | + (bfd *, struct bfd_link_info *); | |
28797 | + | |
28798 | +extern bfd_boolean bfd_elf32_arm_add_glue_sections_to_bfd | |
28799 | + (bfd *, struct bfd_link_info *); | |
28800 | + | |
28801 | +/* ELF ARM mapping symbol support */ | |
28802 | +extern bfd_boolean bfd_is_arm_mapping_symbol_name | |
28803 | + (const char * name); | |
28804 | + | |
28805 | +/* ARM Note section processing. */ | |
28806 | +extern bfd_boolean bfd_arm_merge_machines | |
28807 | + (bfd *, bfd *); | |
28808 | + | |
28809 | +extern bfd_boolean bfd_arm_update_notes | |
28810 | + (bfd *, const char *); | |
28811 | + | |
28812 | +extern unsigned int bfd_arm_get_mach_from_notes | |
28813 | + (bfd *, const char *); | |
28814 | + | |
28815 | +/* TI COFF load page support. */ | |
28816 | +extern void bfd_ticoff_set_section_load_page | |
28817 | + (struct bfd_section *, int); | |
28818 | + | |
28819 | +extern int bfd_ticoff_get_section_load_page | |
28820 | + (struct bfd_section *); | |
28821 | + | |
28822 | +/* H8/300 functions. */ | |
28823 | +extern bfd_vma bfd_h8300_pad_address | |
28824 | + (bfd *, bfd_vma); | |
28825 | + | |
28826 | +/* IA64 Itanium code generation. Called from linker. */ | |
28827 | +extern void bfd_elf32_ia64_after_parse | |
28828 | + (int); | |
28829 | + | |
28830 | +extern void bfd_elf64_ia64_after_parse | |
28831 | + (int); | |
28832 | + | |
28833 | +/* This structure is used for a comdat section, as in PE. A comdat | |
28834 | + section is associated with a particular symbol. When the linker | |
28835 | + sees a comdat section, it keeps only one of the sections with a | |
28836 | + given name and associated with a given symbol. */ | |
28837 | + | |
28838 | +struct coff_comdat_info | |
28839 | +{ | |
28840 | + /* The name of the symbol associated with a comdat section. */ | |
28841 | + const char *name; | |
28842 | + | |
28843 | + /* The local symbol table index of the symbol associated with a | |
28844 | + comdat section. This is only meaningful to the object file format | |
28845 | + specific code; it is not an index into the list returned by | |
28846 | + bfd_canonicalize_symtab. */ | |
28847 | + long symbol; | |
28848 | +}; | |
28849 | + | |
28850 | +extern struct coff_comdat_info *bfd_coff_get_comdat_section | |
28851 | + (bfd *, struct bfd_section *); | |
28852 | + | |
28853 | +/* Extracted from init.c. */ | |
28854 | +void bfd_init (void); | |
28855 | + | |
28856 | +/* Extracted from opncls.c. */ | |
28857 | +bfd *bfd_fopen (const char *filename, const char *target, | |
28858 | + const char *mode, int fd); | |
28859 | + | |
28860 | +bfd *bfd_openr (const char *filename, const char *target); | |
28861 | + | |
28862 | +bfd *bfd_fdopenr (const char *filename, const char *target, int fd); | |
28863 | + | |
28864 | +bfd *bfd_openstreamr (const char *, const char *, void *); | |
28865 | + | |
28866 | +bfd *bfd_openr_iovec (const char *filename, const char *target, | |
28867 | + void *(*open) (struct bfd *nbfd, | |
28868 | + void *open_closure), | |
28869 | + void *open_closure, | |
28870 | + file_ptr (*pread) (struct bfd *nbfd, | |
28871 | + void *stream, | |
28872 | + void *buf, | |
28873 | + file_ptr nbytes, | |
28874 | + file_ptr offset), | |
28875 | + int (*close) (struct bfd *nbfd, | |
28876 | + void *stream)); | |
28877 | + | |
28878 | +bfd *bfd_openw (const char *filename, const char *target); | |
28879 | + | |
28880 | +bfd_boolean bfd_close (bfd *abfd); | |
28881 | + | |
28882 | +bfd_boolean bfd_close_all_done (bfd *); | |
28883 | + | |
28884 | +bfd *bfd_create (const char *filename, bfd *templ); | |
28885 | + | |
28886 | +bfd_boolean bfd_make_writable (bfd *abfd); | |
28887 | + | |
28888 | +bfd_boolean bfd_make_readable (bfd *abfd); | |
28889 | + | |
28890 | +unsigned long bfd_calc_gnu_debuglink_crc32 | |
28891 | + (unsigned long crc, const unsigned char *buf, bfd_size_type len); | |
28892 | + | |
28893 | +char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir); | |
28894 | + | |
28895 | +struct bfd_section *bfd_create_gnu_debuglink_section | |
28896 | + (bfd *abfd, const char *filename); | |
28897 | + | |
28898 | +bfd_boolean bfd_fill_in_gnu_debuglink_section | |
28899 | + (bfd *abfd, struct bfd_section *sect, const char *filename); | |
28900 | + | |
28901 | +/* Extracted from libbfd.c. */ | |
28902 | + | |
28903 | +/* Byte swapping macros for user section data. */ | |
28904 | + | |
28905 | +#define bfd_put_8(abfd, val, ptr) \ | |
28906 | + ((void) (*((unsigned char *) (ptr)) = (val) & 0xff)) | |
28907 | +#define bfd_put_signed_8 \ | |
28908 | + bfd_put_8 | |
28909 | +#define bfd_get_8(abfd, ptr) \ | |
28910 | + (*(unsigned char *) (ptr) & 0xff) | |
28911 | +#define bfd_get_signed_8(abfd, ptr) \ | |
28912 | + (((*(unsigned char *) (ptr) & 0xff) ^ 0x80) - 0x80) | |
28913 | + | |
28914 | +#define bfd_put_16(abfd, val, ptr) \ | |
28915 | + BFD_SEND (abfd, bfd_putx16, ((val),(ptr))) | |
28916 | +#define bfd_put_signed_16 \ | |
28917 | + bfd_put_16 | |
28918 | +#define bfd_get_16(abfd, ptr) \ | |
28919 | + BFD_SEND (abfd, bfd_getx16, (ptr)) | |
28920 | +#define bfd_get_signed_16(abfd, ptr) \ | |
28921 | + BFD_SEND (abfd, bfd_getx_signed_16, (ptr)) | |
28922 | + | |
28923 | +#define bfd_put_32(abfd, val, ptr) \ | |
28924 | + BFD_SEND (abfd, bfd_putx32, ((val),(ptr))) | |
28925 | +#define bfd_put_signed_32 \ | |
28926 | + bfd_put_32 | |
28927 | +#define bfd_get_32(abfd, ptr) \ | |
28928 | + BFD_SEND (abfd, bfd_getx32, (ptr)) | |
28929 | +#define bfd_get_signed_32(abfd, ptr) \ | |
28930 | + BFD_SEND (abfd, bfd_getx_signed_32, (ptr)) | |
28931 | + | |
28932 | +#define bfd_put_64(abfd, val, ptr) \ | |
28933 | + BFD_SEND (abfd, bfd_putx64, ((val), (ptr))) | |
28934 | +#define bfd_put_signed_64 \ | |
28935 | + bfd_put_64 | |
28936 | +#define bfd_get_64(abfd, ptr) \ | |
28937 | + BFD_SEND (abfd, bfd_getx64, (ptr)) | |
28938 | +#define bfd_get_signed_64(abfd, ptr) \ | |
28939 | + BFD_SEND (abfd, bfd_getx_signed_64, (ptr)) | |
28940 | + | |
28941 | +#define bfd_get(bits, abfd, ptr) \ | |
28942 | + ((bits) == 8 ? (bfd_vma) bfd_get_8 (abfd, ptr) \ | |
28943 | + : (bits) == 16 ? bfd_get_16 (abfd, ptr) \ | |
28944 | + : (bits) == 32 ? bfd_get_32 (abfd, ptr) \ | |
28945 | + : (bits) == 64 ? bfd_get_64 (abfd, ptr) \ | |
28946 | + : (abort (), (bfd_vma) - 1)) | |
28947 | + | |
28948 | +#define bfd_put(bits, abfd, val, ptr) \ | |
28949 | + ((bits) == 8 ? bfd_put_8 (abfd, val, ptr) \ | |
28950 | + : (bits) == 16 ? bfd_put_16 (abfd, val, ptr) \ | |
28951 | + : (bits) == 32 ? bfd_put_32 (abfd, val, ptr) \ | |
28952 | + : (bits) == 64 ? bfd_put_64 (abfd, val, ptr) \ | |
28953 | + : (abort (), (void) 0)) | |
28954 | + | |
28955 | + | |
28956 | +/* Byte swapping macros for file header data. */ | |
28957 | + | |
28958 | +#define bfd_h_put_8(abfd, val, ptr) \ | |
28959 | + bfd_put_8 (abfd, val, ptr) | |
28960 | +#define bfd_h_put_signed_8(abfd, val, ptr) \ | |
28961 | + bfd_put_8 (abfd, val, ptr) | |
28962 | +#define bfd_h_get_8(abfd, ptr) \ | |
28963 | + bfd_get_8 (abfd, ptr) | |
28964 | +#define bfd_h_get_signed_8(abfd, ptr) \ | |
28965 | + bfd_get_signed_8 (abfd, ptr) | |
28966 | + | |
28967 | +#define bfd_h_put_16(abfd, val, ptr) \ | |
28968 | + BFD_SEND (abfd, bfd_h_putx16, (val, ptr)) | |
28969 | +#define bfd_h_put_signed_16 \ | |
28970 | + bfd_h_put_16 | |
28971 | +#define bfd_h_get_16(abfd, ptr) \ | |
28972 | + BFD_SEND (abfd, bfd_h_getx16, (ptr)) | |
28973 | +#define bfd_h_get_signed_16(abfd, ptr) \ | |
28974 | + BFD_SEND (abfd, bfd_h_getx_signed_16, (ptr)) | |
28975 | + | |
28976 | +#define bfd_h_put_32(abfd, val, ptr) \ | |
28977 | + BFD_SEND (abfd, bfd_h_putx32, (val, ptr)) | |
28978 | +#define bfd_h_put_signed_32 \ | |
28979 | + bfd_h_put_32 | |
28980 | +#define bfd_h_get_32(abfd, ptr) \ | |
28981 | + BFD_SEND (abfd, bfd_h_getx32, (ptr)) | |
28982 | +#define bfd_h_get_signed_32(abfd, ptr) \ | |
28983 | + BFD_SEND (abfd, bfd_h_getx_signed_32, (ptr)) | |
28984 | + | |
28985 | +#define bfd_h_put_64(abfd, val, ptr) \ | |
28986 | + BFD_SEND (abfd, bfd_h_putx64, (val, ptr)) | |
28987 | +#define bfd_h_put_signed_64 \ | |
28988 | + bfd_h_put_64 | |
28989 | +#define bfd_h_get_64(abfd, ptr) \ | |
28990 | + BFD_SEND (abfd, bfd_h_getx64, (ptr)) | |
28991 | +#define bfd_h_get_signed_64(abfd, ptr) \ | |
28992 | + BFD_SEND (abfd, bfd_h_getx_signed_64, (ptr)) | |
28993 | + | |
28994 | +/* Aliases for the above, which should eventually go away. */ | |
28995 | + | |
28996 | +#define H_PUT_64 bfd_h_put_64 | |
28997 | +#define H_PUT_32 bfd_h_put_32 | |
28998 | +#define H_PUT_16 bfd_h_put_16 | |
28999 | +#define H_PUT_8 bfd_h_put_8 | |
29000 | +#define H_PUT_S64 bfd_h_put_signed_64 | |
29001 | +#define H_PUT_S32 bfd_h_put_signed_32 | |
29002 | +#define H_PUT_S16 bfd_h_put_signed_16 | |
29003 | +#define H_PUT_S8 bfd_h_put_signed_8 | |
29004 | +#define H_GET_64 bfd_h_get_64 | |
29005 | +#define H_GET_32 bfd_h_get_32 | |
29006 | +#define H_GET_16 bfd_h_get_16 | |
29007 | +#define H_GET_8 bfd_h_get_8 | |
29008 | +#define H_GET_S64 bfd_h_get_signed_64 | |
29009 | +#define H_GET_S32 bfd_h_get_signed_32 | |
29010 | +#define H_GET_S16 bfd_h_get_signed_16 | |
29011 | +#define H_GET_S8 bfd_h_get_signed_8 | |
29012 | + | |
29013 | + | |
29014 | +/* Extracted from bfdio.c. */ | |
29015 | +long bfd_get_mtime (bfd *abfd); | |
29016 | + | |
29017 | +long bfd_get_size (bfd *abfd); | |
29018 | + | |
29019 | +/* Extracted from bfdwin.c. */ | |
29020 | +/* Extracted from section.c. */ | |
29021 | +typedef struct bfd_section | |
29022 | +{ | |
29023 | + /* The name of the section; the name isn't a copy, the pointer is | |
29024 | + the same as that passed to bfd_make_section. */ | |
29025 | + const char *name; | |
29026 | + | |
29027 | + /* A unique sequence number. */ | |
29028 | + int id; | |
29029 | + | |
29030 | + /* Which section in the bfd; 0..n-1 as sections are created in a bfd. */ | |
29031 | + int index; | |
29032 | + | |
29033 | + /* The next section in the list belonging to the BFD, or NULL. */ | |
29034 | + struct bfd_section *next; | |
29035 | + | |
29036 | + /* The previous section in the list belonging to the BFD, or NULL. */ | |
29037 | + struct bfd_section *prev; | |
29038 | + | |
29039 | + /* The field flags contains attributes of the section. Some | |
29040 | + flags are read in from the object file, and some are | |
29041 | + synthesized from other information. */ | |
29042 | + flagword flags; | |
29043 | + | |
29044 | +#define SEC_NO_FLAGS 0x000 | |
29045 | + | |
29046 | + /* Tells the OS to allocate space for this section when loading. | |
29047 | + This is clear for a section containing debug information only. */ | |
29048 | +#define SEC_ALLOC 0x001 | |
29049 | + | |
29050 | + /* Tells the OS to load the section from the file when loading. | |
29051 | + This is clear for a .bss section. */ | |
29052 | +#define SEC_LOAD 0x002 | |
29053 | + | |
29054 | + /* The section contains data still to be relocated, so there is | |
29055 | + some relocation information too. */ | |
29056 | +#define SEC_RELOC 0x004 | |
29057 | + | |
29058 | + /* A signal to the OS that the section contains read only data. */ | |
29059 | +#define SEC_READONLY 0x008 | |
29060 | + | |
29061 | + /* The section contains code only. */ | |
29062 | +#define SEC_CODE 0x010 | |
29063 | + | |
29064 | + /* The section contains data only. */ | |
29065 | +#define SEC_DATA 0x020 | |
29066 | + | |
29067 | + /* The section will reside in ROM. */ | |
29068 | +#define SEC_ROM 0x040 | |
29069 | + | |
29070 | + /* The section contains constructor information. This section | |
29071 | + type is used by the linker to create lists of constructors and | |
29072 | + destructors used by <<g++>>. When a back end sees a symbol | |
29073 | + which should be used in a constructor list, it creates a new | |
29074 | + section for the type of name (e.g., <<__CTOR_LIST__>>), attaches | |
29075 | + the symbol to it, and builds a relocation. To build the lists | |
29076 | + of constructors, all the linker has to do is catenate all the | |
29077 | + sections called <<__CTOR_LIST__>> and relocate the data | |
29078 | + contained within - exactly the operations it would peform on | |
29079 | + standard data. */ | |
29080 | +#define SEC_CONSTRUCTOR 0x080 | |
29081 | + | |
29082 | + /* The section has contents - a data section could be | |
29083 | + <<SEC_ALLOC>> | <<SEC_HAS_CONTENTS>>; a debug section could be | |
29084 | + <<SEC_HAS_CONTENTS>> */ | |
29085 | +#define SEC_HAS_CONTENTS 0x100 | |
29086 | + | |
29087 | + /* An instruction to the linker to not output the section | |
29088 | + even if it has information which would normally be written. */ | |
29089 | +#define SEC_NEVER_LOAD 0x200 | |
29090 | + | |
29091 | + /* The section contains thread local data. */ | |
29092 | +#define SEC_THREAD_LOCAL 0x400 | |
29093 | + | |
29094 | + /* The section has GOT references. This flag is only for the | |
29095 | + linker, and is currently only used by the elf32-hppa back end. | |
29096 | + It will be set if global offset table references were detected | |
29097 | + in this section, which indicate to the linker that the section | |
29098 | + contains PIC code, and must be handled specially when doing a | |
29099 | + static link. */ | |
29100 | +#define SEC_HAS_GOT_REF 0x800 | |
29101 | + | |
29102 | + /* The section contains common symbols (symbols may be defined | |
29103 | + multiple times, the value of a symbol is the amount of | |
29104 | + space it requires, and the largest symbol value is the one | |
29105 | + used). Most targets have exactly one of these (which we | |
29106 | + translate to bfd_com_section_ptr), but ECOFF has two. */ | |
29107 | +#define SEC_IS_COMMON 0x1000 | |
29108 | + | |
29109 | + /* The section contains only debugging information. For | |
29110 | + example, this is set for ELF .debug and .stab sections. | |
29111 | + strip tests this flag to see if a section can be | |
29112 | + discarded. */ | |
29113 | +#define SEC_DEBUGGING 0x2000 | |
29114 | + | |
29115 | + /* The contents of this section are held in memory pointed to | |
29116 | + by the contents field. This is checked by bfd_get_section_contents, | |
29117 | + and the data is retrieved from memory if appropriate. */ | |
29118 | +#define SEC_IN_MEMORY 0x4000 | |
29119 | + | |
29120 | + /* The contents of this section are to be excluded by the | |
29121 | + linker for executable and shared objects unless those | |
29122 | + objects are to be further relocated. */ | |
29123 | +#define SEC_EXCLUDE 0x8000 | |
29124 | + | |
29125 | + /* The contents of this section are to be sorted based on the sum of | |
29126 | + the symbol and addend values specified by the associated relocation | |
29127 | + entries. Entries without associated relocation entries will be | |
29128 | + appended to the end of the section in an unspecified order. */ | |
29129 | +#define SEC_SORT_ENTRIES 0x10000 | |
29130 | + | |
29131 | + /* When linking, duplicate sections of the same name should be | |
29132 | + discarded, rather than being combined into a single section as | |
29133 | + is usually done. This is similar to how common symbols are | |
29134 | + handled. See SEC_LINK_DUPLICATES below. */ | |
29135 | +#define SEC_LINK_ONCE 0x20000 | |
29136 | + | |
29137 | + /* If SEC_LINK_ONCE is set, this bitfield describes how the linker | |
29138 | + should handle duplicate sections. */ | |
29139 | +#define SEC_LINK_DUPLICATES 0x40000 | |
29140 | + | |
29141 | + /* This value for SEC_LINK_DUPLICATES means that duplicate | |
29142 | + sections with the same name should simply be discarded. */ | |
29143 | +#define SEC_LINK_DUPLICATES_DISCARD 0x0 | |
29144 | + | |
29145 | + /* This value for SEC_LINK_DUPLICATES means that the linker | |
29146 | + should warn if there are any duplicate sections, although | |
29147 | + it should still only link one copy. */ | |
29148 | +#define SEC_LINK_DUPLICATES_ONE_ONLY 0x80000 | |
29149 | + | |
29150 | + /* This value for SEC_LINK_DUPLICATES means that the linker | |
29151 | + should warn if any duplicate sections are a different size. */ | |
29152 | +#define SEC_LINK_DUPLICATES_SAME_SIZE 0x100000 | |
29153 | + | |
29154 | + /* This value for SEC_LINK_DUPLICATES means that the linker | |
29155 | + should warn if any duplicate sections contain different | |
29156 | + contents. */ | |
29157 | +#define SEC_LINK_DUPLICATES_SAME_CONTENTS \ | |
29158 | + (SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE) | |
29159 | + | |
29160 | + /* This section was created by the linker as part of dynamic | |
29161 | + relocation or other arcane processing. It is skipped when | |
29162 | + going through the first-pass output, trusting that someone | |
29163 | + else up the line will take care of it later. */ | |
29164 | +#define SEC_LINKER_CREATED 0x200000 | |
29165 | + | |
29166 | + /* This section should not be subject to garbage collection. */ | |
29167 | +#define SEC_KEEP 0x400000 | |
29168 | + | |
29169 | + /* This section contains "short" data, and should be placed | |
29170 | + "near" the GP. */ | |
29171 | +#define SEC_SMALL_DATA 0x800000 | |
29172 | + | |
29173 | + /* Attempt to merge identical entities in the section. | |
29174 | + Entity size is given in the entsize field. */ | |
29175 | +#define SEC_MERGE 0x1000000 | |
29176 | + | |
29177 | + /* If given with SEC_MERGE, entities to merge are zero terminated | |
29178 | + strings where entsize specifies character size instead of fixed | |
29179 | + size entries. */ | |
29180 | +#define SEC_STRINGS 0x2000000 | |
29181 | + | |
29182 | + /* This section contains data about section groups. */ | |
29183 | +#define SEC_GROUP 0x4000000 | |
29184 | + | |
29185 | + /* The section is a COFF shared library section. This flag is | |
29186 | + only for the linker. If this type of section appears in | |
29187 | + the input file, the linker must copy it to the output file | |
29188 | + without changing the vma or size. FIXME: Although this | |
29189 | + was originally intended to be general, it really is COFF | |
29190 | + specific (and the flag was renamed to indicate this). It | |
29191 | + might be cleaner to have some more general mechanism to | |
29192 | + allow the back end to control what the linker does with | |
29193 | + sections. */ | |
29194 | +#define SEC_COFF_SHARED_LIBRARY 0x10000000 | |
29195 | + | |
29196 | + /* This section contains data which may be shared with other | |
29197 | + executables or shared objects. This is for COFF only. */ | |
29198 | +#define SEC_COFF_SHARED 0x20000000 | |
29199 | + | |
29200 | + /* When a section with this flag is being linked, then if the size of | |
29201 | + the input section is less than a page, it should not cross a page | |
29202 | + boundary. If the size of the input section is one page or more, | |
29203 | + it should be aligned on a page boundary. This is for TI | |
29204 | + TMS320C54X only. */ | |
29205 | +#define SEC_TIC54X_BLOCK 0x40000000 | |
29206 | + | |
29207 | + /* Conditionally link this section; do not link if there are no | |
29208 | + references found to any symbol in the section. This is for TI | |
29209 | + TMS320C54X only. */ | |
29210 | +#define SEC_TIC54X_CLINK 0x80000000 | |
29211 | + | |
29212 | + /* End of section flags. */ | |
29213 | + | |
29214 | + /* Some internal packed boolean fields. */ | |
29215 | + | |
29216 | + /* See the vma field. */ | |
29217 | + unsigned int user_set_vma : 1; | |
29218 | + | |
29219 | + /* A mark flag used by some of the linker backends. */ | |
29220 | + unsigned int linker_mark : 1; | |
29221 | + | |
29222 | + /* Another mark flag used by some of the linker backends. Set for | |
29223 | + output sections that have an input section. */ | |
29224 | + unsigned int linker_has_input : 1; | |
29225 | + | |
29226 | + /* Mark flags used by some linker backends for garbage collection. */ | |
29227 | + unsigned int gc_mark : 1; | |
29228 | + unsigned int gc_mark_from_eh : 1; | |
29229 | + | |
29230 | + /* The following flags are used by the ELF linker. */ | |
29231 | + | |
29232 | + /* Mark sections which have been allocated to segments. */ | |
29233 | + unsigned int segment_mark : 1; | |
29234 | + | |
29235 | + /* Type of sec_info information. */ | |
29236 | + unsigned int sec_info_type:3; | |
29237 | +#define ELF_INFO_TYPE_NONE 0 | |
29238 | +#define ELF_INFO_TYPE_STABS 1 | |
29239 | +#define ELF_INFO_TYPE_MERGE 2 | |
29240 | +#define ELF_INFO_TYPE_EH_FRAME 3 | |
29241 | +#define ELF_INFO_TYPE_JUST_SYMS 4 | |
29242 | + | |
29243 | + /* Nonzero if this section uses RELA relocations, rather than REL. */ | |
29244 | + unsigned int use_rela_p:1; | |
29245 | + | |
29246 | + /* Bits used by various backends. The generic code doesn't touch | |
29247 | + these fields. */ | |
29248 | + | |
29249 | + /* Nonzero if this section has TLS related relocations. */ | |
29250 | + unsigned int has_tls_reloc:1; | |
29251 | + | |
29252 | + /* Nonzero if this section has a gp reloc. */ | |
29253 | + unsigned int has_gp_reloc:1; | |
29254 | + | |
29255 | + /* Nonzero if this section needs the relax finalize pass. */ | |
29256 | + unsigned int need_finalize_relax:1; | |
29257 | + | |
29258 | + /* Whether relocations have been processed. */ | |
29259 | + unsigned int reloc_done : 1; | |
29260 | + | |
29261 | + /* End of internal packed boolean fields. */ | |
29262 | + | |
29263 | + /* The virtual memory address of the section - where it will be | |
29264 | + at run time. The symbols are relocated against this. The | |
29265 | + user_set_vma flag is maintained by bfd; if it's not set, the | |
29266 | + backend can assign addresses (for example, in <<a.out>>, where | |
29267 | + the default address for <<.data>> is dependent on the specific | |
29268 | + target and various flags). */ | |
29269 | + bfd_vma vma; | |
29270 | + | |
29271 | + /* The load address of the section - where it would be in a | |
29272 | + rom image; really only used for writing section header | |
29273 | + information. */ | |
29274 | + bfd_vma lma; | |
29275 | + | |
29276 | + /* The size of the section in octets, as it will be output. | |
29277 | + Contains a value even if the section has no contents (e.g., the | |
29278 | + size of <<.bss>>). */ | |
29279 | + bfd_size_type size; | |
29280 | + | |
29281 | + /* For input sections, the original size on disk of the section, in | |
29282 | + octets. This field is used by the linker relaxation code. It is | |
29283 | + currently only set for sections where the linker relaxation scheme | |
29284 | + doesn't cache altered section and reloc contents (stabs, eh_frame, | |
29285 | + SEC_MERGE, some coff relaxing targets), and thus the original size | |
29286 | + needs to be kept to read the section multiple times. | |
29287 | + For output sections, rawsize holds the section size calculated on | |
29288 | + a previous linker relaxation pass. */ | |
29289 | + bfd_size_type rawsize; | |
29290 | + | |
29291 | + /* If this section is going to be output, then this value is the | |
29292 | + offset in *bytes* into the output section of the first byte in the | |
29293 | + input section (byte ==> smallest addressable unit on the | |
29294 | + target). In most cases, if this was going to start at the | |
29295 | + 100th octet (8-bit quantity) in the output section, this value | |
29296 | + would be 100. However, if the target byte size is 16 bits | |
29297 | + (bfd_octets_per_byte is "2"), this value would be 50. */ | |
29298 | + bfd_vma output_offset; | |
29299 | + | |
29300 | + /* The output section through which to map on output. */ | |
29301 | + struct bfd_section *output_section; | |
29302 | + | |
29303 | + /* The alignment requirement of the section, as an exponent of 2 - | |
29304 | + e.g., 3 aligns to 2^3 (or 8). */ | |
29305 | + unsigned int alignment_power; | |
29306 | + | |
29307 | + /* If an input section, a pointer to a vector of relocation | |
29308 | + records for the data in this section. */ | |
29309 | + struct reloc_cache_entry *relocation; | |
29310 | + | |
29311 | + /* If an output section, a pointer to a vector of pointers to | |
29312 | + relocation records for the data in this section. */ | |
29313 | + struct reloc_cache_entry **orelocation; | |
29314 | + | |
29315 | + /* The number of relocation records in one of the above. */ | |
29316 | + unsigned reloc_count; | |
29317 | + | |
29318 | + /* Information below is back end specific - and not always used | |
29319 | + or updated. */ | |
29320 | + | |
29321 | + /* File position of section data. */ | |
29322 | + file_ptr filepos; | |
29323 | + | |
29324 | + /* File position of relocation info. */ | |
29325 | + file_ptr rel_filepos; | |
29326 | + | |
29327 | + /* File position of line data. */ | |
29328 | + file_ptr line_filepos; | |
29329 | + | |
29330 | + /* Pointer to data for applications. */ | |
29331 | + void *userdata; | |
29332 | + | |
29333 | + /* If the SEC_IN_MEMORY flag is set, this points to the actual | |
29334 | + contents. */ | |
29335 | + unsigned char *contents; | |
29336 | + | |
29337 | + /* Attached line number information. */ | |
29338 | + alent *lineno; | |
29339 | + | |
29340 | + /* Number of line number records. */ | |
29341 | + unsigned int lineno_count; | |
29342 | + | |
29343 | + /* Entity size for merging purposes. */ | |
29344 | + unsigned int entsize; | |
29345 | + | |
29346 | + /* Points to the kept section if this section is a link-once section, | |
29347 | + and is discarded. */ | |
29348 | + struct bfd_section *kept_section; | |
29349 | + | |
29350 | + /* When a section is being output, this value changes as more | |
29351 | + linenumbers are written out. */ | |
29352 | + file_ptr moving_line_filepos; | |
29353 | + | |
29354 | + /* What the section number is in the target world. */ | |
29355 | + int target_index; | |
29356 | + | |
29357 | + void *used_by_bfd; | |
29358 | + | |
29359 | + /* If this is a constructor section then here is a list of the | |
29360 | + relocations created to relocate items within it. */ | |
29361 | + struct relent_chain *constructor_chain; | |
29362 | + | |
29363 | + /* The BFD which owns the section. */ | |
29364 | + bfd *owner; | |
29365 | + | |
29366 | + /* A symbol which points at this section only. */ | |
29367 | + struct bfd_symbol *symbol; | |
29368 | + struct bfd_symbol **symbol_ptr_ptr; | |
29369 | + | |
29370 | + /* Early in the link process, map_head and map_tail are used to build | |
29371 | + a list of input sections attached to an output section. Later, | |
29372 | + output sections use these fields for a list of bfd_link_order | |
29373 | + structs. */ | |
29374 | + union { | |
29375 | + struct bfd_link_order *link_order; | |
29376 | + struct bfd_section *s; | |
29377 | + } map_head, map_tail; | |
29378 | +} asection; | |
29379 | + | |
29380 | +/* These sections are global, and are managed by BFD. The application | |
29381 | + and target back end are not permitted to change the values in | |
29382 | + these sections. New code should use the section_ptr macros rather | |
29383 | + than referring directly to the const sections. The const sections | |
29384 | + may eventually vanish. */ | |
29385 | +#define BFD_ABS_SECTION_NAME "*ABS*" | |
29386 | +#define BFD_UND_SECTION_NAME "*UND*" | |
29387 | +#define BFD_COM_SECTION_NAME "*COM*" | |
29388 | +#define BFD_IND_SECTION_NAME "*IND*" | |
29389 | + | |
29390 | +/* The absolute section. */ | |
29391 | +extern asection bfd_abs_section; | |
29392 | +#define bfd_abs_section_ptr ((asection *) &bfd_abs_section) | |
29393 | +#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr) | |
29394 | +/* Pointer to the undefined section. */ | |
29395 | +extern asection bfd_und_section; | |
29396 | +#define bfd_und_section_ptr ((asection *) &bfd_und_section) | |
29397 | +#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr) | |
29398 | +/* Pointer to the common section. */ | |
29399 | +extern asection bfd_com_section; | |
29400 | +#define bfd_com_section_ptr ((asection *) &bfd_com_section) | |
29401 | +/* Pointer to the indirect section. */ | |
29402 | +extern asection bfd_ind_section; | |
29403 | +#define bfd_ind_section_ptr ((asection *) &bfd_ind_section) | |
29404 | +#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr) | |
29405 | + | |
29406 | +#define bfd_is_const_section(SEC) \ | |
29407 | + ( ((SEC) == bfd_abs_section_ptr) \ | |
29408 | + || ((SEC) == bfd_und_section_ptr) \ | |
29409 | + || ((SEC) == bfd_com_section_ptr) \ | |
29410 | + || ((SEC) == bfd_ind_section_ptr)) | |
29411 | + | |
29412 | +extern const struct bfd_symbol * const bfd_abs_symbol; | |
29413 | +extern const struct bfd_symbol * const bfd_com_symbol; | |
29414 | +extern const struct bfd_symbol * const bfd_und_symbol; | |
29415 | +extern const struct bfd_symbol * const bfd_ind_symbol; | |
29416 | + | |
29417 | +/* Macros to handle insertion and deletion of a bfd's sections. These | |
29418 | + only handle the list pointers, ie. do not adjust section_count, | |
29419 | + target_index etc. */ | |
29420 | +#define bfd_section_list_remove(ABFD, S) \ | |
29421 | + do \ | |
29422 | + { \ | |
29423 | + asection *_s = S; \ | |
29424 | + asection *_next = _s->next; \ | |
29425 | + asection *_prev = _s->prev; \ | |
29426 | + if (_prev) \ | |
29427 | + _prev->next = _next; \ | |
29428 | + else \ | |
29429 | + (ABFD)->sections = _next; \ | |
29430 | + if (_next) \ | |
29431 | + _next->prev = _prev; \ | |
29432 | + else \ | |
29433 | + (ABFD)->section_last = _prev; \ | |
29434 | + } \ | |
29435 | + while (0) | |
29436 | +#define bfd_section_list_append(ABFD, S) \ | |
29437 | + do \ | |
29438 | + { \ | |
29439 | + asection *_s = S; \ | |
29440 | + bfd *_abfd = ABFD; \ | |
29441 | + _s->next = NULL; \ | |
29442 | + if (_abfd->section_last) \ | |
29443 | + { \ | |
29444 | + _s->prev = _abfd->section_last; \ | |
29445 | + _abfd->section_last->next = _s; \ | |
29446 | + } \ | |
29447 | + else \ | |
29448 | + { \ | |
29449 | + _s->prev = NULL; \ | |
29450 | + _abfd->sections = _s; \ | |
29451 | + } \ | |
29452 | + _abfd->section_last = _s; \ | |
29453 | + } \ | |
29454 | + while (0) | |
29455 | +#define bfd_section_list_prepend(ABFD, S) \ | |
29456 | + do \ | |
29457 | + { \ | |
29458 | + asection *_s = S; \ | |
29459 | + bfd *_abfd = ABFD; \ | |
29460 | + _s->prev = NULL; \ | |
29461 | + if (_abfd->sections) \ | |
29462 | + { \ | |
29463 | + _s->next = _abfd->sections; \ | |
29464 | + _abfd->sections->prev = _s; \ | |
29465 | + } \ | |
29466 | + else \ | |
29467 | + { \ | |
29468 | + _s->next = NULL; \ | |
29469 | + _abfd->section_last = _s; \ | |
29470 | + } \ | |
29471 | + _abfd->sections = _s; \ | |
29472 | + } \ | |
29473 | + while (0) | |
29474 | +#define bfd_section_list_insert_after(ABFD, A, S) \ | |
29475 | + do \ | |
29476 | + { \ | |
29477 | + asection *_a = A; \ | |
29478 | + asection *_s = S; \ | |
29479 | + asection *_next = _a->next; \ | |
29480 | + _s->next = _next; \ | |
29481 | + _s->prev = _a; \ | |
29482 | + _a->next = _s; \ | |
29483 | + if (_next) \ | |
29484 | + _next->prev = _s; \ | |
29485 | + else \ | |
29486 | + (ABFD)->section_last = _s; \ | |
29487 | + } \ | |
29488 | + while (0) | |
29489 | +#define bfd_section_list_insert_before(ABFD, B, S) \ | |
29490 | + do \ | |
29491 | + { \ | |
29492 | + asection *_b = B; \ | |
29493 | + asection *_s = S; \ | |
29494 | + asection *_prev = _b->prev; \ | |
29495 | + _s->prev = _prev; \ | |
29496 | + _s->next = _b; \ | |
29497 | + _b->prev = _s; \ | |
29498 | + if (_prev) \ | |
29499 | + _prev->next = _s; \ | |
29500 | + else \ | |
29501 | + (ABFD)->sections = _s; \ | |
29502 | + } \ | |
29503 | + while (0) | |
29504 | +#define bfd_section_removed_from_list(ABFD, S) \ | |
29505 | + ((S)->next == NULL ? (ABFD)->section_last != (S) : (S)->next->prev != (S)) | |
29506 | + | |
29507 | +void bfd_section_list_clear (bfd *); | |
29508 | + | |
29509 | +asection *bfd_get_section_by_name (bfd *abfd, const char *name); | |
29510 | + | |
29511 | +asection *bfd_get_section_by_name_if | |
29512 | + (bfd *abfd, | |
29513 | + const char *name, | |
29514 | + bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj), | |
29515 | + void *obj); | |
29516 | + | |
29517 | +char *bfd_get_unique_section_name | |
29518 | + (bfd *abfd, const char *templat, int *count); | |
29519 | + | |
29520 | +asection *bfd_make_section_old_way (bfd *abfd, const char *name); | |
29521 | + | |
29522 | +asection *bfd_make_section_anyway_with_flags | |
29523 | + (bfd *abfd, const char *name, flagword flags); | |
29524 | + | |
29525 | +asection *bfd_make_section_anyway (bfd *abfd, const char *name); | |
29526 | + | |
29527 | +asection *bfd_make_section_with_flags | |
29528 | + (bfd *, const char *name, flagword flags); | |
29529 | + | |
29530 | +asection *bfd_make_section (bfd *, const char *name); | |
29531 | + | |
29532 | +bfd_boolean bfd_set_section_flags | |
29533 | + (bfd *abfd, asection *sec, flagword flags); | |
29534 | + | |
29535 | +void bfd_map_over_sections | |
29536 | + (bfd *abfd, | |
29537 | + void (*func) (bfd *abfd, asection *sect, void *obj), | |
29538 | + void *obj); | |
29539 | + | |
29540 | +asection *bfd_sections_find_if | |
29541 | + (bfd *abfd, | |
29542 | + bfd_boolean (*operation) (bfd *abfd, asection *sect, void *obj), | |
29543 | + void *obj); | |
29544 | + | |
29545 | +bfd_boolean bfd_set_section_size | |
29546 | + (bfd *abfd, asection *sec, bfd_size_type val); | |
29547 | + | |
29548 | +bfd_boolean bfd_set_section_contents | |
29549 | + (bfd *abfd, asection *section, const void *data, | |
29550 | + file_ptr offset, bfd_size_type count); | |
29551 | + | |
29552 | +bfd_boolean bfd_get_section_contents | |
29553 | + (bfd *abfd, asection *section, void *location, file_ptr offset, | |
29554 | + bfd_size_type count); | |
29555 | + | |
29556 | +bfd_boolean bfd_malloc_and_get_section | |
29557 | + (bfd *abfd, asection *section, bfd_byte **buf); | |
29558 | + | |
29559 | +bfd_boolean bfd_copy_private_section_data | |
29560 | + (bfd *ibfd, asection *isec, bfd *obfd, asection *osec); | |
29561 | + | |
29562 | +#define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \ | |
29563 | + BFD_SEND (obfd, _bfd_copy_private_section_data, \ | |
29564 | + (ibfd, isection, obfd, osection)) | |
29565 | +bfd_boolean bfd_generic_is_group_section (bfd *, const asection *sec); | |
29566 | + | |
29567 | +bfd_boolean bfd_generic_discard_group (bfd *abfd, asection *group); | |
29568 | + | |
29569 | +/* Extracted from archures.c. */ | |
29570 | +enum bfd_architecture | |
29571 | +{ | |
29572 | + bfd_arch_unknown, /* File arch not known. */ | |
29573 | + bfd_arch_obscure, /* Arch known, not one of these. */ | |
29574 | + bfd_arch_m68k, /* Motorola 68xxx */ | |
29575 | +#define bfd_mach_m68000 1 | |
29576 | +#define bfd_mach_m68008 2 | |
29577 | +#define bfd_mach_m68010 3 | |
29578 | +#define bfd_mach_m68020 4 | |
29579 | +#define bfd_mach_m68030 5 | |
29580 | +#define bfd_mach_m68040 6 | |
29581 | +#define bfd_mach_m68060 7 | |
29582 | +#define bfd_mach_cpu32 8 | |
29583 | +#define bfd_mach_mcf5200 9 | |
29584 | +#define bfd_mach_mcf5206e 10 | |
29585 | +#define bfd_mach_mcf5307 11 | |
29586 | +#define bfd_mach_mcf5407 12 | |
29587 | +#define bfd_mach_mcf528x 13 | |
29588 | +#define bfd_mach_mcfv4e 14 | |
29589 | +#define bfd_mach_mcf521x 15 | |
29590 | +#define bfd_mach_mcf5249 16 | |
29591 | +#define bfd_mach_mcf547x 17 | |
29592 | +#define bfd_mach_mcf548x 18 | |
29593 | + bfd_arch_vax, /* DEC Vax */ | |
29594 | + bfd_arch_i960, /* Intel 960 */ | |
29595 | + /* The order of the following is important. | |
29596 | + lower number indicates a machine type that | |
29597 | + only accepts a subset of the instructions | |
29598 | + available to machines with higher numbers. | |
29599 | + The exception is the "ca", which is | |
29600 | + incompatible with all other machines except | |
29601 | + "core". */ | |
29602 | + | |
29603 | +#define bfd_mach_i960_core 1 | |
29604 | +#define bfd_mach_i960_ka_sa 2 | |
29605 | +#define bfd_mach_i960_kb_sb 3 | |
29606 | +#define bfd_mach_i960_mc 4 | |
29607 | +#define bfd_mach_i960_xa 5 | |
29608 | +#define bfd_mach_i960_ca 6 | |
29609 | +#define bfd_mach_i960_jx 7 | |
29610 | +#define bfd_mach_i960_hx 8 | |
29611 | + | |
29612 | + bfd_arch_or32, /* OpenRISC 32 */ | |
29613 | + | |
29614 | + bfd_arch_a29k, /* AMD 29000 */ | |
29615 | + bfd_arch_sparc, /* SPARC */ | |
29616 | +#define bfd_mach_sparc 1 | |
29617 | +/* The difference between v8plus and v9 is that v9 is a true 64 bit env. */ | |
29618 | +#define bfd_mach_sparc_sparclet 2 | |
29619 | +#define bfd_mach_sparc_sparclite 3 | |
29620 | +#define bfd_mach_sparc_v8plus 4 | |
29621 | +#define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns. */ | |
29622 | +#define bfd_mach_sparc_sparclite_le 6 | |
29623 | +#define bfd_mach_sparc_v9 7 | |
29624 | +#define bfd_mach_sparc_v9a 8 /* with ultrasparc add'ns. */ | |
29625 | +#define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */ | |
29626 | +#define bfd_mach_sparc_v9b 10 /* with cheetah add'ns. */ | |
29627 | +/* Nonzero if MACH has the v9 instruction set. */ | |
29628 | +#define bfd_mach_sparc_v9_p(mach) \ | |
29629 | + ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9b \ | |
29630 | + && (mach) != bfd_mach_sparc_sparclite_le) | |
29631 | +/* Nonzero if MACH is a 64 bit sparc architecture. */ | |
29632 | +#define bfd_mach_sparc_64bit_p(mach) \ | |
29633 | + ((mach) >= bfd_mach_sparc_v9 && (mach) != bfd_mach_sparc_v8plusb) | |
29634 | + bfd_arch_mips, /* MIPS Rxxxx */ | |
29635 | +#define bfd_mach_mips3000 3000 | |
29636 | +#define bfd_mach_mips3900 3900 | |
29637 | +#define bfd_mach_mips4000 4000 | |
29638 | +#define bfd_mach_mips4010 4010 | |
29639 | +#define bfd_mach_mips4100 4100 | |
29640 | +#define bfd_mach_mips4111 4111 | |
29641 | +#define bfd_mach_mips4120 4120 | |
29642 | +#define bfd_mach_mips4300 4300 | |
29643 | +#define bfd_mach_mips4400 4400 | |
29644 | +#define bfd_mach_mips4600 4600 | |
29645 | +#define bfd_mach_mips4650 4650 | |
29646 | +#define bfd_mach_mips5000 5000 | |
29647 | +#define bfd_mach_mips5400 5400 | |
29648 | +#define bfd_mach_mips5500 5500 | |
29649 | +#define bfd_mach_mips6000 6000 | |
29650 | +#define bfd_mach_mips7000 7000 | |
29651 | +#define bfd_mach_mips8000 8000 | |
29652 | +#define bfd_mach_mips9000 9000 | |
29653 | +#define bfd_mach_mips10000 10000 | |
29654 | +#define bfd_mach_mips12000 12000 | |
29655 | +#define bfd_mach_mips16 16 | |
29656 | +#define bfd_mach_mips5 5 | |
29657 | +#define bfd_mach_mips_sb1 12310201 /* octal 'SB', 01 */ | |
29658 | +#define bfd_mach_mipsisa32 32 | |
29659 | +#define bfd_mach_mipsisa32r2 33 | |
29660 | +#define bfd_mach_mipsisa64 64 | |
29661 | +#define bfd_mach_mipsisa64r2 65 | |
29662 | + bfd_arch_i386, /* Intel 386 */ | |
29663 | +#define bfd_mach_i386_i386 1 | |
29664 | +#define bfd_mach_i386_i8086 2 | |
29665 | +#define bfd_mach_i386_i386_intel_syntax 3 | |
29666 | +#define bfd_mach_x86_64 64 | |
29667 | +#define bfd_mach_x86_64_intel_syntax 65 | |
29668 | + bfd_arch_we32k, /* AT&T WE32xxx */ | |
29669 | + bfd_arch_tahoe, /* CCI/Harris Tahoe */ | |
29670 | + bfd_arch_i860, /* Intel 860 */ | |
29671 | + bfd_arch_i370, /* IBM 360/370 Mainframes */ | |
29672 | + bfd_arch_romp, /* IBM ROMP PC/RT */ | |
29673 | + bfd_arch_alliant, /* Alliant */ | |
29674 | + bfd_arch_convex, /* Convex */ | |
29675 | + bfd_arch_m88k, /* Motorola 88xxx */ | |
29676 | + bfd_arch_m98k, /* Motorola 98xxx */ | |
29677 | + bfd_arch_pyramid, /* Pyramid Technology */ | |
29678 | + bfd_arch_h8300, /* Renesas H8/300 (formerly Hitachi H8/300) */ | |
29679 | +#define bfd_mach_h8300 1 | |
29680 | +#define bfd_mach_h8300h 2 | |
29681 | +#define bfd_mach_h8300s 3 | |
29682 | +#define bfd_mach_h8300hn 4 | |
29683 | +#define bfd_mach_h8300sn 5 | |
29684 | +#define bfd_mach_h8300sx 6 | |
29685 | +#define bfd_mach_h8300sxn 7 | |
29686 | + bfd_arch_pdp11, /* DEC PDP-11 */ | |
29687 | + bfd_arch_powerpc, /* PowerPC */ | |
29688 | +#define bfd_mach_ppc 32 | |
29689 | +#define bfd_mach_ppc64 64 | |
29690 | +#define bfd_mach_ppc_403 403 | |
29691 | +#define bfd_mach_ppc_403gc 4030 | |
29692 | +#define bfd_mach_ppc_505 505 | |
29693 | +#define bfd_mach_ppc_601 601 | |
29694 | +#define bfd_mach_ppc_602 602 | |
29695 | +#define bfd_mach_ppc_603 603 | |
29696 | +#define bfd_mach_ppc_ec603e 6031 | |
29697 | +#define bfd_mach_ppc_604 604 | |
29698 | +#define bfd_mach_ppc_620 620 | |
29699 | +#define bfd_mach_ppc_630 630 | |
29700 | +#define bfd_mach_ppc_750 750 | |
29701 | +#define bfd_mach_ppc_860 860 | |
29702 | +#define bfd_mach_ppc_a35 35 | |
29703 | +#define bfd_mach_ppc_rs64ii 642 | |
29704 | +#define bfd_mach_ppc_rs64iii 643 | |
29705 | +#define bfd_mach_ppc_7400 7400 | |
29706 | +#define bfd_mach_ppc_e500 500 | |
29707 | + bfd_arch_rs6000, /* IBM RS/6000 */ | |
29708 | +#define bfd_mach_rs6k 6000 | |
29709 | +#define bfd_mach_rs6k_rs1 6001 | |
29710 | +#define bfd_mach_rs6k_rsc 6003 | |
29711 | +#define bfd_mach_rs6k_rs2 6002 | |
29712 | + bfd_arch_hppa, /* HP PA RISC */ | |
29713 | +#define bfd_mach_hppa10 10 | |
29714 | +#define bfd_mach_hppa11 11 | |
29715 | +#define bfd_mach_hppa20 20 | |
29716 | +#define bfd_mach_hppa20w 25 | |
29717 | + bfd_arch_d10v, /* Mitsubishi D10V */ | |
29718 | +#define bfd_mach_d10v 1 | |
29719 | +#define bfd_mach_d10v_ts2 2 | |
29720 | +#define bfd_mach_d10v_ts3 3 | |
29721 | + bfd_arch_d30v, /* Mitsubishi D30V */ | |
29722 | + bfd_arch_dlx, /* DLX */ | |
29723 | + bfd_arch_m68hc11, /* Motorola 68HC11 */ | |
29724 | + bfd_arch_m68hc12, /* Motorola 68HC12 */ | |
29725 | +#define bfd_mach_m6812_default 0 | |
29726 | +#define bfd_mach_m6812 1 | |
29727 | +#define bfd_mach_m6812s 2 | |
29728 | + bfd_arch_z8k, /* Zilog Z8000 */ | |
29729 | +#define bfd_mach_z8001 1 | |
29730 | +#define bfd_mach_z8002 2 | |
29731 | + bfd_arch_h8500, /* Renesas H8/500 (formerly Hitachi H8/500) */ | |
29732 | + bfd_arch_sh, /* Renesas / SuperH SH (formerly Hitachi SH) */ | |
29733 | +#define bfd_mach_sh 1 | |
29734 | +#define bfd_mach_sh2 0x20 | |
29735 | +#define bfd_mach_sh_dsp 0x2d | |
29736 | +#define bfd_mach_sh2a 0x2a | |
29737 | +#define bfd_mach_sh2a_nofpu 0x2b | |
29738 | +#define bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu 0x2a1 | |
29739 | +#define bfd_mach_sh2a_nofpu_or_sh3_nommu 0x2a2 | |
29740 | +#define bfd_mach_sh2a_or_sh4 0x2a3 | |
29741 | +#define bfd_mach_sh2a_or_sh3e 0x2a4 | |
29742 | +#define bfd_mach_sh2e 0x2e | |
29743 | +#define bfd_mach_sh3 0x30 | |
29744 | +#define bfd_mach_sh3_nommu 0x31 | |
29745 | +#define bfd_mach_sh3_dsp 0x3d | |
29746 | +#define bfd_mach_sh3e 0x3e | |
29747 | +#define bfd_mach_sh4 0x40 | |
29748 | +#define bfd_mach_sh4_nofpu 0x41 | |
29749 | +#define bfd_mach_sh4_nommu_nofpu 0x42 | |
29750 | +#define bfd_mach_sh4a 0x4a | |
29751 | +#define bfd_mach_sh4a_nofpu 0x4b | |
29752 | +#define bfd_mach_sh4al_dsp 0x4d | |
29753 | +#define bfd_mach_sh5 0x50 | |
29754 | + bfd_arch_alpha, /* Dec Alpha */ | |
29755 | +#define bfd_mach_alpha_ev4 0x10 | |
29756 | +#define bfd_mach_alpha_ev5 0x20 | |
29757 | +#define bfd_mach_alpha_ev6 0x30 | |
29758 | + bfd_arch_arm, /* Advanced Risc Machines ARM. */ | |
29759 | +#define bfd_mach_arm_unknown 0 | |
29760 | +#define bfd_mach_arm_2 1 | |
29761 | +#define bfd_mach_arm_2a 2 | |
29762 | +#define bfd_mach_arm_3 3 | |
29763 | +#define bfd_mach_arm_3M 4 | |
29764 | +#define bfd_mach_arm_4 5 | |
29765 | +#define bfd_mach_arm_4T 6 | |
29766 | +#define bfd_mach_arm_5 7 | |
29767 | +#define bfd_mach_arm_5T 8 | |
29768 | +#define bfd_mach_arm_5TE 9 | |
29769 | +#define bfd_mach_arm_XScale 10 | |
29770 | +#define bfd_mach_arm_ep9312 11 | |
29771 | +#define bfd_mach_arm_iWMMXt 12 | |
29772 | + bfd_arch_ns32k, /* National Semiconductors ns32000 */ | |
29773 | + bfd_arch_w65, /* WDC 65816 */ | |
29774 | + bfd_arch_tic30, /* Texas Instruments TMS320C30 */ | |
29775 | + bfd_arch_tic4x, /* Texas Instruments TMS320C3X/4X */ | |
29776 | +#define bfd_mach_tic3x 30 | |
29777 | +#define bfd_mach_tic4x 40 | |
29778 | + bfd_arch_tic54x, /* Texas Instruments TMS320C54X */ | |
29779 | + bfd_arch_tic80, /* TI TMS320c80 (MVP) */ | |
29780 | + bfd_arch_v850, /* NEC V850 */ | |
29781 | +#define bfd_mach_v850 1 | |
29782 | +#define bfd_mach_v850e 'E' | |
29783 | +#define bfd_mach_v850e1 '1' | |
29784 | + bfd_arch_arc, /* ARC Cores */ | |
29785 | +#define bfd_mach_arc_5 5 | |
29786 | +#define bfd_mach_arc_6 6 | |
29787 | +#define bfd_mach_arc_7 7 | |
29788 | +#define bfd_mach_arc_8 8 | |
29789 | + bfd_arch_m32c, /* Renesas M16C/M32C. */ | |
29790 | +#define bfd_mach_m16c 0x75 | |
29791 | +#define bfd_mach_m32c 0x78 | |
29792 | + bfd_arch_m32r, /* Renesas M32R (formerly Mitsubishi M32R/D) */ | |
29793 | +#define bfd_mach_m32r 1 /* For backwards compatibility. */ | |
29794 | +#define bfd_mach_m32rx 'x' | |
29795 | +#define bfd_mach_m32r2 '2' | |
29796 | + bfd_arch_mn10200, /* Matsushita MN10200 */ | |
29797 | + bfd_arch_mn10300, /* Matsushita MN10300 */ | |
29798 | +#define bfd_mach_mn10300 300 | |
29799 | +#define bfd_mach_am33 330 | |
29800 | +#define bfd_mach_am33_2 332 | |
29801 | + bfd_arch_fr30, | |
29802 | +#define bfd_mach_fr30 0x46523330 | |
29803 | + bfd_arch_frv, | |
29804 | +#define bfd_mach_frv 1 | |
29805 | +#define bfd_mach_frvsimple 2 | |
29806 | +#define bfd_mach_fr300 300 | |
29807 | +#define bfd_mach_fr400 400 | |
29808 | +#define bfd_mach_fr450 450 | |
29809 | +#define bfd_mach_frvtomcat 499 /* fr500 prototype */ | |
29810 | +#define bfd_mach_fr500 500 | |
29811 | +#define bfd_mach_fr550 550 | |
29812 | + bfd_arch_mcore, | |
29813 | + bfd_arch_ia64, /* HP/Intel ia64 */ | |
29814 | +#define bfd_mach_ia64_elf64 64 | |
29815 | +#define bfd_mach_ia64_elf32 32 | |
29816 | + bfd_arch_ip2k, /* Ubicom IP2K microcontrollers. */ | |
29817 | +#define bfd_mach_ip2022 1 | |
29818 | +#define bfd_mach_ip2022ext 2 | |
29819 | + bfd_arch_iq2000, /* Vitesse IQ2000. */ | |
29820 | +#define bfd_mach_iq2000 1 | |
29821 | +#define bfd_mach_iq10 2 | |
29822 | + bfd_arch_ms1, | |
29823 | +#define bfd_mach_ms1 1 | |
29824 | +#define bfd_mach_mrisc2 2 | |
29825 | + bfd_arch_pj, | |
29826 | + bfd_arch_avr, /* Atmel AVR microcontrollers. */ | |
29827 | +#define bfd_mach_avr1 1 | |
29828 | +#define bfd_mach_avr2 2 | |
29829 | +#define bfd_mach_avr3 3 | |
29830 | +#define bfd_mach_avr4 4 | |
29831 | +#define bfd_mach_avr5 5 | |
29832 | + bfd_arch_cr16c, /* National Semiconductor CompactRISC. */ | |
29833 | +#define bfd_mach_cr16c 1 | |
29834 | + bfd_arch_crx, /* National Semiconductor CRX. */ | |
29835 | +#define bfd_mach_crx 1 | |
29836 | + bfd_arch_cris, /* Axis CRIS */ | |
29837 | +#define bfd_mach_cris_v0_v10 255 | |
29838 | +#define bfd_mach_cris_v32 32 | |
29839 | +#define bfd_mach_cris_v10_v32 1032 | |
29840 | + bfd_arch_s390, /* IBM s390 */ | |
29841 | +#define bfd_mach_s390_31 31 | |
29842 | +#define bfd_mach_s390_64 64 | |
29843 | + bfd_arch_openrisc, /* OpenRISC */ | |
29844 | + bfd_arch_mmix, /* Donald Knuth's educational processor. */ | |
29845 | + bfd_arch_xstormy16, | |
29846 | +#define bfd_mach_xstormy16 1 | |
29847 | + bfd_arch_msp430, /* Texas Instruments MSP430 architecture. */ | |
29848 | +#define bfd_mach_msp11 11 | |
29849 | +#define bfd_mach_msp110 110 | |
29850 | +#define bfd_mach_msp12 12 | |
29851 | +#define bfd_mach_msp13 13 | |
29852 | +#define bfd_mach_msp14 14 | |
29853 | +#define bfd_mach_msp15 15 | |
29854 | +#define bfd_mach_msp16 16 | |
29855 | +#define bfd_mach_msp31 31 | |
29856 | +#define bfd_mach_msp32 32 | |
29857 | +#define bfd_mach_msp33 33 | |
29858 | +#define bfd_mach_msp41 41 | |
29859 | +#define bfd_mach_msp42 42 | |
29860 | +#define bfd_mach_msp43 43 | |
29861 | +#define bfd_mach_msp44 44 | |
29862 | + bfd_arch_xtensa, /* Tensilica's Xtensa cores. */ | |
29863 | +#define bfd_mach_xtensa 1 | |
29864 | + bfd_arch_maxq, /* Dallas MAXQ 10/20 */ | |
29865 | +#define bfd_mach_maxq10 10 | |
29866 | +#define bfd_mach_maxq20 20 | |
29867 | + bfd_arch_last | |
29868 | + }; | |
29869 | + | |
29870 | +typedef struct bfd_arch_info | |
29871 | +{ | |
29872 | + int bits_per_word; | |
29873 | + int bits_per_address; | |
29874 | + int bits_per_byte; | |
29875 | + enum bfd_architecture arch; | |
29876 | + unsigned long mach; | |
29877 | + const char *arch_name; | |
29878 | + const char *printable_name; | |
29879 | + unsigned int section_align_power; | |
29880 | + /* TRUE if this is the default machine for the architecture. | |
29881 | + The default arch should be the first entry for an arch so that | |
29882 | + all the entries for that arch can be accessed via <<next>>. */ | |
29883 | + bfd_boolean the_default; | |
29884 | + const struct bfd_arch_info * (*compatible) | |
29885 | + (const struct bfd_arch_info *a, const struct bfd_arch_info *b); | |
29886 | + | |
29887 | + bfd_boolean (*scan) (const struct bfd_arch_info *, const char *); | |
29888 | + | |
29889 | + const struct bfd_arch_info *next; | |
29890 | +} | |
29891 | +bfd_arch_info_type; | |
29892 | + | |
29893 | +const char *bfd_printable_name (bfd *abfd); | |
29894 | + | |
29895 | +const bfd_arch_info_type *bfd_scan_arch (const char *string); | |
29896 | + | |
29897 | +const char **bfd_arch_list (void); | |
29898 | + | |
29899 | +const bfd_arch_info_type *bfd_arch_get_compatible | |
29900 | + (const bfd *abfd, const bfd *bbfd, bfd_boolean accept_unknowns); | |
29901 | + | |
29902 | +void bfd_set_arch_info (bfd *abfd, const bfd_arch_info_type *arg); | |
29903 | + | |
29904 | +enum bfd_architecture bfd_get_arch (bfd *abfd); | |
29905 | + | |
29906 | +unsigned long bfd_get_mach (bfd *abfd); | |
29907 | + | |
29908 | +unsigned int bfd_arch_bits_per_byte (bfd *abfd); | |
29909 | + | |
29910 | +unsigned int bfd_arch_bits_per_address (bfd *abfd); | |
29911 | + | |
29912 | +const bfd_arch_info_type *bfd_get_arch_info (bfd *abfd); | |
29913 | + | |
29914 | +const bfd_arch_info_type *bfd_lookup_arch | |
29915 | + (enum bfd_architecture arch, unsigned long machine); | |
29916 | + | |
29917 | +const char *bfd_printable_arch_mach | |
29918 | + (enum bfd_architecture arch, unsigned long machine); | |
29919 | + | |
29920 | +unsigned int bfd_octets_per_byte (bfd *abfd); | |
29921 | + | |
29922 | +unsigned int bfd_arch_mach_octets_per_byte | |
29923 | + (enum bfd_architecture arch, unsigned long machine); | |
29924 | + | |
29925 | +/* Extracted from reloc.c. */ | |
29926 | +typedef enum bfd_reloc_status | |
29927 | +{ | |
29928 | + /* No errors detected. */ | |
29929 | + bfd_reloc_ok, | |
29930 | + | |
29931 | + /* The relocation was performed, but there was an overflow. */ | |
29932 | + bfd_reloc_overflow, | |
29933 | + | |
29934 | + /* The address to relocate was not within the section supplied. */ | |
29935 | + bfd_reloc_outofrange, | |
29936 | + | |
29937 | + /* Used by special functions. */ | |
29938 | + bfd_reloc_continue, | |
29939 | + | |
29940 | + /* Unsupported relocation size requested. */ | |
29941 | + bfd_reloc_notsupported, | |
29942 | + | |
29943 | + /* Unused. */ | |
29944 | + bfd_reloc_other, | |
29945 | + | |
29946 | + /* The symbol to relocate against was undefined. */ | |
29947 | + bfd_reloc_undefined, | |
29948 | + | |
29949 | + /* The relocation was performed, but may not be ok - presently | |
29950 | + generated only when linking i960 coff files with i960 b.out | |
29951 | + symbols. If this type is returned, the error_message argument | |
29952 | + to bfd_perform_relocation will be set. */ | |
29953 | + bfd_reloc_dangerous | |
29954 | + } | |
29955 | + bfd_reloc_status_type; | |
29956 | + | |
29957 | + | |
29958 | +typedef struct reloc_cache_entry | |
29959 | +{ | |
29960 | + /* A pointer into the canonical table of pointers. */ | |
29961 | + struct bfd_symbol **sym_ptr_ptr; | |
29962 | + | |
29963 | + /* offset in section. */ | |
29964 | + bfd_size_type address; | |
29965 | + | |
29966 | + /* addend for relocation value. */ | |
29967 | + bfd_vma addend; | |
29968 | + | |
29969 | + /* Pointer to how to perform the required relocation. */ | |
29970 | + reloc_howto_type *howto; | |
29971 | + | |
29972 | +} | |
29973 | +arelent; | |
29974 | + | |
29975 | +enum complain_overflow | |
29976 | +{ | |
29977 | + /* Do not complain on overflow. */ | |
29978 | + complain_overflow_dont, | |
29979 | + | |
29980 | + /* Complain if the bitfield overflows, whether it is considered | |
29981 | + as signed or unsigned. */ | |
29982 | + complain_overflow_bitfield, | |
29983 | + | |
29984 | + /* Complain if the value overflows when considered as signed | |
29985 | + number. */ | |
29986 | + complain_overflow_signed, | |
29987 | + | |
29988 | + /* Complain if the value overflows when considered as an | |
29989 | + unsigned number. */ | |
29990 | + complain_overflow_unsigned | |
29991 | +}; | |
29992 | + | |
29993 | +struct reloc_howto_struct | |
29994 | +{ | |
29995 | + /* The type field has mainly a documentary use - the back end can | |
29996 | + do what it wants with it, though normally the back end's | |
29997 | + external idea of what a reloc number is stored | |
29998 | + in this field. For example, a PC relative word relocation | |
29999 | + in a coff environment has the type 023 - because that's | |
30000 | + what the outside world calls a R_PCRWORD reloc. */ | |
30001 | + unsigned int type; | |
30002 | + | |
30003 | + /* The value the final relocation is shifted right by. This drops | |
30004 | + unwanted data from the relocation. */ | |
30005 | + unsigned int rightshift; | |
30006 | + | |
30007 | + /* The size of the item to be relocated. This is *not* a | |
30008 | + power-of-two measure. To get the number of bytes operated | |
30009 | + on by a type of relocation, use bfd_get_reloc_size. */ | |
30010 | + int size; | |
30011 | + | |
30012 | + /* The number of bits in the item to be relocated. This is used | |
30013 | + when doing overflow checking. */ | |
30014 | + unsigned int bitsize; | |
30015 | + | |
30016 | + /* Notes that the relocation is relative to the location in the | |
30017 | + data section of the addend. The relocation function will | |
30018 | + subtract from the relocation value the address of the location | |
30019 | + being relocated. */ | |
30020 | + bfd_boolean pc_relative; | |
30021 | + | |
30022 | + /* The bit position of the reloc value in the destination. | |
30023 | + The relocated value is left shifted by this amount. */ | |
30024 | + unsigned int bitpos; | |
30025 | + | |
30026 | + /* What type of overflow error should be checked for when | |
30027 | + relocating. */ | |
30028 | + enum complain_overflow complain_on_overflow; | |
30029 | + | |
30030 | + /* If this field is non null, then the supplied function is | |
30031 | + called rather than the normal function. This allows really | |
30032 | + strange relocation methods to be accommodated (e.g., i960 callj | |
30033 | + instructions). */ | |
30034 | + bfd_reloc_status_type (*special_function) | |
30035 | + (bfd *, arelent *, struct bfd_symbol *, void *, asection *, | |
30036 | + bfd *, char **); | |
30037 | + | |
30038 | + /* The textual name of the relocation type. */ | |
30039 | + char *name; | |
30040 | + | |
30041 | + /* Some formats record a relocation addend in the section contents | |
30042 | + rather than with the relocation. For ELF formats this is the | |
30043 | + distinction between USE_REL and USE_RELA (though the code checks | |
30044 | + for USE_REL == 1/0). The value of this field is TRUE if the | |
30045 | + addend is recorded with the section contents; when performing a | |
30046 | + partial link (ld -r) the section contents (the data) will be | |
30047 | + modified. The value of this field is FALSE if addends are | |
30048 | + recorded with the relocation (in arelent.addend); when performing | |
30049 | + a partial link the relocation will be modified. | |
30050 | + All relocations for all ELF USE_RELA targets should set this field | |
30051 | + to FALSE (values of TRUE should be looked on with suspicion). | |
30052 | + However, the converse is not true: not all relocations of all ELF | |
30053 | + USE_REL targets set this field to TRUE. Why this is so is peculiar | |
30054 | + to each particular target. For relocs that aren't used in partial | |
30055 | + links (e.g. GOT stuff) it doesn't matter what this is set to. */ | |
30056 | + bfd_boolean partial_inplace; | |
30057 | + | |
30058 | + /* src_mask selects the part of the instruction (or data) to be used | |
30059 | + in the relocation sum. If the target relocations don't have an | |
30060 | + addend in the reloc, eg. ELF USE_REL, src_mask will normally equal | |
30061 | + dst_mask to extract the addend from the section contents. If | |
30062 | + relocations do have an addend in the reloc, eg. ELF USE_RELA, this | |
30063 | + field should be zero. Non-zero values for ELF USE_RELA targets are | |
30064 | + bogus as in those cases the value in the dst_mask part of the | |
30065 | + section contents should be treated as garbage. */ | |
30066 | + bfd_vma src_mask; | |
30067 | + | |
30068 | + /* dst_mask selects which parts of the instruction (or data) are | |
30069 | + replaced with a relocated value. */ | |
30070 | + bfd_vma dst_mask; | |
30071 | + | |
30072 | + /* When some formats create PC relative instructions, they leave | |
30073 | + the value of the pc of the place being relocated in the offset | |
30074 | + slot of the instruction, so that a PC relative relocation can | |
30075 | + be made just by adding in an ordinary offset (e.g., sun3 a.out). | |
30076 | + Some formats leave the displacement part of an instruction | |
30077 | + empty (e.g., m88k bcs); this flag signals the fact. */ | |
30078 | + bfd_boolean pcrel_offset; | |
30079 | +}; | |
30080 | + | |
30081 | +#define HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \ | |
30082 | + { (unsigned) C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC } | |
30083 | +#define NEWHOWTO(FUNCTION, NAME, SIZE, REL, IN) \ | |
30084 | + HOWTO (0, 0, SIZE, 0, REL, 0, complain_overflow_dont, FUNCTION, \ | |
30085 | + NAME, FALSE, 0, 0, IN) | |
30086 | + | |
30087 | +#define EMPTY_HOWTO(C) \ | |
30088 | + HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \ | |
30089 | + NULL, FALSE, 0, 0, FALSE) | |
30090 | + | |
30091 | +#define HOWTO_PREPARE(relocation, symbol) \ | |
30092 | + { \ | |
30093 | + if (symbol != NULL) \ | |
30094 | + { \ | |
30095 | + if (bfd_is_com_section (symbol->section)) \ | |
30096 | + { \ | |
30097 | + relocation = 0; \ | |
30098 | + } \ | |
30099 | + else \ | |
30100 | + { \ | |
30101 | + relocation = symbol->value; \ | |
30102 | + } \ | |
30103 | + } \ | |
30104 | + } | |
30105 | + | |
30106 | +unsigned int bfd_get_reloc_size (reloc_howto_type *); | |
30107 | + | |
30108 | +typedef struct relent_chain | |
30109 | +{ | |
30110 | + arelent relent; | |
30111 | + struct relent_chain *next; | |
30112 | +} | |
30113 | +arelent_chain; | |
30114 | + | |
30115 | +bfd_reloc_status_type bfd_check_overflow | |
30116 | + (enum complain_overflow how, | |
30117 | + unsigned int bitsize, | |
30118 | + unsigned int rightshift, | |
30119 | + unsigned int addrsize, | |
30120 | + bfd_vma relocation); | |
30121 | + | |
30122 | +bfd_reloc_status_type bfd_perform_relocation | |
30123 | + (bfd *abfd, | |
30124 | + arelent *reloc_entry, | |
30125 | + void *data, | |
30126 | + asection *input_section, | |
30127 | + bfd *output_bfd, | |
30128 | + char **error_message); | |
30129 | + | |
30130 | +bfd_reloc_status_type bfd_install_relocation | |
30131 | + (bfd *abfd, | |
30132 | + arelent *reloc_entry, | |
30133 | + void *data, bfd_vma data_start, | |
30134 | + asection *input_section, | |
30135 | + char **error_message); | |
30136 | + | |
30137 | +enum bfd_reloc_code_real { | |
30138 | + _dummy_first_bfd_reloc_code_real, | |
30139 | + | |
30140 | + | |
30141 | +/* Basic absolute relocations of N bits. */ | |
30142 | + BFD_RELOC_64, | |
30143 | + BFD_RELOC_32, | |
30144 | + BFD_RELOC_26, | |
30145 | + BFD_RELOC_24, | |
30146 | + BFD_RELOC_16, | |
30147 | + BFD_RELOC_14, | |
30148 | + BFD_RELOC_8, | |
30149 | + | |
30150 | +/* PC-relative relocations. Sometimes these are relative to the address | |
30151 | +of the relocation itself; sometimes they are relative to the start of | |
30152 | +the section containing the relocation. It depends on the specific target. | |
30153 | + | |
30154 | +The 24-bit relocation is used in some Intel 960 configurations. */ | |
30155 | + BFD_RELOC_64_PCREL, | |
30156 | + BFD_RELOC_32_PCREL, | |
30157 | + BFD_RELOC_24_PCREL, | |
30158 | + BFD_RELOC_16_PCREL, | |
30159 | + BFD_RELOC_12_PCREL, | |
30160 | + BFD_RELOC_8_PCREL, | |
30161 | + | |
30162 | +/* Section relative relocations. Some targets need this for DWARF2. */ | |
30163 | + BFD_RELOC_32_SECREL, | |
30164 | + | |
30165 | +/* For ELF. */ | |
30166 | + BFD_RELOC_32_GOT_PCREL, | |
30167 | + BFD_RELOC_16_GOT_PCREL, | |
30168 | + BFD_RELOC_8_GOT_PCREL, | |
30169 | + BFD_RELOC_32_GOTOFF, | |
30170 | + BFD_RELOC_16_GOTOFF, | |
30171 | + BFD_RELOC_LO16_GOTOFF, | |
30172 | + BFD_RELOC_HI16_GOTOFF, | |
30173 | + BFD_RELOC_HI16_S_GOTOFF, | |
30174 | + BFD_RELOC_8_GOTOFF, | |
30175 | + BFD_RELOC_64_PLT_PCREL, | |
30176 | + BFD_RELOC_32_PLT_PCREL, | |
30177 | + BFD_RELOC_24_PLT_PCREL, | |
30178 | + BFD_RELOC_16_PLT_PCREL, | |
30179 | + BFD_RELOC_8_PLT_PCREL, | |
30180 | + BFD_RELOC_64_PLTOFF, | |
30181 | + BFD_RELOC_32_PLTOFF, | |
30182 | + BFD_RELOC_16_PLTOFF, | |
30183 | + BFD_RELOC_LO16_PLTOFF, | |
30184 | + BFD_RELOC_HI16_PLTOFF, | |
30185 | + BFD_RELOC_HI16_S_PLTOFF, | |
30186 | + BFD_RELOC_8_PLTOFF, | |
30187 | + | |
30188 | +/* Relocations used by 68K ELF. */ | |
30189 | + BFD_RELOC_68K_GLOB_DAT, | |
30190 | + BFD_RELOC_68K_JMP_SLOT, | |
30191 | + BFD_RELOC_68K_RELATIVE, | |
30192 | + | |
30193 | +/* Linkage-table relative. */ | |
30194 | + BFD_RELOC_32_BASEREL, | |
30195 | + BFD_RELOC_16_BASEREL, | |
30196 | + BFD_RELOC_LO16_BASEREL, | |
30197 | + BFD_RELOC_HI16_BASEREL, | |
30198 | + BFD_RELOC_HI16_S_BASEREL, | |
30199 | + BFD_RELOC_8_BASEREL, | |
30200 | + BFD_RELOC_RVA, | |
30201 | + | |
30202 | +/* Absolute 8-bit relocation, but used to form an address like 0xFFnn. */ | |
30203 | + BFD_RELOC_8_FFnn, | |
30204 | + | |
30205 | +/* These PC-relative relocations are stored as word displacements -- | |
30206 | +i.e., byte displacements shifted right two bits. The 30-bit word | |
30207 | +displacement (<<32_PCREL_S2>> -- 32 bits, shifted 2) is used on the | |
30208 | +SPARC. (SPARC tools generally refer to this as <<WDISP30>>.) The | |
30209 | +signed 16-bit displacement is used on the MIPS, and the 23-bit | |
30210 | +displacement is used on the Alpha. */ | |
30211 | + BFD_RELOC_32_PCREL_S2, | |
30212 | + BFD_RELOC_16_PCREL_S2, | |
30213 | + BFD_RELOC_23_PCREL_S2, | |
30214 | + | |
30215 | +/* High 22 bits and low 10 bits of 32-bit value, placed into lower bits of | |
30216 | +the target word. These are used on the SPARC. */ | |
30217 | + BFD_RELOC_HI22, | |
30218 | + BFD_RELOC_LO10, | |
30219 | + | |
30220 | +/* For systems that allocate a Global Pointer register, these are | |
30221 | +displacements off that register. These relocation types are | |
30222 | +handled specially, because the value the register will have is | |
30223 | +decided relatively late. */ | |
30224 | + BFD_RELOC_GPREL16, | |
30225 | + BFD_RELOC_GPREL32, | |
30226 | + | |
30227 | +/* Reloc types used for i960/b.out. */ | |
30228 | + BFD_RELOC_I960_CALLJ, | |
30229 | + | |
30230 | +/* SPARC ELF relocations. There is probably some overlap with other | |
30231 | +relocation types already defined. */ | |
30232 | + BFD_RELOC_NONE, | |
30233 | + BFD_RELOC_SPARC_WDISP22, | |
30234 | + BFD_RELOC_SPARC22, | |
30235 | + BFD_RELOC_SPARC13, | |
30236 | + BFD_RELOC_SPARC_GOT10, | |
30237 | + BFD_RELOC_SPARC_GOT13, | |
30238 | + BFD_RELOC_SPARC_GOT22, | |
30239 | + BFD_RELOC_SPARC_PC10, | |
30240 | + BFD_RELOC_SPARC_PC22, | |
30241 | + BFD_RELOC_SPARC_WPLT30, | |
30242 | + BFD_RELOC_SPARC_COPY, | |
30243 | + BFD_RELOC_SPARC_GLOB_DAT, | |
30244 | + BFD_RELOC_SPARC_JMP_SLOT, | |
30245 | + BFD_RELOC_SPARC_RELATIVE, | |
30246 | + BFD_RELOC_SPARC_UA16, | |
30247 | + BFD_RELOC_SPARC_UA32, | |
30248 | + BFD_RELOC_SPARC_UA64, | |
30249 | + | |
30250 | +/* I think these are specific to SPARC a.out (e.g., Sun 4). */ | |
30251 | + BFD_RELOC_SPARC_BASE13, | |
30252 | + BFD_RELOC_SPARC_BASE22, | |
30253 | + | |
30254 | +/* SPARC64 relocations */ | |
30255 | +#define BFD_RELOC_SPARC_64 BFD_RELOC_64 | |
30256 | + BFD_RELOC_SPARC_10, | |
30257 | + BFD_RELOC_SPARC_11, | |
30258 | + BFD_RELOC_SPARC_OLO10, | |
30259 | + BFD_RELOC_SPARC_HH22, | |
30260 | + BFD_RELOC_SPARC_HM10, | |
30261 | + BFD_RELOC_SPARC_LM22, | |
30262 | + BFD_RELOC_SPARC_PC_HH22, | |
30263 | + BFD_RELOC_SPARC_PC_HM10, | |
30264 | + BFD_RELOC_SPARC_PC_LM22, | |
30265 | + BFD_RELOC_SPARC_WDISP16, | |
30266 | + BFD_RELOC_SPARC_WDISP19, | |
30267 | + BFD_RELOC_SPARC_7, | |
30268 | + BFD_RELOC_SPARC_6, | |
30269 | + BFD_RELOC_SPARC_5, | |
30270 | +#define BFD_RELOC_SPARC_DISP64 BFD_RELOC_64_PCREL | |
30271 | + BFD_RELOC_SPARC_PLT32, | |
30272 | + BFD_RELOC_SPARC_PLT64, | |
30273 | + BFD_RELOC_SPARC_HIX22, | |
30274 | + BFD_RELOC_SPARC_LOX10, | |
30275 | + BFD_RELOC_SPARC_H44, | |
30276 | + BFD_RELOC_SPARC_M44, | |
30277 | + BFD_RELOC_SPARC_L44, | |
30278 | + BFD_RELOC_SPARC_REGISTER, | |
30279 | + | |
30280 | +/* SPARC little endian relocation */ | |
30281 | + BFD_RELOC_SPARC_REV32, | |
30282 | + | |
30283 | +/* SPARC TLS relocations */ | |
30284 | + BFD_RELOC_SPARC_TLS_GD_HI22, | |
30285 | + BFD_RELOC_SPARC_TLS_GD_LO10, | |
30286 | + BFD_RELOC_SPARC_TLS_GD_ADD, | |
30287 | + BFD_RELOC_SPARC_TLS_GD_CALL, | |
30288 | + BFD_RELOC_SPARC_TLS_LDM_HI22, | |
30289 | + BFD_RELOC_SPARC_TLS_LDM_LO10, | |
30290 | + BFD_RELOC_SPARC_TLS_LDM_ADD, | |
30291 | + BFD_RELOC_SPARC_TLS_LDM_CALL, | |
30292 | + BFD_RELOC_SPARC_TLS_LDO_HIX22, | |
30293 | + BFD_RELOC_SPARC_TLS_LDO_LOX10, | |
30294 | + BFD_RELOC_SPARC_TLS_LDO_ADD, | |
30295 | + BFD_RELOC_SPARC_TLS_IE_HI22, | |
30296 | + BFD_RELOC_SPARC_TLS_IE_LO10, | |
30297 | + BFD_RELOC_SPARC_TLS_IE_LD, | |
30298 | + BFD_RELOC_SPARC_TLS_IE_LDX, | |
30299 | + BFD_RELOC_SPARC_TLS_IE_ADD, | |
30300 | + BFD_RELOC_SPARC_TLS_LE_HIX22, | |
30301 | + BFD_RELOC_SPARC_TLS_LE_LOX10, | |
30302 | + BFD_RELOC_SPARC_TLS_DTPMOD32, | |
30303 | + BFD_RELOC_SPARC_TLS_DTPMOD64, | |
30304 | + BFD_RELOC_SPARC_TLS_DTPOFF32, | |
30305 | + BFD_RELOC_SPARC_TLS_DTPOFF64, | |
30306 | + BFD_RELOC_SPARC_TLS_TPOFF32, | |
30307 | + BFD_RELOC_SPARC_TLS_TPOFF64, | |
30308 | + | |
30309 | +/* Alpha ECOFF and ELF relocations. Some of these treat the symbol or | |
30310 | +"addend" in some special way. | |
30311 | +For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when | |
30312 | +writing; when reading, it will be the absolute section symbol. The | |
30313 | +addend is the displacement in bytes of the "lda" instruction from | |
30314 | +the "ldah" instruction (which is at the address of this reloc). */ | |
30315 | + BFD_RELOC_ALPHA_GPDISP_HI16, | |
30316 | + | |
30317 | +/* For GPDISP_LO16 ("ignore") relocations, the symbol is handled as | |
30318 | +with GPDISP_HI16 relocs. The addend is ignored when writing the | |
30319 | +relocations out, and is filled in with the file's GP value on | |
30320 | +reading, for convenience. */ | |
30321 | + BFD_RELOC_ALPHA_GPDISP_LO16, | |
30322 | + | |
30323 | +/* The ELF GPDISP relocation is exactly the same as the GPDISP_HI16 | |
30324 | +relocation except that there is no accompanying GPDISP_LO16 | |
30325 | +relocation. */ | |
30326 | + BFD_RELOC_ALPHA_GPDISP, | |
30327 | + | |
30328 | +/* The Alpha LITERAL/LITUSE relocs are produced by a symbol reference; | |
30329 | +the assembler turns it into a LDQ instruction to load the address of | |
30330 | +the symbol, and then fills in a register in the real instruction. | |
30331 | + | |
30332 | +The LITERAL reloc, at the LDQ instruction, refers to the .lita | |
30333 | +section symbol. The addend is ignored when writing, but is filled | |
30334 | +in with the file's GP value on reading, for convenience, as with the | |
30335 | +GPDISP_LO16 reloc. | |
30336 | + | |
30337 | +The ELF_LITERAL reloc is somewhere between 16_GOTOFF and GPDISP_LO16. | |
30338 | +It should refer to the symbol to be referenced, as with 16_GOTOFF, | |
30339 | +but it generates output not based on the position within the .got | |
30340 | +section, but relative to the GP value chosen for the file during the | |
30341 | +final link stage. | |
30342 | + | |
30343 | +The LITUSE reloc, on the instruction using the loaded address, gives | |
30344 | +information to the linker that it might be able to use to optimize | |
30345 | +away some literal section references. The symbol is ignored (read | |
30346 | +as the absolute section symbol), and the "addend" indicates the type | |
30347 | +of instruction using the register: | |
30348 | +1 - "memory" fmt insn | |
30349 | +2 - byte-manipulation (byte offset reg) | |
30350 | +3 - jsr (target of branch) */ | |
30351 | + BFD_RELOC_ALPHA_LITERAL, | |
30352 | + BFD_RELOC_ALPHA_ELF_LITERAL, | |
30353 | + BFD_RELOC_ALPHA_LITUSE, | |
30354 | + | |
30355 | +/* The HINT relocation indicates a value that should be filled into the | |
30356 | +"hint" field of a jmp/jsr/ret instruction, for possible branch- | |
30357 | +prediction logic which may be provided on some processors. */ | |
30358 | + BFD_RELOC_ALPHA_HINT, | |
30359 | + | |
30360 | +/* The LINKAGE relocation outputs a linkage pair in the object file, | |
30361 | +which is filled by the linker. */ | |
30362 | + BFD_RELOC_ALPHA_LINKAGE, | |
30363 | + | |
30364 | +/* The CODEADDR relocation outputs a STO_CA in the object file, | |
30365 | +which is filled by the linker. */ | |
30366 | + BFD_RELOC_ALPHA_CODEADDR, | |
30367 | + | |
30368 | +/* The GPREL_HI/LO relocations together form a 32-bit offset from the | |
30369 | +GP register. */ | |
30370 | + BFD_RELOC_ALPHA_GPREL_HI16, | |
30371 | + BFD_RELOC_ALPHA_GPREL_LO16, | |
30372 | + | |
30373 | +/* Like BFD_RELOC_23_PCREL_S2, except that the source and target must | |
30374 | +share a common GP, and the target address is adjusted for | |
30375 | +STO_ALPHA_STD_GPLOAD. */ | |
30376 | + BFD_RELOC_ALPHA_BRSGP, | |
30377 | + | |
30378 | +/* Alpha thread-local storage relocations. */ | |
30379 | + BFD_RELOC_ALPHA_TLSGD, | |
30380 | + BFD_RELOC_ALPHA_TLSLDM, | |
30381 | + BFD_RELOC_ALPHA_DTPMOD64, | |
30382 | + BFD_RELOC_ALPHA_GOTDTPREL16, | |
30383 | + BFD_RELOC_ALPHA_DTPREL64, | |
30384 | + BFD_RELOC_ALPHA_DTPREL_HI16, | |
30385 | + BFD_RELOC_ALPHA_DTPREL_LO16, | |
30386 | + BFD_RELOC_ALPHA_DTPREL16, | |
30387 | + BFD_RELOC_ALPHA_GOTTPREL16, | |
30388 | + BFD_RELOC_ALPHA_TPREL64, | |
30389 | + BFD_RELOC_ALPHA_TPREL_HI16, | |
30390 | + BFD_RELOC_ALPHA_TPREL_LO16, | |
30391 | + BFD_RELOC_ALPHA_TPREL16, | |
30392 | + | |
30393 | +/* Bits 27..2 of the relocation address shifted right 2 bits; | |
30394 | +simple reloc otherwise. */ | |
30395 | + BFD_RELOC_MIPS_JMP, | |
30396 | + | |
30397 | +/* The MIPS16 jump instruction. */ | |
30398 | + BFD_RELOC_MIPS16_JMP, | |
30399 | + | |
30400 | +/* MIPS16 GP relative reloc. */ | |
30401 | + BFD_RELOC_MIPS16_GPREL, | |
30402 | + | |
30403 | +/* High 16 bits of 32-bit value; simple reloc. */ | |
30404 | + BFD_RELOC_HI16, | |
30405 | + | |
30406 | +/* High 16 bits of 32-bit value but the low 16 bits will be sign | |
30407 | +extended and added to form the final result. If the low 16 | |
30408 | +bits form a negative number, we need to add one to the high value | |
30409 | +to compensate for the borrow when the low bits are added. */ | |
30410 | + BFD_RELOC_HI16_S, | |
30411 | + | |
30412 | +/* Low 16 bits. */ | |
30413 | + BFD_RELOC_LO16, | |
30414 | + | |
30415 | +/* High 16 bits of 32-bit pc-relative value */ | |
30416 | + BFD_RELOC_HI16_PCREL, | |
30417 | + | |
30418 | +/* High 16 bits of 32-bit pc-relative value, adjusted */ | |
30419 | + BFD_RELOC_HI16_S_PCREL, | |
30420 | + | |
30421 | +/* Low 16 bits of pc-relative value */ | |
30422 | + BFD_RELOC_LO16_PCREL, | |
30423 | + | |
30424 | +/* MIPS16 high 16 bits of 32-bit value. */ | |
30425 | + BFD_RELOC_MIPS16_HI16, | |
30426 | + | |
30427 | +/* MIPS16 high 16 bits of 32-bit value but the low 16 bits will be sign | |
30428 | +extended and added to form the final result. If the low 16 | |
30429 | +bits form a negative number, we need to add one to the high value | |
30430 | +to compensate for the borrow when the low bits are added. */ | |
30431 | + BFD_RELOC_MIPS16_HI16_S, | |
30432 | + | |
30433 | +/* MIPS16 low 16 bits. */ | |
30434 | + BFD_RELOC_MIPS16_LO16, | |
30435 | + | |
30436 | +/* Relocation against a MIPS literal section. */ | |
30437 | + BFD_RELOC_MIPS_LITERAL, | |
30438 | + | |
30439 | +/* MIPS ELF relocations. */ | |
30440 | + BFD_RELOC_MIPS_GOT16, | |
30441 | + BFD_RELOC_MIPS_CALL16, | |
30442 | + BFD_RELOC_MIPS_GOT_HI16, | |
30443 | + BFD_RELOC_MIPS_GOT_LO16, | |
30444 | + BFD_RELOC_MIPS_CALL_HI16, | |
30445 | + BFD_RELOC_MIPS_CALL_LO16, | |
30446 | + BFD_RELOC_MIPS_SUB, | |
30447 | + BFD_RELOC_MIPS_GOT_PAGE, | |
30448 | + BFD_RELOC_MIPS_GOT_OFST, | |
30449 | + BFD_RELOC_MIPS_GOT_DISP, | |
30450 | + BFD_RELOC_MIPS_SHIFT5, | |
30451 | + BFD_RELOC_MIPS_SHIFT6, | |
30452 | + BFD_RELOC_MIPS_INSERT_A, | |
30453 | + BFD_RELOC_MIPS_INSERT_B, | |
30454 | + BFD_RELOC_MIPS_DELETE, | |
30455 | + BFD_RELOC_MIPS_HIGHEST, | |
30456 | + BFD_RELOC_MIPS_HIGHER, | |
30457 | + BFD_RELOC_MIPS_SCN_DISP, | |
30458 | + BFD_RELOC_MIPS_REL16, | |
30459 | + BFD_RELOC_MIPS_RELGOT, | |
30460 | + BFD_RELOC_MIPS_JALR, | |
30461 | + BFD_RELOC_MIPS_TLS_DTPMOD32, | |
30462 | + BFD_RELOC_MIPS_TLS_DTPREL32, | |
30463 | + BFD_RELOC_MIPS_TLS_DTPMOD64, | |
30464 | + BFD_RELOC_MIPS_TLS_DTPREL64, | |
30465 | + BFD_RELOC_MIPS_TLS_GD, | |
30466 | + BFD_RELOC_MIPS_TLS_LDM, | |
30467 | + BFD_RELOC_MIPS_TLS_DTPREL_HI16, | |
30468 | + BFD_RELOC_MIPS_TLS_DTPREL_LO16, | |
30469 | + BFD_RELOC_MIPS_TLS_GOTTPREL, | |
30470 | + BFD_RELOC_MIPS_TLS_TPREL32, | |
30471 | + BFD_RELOC_MIPS_TLS_TPREL64, | |
30472 | + BFD_RELOC_MIPS_TLS_TPREL_HI16, | |
30473 | + BFD_RELOC_MIPS_TLS_TPREL_LO16, | |
30474 | + | |
30475 | + | |
30476 | +/* Fujitsu Frv Relocations. */ | |
30477 | + BFD_RELOC_FRV_LABEL16, | |
30478 | + BFD_RELOC_FRV_LABEL24, | |
30479 | + BFD_RELOC_FRV_LO16, | |
30480 | + BFD_RELOC_FRV_HI16, | |
30481 | + BFD_RELOC_FRV_GPREL12, | |
30482 | + BFD_RELOC_FRV_GPRELU12, | |
30483 | + BFD_RELOC_FRV_GPREL32, | |
30484 | + BFD_RELOC_FRV_GPRELHI, | |
30485 | + BFD_RELOC_FRV_GPRELLO, | |
30486 | + BFD_RELOC_FRV_GOT12, | |
30487 | + BFD_RELOC_FRV_GOTHI, | |
30488 | + BFD_RELOC_FRV_GOTLO, | |
30489 | + BFD_RELOC_FRV_FUNCDESC, | |
30490 | + BFD_RELOC_FRV_FUNCDESC_GOT12, | |
30491 | + BFD_RELOC_FRV_FUNCDESC_GOTHI, | |
30492 | + BFD_RELOC_FRV_FUNCDESC_GOTLO, | |
30493 | + BFD_RELOC_FRV_FUNCDESC_VALUE, | |
30494 | + BFD_RELOC_FRV_FUNCDESC_GOTOFF12, | |
30495 | + BFD_RELOC_FRV_FUNCDESC_GOTOFFHI, | |
30496 | + BFD_RELOC_FRV_FUNCDESC_GOTOFFLO, | |
30497 | + BFD_RELOC_FRV_GOTOFF12, | |
30498 | + BFD_RELOC_FRV_GOTOFFHI, | |
30499 | + BFD_RELOC_FRV_GOTOFFLO, | |
30500 | + BFD_RELOC_FRV_GETTLSOFF, | |
30501 | + BFD_RELOC_FRV_TLSDESC_VALUE, | |
30502 | + BFD_RELOC_FRV_GOTTLSDESC12, | |
30503 | + BFD_RELOC_FRV_GOTTLSDESCHI, | |
30504 | + BFD_RELOC_FRV_GOTTLSDESCLO, | |
30505 | + BFD_RELOC_FRV_TLSMOFF12, | |
30506 | + BFD_RELOC_FRV_TLSMOFFHI, | |
30507 | + BFD_RELOC_FRV_TLSMOFFLO, | |
30508 | + BFD_RELOC_FRV_GOTTLSOFF12, | |
30509 | + BFD_RELOC_FRV_GOTTLSOFFHI, | |
30510 | + BFD_RELOC_FRV_GOTTLSOFFLO, | |
30511 | + BFD_RELOC_FRV_TLSOFF, | |
30512 | + BFD_RELOC_FRV_TLSDESC_RELAX, | |
30513 | + BFD_RELOC_FRV_GETTLSOFF_RELAX, | |
30514 | + BFD_RELOC_FRV_TLSOFF_RELAX, | |
30515 | + BFD_RELOC_FRV_TLSMOFF, | |
30516 | + | |
30517 | + | |
30518 | +/* This is a 24bit GOT-relative reloc for the mn10300. */ | |
30519 | + BFD_RELOC_MN10300_GOTOFF24, | |
30520 | + | |
30521 | +/* This is a 32bit GOT-relative reloc for the mn10300, offset by two bytes | |
30522 | +in the instruction. */ | |
30523 | + BFD_RELOC_MN10300_GOT32, | |
30524 | + | |
30525 | +/* This is a 24bit GOT-relative reloc for the mn10300, offset by two bytes | |
30526 | +in the instruction. */ | |
30527 | + BFD_RELOC_MN10300_GOT24, | |
30528 | + | |
30529 | +/* This is a 16bit GOT-relative reloc for the mn10300, offset by two bytes | |
30530 | +in the instruction. */ | |
30531 | + BFD_RELOC_MN10300_GOT16, | |
30532 | + | |
30533 | +/* Copy symbol at runtime. */ | |
30534 | + BFD_RELOC_MN10300_COPY, | |
30535 | + | |
30536 | +/* Create GOT entry. */ | |
30537 | + BFD_RELOC_MN10300_GLOB_DAT, | |
30538 | + | |
30539 | +/* Create PLT entry. */ | |
30540 | + BFD_RELOC_MN10300_JMP_SLOT, | |
30541 | + | |
30542 | +/* Adjust by program base. */ | |
30543 | + BFD_RELOC_MN10300_RELATIVE, | |
30544 | + | |
30545 | + | |
30546 | +/* i386/elf relocations */ | |
30547 | + BFD_RELOC_386_GOT32, | |
30548 | + BFD_RELOC_386_PLT32, | |
30549 | + BFD_RELOC_386_COPY, | |
30550 | + BFD_RELOC_386_GLOB_DAT, | |
30551 | + BFD_RELOC_386_JUMP_SLOT, | |
30552 | + BFD_RELOC_386_RELATIVE, | |
30553 | + BFD_RELOC_386_GOTOFF, | |
30554 | + BFD_RELOC_386_GOTPC, | |
30555 | + BFD_RELOC_386_TLS_TPOFF, | |
30556 | + BFD_RELOC_386_TLS_IE, | |
30557 | + BFD_RELOC_386_TLS_GOTIE, | |
30558 | + BFD_RELOC_386_TLS_LE, | |
30559 | + BFD_RELOC_386_TLS_GD, | |
30560 | + BFD_RELOC_386_TLS_LDM, | |
30561 | + BFD_RELOC_386_TLS_LDO_32, | |
30562 | + BFD_RELOC_386_TLS_IE_32, | |
30563 | + BFD_RELOC_386_TLS_LE_32, | |
30564 | + BFD_RELOC_386_TLS_DTPMOD32, | |
30565 | + BFD_RELOC_386_TLS_DTPOFF32, | |
30566 | + BFD_RELOC_386_TLS_TPOFF32, | |
30567 | + | |
30568 | +/* x86-64/elf relocations */ | |
30569 | + BFD_RELOC_X86_64_GOT32, | |
30570 | + BFD_RELOC_X86_64_PLT32, | |
30571 | + BFD_RELOC_X86_64_COPY, | |
30572 | + BFD_RELOC_X86_64_GLOB_DAT, | |
30573 | + BFD_RELOC_X86_64_JUMP_SLOT, | |
30574 | + BFD_RELOC_X86_64_RELATIVE, | |
30575 | + BFD_RELOC_X86_64_GOTPCREL, | |
30576 | + BFD_RELOC_X86_64_32S, | |
30577 | + BFD_RELOC_X86_64_DTPMOD64, | |
30578 | + BFD_RELOC_X86_64_DTPOFF64, | |
30579 | + BFD_RELOC_X86_64_TPOFF64, | |
30580 | + BFD_RELOC_X86_64_TLSGD, | |
30581 | + BFD_RELOC_X86_64_TLSLD, | |
30582 | + BFD_RELOC_X86_64_DTPOFF32, | |
30583 | + BFD_RELOC_X86_64_GOTTPOFF, | |
30584 | + BFD_RELOC_X86_64_TPOFF32, | |
30585 | + BFD_RELOC_X86_64_GOTOFF64, | |
30586 | + BFD_RELOC_X86_64_GOTPC32, | |
30587 | + | |
30588 | +/* ns32k relocations */ | |
30589 | + BFD_RELOC_NS32K_IMM_8, | |
30590 | + BFD_RELOC_NS32K_IMM_16, | |
30591 | + BFD_RELOC_NS32K_IMM_32, | |
30592 | + BFD_RELOC_NS32K_IMM_8_PCREL, | |
30593 | + BFD_RELOC_NS32K_IMM_16_PCREL, | |
30594 | + BFD_RELOC_NS32K_IMM_32_PCREL, | |
30595 | + BFD_RELOC_NS32K_DISP_8, | |
30596 | + BFD_RELOC_NS32K_DISP_16, | |
30597 | + BFD_RELOC_NS32K_DISP_32, | |
30598 | + BFD_RELOC_NS32K_DISP_8_PCREL, | |
30599 | + BFD_RELOC_NS32K_DISP_16_PCREL, | |
30600 | + BFD_RELOC_NS32K_DISP_32_PCREL, | |
30601 | + | |
30602 | +/* PDP11 relocations */ | |
30603 | + BFD_RELOC_PDP11_DISP_8_PCREL, | |
30604 | + BFD_RELOC_PDP11_DISP_6_PCREL, | |
30605 | + | |
30606 | +/* Picojava relocs. Not all of these appear in object files. */ | |
30607 | + BFD_RELOC_PJ_CODE_HI16, | |
30608 | + BFD_RELOC_PJ_CODE_LO16, | |
30609 | + BFD_RELOC_PJ_CODE_DIR16, | |
30610 | + BFD_RELOC_PJ_CODE_DIR32, | |
30611 | + BFD_RELOC_PJ_CODE_REL16, | |
30612 | + BFD_RELOC_PJ_CODE_REL32, | |
30613 | + | |
30614 | +/* Power(rs6000) and PowerPC relocations. */ | |
30615 | + BFD_RELOC_PPC_B26, | |
30616 | + BFD_RELOC_PPC_BA26, | |
30617 | + BFD_RELOC_PPC_TOC16, | |
30618 | + BFD_RELOC_PPC_B16, | |
30619 | + BFD_RELOC_PPC_B16_BRTAKEN, | |
30620 | + BFD_RELOC_PPC_B16_BRNTAKEN, | |
30621 | + BFD_RELOC_PPC_BA16, | |
30622 | + BFD_RELOC_PPC_BA16_BRTAKEN, | |
30623 | + BFD_RELOC_PPC_BA16_BRNTAKEN, | |
30624 | + BFD_RELOC_PPC_COPY, | |
30625 | + BFD_RELOC_PPC_GLOB_DAT, | |
30626 | + BFD_RELOC_PPC_JMP_SLOT, | |
30627 | + BFD_RELOC_PPC_RELATIVE, | |
30628 | + BFD_RELOC_PPC_LOCAL24PC, | |
30629 | + BFD_RELOC_PPC_EMB_NADDR32, | |
30630 | + BFD_RELOC_PPC_EMB_NADDR16, | |
30631 | + BFD_RELOC_PPC_EMB_NADDR16_LO, | |
30632 | + BFD_RELOC_PPC_EMB_NADDR16_HI, | |
30633 | + BFD_RELOC_PPC_EMB_NADDR16_HA, | |
30634 | + BFD_RELOC_PPC_EMB_SDAI16, | |
30635 | + BFD_RELOC_PPC_EMB_SDA2I16, | |
30636 | + BFD_RELOC_PPC_EMB_SDA2REL, | |
30637 | + BFD_RELOC_PPC_EMB_SDA21, | |
30638 | + BFD_RELOC_PPC_EMB_MRKREF, | |
30639 | + BFD_RELOC_PPC_EMB_RELSEC16, | |
30640 | + BFD_RELOC_PPC_EMB_RELST_LO, | |
30641 | + BFD_RELOC_PPC_EMB_RELST_HI, | |
30642 | + BFD_RELOC_PPC_EMB_RELST_HA, | |
30643 | + BFD_RELOC_PPC_EMB_BIT_FLD, | |
30644 | + BFD_RELOC_PPC_EMB_RELSDA, | |
30645 | + BFD_RELOC_PPC64_HIGHER, | |
30646 | + BFD_RELOC_PPC64_HIGHER_S, | |
30647 | + BFD_RELOC_PPC64_HIGHEST, | |
30648 | + BFD_RELOC_PPC64_HIGHEST_S, | |
30649 | + BFD_RELOC_PPC64_TOC16_LO, | |
30650 | + BFD_RELOC_PPC64_TOC16_HI, | |
30651 | + BFD_RELOC_PPC64_TOC16_HA, | |
30652 | + BFD_RELOC_PPC64_TOC, | |
30653 | + BFD_RELOC_PPC64_PLTGOT16, | |
30654 | + BFD_RELOC_PPC64_PLTGOT16_LO, | |
30655 | + BFD_RELOC_PPC64_PLTGOT16_HI, | |
30656 | + BFD_RELOC_PPC64_PLTGOT16_HA, | |
30657 | + BFD_RELOC_PPC64_ADDR16_DS, | |
30658 | + BFD_RELOC_PPC64_ADDR16_LO_DS, | |
30659 | + BFD_RELOC_PPC64_GOT16_DS, | |
30660 | + BFD_RELOC_PPC64_GOT16_LO_DS, | |
30661 | + BFD_RELOC_PPC64_PLT16_LO_DS, | |
30662 | + BFD_RELOC_PPC64_SECTOFF_DS, | |
30663 | + BFD_RELOC_PPC64_SECTOFF_LO_DS, | |
30664 | + BFD_RELOC_PPC64_TOC16_DS, | |
30665 | + BFD_RELOC_PPC64_TOC16_LO_DS, | |
30666 | + BFD_RELOC_PPC64_PLTGOT16_DS, | |
30667 | + BFD_RELOC_PPC64_PLTGOT16_LO_DS, | |
30668 | + | |
30669 | +/* PowerPC and PowerPC64 thread-local storage relocations. */ | |
30670 | + BFD_RELOC_PPC_TLS, | |
30671 | + BFD_RELOC_PPC_DTPMOD, | |
30672 | + BFD_RELOC_PPC_TPREL16, | |
30673 | + BFD_RELOC_PPC_TPREL16_LO, | |
30674 | + BFD_RELOC_PPC_TPREL16_HI, | |
30675 | + BFD_RELOC_PPC_TPREL16_HA, | |
30676 | + BFD_RELOC_PPC_TPREL, | |
30677 | + BFD_RELOC_PPC_DTPREL16, | |
30678 | + BFD_RELOC_PPC_DTPREL16_LO, | |
30679 | + BFD_RELOC_PPC_DTPREL16_HI, | |
30680 | + BFD_RELOC_PPC_DTPREL16_HA, | |
30681 | + BFD_RELOC_PPC_DTPREL, | |
30682 | + BFD_RELOC_PPC_GOT_TLSGD16, | |
30683 | + BFD_RELOC_PPC_GOT_TLSGD16_LO, | |
30684 | + BFD_RELOC_PPC_GOT_TLSGD16_HI, | |
30685 | + BFD_RELOC_PPC_GOT_TLSGD16_HA, | |
30686 | + BFD_RELOC_PPC_GOT_TLSLD16, | |
30687 | + BFD_RELOC_PPC_GOT_TLSLD16_LO, | |
30688 | + BFD_RELOC_PPC_GOT_TLSLD16_HI, | |
30689 | + BFD_RELOC_PPC_GOT_TLSLD16_HA, | |
30690 | + BFD_RELOC_PPC_GOT_TPREL16, | |
30691 | + BFD_RELOC_PPC_GOT_TPREL16_LO, | |
30692 | + BFD_RELOC_PPC_GOT_TPREL16_HI, | |
30693 | + BFD_RELOC_PPC_GOT_TPREL16_HA, | |
30694 | + BFD_RELOC_PPC_GOT_DTPREL16, | |
30695 | + BFD_RELOC_PPC_GOT_DTPREL16_LO, | |
30696 | + BFD_RELOC_PPC_GOT_DTPREL16_HI, | |
30697 | + BFD_RELOC_PPC_GOT_DTPREL16_HA, | |
30698 | + BFD_RELOC_PPC64_TPREL16_DS, | |
30699 | + BFD_RELOC_PPC64_TPREL16_LO_DS, | |
30700 | + BFD_RELOC_PPC64_TPREL16_HIGHER, | |
30701 | + BFD_RELOC_PPC64_TPREL16_HIGHERA, | |
30702 | + BFD_RELOC_PPC64_TPREL16_HIGHEST, | |
30703 | + BFD_RELOC_PPC64_TPREL16_HIGHESTA, | |
30704 | + BFD_RELOC_PPC64_DTPREL16_DS, | |
30705 | + BFD_RELOC_PPC64_DTPREL16_LO_DS, | |
30706 | + BFD_RELOC_PPC64_DTPREL16_HIGHER, | |
30707 | + BFD_RELOC_PPC64_DTPREL16_HIGHERA, | |
30708 | + BFD_RELOC_PPC64_DTPREL16_HIGHEST, | |
30709 | + BFD_RELOC_PPC64_DTPREL16_HIGHESTA, | |
30710 | + | |
30711 | +/* IBM 370/390 relocations */ | |
30712 | + BFD_RELOC_I370_D12, | |
30713 | + | |
30714 | +/* The type of reloc used to build a constructor table - at the moment | |
30715 | +probably a 32 bit wide absolute relocation, but the target can choose. | |
30716 | +It generally does map to one of the other relocation types. */ | |
30717 | + BFD_RELOC_CTOR, | |
30718 | + | |
30719 | +/* ARM 26 bit pc-relative branch. The lowest two bits must be zero and are | |
30720 | +not stored in the instruction. */ | |
30721 | + BFD_RELOC_ARM_PCREL_BRANCH, | |
30722 | + | |
30723 | +/* ARM 26 bit pc-relative branch. The lowest bit must be zero and is | |
30724 | +not stored in the instruction. The 2nd lowest bit comes from a 1 bit | |
30725 | +field in the instruction. */ | |
30726 | + BFD_RELOC_ARM_PCREL_BLX, | |
30727 | + | |
30728 | +/* Thumb 22 bit pc-relative branch. The lowest bit must be zero and is | |
30729 | +not stored in the instruction. The 2nd lowest bit comes from a 1 bit | |
30730 | +field in the instruction. */ | |
30731 | + BFD_RELOC_THUMB_PCREL_BLX, | |
30732 | + | |
30733 | +/* Thumb 7-, 9-, 12-, 20-, 23-, and 25-bit pc-relative branches. | |
30734 | +The lowest bit must be zero and is not stored in the instruction. | |
30735 | +Note that the corresponding ELF R_ARM_THM_JUMPnn constant has an | |
30736 | +"nn" one smaller in all cases. Note further that BRANCH23 | |
30737 | +corresponds to R_ARM_THM_CALL. */ | |
30738 | + BFD_RELOC_THUMB_PCREL_BRANCH7, | |
30739 | + BFD_RELOC_THUMB_PCREL_BRANCH9, | |
30740 | + BFD_RELOC_THUMB_PCREL_BRANCH12, | |
30741 | + BFD_RELOC_THUMB_PCREL_BRANCH20, | |
30742 | + BFD_RELOC_THUMB_PCREL_BRANCH23, | |
30743 | + BFD_RELOC_THUMB_PCREL_BRANCH25, | |
30744 | + | |
30745 | +/* 12-bit immediate offset, used in ARM-format ldr and str instructions. */ | |
30746 | + BFD_RELOC_ARM_OFFSET_IMM, | |
30747 | + | |
30748 | +/* 5-bit immediate offset, used in Thumb-format ldr and str instructions. */ | |
30749 | + BFD_RELOC_ARM_THUMB_OFFSET, | |
30750 | + | |
30751 | +/* Pc-relative or absolute relocation depending on target. Used for | |
30752 | +entries in .init_array sections. */ | |
30753 | + BFD_RELOC_ARM_TARGET1, | |
30754 | + | |
30755 | +/* Read-only segment base relative address. */ | |
30756 | + BFD_RELOC_ARM_ROSEGREL32, | |
30757 | + | |
30758 | +/* Data segment base relative address. */ | |
30759 | + BFD_RELOC_ARM_SBREL32, | |
30760 | + | |
30761 | +/* This reloc is used for references to RTTI data from exception handling | |
30762 | +tables. The actual definition depends on the target. It may be a | |
30763 | +pc-relative or some form of GOT-indirect relocation. */ | |
30764 | + BFD_RELOC_ARM_TARGET2, | |
30765 | + | |
30766 | +/* 31-bit PC relative address. */ | |
30767 | + BFD_RELOC_ARM_PREL31, | |
30768 | + | |
30769 | +/* Relocations for setting up GOTs and PLTs for shared libraries. */ | |
30770 | + BFD_RELOC_ARM_JUMP_SLOT, | |
30771 | + BFD_RELOC_ARM_GLOB_DAT, | |
30772 | + BFD_RELOC_ARM_GOT32, | |
30773 | + BFD_RELOC_ARM_PLT32, | |
30774 | + BFD_RELOC_ARM_RELATIVE, | |
30775 | + BFD_RELOC_ARM_GOTOFF, | |
30776 | + BFD_RELOC_ARM_GOTPC, | |
30777 | + | |
30778 | +/* ARM thread-local storage relocations. */ | |
30779 | + BFD_RELOC_ARM_TLS_GD32, | |
30780 | + BFD_RELOC_ARM_TLS_LDO32, | |
30781 | + BFD_RELOC_ARM_TLS_LDM32, | |
30782 | + BFD_RELOC_ARM_TLS_DTPOFF32, | |
30783 | + BFD_RELOC_ARM_TLS_DTPMOD32, | |
30784 | + BFD_RELOC_ARM_TLS_TPOFF32, | |
30785 | + BFD_RELOC_ARM_TLS_IE32, | |
30786 | + BFD_RELOC_ARM_TLS_LE32, | |
30787 | + | |
30788 | +/* These relocs are only used within the ARM assembler. They are not | |
30789 | +(at present) written to any object files. */ | |
30790 | + BFD_RELOC_ARM_IMMEDIATE, | |
30791 | + BFD_RELOC_ARM_ADRL_IMMEDIATE, | |
30792 | + BFD_RELOC_ARM_T32_IMMEDIATE, | |
30793 | + BFD_RELOC_ARM_SHIFT_IMM, | |
30794 | + BFD_RELOC_ARM_SMI, | |
30795 | + BFD_RELOC_ARM_SWI, | |
30796 | + BFD_RELOC_ARM_MULTI, | |
30797 | + BFD_RELOC_ARM_CP_OFF_IMM, | |
30798 | + BFD_RELOC_ARM_CP_OFF_IMM_S2, | |
30799 | + BFD_RELOC_ARM_ADR_IMM, | |
30800 | + BFD_RELOC_ARM_LDR_IMM, | |
30801 | + BFD_RELOC_ARM_LITERAL, | |
30802 | + BFD_RELOC_ARM_IN_POOL, | |
30803 | + BFD_RELOC_ARM_OFFSET_IMM8, | |
30804 | + BFD_RELOC_ARM_T32_OFFSET_U8, | |
30805 | + BFD_RELOC_ARM_T32_OFFSET_IMM, | |
30806 | + BFD_RELOC_ARM_HWLITERAL, | |
30807 | + BFD_RELOC_ARM_THUMB_ADD, | |
30808 | + BFD_RELOC_ARM_THUMB_IMM, | |
30809 | + BFD_RELOC_ARM_THUMB_SHIFT, | |
30810 | + | |
30811 | +/* Renesas / SuperH SH relocs. Not all of these appear in object files. */ | |
30812 | + BFD_RELOC_SH_PCDISP8BY2, | |
30813 | + BFD_RELOC_SH_PCDISP12BY2, | |
30814 | + BFD_RELOC_SH_IMM3, | |
30815 | + BFD_RELOC_SH_IMM3U, | |
30816 | + BFD_RELOC_SH_DISP12, | |
30817 | + BFD_RELOC_SH_DISP12BY2, | |
30818 | + BFD_RELOC_SH_DISP12BY4, | |
30819 | + BFD_RELOC_SH_DISP12BY8, | |
30820 | + BFD_RELOC_SH_DISP20, | |
30821 | + BFD_RELOC_SH_DISP20BY8, | |
30822 | + BFD_RELOC_SH_IMM4, | |
30823 | + BFD_RELOC_SH_IMM4BY2, | |
30824 | + BFD_RELOC_SH_IMM4BY4, | |
30825 | + BFD_RELOC_SH_IMM8, | |
30826 | + BFD_RELOC_SH_IMM8BY2, | |
30827 | + BFD_RELOC_SH_IMM8BY4, | |
30828 | + BFD_RELOC_SH_PCRELIMM8BY2, | |
30829 | + BFD_RELOC_SH_PCRELIMM8BY4, | |
30830 | + BFD_RELOC_SH_SWITCH16, | |
30831 | + BFD_RELOC_SH_SWITCH32, | |
30832 | + BFD_RELOC_SH_USES, | |
30833 | + BFD_RELOC_SH_COUNT, | |
30834 | + BFD_RELOC_SH_ALIGN, | |
30835 | + BFD_RELOC_SH_CODE, | |
30836 | + BFD_RELOC_SH_DATA, | |
30837 | + BFD_RELOC_SH_LABEL, | |
30838 | + BFD_RELOC_SH_LOOP_START, | |
30839 | + BFD_RELOC_SH_LOOP_END, | |
30840 | + BFD_RELOC_SH_COPY, | |
30841 | + BFD_RELOC_SH_GLOB_DAT, | |
30842 | + BFD_RELOC_SH_JMP_SLOT, | |
30843 | + BFD_RELOC_SH_RELATIVE, | |
30844 | + BFD_RELOC_SH_GOTPC, | |
30845 | + BFD_RELOC_SH_GOT_LOW16, | |
30846 | + BFD_RELOC_SH_GOT_MEDLOW16, | |
30847 | + BFD_RELOC_SH_GOT_MEDHI16, | |
30848 | + BFD_RELOC_SH_GOT_HI16, | |
30849 | + BFD_RELOC_SH_GOTPLT_LOW16, | |
30850 | + BFD_RELOC_SH_GOTPLT_MEDLOW16, | |
30851 | + BFD_RELOC_SH_GOTPLT_MEDHI16, | |
30852 | + BFD_RELOC_SH_GOTPLT_HI16, | |
30853 | + BFD_RELOC_SH_PLT_LOW16, | |
30854 | + BFD_RELOC_SH_PLT_MEDLOW16, | |
30855 | + BFD_RELOC_SH_PLT_MEDHI16, | |
30856 | + BFD_RELOC_SH_PLT_HI16, | |
30857 | + BFD_RELOC_SH_GOTOFF_LOW16, | |
30858 | + BFD_RELOC_SH_GOTOFF_MEDLOW16, | |
30859 | + BFD_RELOC_SH_GOTOFF_MEDHI16, | |
30860 | + BFD_RELOC_SH_GOTOFF_HI16, | |
30861 | + BFD_RELOC_SH_GOTPC_LOW16, | |
30862 | + BFD_RELOC_SH_GOTPC_MEDLOW16, | |
30863 | + BFD_RELOC_SH_GOTPC_MEDHI16, | |
30864 | + BFD_RELOC_SH_GOTPC_HI16, | |
30865 | + BFD_RELOC_SH_COPY64, | |
30866 | + BFD_RELOC_SH_GLOB_DAT64, | |
30867 | + BFD_RELOC_SH_JMP_SLOT64, | |
30868 | + BFD_RELOC_SH_RELATIVE64, | |
30869 | + BFD_RELOC_SH_GOT10BY4, | |
30870 | + BFD_RELOC_SH_GOT10BY8, | |
30871 | + BFD_RELOC_SH_GOTPLT10BY4, | |
30872 | + BFD_RELOC_SH_GOTPLT10BY8, | |
30873 | + BFD_RELOC_SH_GOTPLT32, | |
30874 | + BFD_RELOC_SH_SHMEDIA_CODE, | |
30875 | + BFD_RELOC_SH_IMMU5, | |
30876 | + BFD_RELOC_SH_IMMS6, | |
30877 | + BFD_RELOC_SH_IMMS6BY32, | |
30878 | + BFD_RELOC_SH_IMMU6, | |
30879 | + BFD_RELOC_SH_IMMS10, | |
30880 | + BFD_RELOC_SH_IMMS10BY2, | |
30881 | + BFD_RELOC_SH_IMMS10BY4, | |
30882 | + BFD_RELOC_SH_IMMS10BY8, | |
30883 | + BFD_RELOC_SH_IMMS16, | |
30884 | + BFD_RELOC_SH_IMMU16, | |
30885 | + BFD_RELOC_SH_IMM_LOW16, | |
30886 | + BFD_RELOC_SH_IMM_LOW16_PCREL, | |
30887 | + BFD_RELOC_SH_IMM_MEDLOW16, | |
30888 | + BFD_RELOC_SH_IMM_MEDLOW16_PCREL, | |
30889 | + BFD_RELOC_SH_IMM_MEDHI16, | |
30890 | + BFD_RELOC_SH_IMM_MEDHI16_PCREL, | |
30891 | + BFD_RELOC_SH_IMM_HI16, | |
30892 | + BFD_RELOC_SH_IMM_HI16_PCREL, | |
30893 | + BFD_RELOC_SH_PT_16, | |
30894 | + BFD_RELOC_SH_TLS_GD_32, | |
30895 | + BFD_RELOC_SH_TLS_LD_32, | |
30896 | + BFD_RELOC_SH_TLS_LDO_32, | |
30897 | + BFD_RELOC_SH_TLS_IE_32, | |
30898 | + BFD_RELOC_SH_TLS_LE_32, | |
30899 | + BFD_RELOC_SH_TLS_DTPMOD32, | |
30900 | + BFD_RELOC_SH_TLS_DTPOFF32, | |
30901 | + BFD_RELOC_SH_TLS_TPOFF32, | |
30902 | + | |
30903 | +/* ARC Cores relocs. | |
30904 | +ARC 22 bit pc-relative branch. The lowest two bits must be zero and are | |
30905 | +not stored in the instruction. The high 20 bits are installed in bits 26 | |
30906 | +through 7 of the instruction. */ | |
30907 | + BFD_RELOC_ARC_B22_PCREL, | |
30908 | + | |
30909 | +/* ARC 26 bit absolute branch. The lowest two bits must be zero and are not | |
30910 | +stored in the instruction. The high 24 bits are installed in bits 23 | |
30911 | +through 0. */ | |
30912 | + BFD_RELOC_ARC_B26, | |
30913 | + | |
30914 | +/* Mitsubishi D10V relocs. | |
30915 | +This is a 10-bit reloc with the right 2 bits | |
30916 | +assumed to be 0. */ | |
30917 | + BFD_RELOC_D10V_10_PCREL_R, | |
30918 | + | |
30919 | +/* Mitsubishi D10V relocs. | |
30920 | +This is a 10-bit reloc with the right 2 bits | |
30921 | +assumed to be 0. This is the same as the previous reloc | |
30922 | +except it is in the left container, i.e., | |
30923 | +shifted left 15 bits. */ | |
30924 | + BFD_RELOC_D10V_10_PCREL_L, | |
30925 | + | |
30926 | +/* This is an 18-bit reloc with the right 2 bits | |
30927 | +assumed to be 0. */ | |
30928 | + BFD_RELOC_D10V_18, | |
30929 | + | |
30930 | +/* This is an 18-bit reloc with the right 2 bits | |
30931 | +assumed to be 0. */ | |
30932 | + BFD_RELOC_D10V_18_PCREL, | |
30933 | + | |
30934 | +/* Mitsubishi D30V relocs. | |
30935 | +This is a 6-bit absolute reloc. */ | |
30936 | + BFD_RELOC_D30V_6, | |
30937 | + | |
30938 | +/* This is a 6-bit pc-relative reloc with | |
30939 | +the right 3 bits assumed to be 0. */ | |
30940 | + BFD_RELOC_D30V_9_PCREL, | |
30941 | + | |
30942 | +/* This is a 6-bit pc-relative reloc with | |
30943 | +the right 3 bits assumed to be 0. Same | |
30944 | +as the previous reloc but on the right side | |
30945 | +of the container. */ | |
30946 | + BFD_RELOC_D30V_9_PCREL_R, | |
30947 | + | |
30948 | +/* This is a 12-bit absolute reloc with the | |
30949 | +right 3 bitsassumed to be 0. */ | |
30950 | + BFD_RELOC_D30V_15, | |
30951 | + | |
30952 | +/* This is a 12-bit pc-relative reloc with | |
30953 | +the right 3 bits assumed to be 0. */ | |
30954 | + BFD_RELOC_D30V_15_PCREL, | |
30955 | + | |
30956 | +/* This is a 12-bit pc-relative reloc with | |
30957 | +the right 3 bits assumed to be 0. Same | |
30958 | +as the previous reloc but on the right side | |
30959 | +of the container. */ | |
30960 | + BFD_RELOC_D30V_15_PCREL_R, | |
30961 | + | |
30962 | +/* This is an 18-bit absolute reloc with | |
30963 | +the right 3 bits assumed to be 0. */ | |
30964 | + BFD_RELOC_D30V_21, | |
30965 | + | |
30966 | +/* This is an 18-bit pc-relative reloc with | |
30967 | +the right 3 bits assumed to be 0. */ | |
30968 | + BFD_RELOC_D30V_21_PCREL, | |
30969 | + | |
30970 | +/* This is an 18-bit pc-relative reloc with | |
30971 | +the right 3 bits assumed to be 0. Same | |
30972 | +as the previous reloc but on the right side | |
30973 | +of the container. */ | |
30974 | + BFD_RELOC_D30V_21_PCREL_R, | |
30975 | + | |
30976 | +/* This is a 32-bit absolute reloc. */ | |
30977 | + BFD_RELOC_D30V_32, | |
30978 | + | |
30979 | +/* This is a 32-bit pc-relative reloc. */ | |
30980 | + BFD_RELOC_D30V_32_PCREL, | |
30981 | + | |
30982 | +/* DLX relocs */ | |
30983 | + BFD_RELOC_DLX_HI16_S, | |
30984 | + | |
30985 | +/* DLX relocs */ | |
30986 | + BFD_RELOC_DLX_LO16, | |
30987 | + | |
30988 | +/* DLX relocs */ | |
30989 | + BFD_RELOC_DLX_JMP26, | |
30990 | + | |
30991 | +/* Renesas M16C/M32C Relocations. */ | |
30992 | + BFD_RELOC_M16C_8_PCREL8, | |
30993 | + BFD_RELOC_M16C_16_PCREL8, | |
30994 | + BFD_RELOC_M16C_8_PCREL16, | |
30995 | + BFD_RELOC_M16C_8_ELABEL24, | |
30996 | + BFD_RELOC_M16C_8_ABS16, | |
30997 | + BFD_RELOC_M16C_16_ABS16, | |
30998 | + BFD_RELOC_M16C_16_ABS24, | |
30999 | + BFD_RELOC_M16C_16_ABS32, | |
31000 | + BFD_RELOC_M16C_24_ABS16, | |
31001 | + BFD_RELOC_M16C_24_ABS24, | |
31002 | + BFD_RELOC_M16C_24_ABS32, | |
31003 | + BFD_RELOC_M16C_32_ABS16, | |
31004 | + BFD_RELOC_M16C_32_ABS24, | |
31005 | + BFD_RELOC_M16C_32_ABS32, | |
31006 | + BFD_RELOC_M16C_40_ABS16, | |
31007 | + BFD_RELOC_M16C_40_ABS24, | |
31008 | + BFD_RELOC_M16C_40_ABS32, | |
31009 | + | |
31010 | +/* Renesas M32R (formerly Mitsubishi M32R) relocs. | |
31011 | +This is a 24 bit absolute address. */ | |
31012 | + BFD_RELOC_M32R_24, | |
31013 | + | |
31014 | +/* This is a 10-bit pc-relative reloc with the right 2 bits assumed to be 0. */ | |
31015 | + BFD_RELOC_M32R_10_PCREL, | |
31016 | + | |
31017 | +/* This is an 18-bit reloc with the right 2 bits assumed to be 0. */ | |
31018 | + BFD_RELOC_M32R_18_PCREL, | |
31019 | + | |
31020 | +/* This is a 26-bit reloc with the right 2 bits assumed to be 0. */ | |
31021 | + BFD_RELOC_M32R_26_PCREL, | |
31022 | + | |
31023 | +/* This is a 16-bit reloc containing the high 16 bits of an address | |
31024 | +used when the lower 16 bits are treated as unsigned. */ | |
31025 | + BFD_RELOC_M32R_HI16_ULO, | |
31026 | + | |
31027 | +/* This is a 16-bit reloc containing the high 16 bits of an address | |
31028 | +used when the lower 16 bits are treated as signed. */ | |
31029 | + BFD_RELOC_M32R_HI16_SLO, | |
31030 | + | |
31031 | +/* This is a 16-bit reloc containing the lower 16 bits of an address. */ | |
31032 | + BFD_RELOC_M32R_LO16, | |
31033 | + | |
31034 | +/* This is a 16-bit reloc containing the small data area offset for use in | |
31035 | +add3, load, and store instructions. */ | |
31036 | + BFD_RELOC_M32R_SDA16, | |
31037 | + | |
31038 | +/* For PIC. */ | |
31039 | + BFD_RELOC_M32R_GOT24, | |
31040 | + BFD_RELOC_M32R_26_PLTREL, | |
31041 | + BFD_RELOC_M32R_COPY, | |
31042 | + BFD_RELOC_M32R_GLOB_DAT, | |
31043 | + BFD_RELOC_M32R_JMP_SLOT, | |
31044 | + BFD_RELOC_M32R_RELATIVE, | |
31045 | + BFD_RELOC_M32R_GOTOFF, | |
31046 | + BFD_RELOC_M32R_GOTOFF_HI_ULO, | |
31047 | + BFD_RELOC_M32R_GOTOFF_HI_SLO, | |
31048 | + BFD_RELOC_M32R_GOTOFF_LO, | |
31049 | + BFD_RELOC_M32R_GOTPC24, | |
31050 | + BFD_RELOC_M32R_GOT16_HI_ULO, | |
31051 | + BFD_RELOC_M32R_GOT16_HI_SLO, | |
31052 | + BFD_RELOC_M32R_GOT16_LO, | |
31053 | + BFD_RELOC_M32R_GOTPC_HI_ULO, | |
31054 | + BFD_RELOC_M32R_GOTPC_HI_SLO, | |
31055 | + BFD_RELOC_M32R_GOTPC_LO, | |
31056 | + | |
31057 | +/* This is a 9-bit reloc */ | |
31058 | + BFD_RELOC_V850_9_PCREL, | |
31059 | + | |
31060 | +/* This is a 22-bit reloc */ | |
31061 | + BFD_RELOC_V850_22_PCREL, | |
31062 | + | |
31063 | +/* This is a 16 bit offset from the short data area pointer. */ | |
31064 | + BFD_RELOC_V850_SDA_16_16_OFFSET, | |
31065 | + | |
31066 | +/* This is a 16 bit offset (of which only 15 bits are used) from the | |
31067 | +short data area pointer. */ | |
31068 | + BFD_RELOC_V850_SDA_15_16_OFFSET, | |
31069 | + | |
31070 | +/* This is a 16 bit offset from the zero data area pointer. */ | |
31071 | + BFD_RELOC_V850_ZDA_16_16_OFFSET, | |
31072 | + | |
31073 | +/* This is a 16 bit offset (of which only 15 bits are used) from the | |
31074 | +zero data area pointer. */ | |
31075 | + BFD_RELOC_V850_ZDA_15_16_OFFSET, | |
31076 | + | |
31077 | +/* This is an 8 bit offset (of which only 6 bits are used) from the | |
31078 | +tiny data area pointer. */ | |
31079 | + BFD_RELOC_V850_TDA_6_8_OFFSET, | |
31080 | + | |
31081 | +/* This is an 8bit offset (of which only 7 bits are used) from the tiny | |
31082 | +data area pointer. */ | |
31083 | + BFD_RELOC_V850_TDA_7_8_OFFSET, | |
31084 | + | |
31085 | +/* This is a 7 bit offset from the tiny data area pointer. */ | |
31086 | + BFD_RELOC_V850_TDA_7_7_OFFSET, | |
31087 | + | |
31088 | +/* This is a 16 bit offset from the tiny data area pointer. */ | |
31089 | + BFD_RELOC_V850_TDA_16_16_OFFSET, | |
31090 | + | |
31091 | +/* This is a 5 bit offset (of which only 4 bits are used) from the tiny | |
31092 | +data area pointer. */ | |
31093 | + BFD_RELOC_V850_TDA_4_5_OFFSET, | |
31094 | + | |
31095 | +/* This is a 4 bit offset from the tiny data area pointer. */ | |
31096 | + BFD_RELOC_V850_TDA_4_4_OFFSET, | |
31097 | + | |
31098 | +/* This is a 16 bit offset from the short data area pointer, with the | |
31099 | +bits placed non-contiguously in the instruction. */ | |
31100 | + BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET, | |
31101 | + | |
31102 | +/* This is a 16 bit offset from the zero data area pointer, with the | |
31103 | +bits placed non-contiguously in the instruction. */ | |
31104 | + BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET, | |
31105 | + | |
31106 | +/* This is a 6 bit offset from the call table base pointer. */ | |
31107 | + BFD_RELOC_V850_CALLT_6_7_OFFSET, | |
31108 | + | |
31109 | +/* This is a 16 bit offset from the call table base pointer. */ | |
31110 | + BFD_RELOC_V850_CALLT_16_16_OFFSET, | |
31111 | + | |
31112 | +/* Used for relaxing indirect function calls. */ | |
31113 | + BFD_RELOC_V850_LONGCALL, | |
31114 | + | |
31115 | +/* Used for relaxing indirect jumps. */ | |
31116 | + BFD_RELOC_V850_LONGJUMP, | |
31117 | + | |
31118 | +/* Used to maintain alignment whilst relaxing. */ | |
31119 | + BFD_RELOC_V850_ALIGN, | |
31120 | + | |
31121 | +/* This is a variation of BFD_RELOC_LO16 that can be used in v850e ld.bu | |
31122 | +instructions. */ | |
31123 | + BFD_RELOC_V850_LO16_SPLIT_OFFSET, | |
31124 | + | |
31125 | +/* This is a 32bit pcrel reloc for the mn10300, offset by two bytes in the | |
31126 | +instruction. */ | |
31127 | + BFD_RELOC_MN10300_32_PCREL, | |
31128 | + | |
31129 | +/* This is a 16bit pcrel reloc for the mn10300, offset by two bytes in the | |
31130 | +instruction. */ | |
31131 | + BFD_RELOC_MN10300_16_PCREL, | |
31132 | + | |
31133 | +/* This is a 8bit DP reloc for the tms320c30, where the most | |
31134 | +significant 8 bits of a 24 bit word are placed into the least | |
31135 | +significant 8 bits of the opcode. */ | |
31136 | + BFD_RELOC_TIC30_LDP, | |
31137 | + | |
31138 | +/* This is a 7bit reloc for the tms320c54x, where the least | |
31139 | +significant 7 bits of a 16 bit word are placed into the least | |
31140 | +significant 7 bits of the opcode. */ | |
31141 | + BFD_RELOC_TIC54X_PARTLS7, | |
31142 | + | |
31143 | +/* This is a 9bit DP reloc for the tms320c54x, where the most | |
31144 | +significant 9 bits of a 16 bit word are placed into the least | |
31145 | +significant 9 bits of the opcode. */ | |
31146 | + BFD_RELOC_TIC54X_PARTMS9, | |
31147 | + | |
31148 | +/* This is an extended address 23-bit reloc for the tms320c54x. */ | |
31149 | + BFD_RELOC_TIC54X_23, | |
31150 | + | |
31151 | +/* This is a 16-bit reloc for the tms320c54x, where the least | |
31152 | +significant 16 bits of a 23-bit extended address are placed into | |
31153 | +the opcode. */ | |
31154 | + BFD_RELOC_TIC54X_16_OF_23, | |
31155 | + | |
31156 | +/* This is a reloc for the tms320c54x, where the most | |
31157 | +significant 7 bits of a 23-bit extended address are placed into | |
31158 | +the opcode. */ | |
31159 | + BFD_RELOC_TIC54X_MS7_OF_23, | |
31160 | + | |
31161 | +/* This is a 48 bit reloc for the FR30 that stores 32 bits. */ | |
31162 | + BFD_RELOC_FR30_48, | |
31163 | + | |
31164 | +/* This is a 32 bit reloc for the FR30 that stores 20 bits split up into | |
31165 | +two sections. */ | |
31166 | + BFD_RELOC_FR30_20, | |
31167 | + | |
31168 | +/* This is a 16 bit reloc for the FR30 that stores a 6 bit word offset in | |
31169 | +4 bits. */ | |
31170 | + BFD_RELOC_FR30_6_IN_4, | |
31171 | + | |
31172 | +/* This is a 16 bit reloc for the FR30 that stores an 8 bit byte offset | |
31173 | +into 8 bits. */ | |
31174 | + BFD_RELOC_FR30_8_IN_8, | |
31175 | + | |
31176 | +/* This is a 16 bit reloc for the FR30 that stores a 9 bit short offset | |
31177 | +into 8 bits. */ | |
31178 | + BFD_RELOC_FR30_9_IN_8, | |
31179 | + | |
31180 | +/* This is a 16 bit reloc for the FR30 that stores a 10 bit word offset | |
31181 | +into 8 bits. */ | |
31182 | + BFD_RELOC_FR30_10_IN_8, | |
31183 | + | |
31184 | +/* This is a 16 bit reloc for the FR30 that stores a 9 bit pc relative | |
31185 | +short offset into 8 bits. */ | |
31186 | + BFD_RELOC_FR30_9_PCREL, | |
31187 | + | |
31188 | +/* This is a 16 bit reloc for the FR30 that stores a 12 bit pc relative | |
31189 | +short offset into 11 bits. */ | |
31190 | + BFD_RELOC_FR30_12_PCREL, | |
31191 | + | |
31192 | +/* Motorola Mcore relocations. */ | |
31193 | + BFD_RELOC_MCORE_PCREL_IMM8BY4, | |
31194 | + BFD_RELOC_MCORE_PCREL_IMM11BY2, | |
31195 | + BFD_RELOC_MCORE_PCREL_IMM4BY2, | |
31196 | + BFD_RELOC_MCORE_PCREL_32, | |
31197 | + BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2, | |
31198 | + BFD_RELOC_MCORE_RVA, | |
31199 | + | |
31200 | +/* These are relocations for the GETA instruction. */ | |
31201 | + BFD_RELOC_MMIX_GETA, | |
31202 | + BFD_RELOC_MMIX_GETA_1, | |
31203 | + BFD_RELOC_MMIX_GETA_2, | |
31204 | + BFD_RELOC_MMIX_GETA_3, | |
31205 | + | |
31206 | +/* These are relocations for a conditional branch instruction. */ | |
31207 | + BFD_RELOC_MMIX_CBRANCH, | |
31208 | + BFD_RELOC_MMIX_CBRANCH_J, | |
31209 | + BFD_RELOC_MMIX_CBRANCH_1, | |
31210 | + BFD_RELOC_MMIX_CBRANCH_2, | |
31211 | + BFD_RELOC_MMIX_CBRANCH_3, | |
31212 | + | |
31213 | +/* These are relocations for the PUSHJ instruction. */ | |
31214 | + BFD_RELOC_MMIX_PUSHJ, | |
31215 | + BFD_RELOC_MMIX_PUSHJ_1, | |
31216 | + BFD_RELOC_MMIX_PUSHJ_2, | |
31217 | + BFD_RELOC_MMIX_PUSHJ_3, | |
31218 | + BFD_RELOC_MMIX_PUSHJ_STUBBABLE, | |
31219 | + | |
31220 | +/* These are relocations for the JMP instruction. */ | |
31221 | + BFD_RELOC_MMIX_JMP, | |
31222 | + BFD_RELOC_MMIX_JMP_1, | |
31223 | + BFD_RELOC_MMIX_JMP_2, | |
31224 | + BFD_RELOC_MMIX_JMP_3, | |
31225 | + | |
31226 | +/* This is a relocation for a relative address as in a GETA instruction or | |
31227 | +a branch. */ | |
31228 | + BFD_RELOC_MMIX_ADDR19, | |
31229 | + | |
31230 | +/* This is a relocation for a relative address as in a JMP instruction. */ | |
31231 | + BFD_RELOC_MMIX_ADDR27, | |
31232 | + | |
31233 | +/* This is a relocation for an instruction field that may be a general | |
31234 | +register or a value 0..255. */ | |
31235 | + BFD_RELOC_MMIX_REG_OR_BYTE, | |
31236 | + | |
31237 | +/* This is a relocation for an instruction field that may be a general | |
31238 | +register. */ | |
31239 | + BFD_RELOC_MMIX_REG, | |
31240 | + | |
31241 | +/* This is a relocation for two instruction fields holding a register and | |
31242 | +an offset, the equivalent of the relocation. */ | |
31243 | + BFD_RELOC_MMIX_BASE_PLUS_OFFSET, | |
31244 | + | |
31245 | +/* This relocation is an assertion that the expression is not allocated as | |
31246 | +a global register. It does not modify contents. */ | |
31247 | + BFD_RELOC_MMIX_LOCAL, | |
31248 | + | |
31249 | +/* This is a 16 bit reloc for the AVR that stores 8 bit pc relative | |
31250 | +short offset into 7 bits. */ | |
31251 | + BFD_RELOC_AVR_7_PCREL, | |
31252 | + | |
31253 | +/* This is a 16 bit reloc for the AVR that stores 13 bit pc relative | |
31254 | +short offset into 12 bits. */ | |
31255 | + BFD_RELOC_AVR_13_PCREL, | |
31256 | + | |
31257 | +/* This is a 16 bit reloc for the AVR that stores 17 bit value (usually | |
31258 | +program memory address) into 16 bits. */ | |
31259 | + BFD_RELOC_AVR_16_PM, | |
31260 | + | |
31261 | +/* This is a 16 bit reloc for the AVR that stores 8 bit value (usually | |
31262 | +data memory address) into 8 bit immediate value of LDI insn. */ | |
31263 | + BFD_RELOC_AVR_LO8_LDI, | |
31264 | + | |
31265 | +/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit | |
31266 | +of data memory address) into 8 bit immediate value of LDI insn. */ | |
31267 | + BFD_RELOC_AVR_HI8_LDI, | |
31268 | + | |
31269 | +/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit | |
31270 | +of program memory address) into 8 bit immediate value of LDI insn. */ | |
31271 | + BFD_RELOC_AVR_HH8_LDI, | |
31272 | + | |
31273 | +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value | |
31274 | +(usually data memory address) into 8 bit immediate value of SUBI insn. */ | |
31275 | + BFD_RELOC_AVR_LO8_LDI_NEG, | |
31276 | + | |
31277 | +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value | |
31278 | +(high 8 bit of data memory address) into 8 bit immediate value of | |
31279 | +SUBI insn. */ | |
31280 | + BFD_RELOC_AVR_HI8_LDI_NEG, | |
31281 | + | |
31282 | +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value | |
31283 | +(most high 8 bit of program memory address) into 8 bit immediate value | |
31284 | +of LDI or SUBI insn. */ | |
31285 | + BFD_RELOC_AVR_HH8_LDI_NEG, | |
31286 | + | |
31287 | +/* This is a 16 bit reloc for the AVR that stores 8 bit value (usually | |
31288 | +command address) into 8 bit immediate value of LDI insn. */ | |
31289 | + BFD_RELOC_AVR_LO8_LDI_PM, | |
31290 | + | |
31291 | +/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit | |
31292 | +of command address) into 8 bit immediate value of LDI insn. */ | |
31293 | + BFD_RELOC_AVR_HI8_LDI_PM, | |
31294 | + | |
31295 | +/* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit | |
31296 | +of command address) into 8 bit immediate value of LDI insn. */ | |
31297 | + BFD_RELOC_AVR_HH8_LDI_PM, | |
31298 | + | |
31299 | +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value | |
31300 | +(usually command address) into 8 bit immediate value of SUBI insn. */ | |
31301 | + BFD_RELOC_AVR_LO8_LDI_PM_NEG, | |
31302 | + | |
31303 | +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value | |
31304 | +(high 8 bit of 16 bit command address) into 8 bit immediate value | |
31305 | +of SUBI insn. */ | |
31306 | + BFD_RELOC_AVR_HI8_LDI_PM_NEG, | |
31307 | + | |
31308 | +/* This is a 16 bit reloc for the AVR that stores negated 8 bit value | |
31309 | +(high 6 bit of 22 bit command address) into 8 bit immediate | |
31310 | +value of SUBI insn. */ | |
31311 | + BFD_RELOC_AVR_HH8_LDI_PM_NEG, | |
31312 | + | |
31313 | +/* This is a 32 bit reloc for the AVR that stores 23 bit value | |
31314 | +into 22 bits. */ | |
31315 | + BFD_RELOC_AVR_CALL, | |
31316 | + | |
31317 | +/* This is a 16 bit reloc for the AVR that stores all needed bits | |
31318 | +for absolute addressing with ldi with overflow check to linktime */ | |
31319 | + BFD_RELOC_AVR_LDI, | |
31320 | + | |
31321 | +/* This is a 6 bit reloc for the AVR that stores offset for ldd/std | |
31322 | +instructions */ | |
31323 | + BFD_RELOC_AVR_6, | |
31324 | + | |
31325 | +/* This is a 6 bit reloc for the AVR that stores offset for adiw/sbiw | |
31326 | +instructions */ | |
31327 | + BFD_RELOC_AVR_6_ADIW, | |
31328 | + | |
31329 | +/* Direct 12 bit. */ | |
31330 | + BFD_RELOC_390_12, | |
31331 | + | |
31332 | +/* 12 bit GOT offset. */ | |
31333 | + BFD_RELOC_390_GOT12, | |
31334 | + | |
31335 | +/* 32 bit PC relative PLT address. */ | |
31336 | + BFD_RELOC_390_PLT32, | |
31337 | + | |
31338 | +/* Copy symbol at runtime. */ | |
31339 | + BFD_RELOC_390_COPY, | |
31340 | + | |
31341 | +/* Create GOT entry. */ | |
31342 | + BFD_RELOC_390_GLOB_DAT, | |
31343 | + | |
31344 | +/* Create PLT entry. */ | |
31345 | + BFD_RELOC_390_JMP_SLOT, | |
31346 | + | |
31347 | +/* Adjust by program base. */ | |
31348 | + BFD_RELOC_390_RELATIVE, | |
31349 | + | |
31350 | +/* 32 bit PC relative offset to GOT. */ | |
31351 | + BFD_RELOC_390_GOTPC, | |
31352 | + | |
31353 | +/* 16 bit GOT offset. */ | |
31354 | + BFD_RELOC_390_GOT16, | |
31355 | + | |
31356 | +/* PC relative 16 bit shifted by 1. */ | |
31357 | + BFD_RELOC_390_PC16DBL, | |
31358 | + | |
31359 | +/* 16 bit PC rel. PLT shifted by 1. */ | |
31360 | + BFD_RELOC_390_PLT16DBL, | |
31361 | + | |
31362 | +/* PC relative 32 bit shifted by 1. */ | |
31363 | + BFD_RELOC_390_PC32DBL, | |
31364 | + | |
31365 | +/* 32 bit PC rel. PLT shifted by 1. */ | |
31366 | + BFD_RELOC_390_PLT32DBL, | |
31367 | + | |
31368 | +/* 32 bit PC rel. GOT shifted by 1. */ | |
31369 | + BFD_RELOC_390_GOTPCDBL, | |
31370 | + | |
31371 | +/* 64 bit GOT offset. */ | |
31372 | + BFD_RELOC_390_GOT64, | |
31373 | + | |
31374 | +/* 64 bit PC relative PLT address. */ | |
31375 | + BFD_RELOC_390_PLT64, | |
31376 | + | |
31377 | +/* 32 bit rel. offset to GOT entry. */ | |
31378 | + BFD_RELOC_390_GOTENT, | |
31379 | + | |
31380 | +/* 64 bit offset to GOT. */ | |
31381 | + BFD_RELOC_390_GOTOFF64, | |
31382 | + | |
31383 | +/* 12-bit offset to symbol-entry within GOT, with PLT handling. */ | |
31384 | + BFD_RELOC_390_GOTPLT12, | |
31385 | + | |
31386 | +/* 16-bit offset to symbol-entry within GOT, with PLT handling. */ | |
31387 | + BFD_RELOC_390_GOTPLT16, | |
31388 | + | |
31389 | +/* 32-bit offset to symbol-entry within GOT, with PLT handling. */ | |
31390 | + BFD_RELOC_390_GOTPLT32, | |
31391 | + | |
31392 | +/* 64-bit offset to symbol-entry within GOT, with PLT handling. */ | |
31393 | + BFD_RELOC_390_GOTPLT64, | |
31394 | + | |
31395 | +/* 32-bit rel. offset to symbol-entry within GOT, with PLT handling. */ | |
31396 | + BFD_RELOC_390_GOTPLTENT, | |
31397 | + | |
31398 | +/* 16-bit rel. offset from the GOT to a PLT entry. */ | |
31399 | + BFD_RELOC_390_PLTOFF16, | |
31400 | + | |
31401 | +/* 32-bit rel. offset from the GOT to a PLT entry. */ | |
31402 | + BFD_RELOC_390_PLTOFF32, | |
31403 | + | |
31404 | +/* 64-bit rel. offset from the GOT to a PLT entry. */ | |
31405 | + BFD_RELOC_390_PLTOFF64, | |
31406 | + | |
31407 | +/* s390 tls relocations. */ | |
31408 | + BFD_RELOC_390_TLS_LOAD, | |
31409 | + BFD_RELOC_390_TLS_GDCALL, | |
31410 | + BFD_RELOC_390_TLS_LDCALL, | |
31411 | + BFD_RELOC_390_TLS_GD32, | |
31412 | + BFD_RELOC_390_TLS_GD64, | |
31413 | + BFD_RELOC_390_TLS_GOTIE12, | |
31414 | + BFD_RELOC_390_TLS_GOTIE32, | |
31415 | + BFD_RELOC_390_TLS_GOTIE64, | |
31416 | + BFD_RELOC_390_TLS_LDM32, | |
31417 | + BFD_RELOC_390_TLS_LDM64, | |
31418 | + BFD_RELOC_390_TLS_IE32, | |
31419 | + BFD_RELOC_390_TLS_IE64, | |
31420 | + BFD_RELOC_390_TLS_IEENT, | |
31421 | + BFD_RELOC_390_TLS_LE32, | |
31422 | + BFD_RELOC_390_TLS_LE64, | |
31423 | + BFD_RELOC_390_TLS_LDO32, | |
31424 | + BFD_RELOC_390_TLS_LDO64, | |
31425 | + BFD_RELOC_390_TLS_DTPMOD, | |
31426 | + BFD_RELOC_390_TLS_DTPOFF, | |
31427 | + BFD_RELOC_390_TLS_TPOFF, | |
31428 | + | |
31429 | +/* Long displacement extension. */ | |
31430 | + BFD_RELOC_390_20, | |
31431 | + BFD_RELOC_390_GOT20, | |
31432 | + BFD_RELOC_390_GOTPLT20, | |
31433 | + BFD_RELOC_390_TLS_GOTIE20, | |
31434 | + | |
31435 | +/* Scenix IP2K - 9-bit register number / data address */ | |
31436 | + BFD_RELOC_IP2K_FR9, | |
31437 | + | |
31438 | +/* Scenix IP2K - 4-bit register/data bank number */ | |
31439 | + BFD_RELOC_IP2K_BANK, | |
31440 | + | |
31441 | +/* Scenix IP2K - low 13 bits of instruction word address */ | |
31442 | + BFD_RELOC_IP2K_ADDR16CJP, | |
31443 | + | |
31444 | +/* Scenix IP2K - high 3 bits of instruction word address */ | |
31445 | + BFD_RELOC_IP2K_PAGE3, | |
31446 | + | |
31447 | +/* Scenix IP2K - ext/low/high 8 bits of data address */ | |
31448 | + BFD_RELOC_IP2K_LO8DATA, | |
31449 | + BFD_RELOC_IP2K_HI8DATA, | |
31450 | + BFD_RELOC_IP2K_EX8DATA, | |
31451 | + | |
31452 | +/* Scenix IP2K - low/high 8 bits of instruction word address */ | |
31453 | + BFD_RELOC_IP2K_LO8INSN, | |
31454 | + BFD_RELOC_IP2K_HI8INSN, | |
31455 | + | |
31456 | +/* Scenix IP2K - even/odd PC modifier to modify snb pcl.0 */ | |
31457 | + BFD_RELOC_IP2K_PC_SKIP, | |
31458 | + | |
31459 | +/* Scenix IP2K - 16 bit word address in text section. */ | |
31460 | + BFD_RELOC_IP2K_TEXT, | |
31461 | + | |
31462 | +/* Scenix IP2K - 7-bit sp or dp offset */ | |
31463 | + BFD_RELOC_IP2K_FR_OFFSET, | |
31464 | + | |
31465 | +/* Scenix VPE4K coprocessor - data/insn-space addressing */ | |
31466 | + BFD_RELOC_VPE4KMATH_DATA, | |
31467 | + BFD_RELOC_VPE4KMATH_INSN, | |
31468 | + | |
31469 | +/* These two relocations are used by the linker to determine which of | |
31470 | +the entries in a C++ virtual function table are actually used. When | |
31471 | +the --gc-sections option is given, the linker will zero out the entries | |
31472 | +that are not used, so that the code for those functions need not be | |
31473 | +included in the output. | |
31474 | + | |
31475 | +VTABLE_INHERIT is a zero-space relocation used to describe to the | |
31476 | +linker the inheritance tree of a C++ virtual function table. The | |
31477 | +relocation's symbol should be the parent class' vtable, and the | |
31478 | +relocation should be located at the child vtable. | |
31479 | + | |
31480 | +VTABLE_ENTRY is a zero-space relocation that describes the use of a | |
31481 | +virtual function table entry. The reloc's symbol should refer to the | |
31482 | +table of the class mentioned in the code. Off of that base, an offset | |
31483 | +describes the entry that is being used. For Rela hosts, this offset | |
31484 | +is stored in the reloc's addend. For Rel hosts, we are forced to put | |
31485 | +this offset in the reloc's section offset. */ | |
31486 | + BFD_RELOC_VTABLE_INHERIT, | |
31487 | + BFD_RELOC_VTABLE_ENTRY, | |
31488 | + | |
31489 | +/* Intel IA64 Relocations. */ | |
31490 | + BFD_RELOC_IA64_IMM14, | |
31491 | + BFD_RELOC_IA64_IMM22, | |
31492 | + BFD_RELOC_IA64_IMM64, | |
31493 | + BFD_RELOC_IA64_DIR32MSB, | |
31494 | + BFD_RELOC_IA64_DIR32LSB, | |
31495 | + BFD_RELOC_IA64_DIR64MSB, | |
31496 | + BFD_RELOC_IA64_DIR64LSB, | |
31497 | + BFD_RELOC_IA64_GPREL22, | |
31498 | + BFD_RELOC_IA64_GPREL64I, | |
31499 | + BFD_RELOC_IA64_GPREL32MSB, | |
31500 | + BFD_RELOC_IA64_GPREL32LSB, | |
31501 | + BFD_RELOC_IA64_GPREL64MSB, | |
31502 | + BFD_RELOC_IA64_GPREL64LSB, | |
31503 | + BFD_RELOC_IA64_LTOFF22, | |
31504 | + BFD_RELOC_IA64_LTOFF64I, | |
31505 | + BFD_RELOC_IA64_PLTOFF22, | |
31506 | + BFD_RELOC_IA64_PLTOFF64I, | |
31507 | + BFD_RELOC_IA64_PLTOFF64MSB, | |
31508 | + BFD_RELOC_IA64_PLTOFF64LSB, | |
31509 | + BFD_RELOC_IA64_FPTR64I, | |
31510 | + BFD_RELOC_IA64_FPTR32MSB, | |
31511 | + BFD_RELOC_IA64_FPTR32LSB, | |
31512 | + BFD_RELOC_IA64_FPTR64MSB, | |
31513 | + BFD_RELOC_IA64_FPTR64LSB, | |
31514 | + BFD_RELOC_IA64_PCREL21B, | |
31515 | + BFD_RELOC_IA64_PCREL21BI, | |
31516 | + BFD_RELOC_IA64_PCREL21M, | |
31517 | + BFD_RELOC_IA64_PCREL21F, | |
31518 | + BFD_RELOC_IA64_PCREL22, | |
31519 | + BFD_RELOC_IA64_PCREL60B, | |
31520 | + BFD_RELOC_IA64_PCREL64I, | |
31521 | + BFD_RELOC_IA64_PCREL32MSB, | |
31522 | + BFD_RELOC_IA64_PCREL32LSB, | |
31523 | + BFD_RELOC_IA64_PCREL64MSB, | |
31524 | + BFD_RELOC_IA64_PCREL64LSB, | |
31525 | + BFD_RELOC_IA64_LTOFF_FPTR22, | |
31526 | + BFD_RELOC_IA64_LTOFF_FPTR64I, | |
31527 | + BFD_RELOC_IA64_LTOFF_FPTR32MSB, | |
31528 | + BFD_RELOC_IA64_LTOFF_FPTR32LSB, | |
31529 | + BFD_RELOC_IA64_LTOFF_FPTR64MSB, | |
31530 | + BFD_RELOC_IA64_LTOFF_FPTR64LSB, | |
31531 | + BFD_RELOC_IA64_SEGREL32MSB, | |
31532 | + BFD_RELOC_IA64_SEGREL32LSB, | |
31533 | + BFD_RELOC_IA64_SEGREL64MSB, | |
31534 | + BFD_RELOC_IA64_SEGREL64LSB, | |
31535 | + BFD_RELOC_IA64_SECREL32MSB, | |
31536 | + BFD_RELOC_IA64_SECREL32LSB, | |
31537 | + BFD_RELOC_IA64_SECREL64MSB, | |
31538 | + BFD_RELOC_IA64_SECREL64LSB, | |
31539 | + BFD_RELOC_IA64_REL32MSB, | |
31540 | + BFD_RELOC_IA64_REL32LSB, | |
31541 | + BFD_RELOC_IA64_REL64MSB, | |
31542 | + BFD_RELOC_IA64_REL64LSB, | |
31543 | + BFD_RELOC_IA64_LTV32MSB, | |
31544 | + BFD_RELOC_IA64_LTV32LSB, | |
31545 | + BFD_RELOC_IA64_LTV64MSB, | |
31546 | + BFD_RELOC_IA64_LTV64LSB, | |
31547 | + BFD_RELOC_IA64_IPLTMSB, | |
31548 | + BFD_RELOC_IA64_IPLTLSB, | |
31549 | + BFD_RELOC_IA64_COPY, | |
31550 | + BFD_RELOC_IA64_LTOFF22X, | |
31551 | + BFD_RELOC_IA64_LDXMOV, | |
31552 | + BFD_RELOC_IA64_TPREL14, | |
31553 | + BFD_RELOC_IA64_TPREL22, | |
31554 | + BFD_RELOC_IA64_TPREL64I, | |
31555 | + BFD_RELOC_IA64_TPREL64MSB, | |
31556 | + BFD_RELOC_IA64_TPREL64LSB, | |
31557 | + BFD_RELOC_IA64_LTOFF_TPREL22, | |
31558 | + BFD_RELOC_IA64_DTPMOD64MSB, | |
31559 | + BFD_RELOC_IA64_DTPMOD64LSB, | |
31560 | + BFD_RELOC_IA64_LTOFF_DTPMOD22, | |
31561 | + BFD_RELOC_IA64_DTPREL14, | |
31562 | + BFD_RELOC_IA64_DTPREL22, | |
31563 | + BFD_RELOC_IA64_DTPREL64I, | |
31564 | + BFD_RELOC_IA64_DTPREL32MSB, | |
31565 | + BFD_RELOC_IA64_DTPREL32LSB, | |
31566 | + BFD_RELOC_IA64_DTPREL64MSB, | |
31567 | + BFD_RELOC_IA64_DTPREL64LSB, | |
31568 | + BFD_RELOC_IA64_LTOFF_DTPREL22, | |
31569 | + | |
31570 | +/* Motorola 68HC11 reloc. | |
31571 | +This is the 8 bit high part of an absolute address. */ | |
31572 | + BFD_RELOC_M68HC11_HI8, | |
31573 | + | |
31574 | +/* Motorola 68HC11 reloc. | |
31575 | +This is the 8 bit low part of an absolute address. */ | |
31576 | + BFD_RELOC_M68HC11_LO8, | |
31577 | + | |
31578 | +/* Motorola 68HC11 reloc. | |
31579 | +This is the 3 bit of a value. */ | |
31580 | + BFD_RELOC_M68HC11_3B, | |
31581 | + | |
31582 | +/* Motorola 68HC11 reloc. | |
31583 | +This reloc marks the beginning of a jump/call instruction. | |
31584 | +It is used for linker relaxation to correctly identify beginning | |
31585 | +of instruction and change some branches to use PC-relative | |
31586 | +addressing mode. */ | |
31587 | + BFD_RELOC_M68HC11_RL_JUMP, | |
31588 | + | |
31589 | +/* Motorola 68HC11 reloc. | |
31590 | +This reloc marks a group of several instructions that gcc generates | |
31591 | +and for which the linker relaxation pass can modify and/or remove | |
31592 | +some of them. */ | |
31593 | + BFD_RELOC_M68HC11_RL_GROUP, | |
31594 | + | |
31595 | +/* Motorola 68HC11 reloc. | |
31596 | +This is the 16-bit lower part of an address. It is used for 'call' | |
31597 | +instruction to specify the symbol address without any special | |
31598 | +transformation (due to memory bank window). */ | |
31599 | + BFD_RELOC_M68HC11_LO16, | |
31600 | + | |
31601 | +/* Motorola 68HC11 reloc. | |
31602 | +This is a 8-bit reloc that specifies the page number of an address. | |
31603 | +It is used by 'call' instruction to specify the page number of | |
31604 | +the symbol. */ | |
31605 | + BFD_RELOC_M68HC11_PAGE, | |
31606 | + | |
31607 | +/* Motorola 68HC11 reloc. | |
31608 | +This is a 24-bit reloc that represents the address with a 16-bit | |
31609 | +value and a 8-bit page number. The symbol address is transformed | |
31610 | +to follow the 16K memory bank of 68HC12 (seen as mapped in the window). */ | |
31611 | + BFD_RELOC_M68HC11_24, | |
31612 | + | |
31613 | +/* Motorola 68HC12 reloc. | |
31614 | +This is the 5 bits of a value. */ | |
31615 | + BFD_RELOC_M68HC12_5B, | |
31616 | + | |
31617 | +/* NS CR16C Relocations. */ | |
31618 | + BFD_RELOC_16C_NUM08, | |
31619 | + BFD_RELOC_16C_NUM08_C, | |
31620 | + BFD_RELOC_16C_NUM16, | |
31621 | + BFD_RELOC_16C_NUM16_C, | |
31622 | + BFD_RELOC_16C_NUM32, | |
31623 | + BFD_RELOC_16C_NUM32_C, | |
31624 | + BFD_RELOC_16C_DISP04, | |
31625 | + BFD_RELOC_16C_DISP04_C, | |
31626 | + BFD_RELOC_16C_DISP08, | |
31627 | + BFD_RELOC_16C_DISP08_C, | |
31628 | + BFD_RELOC_16C_DISP16, | |
31629 | + BFD_RELOC_16C_DISP16_C, | |
31630 | + BFD_RELOC_16C_DISP24, | |
31631 | + BFD_RELOC_16C_DISP24_C, | |
31632 | + BFD_RELOC_16C_DISP24a, | |
31633 | + BFD_RELOC_16C_DISP24a_C, | |
31634 | + BFD_RELOC_16C_REG04, | |
31635 | + BFD_RELOC_16C_REG04_C, | |
31636 | + BFD_RELOC_16C_REG04a, | |
31637 | + BFD_RELOC_16C_REG04a_C, | |
31638 | + BFD_RELOC_16C_REG14, | |
31639 | + BFD_RELOC_16C_REG14_C, | |
31640 | + BFD_RELOC_16C_REG16, | |
31641 | + BFD_RELOC_16C_REG16_C, | |
31642 | + BFD_RELOC_16C_REG20, | |
31643 | + BFD_RELOC_16C_REG20_C, | |
31644 | + BFD_RELOC_16C_ABS20, | |
31645 | + BFD_RELOC_16C_ABS20_C, | |
31646 | + BFD_RELOC_16C_ABS24, | |
31647 | + BFD_RELOC_16C_ABS24_C, | |
31648 | + BFD_RELOC_16C_IMM04, | |
31649 | + BFD_RELOC_16C_IMM04_C, | |
31650 | + BFD_RELOC_16C_IMM16, | |
31651 | + BFD_RELOC_16C_IMM16_C, | |
31652 | + BFD_RELOC_16C_IMM20, | |
31653 | + BFD_RELOC_16C_IMM20_C, | |
31654 | + BFD_RELOC_16C_IMM24, | |
31655 | + BFD_RELOC_16C_IMM24_C, | |
31656 | + BFD_RELOC_16C_IMM32, | |
31657 | + BFD_RELOC_16C_IMM32_C, | |
31658 | + | |
31659 | +/* NS CRX Relocations. */ | |
31660 | + BFD_RELOC_CRX_REL4, | |
31661 | + BFD_RELOC_CRX_REL8, | |
31662 | + BFD_RELOC_CRX_REL8_CMP, | |
31663 | + BFD_RELOC_CRX_REL16, | |
31664 | + BFD_RELOC_CRX_REL24, | |
31665 | + BFD_RELOC_CRX_REL32, | |
31666 | + BFD_RELOC_CRX_REGREL12, | |
31667 | + BFD_RELOC_CRX_REGREL22, | |
31668 | + BFD_RELOC_CRX_REGREL28, | |
31669 | + BFD_RELOC_CRX_REGREL32, | |
31670 | + BFD_RELOC_CRX_ABS16, | |
31671 | + BFD_RELOC_CRX_ABS32, | |
31672 | + BFD_RELOC_CRX_NUM8, | |
31673 | + BFD_RELOC_CRX_NUM16, | |
31674 | + BFD_RELOC_CRX_NUM32, | |
31675 | + BFD_RELOC_CRX_IMM16, | |
31676 | + BFD_RELOC_CRX_IMM32, | |
31677 | + BFD_RELOC_CRX_SWITCH8, | |
31678 | + BFD_RELOC_CRX_SWITCH16, | |
31679 | + BFD_RELOC_CRX_SWITCH32, | |
31680 | + | |
31681 | +/* These relocs are only used within the CRIS assembler. They are not | |
31682 | +(at present) written to any object files. */ | |
31683 | + BFD_RELOC_CRIS_BDISP8, | |
31684 | + BFD_RELOC_CRIS_UNSIGNED_5, | |
31685 | + BFD_RELOC_CRIS_SIGNED_6, | |
31686 | + BFD_RELOC_CRIS_UNSIGNED_6, | |
31687 | + BFD_RELOC_CRIS_SIGNED_8, | |
31688 | + BFD_RELOC_CRIS_UNSIGNED_8, | |
31689 | + BFD_RELOC_CRIS_SIGNED_16, | |
31690 | + BFD_RELOC_CRIS_UNSIGNED_16, | |
31691 | + BFD_RELOC_CRIS_LAPCQ_OFFSET, | |
31692 | + BFD_RELOC_CRIS_UNSIGNED_4, | |
31693 | + | |
31694 | +/* Relocs used in ELF shared libraries for CRIS. */ | |
31695 | + BFD_RELOC_CRIS_COPY, | |
31696 | + BFD_RELOC_CRIS_GLOB_DAT, | |
31697 | + BFD_RELOC_CRIS_JUMP_SLOT, | |
31698 | + BFD_RELOC_CRIS_RELATIVE, | |
31699 | + | |
31700 | +/* 32-bit offset to symbol-entry within GOT. */ | |
31701 | + BFD_RELOC_CRIS_32_GOT, | |
31702 | + | |
31703 | +/* 16-bit offset to symbol-entry within GOT. */ | |
31704 | + BFD_RELOC_CRIS_16_GOT, | |
31705 | + | |
31706 | +/* 32-bit offset to symbol-entry within GOT, with PLT handling. */ | |
31707 | + BFD_RELOC_CRIS_32_GOTPLT, | |
31708 | + | |
31709 | +/* 16-bit offset to symbol-entry within GOT, with PLT handling. */ | |
31710 | + BFD_RELOC_CRIS_16_GOTPLT, | |
31711 | + | |
31712 | +/* 32-bit offset to symbol, relative to GOT. */ | |
31713 | + BFD_RELOC_CRIS_32_GOTREL, | |
31714 | + | |
31715 | +/* 32-bit offset to symbol with PLT entry, relative to GOT. */ | |
31716 | + BFD_RELOC_CRIS_32_PLT_GOTREL, | |
31717 | + | |
31718 | +/* 32-bit offset to symbol with PLT entry, relative to this relocation. */ | |
31719 | + BFD_RELOC_CRIS_32_PLT_PCREL, | |
31720 | + | |
31721 | +/* Intel i860 Relocations. */ | |
31722 | + BFD_RELOC_860_COPY, | |
31723 | + BFD_RELOC_860_GLOB_DAT, | |
31724 | + BFD_RELOC_860_JUMP_SLOT, | |
31725 | + BFD_RELOC_860_RELATIVE, | |
31726 | + BFD_RELOC_860_PC26, | |
31727 | + BFD_RELOC_860_PLT26, | |
31728 | + BFD_RELOC_860_PC16, | |
31729 | + BFD_RELOC_860_LOW0, | |
31730 | + BFD_RELOC_860_SPLIT0, | |
31731 | + BFD_RELOC_860_LOW1, | |
31732 | + BFD_RELOC_860_SPLIT1, | |
31733 | + BFD_RELOC_860_LOW2, | |
31734 | + BFD_RELOC_860_SPLIT2, | |
31735 | + BFD_RELOC_860_LOW3, | |
31736 | + BFD_RELOC_860_LOGOT0, | |
31737 | + BFD_RELOC_860_SPGOT0, | |
31738 | + BFD_RELOC_860_LOGOT1, | |
31739 | + BFD_RELOC_860_SPGOT1, | |
31740 | + BFD_RELOC_860_LOGOTOFF0, | |
31741 | + BFD_RELOC_860_SPGOTOFF0, | |
31742 | + BFD_RELOC_860_LOGOTOFF1, | |
31743 | + BFD_RELOC_860_SPGOTOFF1, | |
31744 | + BFD_RELOC_860_LOGOTOFF2, | |
31745 | + BFD_RELOC_860_LOGOTOFF3, | |
31746 | + BFD_RELOC_860_LOPC, | |
31747 | + BFD_RELOC_860_HIGHADJ, | |
31748 | + BFD_RELOC_860_HAGOT, | |
31749 | + BFD_RELOC_860_HAGOTOFF, | |
31750 | + BFD_RELOC_860_HAPC, | |
31751 | + BFD_RELOC_860_HIGH, | |
31752 | + BFD_RELOC_860_HIGOT, | |
31753 | + BFD_RELOC_860_HIGOTOFF, | |
31754 | + | |
31755 | +/* OpenRISC Relocations. */ | |
31756 | + BFD_RELOC_OPENRISC_ABS_26, | |
31757 | + BFD_RELOC_OPENRISC_REL_26, | |
31758 | + | |
31759 | +/* H8 elf Relocations. */ | |
31760 | + BFD_RELOC_H8_DIR16A8, | |
31761 | + BFD_RELOC_H8_DIR16R8, | |
31762 | + BFD_RELOC_H8_DIR24A8, | |
31763 | + BFD_RELOC_H8_DIR24R8, | |
31764 | + BFD_RELOC_H8_DIR32A16, | |
31765 | + | |
31766 | +/* Sony Xstormy16 Relocations. */ | |
31767 | + BFD_RELOC_XSTORMY16_REL_12, | |
31768 | + BFD_RELOC_XSTORMY16_12, | |
31769 | + BFD_RELOC_XSTORMY16_24, | |
31770 | + BFD_RELOC_XSTORMY16_FPTR16, | |
31771 | + | |
31772 | +/* Relocations used by VAX ELF. */ | |
31773 | + BFD_RELOC_VAX_GLOB_DAT, | |
31774 | + BFD_RELOC_VAX_JMP_SLOT, | |
31775 | + BFD_RELOC_VAX_RELATIVE, | |
31776 | + | |
31777 | +/* Morpho MS1 - 16 bit immediate relocation. */ | |
31778 | + BFD_RELOC_MS1_PC16, | |
31779 | + | |
31780 | +/* Morpho MS1 - Hi 16 bits of an address. */ | |
31781 | + BFD_RELOC_MS1_HI16, | |
31782 | + | |
31783 | +/* Morpho MS1 - Low 16 bits of an address. */ | |
31784 | + BFD_RELOC_MS1_LO16, | |
31785 | + | |
31786 | +/* Morpho MS1 - Used to tell the linker which vtable entries are used. */ | |
31787 | + BFD_RELOC_MS1_GNU_VTINHERIT, | |
31788 | + | |
31789 | +/* Morpho MS1 - Used to tell the linker which vtable entries are used. */ | |
31790 | + BFD_RELOC_MS1_GNU_VTENTRY, | |
31791 | + | |
31792 | +/* msp430 specific relocation codes */ | |
31793 | + BFD_RELOC_MSP430_10_PCREL, | |
31794 | + BFD_RELOC_MSP430_16_PCREL, | |
31795 | + BFD_RELOC_MSP430_16, | |
31796 | + BFD_RELOC_MSP430_16_PCREL_BYTE, | |
31797 | + BFD_RELOC_MSP430_16_BYTE, | |
31798 | + BFD_RELOC_MSP430_2X_PCREL, | |
31799 | + BFD_RELOC_MSP430_RL_PCREL, | |
31800 | + | |
31801 | +/* IQ2000 Relocations. */ | |
31802 | + BFD_RELOC_IQ2000_OFFSET_16, | |
31803 | + BFD_RELOC_IQ2000_OFFSET_21, | |
31804 | + BFD_RELOC_IQ2000_UHI16, | |
31805 | + | |
31806 | +/* Special Xtensa relocation used only by PLT entries in ELF shared | |
31807 | +objects to indicate that the runtime linker should set the value | |
31808 | +to one of its own internal functions or data structures. */ | |
31809 | + BFD_RELOC_XTENSA_RTLD, | |
31810 | + | |
31811 | +/* Xtensa relocations for ELF shared objects. */ | |
31812 | + BFD_RELOC_XTENSA_GLOB_DAT, | |
31813 | + BFD_RELOC_XTENSA_JMP_SLOT, | |
31814 | + BFD_RELOC_XTENSA_RELATIVE, | |
31815 | + | |
31816 | +/* Xtensa relocation used in ELF object files for symbols that may require | |
31817 | +PLT entries. Otherwise, this is just a generic 32-bit relocation. */ | |
31818 | + BFD_RELOC_XTENSA_PLT, | |
31819 | + | |
31820 | +/* Xtensa relocations to mark the difference of two local symbols. | |
31821 | +These are only needed to support linker relaxation and can be ignored | |
31822 | +when not relaxing. The field is set to the value of the difference | |
31823 | +assuming no relaxation. The relocation encodes the position of the | |
31824 | +first symbol so the linker can determine whether to adjust the field | |
31825 | +value. */ | |
31826 | + BFD_RELOC_XTENSA_DIFF8, | |
31827 | + BFD_RELOC_XTENSA_DIFF16, | |
31828 | + BFD_RELOC_XTENSA_DIFF32, | |
31829 | + | |
31830 | +/* Generic Xtensa relocations for instruction operands. Only the slot | |
31831 | +number is encoded in the relocation. The relocation applies to the | |
31832 | +last PC-relative immediate operand, or if there are no PC-relative | |
31833 | +immediates, to the last immediate operand. */ | |
31834 | + BFD_RELOC_XTENSA_SLOT0_OP, | |
31835 | + BFD_RELOC_XTENSA_SLOT1_OP, | |
31836 | + BFD_RELOC_XTENSA_SLOT2_OP, | |
31837 | + BFD_RELOC_XTENSA_SLOT3_OP, | |
31838 | + BFD_RELOC_XTENSA_SLOT4_OP, | |
31839 | + BFD_RELOC_XTENSA_SLOT5_OP, | |
31840 | + BFD_RELOC_XTENSA_SLOT6_OP, | |
31841 | + BFD_RELOC_XTENSA_SLOT7_OP, | |
31842 | + BFD_RELOC_XTENSA_SLOT8_OP, | |
31843 | + BFD_RELOC_XTENSA_SLOT9_OP, | |
31844 | + BFD_RELOC_XTENSA_SLOT10_OP, | |
31845 | + BFD_RELOC_XTENSA_SLOT11_OP, | |
31846 | + BFD_RELOC_XTENSA_SLOT12_OP, | |
31847 | + BFD_RELOC_XTENSA_SLOT13_OP, | |
31848 | + BFD_RELOC_XTENSA_SLOT14_OP, | |
31849 | + | |
31850 | +/* Alternate Xtensa relocations. Only the slot is encoded in the | |
31851 | +relocation. The meaning of these relocations is opcode-specific. */ | |
31852 | + BFD_RELOC_XTENSA_SLOT0_ALT, | |
31853 | + BFD_RELOC_XTENSA_SLOT1_ALT, | |
31854 | + BFD_RELOC_XTENSA_SLOT2_ALT, | |
31855 | + BFD_RELOC_XTENSA_SLOT3_ALT, | |
31856 | + BFD_RELOC_XTENSA_SLOT4_ALT, | |
31857 | + BFD_RELOC_XTENSA_SLOT5_ALT, | |
31858 | + BFD_RELOC_XTENSA_SLOT6_ALT, | |
31859 | + BFD_RELOC_XTENSA_SLOT7_ALT, | |
31860 | + BFD_RELOC_XTENSA_SLOT8_ALT, | |
31861 | + BFD_RELOC_XTENSA_SLOT9_ALT, | |
31862 | + BFD_RELOC_XTENSA_SLOT10_ALT, | |
31863 | + BFD_RELOC_XTENSA_SLOT11_ALT, | |
31864 | + BFD_RELOC_XTENSA_SLOT12_ALT, | |
31865 | + BFD_RELOC_XTENSA_SLOT13_ALT, | |
31866 | + BFD_RELOC_XTENSA_SLOT14_ALT, | |
31867 | + | |
31868 | +/* Xtensa relocations for backward compatibility. These have all been | |
31869 | +replaced by BFD_RELOC_XTENSA_SLOT0_OP. */ | |
31870 | + BFD_RELOC_XTENSA_OP0, | |
31871 | + BFD_RELOC_XTENSA_OP1, | |
31872 | + BFD_RELOC_XTENSA_OP2, | |
31873 | + | |
31874 | +/* Xtensa relocation to mark that the assembler expanded the | |
31875 | +instructions from an original target. The expansion size is | |
31876 | +encoded in the reloc size. */ | |
31877 | + BFD_RELOC_XTENSA_ASM_EXPAND, | |
31878 | + | |
31879 | +/* Xtensa relocation to mark that the linker should simplify | |
31880 | +assembler-expanded instructions. This is commonly used | |
31881 | +internally by the linker after analysis of a | |
31882 | +BFD_RELOC_XTENSA_ASM_EXPAND. */ | |
31883 | + BFD_RELOC_XTENSA_ASM_SIMPLIFY, | |
31884 | + BFD_RELOC_UNUSED }; | |
31885 | +typedef enum bfd_reloc_code_real bfd_reloc_code_real_type; | |
31886 | +reloc_howto_type *bfd_reloc_type_lookup | |
31887 | + (bfd *abfd, bfd_reloc_code_real_type code); | |
31888 | + | |
31889 | +const char *bfd_get_reloc_code_name (bfd_reloc_code_real_type code); | |
31890 | + | |
31891 | +/* Extracted from syms.c. */ | |
31892 | + | |
31893 | +typedef struct bfd_symbol | |
31894 | +{ | |
31895 | + /* A pointer to the BFD which owns the symbol. This information | |
31896 | + is necessary so that a back end can work out what additional | |
31897 | + information (invisible to the application writer) is carried | |
31898 | + with the symbol. | |
31899 | + | |
31900 | + This field is *almost* redundant, since you can use section->owner | |
31901 | + instead, except that some symbols point to the global sections | |
31902 | + bfd_{abs,com,und}_section. This could be fixed by making | |
31903 | + these globals be per-bfd (or per-target-flavor). FIXME. */ | |
31904 | + struct bfd *the_bfd; /* Use bfd_asymbol_bfd(sym) to access this field. */ | |
31905 | + | |
31906 | + /* The text of the symbol. The name is left alone, and not copied; the | |
31907 | + application may not alter it. */ | |
31908 | + const char *name; | |
31909 | + | |
31910 | + /* The value of the symbol. This really should be a union of a | |
31911 | + numeric value with a pointer, since some flags indicate that | |
31912 | + a pointer to another symbol is stored here. */ | |
31913 | + symvalue value; | |
31914 | + | |
31915 | + /* Attributes of a symbol. */ | |
31916 | +#define BSF_NO_FLAGS 0x00 | |
31917 | + | |
31918 | + /* The symbol has local scope; <<static>> in <<C>>. The value | |
31919 | + is the offset into the section of the data. */ | |
31920 | +#define BSF_LOCAL 0x01 | |
31921 | + | |
31922 | + /* The symbol has global scope; initialized data in <<C>>. The | |
31923 | + value is the offset into the section of the data. */ | |
31924 | +#define BSF_GLOBAL 0x02 | |
31925 | + | |
31926 | + /* The symbol has global scope and is exported. The value is | |
31927 | + the offset into the section of the data. */ | |
31928 | +#define BSF_EXPORT BSF_GLOBAL /* No real difference. */ | |
31929 | + | |
31930 | + /* A normal C symbol would be one of: | |
31931 | + <<BSF_LOCAL>>, <<BSF_FORT_COMM>>, <<BSF_UNDEFINED>> or | |
31932 | + <<BSF_GLOBAL>>. */ | |
31933 | + | |
31934 | + /* The symbol is a debugging record. The value has an arbitrary | |
31935 | + meaning, unless BSF_DEBUGGING_RELOC is also set. */ | |
31936 | +#define BSF_DEBUGGING 0x08 | |
31937 | + | |
31938 | + /* The symbol denotes a function entry point. Used in ELF, | |
31939 | + perhaps others someday. */ | |
31940 | +#define BSF_FUNCTION 0x10 | |
31941 | + | |
31942 | + /* Used by the linker. */ | |
31943 | +#define BSF_KEEP 0x20 | |
31944 | +#define BSF_KEEP_G 0x40 | |
31945 | + | |
31946 | + /* A weak global symbol, overridable without warnings by | |
31947 | + a regular global symbol of the same name. */ | |
31948 | +#define BSF_WEAK 0x80 | |
31949 | + | |
31950 | + /* This symbol was created to point to a section, e.g. ELF's | |
31951 | + STT_SECTION symbols. */ | |
31952 | +#define BSF_SECTION_SYM 0x100 | |
31953 | + | |
31954 | + /* The symbol used to be a common symbol, but now it is | |
31955 | + allocated. */ | |
31956 | +#define BSF_OLD_COMMON 0x200 | |
31957 | + | |
31958 | + /* The default value for common data. */ | |
31959 | +#define BFD_FORT_COMM_DEFAULT_VALUE 0 | |
31960 | + | |
31961 | + /* In some files the type of a symbol sometimes alters its | |
31962 | + location in an output file - ie in coff a <<ISFCN>> symbol | |
31963 | + which is also <<C_EXT>> symbol appears where it was | |
31964 | + declared and not at the end of a section. This bit is set | |
31965 | + by the target BFD part to convey this information. */ | |
31966 | +#define BSF_NOT_AT_END 0x400 | |
31967 | + | |
31968 | + /* Signal that the symbol is the label of constructor section. */ | |
31969 | +#define BSF_CONSTRUCTOR 0x800 | |
31970 | + | |
31971 | + /* Signal that the symbol is a warning symbol. The name is a | |
31972 | + warning. The name of the next symbol is the one to warn about; | |
31973 | + if a reference is made to a symbol with the same name as the next | |
31974 | + symbol, a warning is issued by the linker. */ | |
31975 | +#define BSF_WARNING 0x1000 | |
31976 | + | |
31977 | + /* Signal that the symbol is indirect. This symbol is an indirect | |
31978 | + pointer to the symbol with the same name as the next symbol. */ | |
31979 | +#define BSF_INDIRECT 0x2000 | |
31980 | + | |
31981 | + /* BSF_FILE marks symbols that contain a file name. This is used | |
31982 | + for ELF STT_FILE symbols. */ | |
31983 | +#define BSF_FILE 0x4000 | |
31984 | + | |
31985 | + /* Symbol is from dynamic linking information. */ | |
31986 | +#define BSF_DYNAMIC 0x8000 | |
31987 | + | |
31988 | + /* The symbol denotes a data object. Used in ELF, and perhaps | |
31989 | + others someday. */ | |
31990 | +#define BSF_OBJECT 0x10000 | |
31991 | + | |
31992 | + /* This symbol is a debugging symbol. The value is the offset | |
31993 | + into the section of the data. BSF_DEBUGGING should be set | |
31994 | + as well. */ | |
31995 | +#define BSF_DEBUGGING_RELOC 0x20000 | |
31996 | + | |
31997 | + /* This symbol is thread local. Used in ELF. */ | |
31998 | +#define BSF_THREAD_LOCAL 0x40000 | |
31999 | + | |
32000 | + flagword flags; | |
32001 | + | |
32002 | + /* A pointer to the section to which this symbol is | |
32003 | + relative. This will always be non NULL, there are special | |
32004 | + sections for undefined and absolute symbols. */ | |
32005 | + struct bfd_section *section; | |
32006 | + | |
32007 | + /* Back end special data. */ | |
32008 | + union | |
32009 | + { | |
32010 | + void *p; | |
32011 | + bfd_vma i; | |
32012 | + } | |
32013 | + udata; | |
32014 | +} | |
32015 | +asymbol; | |
32016 | + | |
32017 | +#define bfd_get_symtab_upper_bound(abfd) \ | |
32018 | + BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd)) | |
32019 | + | |
32020 | +bfd_boolean bfd_is_local_label (bfd *abfd, asymbol *sym); | |
32021 | + | |
32022 | +bfd_boolean bfd_is_local_label_name (bfd *abfd, const char *name); | |
32023 | + | |
32024 | +#define bfd_is_local_label_name(abfd, name) \ | |
32025 | + BFD_SEND (abfd, _bfd_is_local_label_name, (abfd, name)) | |
32026 | + | |
32027 | +bfd_boolean bfd_is_target_special_symbol (bfd *abfd, asymbol *sym); | |
32028 | + | |
32029 | +#define bfd_is_target_special_symbol(abfd, sym) \ | |
32030 | + BFD_SEND (abfd, _bfd_is_target_special_symbol, (abfd, sym)) | |
32031 | + | |
32032 | +#define bfd_canonicalize_symtab(abfd, location) \ | |
32033 | + BFD_SEND (abfd, _bfd_canonicalize_symtab, (abfd, location)) | |
32034 | + | |
32035 | +bfd_boolean bfd_set_symtab | |
32036 | + (bfd *abfd, asymbol **location, unsigned int count); | |
32037 | + | |
32038 | +void bfd_print_symbol_vandf (bfd *abfd, void *file, asymbol *symbol); | |
32039 | + | |
32040 | +#define bfd_make_empty_symbol(abfd) \ | |
32041 | + BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd)) | |
32042 | + | |
32043 | +asymbol *_bfd_generic_make_empty_symbol (bfd *); | |
32044 | + | |
32045 | +#define bfd_make_debug_symbol(abfd,ptr,size) \ | |
32046 | + BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size)) | |
32047 | + | |
32048 | +int bfd_decode_symclass (asymbol *symbol); | |
32049 | + | |
32050 | +bfd_boolean bfd_is_undefined_symclass (int symclass); | |
32051 | + | |
32052 | +void bfd_symbol_info (asymbol *symbol, symbol_info *ret); | |
32053 | + | |
32054 | +bfd_boolean bfd_copy_private_symbol_data | |
32055 | + (bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym); | |
32056 | + | |
32057 | +#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \ | |
32058 | + BFD_SEND (obfd, _bfd_copy_private_symbol_data, \ | |
32059 | + (ibfd, isymbol, obfd, osymbol)) | |
32060 | + | |
32061 | +/* Extracted from bfd.c. */ | |
32062 | +struct bfd | |
32063 | +{ | |
32064 | + /* A unique identifier of the BFD */ | |
32065 | + unsigned int id; | |
32066 | + | |
32067 | + /* The filename the application opened the BFD with. */ | |
32068 | + const char *filename; | |
32069 | + | |
32070 | + /* A pointer to the target jump table. */ | |
32071 | + const struct bfd_target *xvec; | |
32072 | + | |
32073 | + /* The IOSTREAM, and corresponding IO vector that provide access | |
32074 | + to the file backing the BFD. */ | |
32075 | + void *iostream; | |
32076 | + const struct bfd_iovec *iovec; | |
32077 | + | |
32078 | + /* Is the file descriptor being cached? That is, can it be closed as | |
32079 | + needed, and re-opened when accessed later? */ | |
32080 | + bfd_boolean cacheable; | |
32081 | + | |
32082 | + /* Marks whether there was a default target specified when the | |
32083 | + BFD was opened. This is used to select which matching algorithm | |
32084 | + to use to choose the back end. */ | |
32085 | + bfd_boolean target_defaulted; | |
32086 | + | |
32087 | + /* The caching routines use these to maintain a | |
32088 | + least-recently-used list of BFDs. */ | |
32089 | + struct bfd *lru_prev, *lru_next; | |
32090 | + | |
32091 | + /* When a file is closed by the caching routines, BFD retains | |
32092 | + state information on the file here... */ | |
32093 | + ufile_ptr where; | |
32094 | + | |
32095 | + /* ... and here: (``once'' means at least once). */ | |
32096 | + bfd_boolean opened_once; | |
32097 | + | |
32098 | + /* Set if we have a locally maintained mtime value, rather than | |
32099 | + getting it from the file each time. */ | |
32100 | + bfd_boolean mtime_set; | |
32101 | + | |
32102 | + /* File modified time, if mtime_set is TRUE. */ | |
32103 | + long mtime; | |
32104 | + | |
32105 | + /* Reserved for an unimplemented file locking extension. */ | |
32106 | + int ifd; | |
32107 | + | |
32108 | + /* The format which belongs to the BFD. (object, core, etc.) */ | |
32109 | + bfd_format format; | |
32110 | + | |
32111 | + /* The direction with which the BFD was opened. */ | |
32112 | + enum bfd_direction | |
32113 | + { | |
32114 | + no_direction = 0, | |
32115 | + read_direction = 1, | |
32116 | + write_direction = 2, | |
32117 | + both_direction = 3 | |
32118 | + } | |
32119 | + direction; | |
32120 | + | |
32121 | + /* Format_specific flags. */ | |
32122 | + flagword flags; | |
32123 | + | |
32124 | + /* Currently my_archive is tested before adding origin to | |
32125 | + anything. I believe that this can become always an add of | |
32126 | + origin, with origin set to 0 for non archive files. */ | |
32127 | + ufile_ptr origin; | |
32128 | + | |
32129 | + /* Remember when output has begun, to stop strange things | |
32130 | + from happening. */ | |
32131 | + bfd_boolean output_has_begun; | |
32132 | + | |
32133 | + /* A hash table for section names. */ | |
32134 | + struct bfd_hash_table section_htab; | |
32135 | + | |
32136 | + /* Pointer to linked list of sections. */ | |
32137 | + struct bfd_section *sections; | |
32138 | + | |
32139 | + /* The last section on the section list. */ | |
32140 | + struct bfd_section *section_last; | |
32141 | + | |
32142 | + /* The number of sections. */ | |
32143 | + unsigned int section_count; | |
32144 | + | |
32145 | + /* Stuff only useful for object files: | |
32146 | + The start address. */ | |
32147 | + bfd_vma start_address; | |
32148 | + | |
32149 | + /* Used for input and output. */ | |
32150 | + unsigned int symcount; | |
32151 | + | |
32152 | + /* Symbol table for output BFD (with symcount entries). */ | |
32153 | + struct bfd_symbol **outsymbols; | |
32154 | + | |
32155 | + /* Used for slurped dynamic symbol tables. */ | |
32156 | + unsigned int dynsymcount; | |
32157 | + | |
32158 | + /* Pointer to structure which contains architecture information. */ | |
32159 | + const struct bfd_arch_info *arch_info; | |
32160 | + | |
32161 | + /* Flag set if symbols from this BFD should not be exported. */ | |
32162 | + bfd_boolean no_export; | |
32163 | + | |
32164 | + /* Stuff only useful for archives. */ | |
32165 | + void *arelt_data; | |
32166 | + struct bfd *my_archive; /* The containing archive BFD. */ | |
32167 | + struct bfd *next; /* The next BFD in the archive. */ | |
32168 | + struct bfd *archive_head; /* The first BFD in the archive. */ | |
32169 | + bfd_boolean has_armap; | |
32170 | + | |
32171 | + /* A chain of BFD structures involved in a link. */ | |
32172 | + struct bfd *link_next; | |
32173 | + | |
32174 | + /* A field used by _bfd_generic_link_add_archive_symbols. This will | |
32175 | + be used only for archive elements. */ | |
32176 | + int archive_pass; | |
32177 | + | |
32178 | + /* Used by the back end to hold private data. */ | |
32179 | + union | |
32180 | + { | |
32181 | + struct aout_data_struct *aout_data; | |
32182 | + struct artdata *aout_ar_data; | |
32183 | + struct _oasys_data *oasys_obj_data; | |
32184 | + struct _oasys_ar_data *oasys_ar_data; | |
32185 | + struct coff_tdata *coff_obj_data; | |
32186 | + struct pe_tdata *pe_obj_data; | |
32187 | + struct xcoff_tdata *xcoff_obj_data; | |
32188 | + struct ecoff_tdata *ecoff_obj_data; | |
32189 | + struct ieee_data_struct *ieee_data; | |
32190 | + struct ieee_ar_data_struct *ieee_ar_data; | |
32191 | + struct srec_data_struct *srec_data; | |
32192 | + struct ihex_data_struct *ihex_data; | |
32193 | + struct tekhex_data_struct *tekhex_data; | |
32194 | + struct elf_obj_tdata *elf_obj_data; | |
32195 | + struct nlm_obj_tdata *nlm_obj_data; | |
32196 | + struct bout_data_struct *bout_data; | |
32197 | + struct mmo_data_struct *mmo_data; | |
32198 | + struct sun_core_struct *sun_core_data; | |
32199 | + struct sco5_core_struct *sco5_core_data; | |
32200 | + struct trad_core_struct *trad_core_data; | |
32201 | + struct som_data_struct *som_data; | |
32202 | + struct hpux_core_struct *hpux_core_data; | |
32203 | + struct hppabsd_core_struct *hppabsd_core_data; | |
32204 | + struct sgi_core_struct *sgi_core_data; | |
32205 | + struct lynx_core_struct *lynx_core_data; | |
32206 | + struct osf_core_struct *osf_core_data; | |
32207 | + struct cisco_core_struct *cisco_core_data; | |
32208 | + struct versados_data_struct *versados_data; | |
32209 | + struct netbsd_core_struct *netbsd_core_data; | |
32210 | + struct mach_o_data_struct *mach_o_data; | |
32211 | + struct mach_o_fat_data_struct *mach_o_fat_data; | |
32212 | + struct bfd_pef_data_struct *pef_data; | |
32213 | + struct bfd_pef_xlib_data_struct *pef_xlib_data; | |
32214 | + struct bfd_sym_data_struct *sym_data; | |
32215 | + void *any; | |
32216 | + } | |
32217 | + tdata; | |
32218 | + | |
32219 | + /* Used by the application to hold private data. */ | |
32220 | + void *usrdata; | |
32221 | + | |
32222 | + /* Where all the allocated stuff under this BFD goes. This is a | |
32223 | + struct objalloc *, but we use void * to avoid requiring the inclusion | |
32224 | + of objalloc.h. */ | |
32225 | + void *memory; | |
32226 | +}; | |
32227 | + | |
32228 | +typedef enum bfd_error | |
32229 | +{ | |
32230 | + bfd_error_no_error = 0, | |
32231 | + bfd_error_system_call, | |
32232 | + bfd_error_invalid_target, | |
32233 | + bfd_error_wrong_format, | |
32234 | + bfd_error_wrong_object_format, | |
32235 | + bfd_error_invalid_operation, | |
32236 | + bfd_error_no_memory, | |
32237 | + bfd_error_no_symbols, | |
32238 | + bfd_error_no_armap, | |
32239 | + bfd_error_no_more_archived_files, | |
32240 | + bfd_error_malformed_archive, | |
32241 | + bfd_error_file_not_recognized, | |
32242 | + bfd_error_file_ambiguously_recognized, | |
32243 | + bfd_error_no_contents, | |
32244 | + bfd_error_nonrepresentable_section, | |
32245 | + bfd_error_no_debug_section, | |
32246 | + bfd_error_bad_value, | |
32247 | + bfd_error_file_truncated, | |
32248 | + bfd_error_file_too_big, | |
32249 | + bfd_error_invalid_error_code | |
32250 | +} | |
32251 | +bfd_error_type; | |
32252 | + | |
32253 | +bfd_error_type bfd_get_error (void); | |
32254 | + | |
32255 | +void bfd_set_error (bfd_error_type error_tag); | |
32256 | + | |
32257 | +const char *bfd_errmsg (bfd_error_type error_tag); | |
32258 | + | |
32259 | +void bfd_perror (const char *message); | |
32260 | + | |
32261 | +typedef void (*bfd_error_handler_type) (const char *, ...); | |
32262 | + | |
32263 | +bfd_error_handler_type bfd_set_error_handler (bfd_error_handler_type); | |
32264 | + | |
32265 | +void bfd_set_error_program_name (const char *); | |
32266 | + | |
32267 | +bfd_error_handler_type bfd_get_error_handler (void); | |
32268 | + | |
32269 | +long bfd_get_reloc_upper_bound (bfd *abfd, asection *sect); | |
32270 | + | |
32271 | +long bfd_canonicalize_reloc | |
32272 | + (bfd *abfd, asection *sec, arelent **loc, asymbol **syms); | |
32273 | + | |
32274 | +void bfd_set_reloc | |
32275 | + (bfd *abfd, asection *sec, arelent **rel, unsigned int count); | |
32276 | + | |
32277 | +bfd_boolean bfd_set_file_flags (bfd *abfd, flagword flags); | |
32278 | + | |
32279 | +int bfd_get_arch_size (bfd *abfd); | |
32280 | + | |
32281 | +int bfd_get_sign_extend_vma (bfd *abfd); | |
32282 | + | |
32283 | +bfd_boolean bfd_set_start_address (bfd *abfd, bfd_vma vma); | |
32284 | + | |
32285 | +unsigned int bfd_get_gp_size (bfd *abfd); | |
32286 | + | |
32287 | +void bfd_set_gp_size (bfd *abfd, unsigned int i); | |
32288 | + | |
32289 | +bfd_vma bfd_scan_vma (const char *string, const char **end, int base); | |
32290 | + | |
32291 | +bfd_boolean bfd_copy_private_header_data (bfd *ibfd, bfd *obfd); | |
32292 | + | |
32293 | +#define bfd_copy_private_header_data(ibfd, obfd) \ | |
32294 | + BFD_SEND (obfd, _bfd_copy_private_header_data, \ | |
32295 | + (ibfd, obfd)) | |
32296 | +bfd_boolean bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd); | |
32297 | + | |
32298 | +#define bfd_copy_private_bfd_data(ibfd, obfd) \ | |
32299 | + BFD_SEND (obfd, _bfd_copy_private_bfd_data, \ | |
32300 | + (ibfd, obfd)) | |
32301 | +bfd_boolean bfd_merge_private_bfd_data (bfd *ibfd, bfd *obfd); | |
32302 | + | |
32303 | +#define bfd_merge_private_bfd_data(ibfd, obfd) \ | |
32304 | + BFD_SEND (obfd, _bfd_merge_private_bfd_data, \ | |
32305 | + (ibfd, obfd)) | |
32306 | +bfd_boolean bfd_set_private_flags (bfd *abfd, flagword flags); | |
32307 | + | |
32308 | +#define bfd_set_private_flags(abfd, flags) \ | |
32309 | + BFD_SEND (abfd, _bfd_set_private_flags, (abfd, flags)) | |
32310 | +#define bfd_sizeof_headers(abfd, reloc) \ | |
32311 | + BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc)) | |
32312 | + | |
32313 | +#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \ | |
32314 | + BFD_SEND (abfd, _bfd_find_nearest_line, \ | |
32315 | + (abfd, sec, syms, off, file, func, line)) | |
32316 | + | |
32317 | +#define bfd_find_line(abfd, syms, sym, file, line) \ | |
32318 | + BFD_SEND (abfd, _bfd_find_line, \ | |
32319 | + (abfd, syms, sym, file, line)) | |
32320 | + | |
32321 | +#define bfd_find_inliner_info(abfd, file, func, line) \ | |
32322 | + BFD_SEND (abfd, _bfd_find_inliner_info, \ | |
32323 | + (abfd, file, func, line)) | |
32324 | + | |
32325 | +#define bfd_debug_info_start(abfd) \ | |
32326 | + BFD_SEND (abfd, _bfd_debug_info_start, (abfd)) | |
32327 | + | |
32328 | +#define bfd_debug_info_end(abfd) \ | |
32329 | + BFD_SEND (abfd, _bfd_debug_info_end, (abfd)) | |
32330 | + | |
32331 | +#define bfd_debug_info_accumulate(abfd, section) \ | |
32332 | + BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section)) | |
32333 | + | |
32334 | +#define bfd_stat_arch_elt(abfd, stat) \ | |
32335 | + BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat)) | |
32336 | + | |
32337 | +#define bfd_update_armap_timestamp(abfd) \ | |
32338 | + BFD_SEND (abfd, _bfd_update_armap_timestamp, (abfd)) | |
32339 | + | |
32340 | +#define bfd_set_arch_mach(abfd, arch, mach)\ | |
32341 | + BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach)) | |
32342 | + | |
32343 | +#define bfd_relax_section(abfd, section, link_info, again) \ | |
32344 | + BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again)) | |
32345 | + | |
32346 | +#define bfd_gc_sections(abfd, link_info) \ | |
32347 | + BFD_SEND (abfd, _bfd_gc_sections, (abfd, link_info)) | |
32348 | + | |
32349 | +#define bfd_merge_sections(abfd, link_info) \ | |
32350 | + BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info)) | |
32351 | + | |
32352 | +#define bfd_is_group_section(abfd, sec) \ | |
32353 | + BFD_SEND (abfd, _bfd_is_group_section, (abfd, sec)) | |
32354 | + | |
32355 | +#define bfd_discard_group(abfd, sec) \ | |
32356 | + BFD_SEND (abfd, _bfd_discard_group, (abfd, sec)) | |
32357 | + | |
32358 | +#define bfd_link_hash_table_create(abfd) \ | |
32359 | + BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd)) | |
32360 | + | |
32361 | +#define bfd_link_hash_table_free(abfd, hash) \ | |
32362 | + BFD_SEND (abfd, _bfd_link_hash_table_free, (hash)) | |
32363 | + | |
32364 | +#define bfd_link_add_symbols(abfd, info) \ | |
32365 | + BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info)) | |
32366 | + | |
32367 | +#define bfd_link_just_syms(abfd, sec, info) \ | |
32368 | + BFD_SEND (abfd, _bfd_link_just_syms, (sec, info)) | |
32369 | + | |
32370 | +#define bfd_final_link(abfd, info) \ | |
32371 | + BFD_SEND (abfd, _bfd_final_link, (abfd, info)) | |
32372 | + | |
32373 | +#define bfd_free_cached_info(abfd) \ | |
32374 | + BFD_SEND (abfd, _bfd_free_cached_info, (abfd)) | |
32375 | + | |
32376 | +#define bfd_get_dynamic_symtab_upper_bound(abfd) \ | |
32377 | + BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd)) | |
32378 | + | |
32379 | +#define bfd_print_private_bfd_data(abfd, file)\ | |
32380 | + BFD_SEND (abfd, _bfd_print_private_bfd_data, (abfd, file)) | |
32381 | + | |
32382 | +#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \ | |
32383 | + BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols)) | |
32384 | + | |
32385 | +#define bfd_get_synthetic_symtab(abfd, count, syms, dyncount, dynsyms, ret) \ | |
32386 | + BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, count, syms, \ | |
32387 | + dyncount, dynsyms, ret)) | |
32388 | + | |
32389 | +#define bfd_get_dynamic_reloc_upper_bound(abfd) \ | |
32390 | + BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd)) | |
32391 | + | |
32392 | +#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \ | |
32393 | + BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms)) | |
32394 | + | |
32395 | +extern bfd_byte *bfd_get_relocated_section_contents | |
32396 | + (bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *, | |
32397 | + bfd_boolean, asymbol **); | |
32398 | + | |
32399 | +bfd_boolean bfd_alt_mach_code (bfd *abfd, int alternative); | |
32400 | + | |
32401 | +struct bfd_preserve | |
32402 | +{ | |
32403 | + void *marker; | |
32404 | + void *tdata; | |
32405 | + flagword flags; | |
32406 | + const struct bfd_arch_info *arch_info; | |
32407 | + struct bfd_section *sections; | |
32408 | + struct bfd_section *section_last; | |
32409 | + unsigned int section_count; | |
32410 | + struct bfd_hash_table section_htab; | |
32411 | +}; | |
32412 | + | |
32413 | +bfd_boolean bfd_preserve_save (bfd *, struct bfd_preserve *); | |
32414 | + | |
32415 | +void bfd_preserve_restore (bfd *, struct bfd_preserve *); | |
32416 | + | |
32417 | +void bfd_preserve_finish (bfd *, struct bfd_preserve *); | |
32418 | + | |
32419 | +/* Extracted from archive.c. */ | |
32420 | +symindex bfd_get_next_mapent | |
32421 | + (bfd *abfd, symindex previous, carsym **sym); | |
32422 | + | |
32423 | +bfd_boolean bfd_set_archive_head (bfd *output, bfd *new_head); | |
32424 | + | |
32425 | +bfd *bfd_openr_next_archived_file (bfd *archive, bfd *previous); | |
32426 | + | |
32427 | +/* Extracted from corefile.c. */ | |
32428 | +const char *bfd_core_file_failing_command (bfd *abfd); | |
32429 | + | |
32430 | +int bfd_core_file_failing_signal (bfd *abfd); | |
32431 | + | |
32432 | +bfd_boolean core_file_matches_executable_p | |
32433 | + (bfd *core_bfd, bfd *exec_bfd); | |
32434 | + | |
32435 | +/* Extracted from targets.c. */ | |
32436 | +#define BFD_SEND(bfd, message, arglist) \ | |
32437 | + ((*((bfd)->xvec->message)) arglist) | |
32438 | + | |
32439 | +#ifdef DEBUG_BFD_SEND | |
32440 | +#undef BFD_SEND | |
32441 | +#define BFD_SEND(bfd, message, arglist) \ | |
32442 | + (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ | |
32443 | + ((*((bfd)->xvec->message)) arglist) : \ | |
32444 | + (bfd_assert (__FILE__,__LINE__), NULL)) | |
32445 | +#endif | |
32446 | +#define BFD_SEND_FMT(bfd, message, arglist) \ | |
32447 | + (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist) | |
32448 | + | |
32449 | +#ifdef DEBUG_BFD_SEND | |
32450 | +#undef BFD_SEND_FMT | |
32451 | +#define BFD_SEND_FMT(bfd, message, arglist) \ | |
32452 | + (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ | |
32453 | + (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist) : \ | |
32454 | + (bfd_assert (__FILE__,__LINE__), NULL)) | |
32455 | +#endif | |
32456 | + | |
32457 | +enum bfd_flavour | |
32458 | +{ | |
32459 | + bfd_target_unknown_flavour, | |
32460 | + bfd_target_aout_flavour, | |
32461 | + bfd_target_coff_flavour, | |
32462 | + bfd_target_ecoff_flavour, | |
32463 | + bfd_target_xcoff_flavour, | |
32464 | + bfd_target_elf_flavour, | |
32465 | + bfd_target_ieee_flavour, | |
32466 | + bfd_target_nlm_flavour, | |
32467 | + bfd_target_oasys_flavour, | |
32468 | + bfd_target_tekhex_flavour, | |
32469 | + bfd_target_srec_flavour, | |
32470 | + bfd_target_ihex_flavour, | |
32471 | + bfd_target_som_flavour, | |
32472 | + bfd_target_os9k_flavour, | |
32473 | + bfd_target_versados_flavour, | |
32474 | + bfd_target_msdos_flavour, | |
32475 | + bfd_target_ovax_flavour, | |
32476 | + bfd_target_evax_flavour, | |
32477 | + bfd_target_mmo_flavour, | |
32478 | + bfd_target_mach_o_flavour, | |
32479 | + bfd_target_pef_flavour, | |
32480 | + bfd_target_pef_xlib_flavour, | |
32481 | + bfd_target_sym_flavour | |
32482 | +}; | |
32483 | + | |
32484 | +enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN }; | |
32485 | + | |
32486 | +/* Forward declaration. */ | |
32487 | +typedef struct bfd_link_info _bfd_link_info; | |
32488 | + | |
32489 | +typedef struct bfd_target | |
32490 | +{ | |
32491 | + /* Identifies the kind of target, e.g., SunOS4, Ultrix, etc. */ | |
32492 | + char *name; | |
32493 | + | |
32494 | + /* The "flavour" of a back end is a general indication about | |
32495 | + the contents of a file. */ | |
32496 | + enum bfd_flavour flavour; | |
32497 | + | |
32498 | + /* The order of bytes within the data area of a file. */ | |
32499 | + enum bfd_endian byteorder; | |
32500 | + | |
32501 | + /* The order of bytes within the header parts of a file. */ | |
32502 | + enum bfd_endian header_byteorder; | |
32503 | + | |
32504 | + /* A mask of all the flags which an executable may have set - | |
32505 | + from the set <<BFD_NO_FLAGS>>, <<HAS_RELOC>>, ...<<D_PAGED>>. */ | |
32506 | + flagword object_flags; | |
32507 | + | |
32508 | + /* A mask of all the flags which a section may have set - from | |
32509 | + the set <<SEC_NO_FLAGS>>, <<SEC_ALLOC>>, ...<<SET_NEVER_LOAD>>. */ | |
32510 | + flagword section_flags; | |
32511 | + | |
32512 | + /* The character normally found at the front of a symbol. | |
32513 | + (if any), perhaps `_'. */ | |
32514 | + char symbol_leading_char; | |
32515 | + | |
32516 | + /* The pad character for file names within an archive header. */ | |
32517 | + char ar_pad_char; | |
32518 | + | |
32519 | + /* The maximum number of characters in an archive header. */ | |
32520 | + unsigned short ar_max_namelen; | |
32521 | + | |
32522 | + /* Entries for byte swapping for data. These are different from the | |
32523 | + other entry points, since they don't take a BFD as the first argument. | |
32524 | + Certain other handlers could do the same. */ | |
32525 | + bfd_uint64_t (*bfd_getx64) (const void *); | |
32526 | + bfd_int64_t (*bfd_getx_signed_64) (const void *); | |
32527 | + void (*bfd_putx64) (bfd_uint64_t, void *); | |
32528 | + bfd_vma (*bfd_getx32) (const void *); | |
32529 | + bfd_signed_vma (*bfd_getx_signed_32) (const void *); | |
32530 | + void (*bfd_putx32) (bfd_vma, void *); | |
32531 | + bfd_vma (*bfd_getx16) (const void *); | |
32532 | + bfd_signed_vma (*bfd_getx_signed_16) (const void *); | |
32533 | + void (*bfd_putx16) (bfd_vma, void *); | |
32534 | + | |
32535 | + /* Byte swapping for the headers. */ | |
32536 | + bfd_uint64_t (*bfd_h_getx64) (const void *); | |
32537 | + bfd_int64_t (*bfd_h_getx_signed_64) (const void *); | |
32538 | + void (*bfd_h_putx64) (bfd_uint64_t, void *); | |
32539 | + bfd_vma (*bfd_h_getx32) (const void *); | |
32540 | + bfd_signed_vma (*bfd_h_getx_signed_32) (const void *); | |
32541 | + void (*bfd_h_putx32) (bfd_vma, void *); | |
32542 | + bfd_vma (*bfd_h_getx16) (const void *); | |
32543 | + bfd_signed_vma (*bfd_h_getx_signed_16) (const void *); | |
32544 | + void (*bfd_h_putx16) (bfd_vma, void *); | |
32545 | + | |
32546 | + /* Format dependent routines: these are vectors of entry points | |
32547 | + within the target vector structure, one for each format to check. */ | |
32548 | + | |
32549 | + /* Check the format of a file being read. Return a <<bfd_target *>> or zero. */ | |
32550 | + const struct bfd_target *(*_bfd_check_format[bfd_type_end]) (bfd *); | |
32551 | + | |
32552 | + /* Set the format of a file being written. */ | |
32553 | + bfd_boolean (*_bfd_set_format[bfd_type_end]) (bfd *); | |
32554 | + | |
32555 | + /* Write cached information into a file being written, at <<bfd_close>>. */ | |
32556 | + bfd_boolean (*_bfd_write_contents[bfd_type_end]) (bfd *); | |
32557 | + | |
32558 | + | |
32559 | + /* Generic entry points. */ | |
32560 | +#define BFD_JUMP_TABLE_GENERIC(NAME) \ | |
32561 | + NAME##_close_and_cleanup, \ | |
32562 | + NAME##_bfd_free_cached_info, \ | |
32563 | + NAME##_new_section_hook, \ | |
32564 | + NAME##_get_section_contents, \ | |
32565 | + NAME##_get_section_contents_in_window | |
32566 | + | |
32567 | + /* Called when the BFD is being closed to do any necessary cleanup. */ | |
32568 | + bfd_boolean (*_close_and_cleanup) (bfd *); | |
32569 | + /* Ask the BFD to free all cached information. */ | |
32570 | + bfd_boolean (*_bfd_free_cached_info) (bfd *); | |
32571 | + /* Called when a new section is created. */ | |
32572 | + bfd_boolean (*_new_section_hook) (bfd *, sec_ptr); | |
32573 | + /* Read the contents of a section. */ | |
32574 | + bfd_boolean (*_bfd_get_section_contents) | |
32575 | + (bfd *, sec_ptr, void *, file_ptr, bfd_size_type); | |
32576 | + bfd_boolean (*_bfd_get_section_contents_in_window) | |
32577 | + (bfd *, sec_ptr, bfd_window *, file_ptr, bfd_size_type); | |
32578 | + | |
32579 | + /* Entry points to copy private data. */ | |
32580 | +#define BFD_JUMP_TABLE_COPY(NAME) \ | |
32581 | + NAME##_bfd_copy_private_bfd_data, \ | |
32582 | + NAME##_bfd_merge_private_bfd_data, \ | |
32583 | + NAME##_bfd_copy_private_section_data, \ | |
32584 | + NAME##_bfd_copy_private_symbol_data, \ | |
32585 | + NAME##_bfd_copy_private_header_data, \ | |
32586 | + NAME##_bfd_set_private_flags, \ | |
32587 | + NAME##_bfd_print_private_bfd_data | |
32588 | + | |
32589 | + /* Called to copy BFD general private data from one object file | |
32590 | + to another. */ | |
32591 | + bfd_boolean (*_bfd_copy_private_bfd_data) (bfd *, bfd *); | |
32592 | + /* Called to merge BFD general private data from one object file | |
32593 | + to a common output file when linking. */ | |
32594 | + bfd_boolean (*_bfd_merge_private_bfd_data) (bfd *, bfd *); | |
32595 | + /* Called to copy BFD private section data from one object file | |
32596 | + to another. */ | |
32597 | + bfd_boolean (*_bfd_copy_private_section_data) | |
32598 | + (bfd *, sec_ptr, bfd *, sec_ptr); | |
32599 | + /* Called to copy BFD private symbol data from one symbol | |
32600 | + to another. */ | |
32601 | + bfd_boolean (*_bfd_copy_private_symbol_data) | |
32602 | + (bfd *, asymbol *, bfd *, asymbol *); | |
32603 | + /* Called to copy BFD private header data from one object file | |
32604 | + to another. */ | |
32605 | + bfd_boolean (*_bfd_copy_private_header_data) | |
32606 | + (bfd *, bfd *); | |
32607 | + /* Called to set private backend flags. */ | |
32608 | + bfd_boolean (*_bfd_set_private_flags) (bfd *, flagword); | |
32609 | + | |
32610 | + /* Called to print private BFD data. */ | |
32611 | + bfd_boolean (*_bfd_print_private_bfd_data) (bfd *, void *); | |
32612 | + | |
32613 | + /* Core file entry points. */ | |
32614 | +#define BFD_JUMP_TABLE_CORE(NAME) \ | |
32615 | + NAME##_core_file_failing_command, \ | |
32616 | + NAME##_core_file_failing_signal, \ | |
32617 | + NAME##_core_file_matches_executable_p | |
32618 | + | |
32619 | + char * (*_core_file_failing_command) (bfd *); | |
32620 | + int (*_core_file_failing_signal) (bfd *); | |
32621 | + bfd_boolean (*_core_file_matches_executable_p) (bfd *, bfd *); | |
32622 | + | |
32623 | + /* Archive entry points. */ | |
32624 | +#define BFD_JUMP_TABLE_ARCHIVE(NAME) \ | |
32625 | + NAME##_slurp_armap, \ | |
32626 | + NAME##_slurp_extended_name_table, \ | |
32627 | + NAME##_construct_extended_name_table, \ | |
32628 | + NAME##_truncate_arname, \ | |
32629 | + NAME##_write_armap, \ | |
32630 | + NAME##_read_ar_hdr, \ | |
32631 | + NAME##_openr_next_archived_file, \ | |
32632 | + NAME##_get_elt_at_index, \ | |
32633 | + NAME##_generic_stat_arch_elt, \ | |
32634 | + NAME##_update_armap_timestamp | |
32635 | + | |
32636 | + bfd_boolean (*_bfd_slurp_armap) (bfd *); | |
32637 | + bfd_boolean (*_bfd_slurp_extended_name_table) (bfd *); | |
32638 | + bfd_boolean (*_bfd_construct_extended_name_table) | |
32639 | + (bfd *, char **, bfd_size_type *, const char **); | |
32640 | + void (*_bfd_truncate_arname) (bfd *, const char *, char *); | |
32641 | + bfd_boolean (*write_armap) | |
32642 | + (bfd *, unsigned int, struct orl *, unsigned int, int); | |
32643 | + void * (*_bfd_read_ar_hdr_fn) (bfd *); | |
32644 | + bfd * (*openr_next_archived_file) (bfd *, bfd *); | |
32645 | +#define bfd_get_elt_at_index(b,i) BFD_SEND (b, _bfd_get_elt_at_index, (b,i)) | |
32646 | + bfd * (*_bfd_get_elt_at_index) (bfd *, symindex); | |
32647 | + int (*_bfd_stat_arch_elt) (bfd *, struct stat *); | |
32648 | + bfd_boolean (*_bfd_update_armap_timestamp) (bfd *); | |
32649 | + | |
32650 | + /* Entry points used for symbols. */ | |
32651 | +#define BFD_JUMP_TABLE_SYMBOLS(NAME) \ | |
32652 | + NAME##_get_symtab_upper_bound, \ | |
32653 | + NAME##_canonicalize_symtab, \ | |
32654 | + NAME##_make_empty_symbol, \ | |
32655 | + NAME##_print_symbol, \ | |
32656 | + NAME##_get_symbol_info, \ | |
32657 | + NAME##_bfd_is_local_label_name, \ | |
32658 | + NAME##_bfd_is_target_special_symbol, \ | |
32659 | + NAME##_get_lineno, \ | |
32660 | + NAME##_find_nearest_line, \ | |
32661 | + _bfd_generic_find_line, \ | |
32662 | + NAME##_find_inliner_info, \ | |
32663 | + NAME##_bfd_make_debug_symbol, \ | |
32664 | + NAME##_read_minisymbols, \ | |
32665 | + NAME##_minisymbol_to_symbol | |
32666 | + | |
32667 | + long (*_bfd_get_symtab_upper_bound) (bfd *); | |
32668 | + long (*_bfd_canonicalize_symtab) | |
32669 | + (bfd *, struct bfd_symbol **); | |
32670 | + struct bfd_symbol * | |
32671 | + (*_bfd_make_empty_symbol) (bfd *); | |
32672 | + void (*_bfd_print_symbol) | |
32673 | + (bfd *, void *, struct bfd_symbol *, bfd_print_symbol_type); | |
32674 | +#define bfd_print_symbol(b,p,s,e) BFD_SEND (b, _bfd_print_symbol, (b,p,s,e)) | |
32675 | + void (*_bfd_get_symbol_info) | |
32676 | + (bfd *, struct bfd_symbol *, symbol_info *); | |
32677 | +#define bfd_get_symbol_info(b,p,e) BFD_SEND (b, _bfd_get_symbol_info, (b,p,e)) | |
32678 | + bfd_boolean (*_bfd_is_local_label_name) (bfd *, const char *); | |
32679 | + bfd_boolean (*_bfd_is_target_special_symbol) (bfd *, asymbol *); | |
32680 | + alent * (*_get_lineno) (bfd *, struct bfd_symbol *); | |
32681 | + bfd_boolean (*_bfd_find_nearest_line) | |
32682 | + (bfd *, struct bfd_section *, struct bfd_symbol **, bfd_vma, | |
32683 | + const char **, const char **, unsigned int *); | |
32684 | + bfd_boolean (*_bfd_find_line) | |
32685 | + (bfd *, struct bfd_symbol **, struct bfd_symbol *, | |
32686 | + const char **, unsigned int *); | |
32687 | + bfd_boolean (*_bfd_find_inliner_info) | |
32688 | + (bfd *, const char **, const char **, unsigned int *); | |
32689 | + /* Back-door to allow format-aware applications to create debug symbols | |
32690 | + while using BFD for everything else. Currently used by the assembler | |
32691 | + when creating COFF files. */ | |
32692 | + asymbol * (*_bfd_make_debug_symbol) | |
32693 | + (bfd *, void *, unsigned long size); | |
32694 | +#define bfd_read_minisymbols(b, d, m, s) \ | |
32695 | + BFD_SEND (b, _read_minisymbols, (b, d, m, s)) | |
32696 | + long (*_read_minisymbols) | |
32697 | + (bfd *, bfd_boolean, void **, unsigned int *); | |
32698 | +#define bfd_minisymbol_to_symbol(b, d, m, f) \ | |
32699 | + BFD_SEND (b, _minisymbol_to_symbol, (b, d, m, f)) | |
32700 | + asymbol * (*_minisymbol_to_symbol) | |
32701 | + (bfd *, bfd_boolean, const void *, asymbol *); | |
32702 | + | |
32703 | + /* Routines for relocs. */ | |
32704 | +#define BFD_JUMP_TABLE_RELOCS(NAME) \ | |
32705 | + NAME##_get_reloc_upper_bound, \ | |
32706 | + NAME##_canonicalize_reloc, \ | |
32707 | + NAME##_bfd_reloc_type_lookup | |
32708 | + | |
32709 | + long (*_get_reloc_upper_bound) (bfd *, sec_ptr); | |
32710 | + long (*_bfd_canonicalize_reloc) | |
32711 | + (bfd *, sec_ptr, arelent **, struct bfd_symbol **); | |
32712 | + /* See documentation on reloc types. */ | |
32713 | + reloc_howto_type * | |
32714 | + (*reloc_type_lookup) (bfd *, bfd_reloc_code_real_type); | |
32715 | + | |
32716 | + /* Routines used when writing an object file. */ | |
32717 | +#define BFD_JUMP_TABLE_WRITE(NAME) \ | |
32718 | + NAME##_set_arch_mach, \ | |
32719 | + NAME##_set_section_contents | |
32720 | + | |
32721 | + bfd_boolean (*_bfd_set_arch_mach) | |
32722 | + (bfd *, enum bfd_architecture, unsigned long); | |
32723 | + bfd_boolean (*_bfd_set_section_contents) | |
32724 | + (bfd *, sec_ptr, const void *, file_ptr, bfd_size_type); | |
32725 | + | |
32726 | + /* Routines used by the linker. */ | |
32727 | +#define BFD_JUMP_TABLE_LINK(NAME) \ | |
32728 | + NAME##_sizeof_headers, \ | |
32729 | + NAME##_bfd_get_relocated_section_contents, \ | |
32730 | + NAME##_bfd_relax_section, \ | |
32731 | + NAME##_bfd_link_hash_table_create, \ | |
32732 | + NAME##_bfd_link_hash_table_free, \ | |
32733 | + NAME##_bfd_link_add_symbols, \ | |
32734 | + NAME##_bfd_link_just_syms, \ | |
32735 | + NAME##_bfd_final_link, \ | |
32736 | + NAME##_bfd_link_split_section, \ | |
32737 | + NAME##_bfd_gc_sections, \ | |
32738 | + NAME##_bfd_merge_sections, \ | |
32739 | + NAME##_bfd_is_group_section, \ | |
32740 | + NAME##_bfd_discard_group, \ | |
32741 | + NAME##_section_already_linked \ | |
32742 | + | |
32743 | + int (*_bfd_sizeof_headers) (bfd *, bfd_boolean); | |
32744 | + bfd_byte * (*_bfd_get_relocated_section_contents) | |
32745 | + (bfd *, struct bfd_link_info *, struct bfd_link_order *, | |
32746 | + bfd_byte *, bfd_boolean, struct bfd_symbol **); | |
32747 | + | |
32748 | + bfd_boolean (*_bfd_relax_section) | |
32749 | + (bfd *, struct bfd_section *, struct bfd_link_info *, bfd_boolean *); | |
32750 | + | |
32751 | + /* Create a hash table for the linker. Different backends store | |
32752 | + different information in this table. */ | |
32753 | + struct bfd_link_hash_table * | |
32754 | + (*_bfd_link_hash_table_create) (bfd *); | |
32755 | + | |
32756 | + /* Release the memory associated with the linker hash table. */ | |
32757 | + void (*_bfd_link_hash_table_free) (struct bfd_link_hash_table *); | |
32758 | + | |
32759 | + /* Add symbols from this object file into the hash table. */ | |
32760 | + bfd_boolean (*_bfd_link_add_symbols) (bfd *, struct bfd_link_info *); | |
32761 | + | |
32762 | + /* Indicate that we are only retrieving symbol values from this section. */ | |
32763 | + void (*_bfd_link_just_syms) (asection *, struct bfd_link_info *); | |
32764 | + | |
32765 | + /* Do a link based on the link_order structures attached to each | |
32766 | + section of the BFD. */ | |
32767 | + bfd_boolean (*_bfd_final_link) (bfd *, struct bfd_link_info *); | |
32768 | + | |
32769 | + /* Should this section be split up into smaller pieces during linking. */ | |
32770 | + bfd_boolean (*_bfd_link_split_section) (bfd *, struct bfd_section *); | |
32771 | + | |
32772 | + /* Remove sections that are not referenced from the output. */ | |
32773 | + bfd_boolean (*_bfd_gc_sections) (bfd *, struct bfd_link_info *); | |
32774 | + | |
32775 | + /* Attempt to merge SEC_MERGE sections. */ | |
32776 | + bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *); | |
32777 | + | |
32778 | + /* Is this section a member of a group? */ | |
32779 | + bfd_boolean (*_bfd_is_group_section) (bfd *, const struct bfd_section *); | |
32780 | + | |
32781 | + /* Discard members of a group. */ | |
32782 | + bfd_boolean (*_bfd_discard_group) (bfd *, struct bfd_section *); | |
32783 | + | |
32784 | + /* Check if SEC has been already linked during a reloceatable or | |
32785 | + final link. */ | |
32786 | + void (*_section_already_linked) (bfd *, struct bfd_section *); | |
32787 | + | |
32788 | + /* Routines to handle dynamic symbols and relocs. */ | |
32789 | +#define BFD_JUMP_TABLE_DYNAMIC(NAME) \ | |
32790 | + NAME##_get_dynamic_symtab_upper_bound, \ | |
32791 | + NAME##_canonicalize_dynamic_symtab, \ | |
32792 | + NAME##_get_synthetic_symtab, \ | |
32793 | + NAME##_get_dynamic_reloc_upper_bound, \ | |
32794 | + NAME##_canonicalize_dynamic_reloc | |
32795 | + | |
32796 | + /* Get the amount of memory required to hold the dynamic symbols. */ | |
32797 | + long (*_bfd_get_dynamic_symtab_upper_bound) (bfd *); | |
32798 | + /* Read in the dynamic symbols. */ | |
32799 | + long (*_bfd_canonicalize_dynamic_symtab) | |
32800 | + (bfd *, struct bfd_symbol **); | |
32801 | + /* Create synthetized symbols. */ | |
32802 | + long (*_bfd_get_synthetic_symtab) | |
32803 | + (bfd *, long, struct bfd_symbol **, long, struct bfd_symbol **, | |
32804 | + struct bfd_symbol **); | |
32805 | + /* Get the amount of memory required to hold the dynamic relocs. */ | |
32806 | + long (*_bfd_get_dynamic_reloc_upper_bound) (bfd *); | |
32807 | + /* Read in the dynamic relocs. */ | |
32808 | + long (*_bfd_canonicalize_dynamic_reloc) | |
32809 | + (bfd *, arelent **, struct bfd_symbol **); | |
32810 | + | |
32811 | + /* Opposite endian version of this target. */ | |
32812 | + const struct bfd_target * alternative_target; | |
32813 | + | |
32814 | + /* Data for use by back-end routines, which isn't | |
32815 | + generic enough to belong in this structure. */ | |
32816 | + const void *backend_data; | |
32817 | + | |
32818 | +} bfd_target; | |
32819 | + | |
32820 | +bfd_boolean bfd_set_default_target (const char *name); | |
32821 | + | |
32822 | +const bfd_target *bfd_find_target (const char *target_name, bfd *abfd); | |
32823 | + | |
32824 | +const char ** bfd_target_list (void); | |
32825 | + | |
32826 | +const bfd_target *bfd_search_for_target | |
32827 | + (int (*search_func) (const bfd_target *, void *), | |
32828 | + void *); | |
32829 | + | |
32830 | +/* Extracted from format.c. */ | |
32831 | +bfd_boolean bfd_check_format (bfd *abfd, bfd_format format); | |
32832 | + | |
32833 | +bfd_boolean bfd_check_format_matches | |
32834 | + (bfd *abfd, bfd_format format, char ***matching); | |
32835 | + | |
32836 | +bfd_boolean bfd_set_format (bfd *abfd, bfd_format format); | |
32837 | + | |
32838 | +const char *bfd_format_string (bfd_format format); | |
32839 | + | |
32840 | +/* Extracted from linker.c. */ | |
32841 | +bfd_boolean bfd_link_split_section (bfd *abfd, asection *sec); | |
32842 | + | |
32843 | +#define bfd_link_split_section(abfd, sec) \ | |
32844 | + BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec)) | |
32845 | + | |
32846 | +void bfd_section_already_linked (bfd *abfd, asection *sec); | |
32847 | + | |
32848 | +#define bfd_section_already_linked(abfd, sec) \ | |
32849 | + BFD_SEND (abfd, _section_already_linked, (abfd, sec)) | |
32850 | + | |
32851 | +/* Extracted from simple.c. */ | |
32852 | +bfd_byte *bfd_simple_get_relocated_section_contents | |
32853 | + (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table); | |
32854 | + | |
32855 | +#ifdef __cplusplus | |
32856 | +} | |
32857 | +#endif | |
32858 | +#endif | |
32859 | --- /dev/null | |
32860 | +++ b/include/asm-x86/bfd.h | |
32861 | @@ -0,0 +1,5 @@ | |
32862 | +#ifdef CONFIG_X86_32 | |
32863 | +# include "bfd_32.h" | |
32864 | +#else | |
32865 | +# include "bfd_64.h" | |
32866 | +#endif | |
32867 | --- a/include/asm-x86/irq_vectors.h | |
32868 | +++ b/include/asm-x86/irq_vectors.h | |
32869 | @@ -16,6 +16,7 @@ | |
32870 | #else | |
32871 | # define IA32_SYSCALL_VECTOR 0x80 | |
32872 | #endif | |
32873 | +#define KDBENTER_VECTOR 0x81 | |
32874 | ||
32875 | /* | |
32876 | * Reserve the lowest usable priority level 0x20 - 0x2f for triggering | |
32877 | @@ -65,6 +66,7 @@ | |
32878 | # define RESCHEDULE_VECTOR 0xfc | |
32879 | # define CALL_FUNCTION_VECTOR 0xfb | |
32880 | # define CALL_FUNCTION_SINGLE_VECTOR 0xfa | |
32881 | +#define KDB_VECTOR 0xf9 | |
32882 | # define THERMAL_APIC_VECTOR 0xf0 | |
32883 | ||
32884 | #else | |
32885 | @@ -77,6 +79,10 @@ | |
32886 | #define THERMAL_APIC_VECTOR 0xfa | |
32887 | #define THRESHOLD_APIC_VECTOR 0xf9 | |
32888 | #define UV_BAU_MESSAGE 0xf8 | |
32889 | +/* Overload KDB_VECTOR with UV_BAU_MESSAGE. By the time the UV hardware is | |
32890 | + * ready, we should have moved to a dynamically allocated vector scheme. | |
32891 | + */ | |
32892 | +#define KDB_VECTOR 0xf8 | |
32893 | #define INVALIDATE_TLB_VECTOR_END 0xf7 | |
32894 | #define INVALIDATE_TLB_VECTOR_START 0xf0 /* f0-f7 used for TLB flush */ | |
32895 | ||
32896 | --- /dev/null | |
32897 | +++ b/include/asm-x86/kdb.h | |
32898 | @@ -0,0 +1,134 @@ | |
32899 | +#ifndef _ASM_KDB_H | |
32900 | +#define _ASM_KDB_H | |
32901 | + | |
32902 | +/* | |
32903 | + * Kernel Debugger Architecture Dependent (x86) Global Headers | |
32904 | + * | |
32905 | + * This file is subject to the terms and conditions of the GNU General Public | |
32906 | + * License. See the file "COPYING" in the main directory of this archive | |
32907 | + * for more details. | |
32908 | + * | |
32909 | + * Copyright (c) 1999-2008 Silicon Graphics, Inc. All Rights Reserved. | |
32910 | + */ | |
32911 | + | |
32912 | +/* | |
32913 | + * KDB_ENTER() is a macro which causes entry into the kernel | |
32914 | + * debugger from any point in the kernel code stream. If it | |
32915 | + * is intended to be used from interrupt level, it must use | |
32916 | + * a non-maskable entry method. The vector is KDB_VECTOR, | |
32917 | + * defined in hw_irq.h | |
32918 | + */ | |
32919 | +#define KDB_ENTER() do {if (kdb_on && !KDB_IS_RUNNING()) { asm("\tint $129\n"); }} while(0) | |
32920 | + | |
32921 | +/* | |
32922 | + * Needed for exported symbols. | |
32923 | + */ | |
32924 | +typedef unsigned long kdb_machreg_t; | |
32925 | + | |
32926 | +/* | |
32927 | + * Per cpu arch specific kdb state. Must be in range 0xff000000. | |
32928 | + */ | |
32929 | +#define KDB_STATE_A_IF 0x01000000 /* Saved IF flag */ | |
32930 | + | |
32931 | + | |
32932 | +#ifdef CONFIG_X86_32 | |
32933 | + | |
32934 | +#define kdb_machreg_fmt "0x%lx" | |
32935 | +#define kdb_machreg_fmt0 "0x%08lx" | |
32936 | +#define kdb_bfd_vma_fmt "0x%lx" | |
32937 | +#define kdb_bfd_vma_fmt0 "0x%08lx" | |
32938 | +#define kdb_elfw_addr_fmt "0x%x" | |
32939 | +#define kdb_elfw_addr_fmt0 "0x%08x" | |
32940 | + | |
32941 | +#else /* CONFIG_X86_32 */ | |
32942 | + | |
32943 | +#define kdb_machreg_fmt "0x%lx" | |
32944 | +#define kdb_machreg_fmt0 "0x%016lx" | |
32945 | +#define kdb_bfd_vma_fmt "0x%lx" | |
32946 | +#define kdb_bfd_vma_fmt0 "0x%016lx" | |
32947 | +#define kdb_elfw_addr_fmt "0x%x" | |
32948 | +#define kdb_elfw_addr_fmt0 "0x%016x" | |
32949 | + | |
32950 | +/* | |
32951 | + * Functions to safely read and write kernel areas. The {to,from}_xxx | |
32952 | + * addresses are not necessarily valid, these functions must check for | |
32953 | + * validity. If the arch already supports get and put routines with | |
32954 | + * suitable validation and/or recovery on invalid addresses then use | |
32955 | + * those routines, otherwise check it yourself. | |
32956 | + */ | |
32957 | + | |
32958 | +/* | |
32959 | + * asm-i386 uaccess.h supplies __copy_to_user which relies on MMU to | |
32960 | + * trap invalid addresses in the _xxx fields. Verify the other address | |
32961 | + * of the pair is valid by accessing the first and last byte ourselves, | |
32962 | + * then any access violations should only be caused by the _xxx | |
32963 | + * addresses, | |
32964 | + */ | |
32965 | + | |
32966 | +#include <asm/uaccess.h> | |
32967 | + | |
32968 | +static inline int | |
32969 | +__kdba_putarea_size(unsigned long to_xxx, void *from, size_t size) | |
32970 | +{ | |
32971 | + mm_segment_t oldfs = get_fs(); | |
32972 | + int r; | |
32973 | + char c; | |
32974 | + c = *((volatile char *)from); | |
32975 | + c = *((volatile char *)from + size - 1); | |
32976 | + | |
32977 | + if (to_xxx < PAGE_OFFSET) { | |
32978 | + return kdb_putuserarea_size(to_xxx, from, size); | |
32979 | + } | |
32980 | + | |
32981 | + set_fs(KERNEL_DS); | |
32982 | + r = __copy_to_user_inatomic((void *)to_xxx, from, size); | |
32983 | + set_fs(oldfs); | |
32984 | + return r; | |
32985 | +} | |
32986 | + | |
32987 | +static inline int | |
32988 | +__kdba_getarea_size(void *to, unsigned long from_xxx, size_t size) | |
32989 | +{ | |
32990 | + mm_segment_t oldfs = get_fs(); | |
32991 | + int r; | |
32992 | + *((volatile char *)to) = '\0'; | |
32993 | + *((volatile char *)to + size - 1) = '\0'; | |
32994 | + | |
32995 | + if (from_xxx < PAGE_OFFSET) { | |
32996 | + return kdb_getuserarea_size(to, from_xxx, size); | |
32997 | + } | |
32998 | + | |
32999 | + set_fs(KERNEL_DS); | |
33000 | + r = __copy_to_user_inatomic(to, (void *)from_xxx, size); | |
33001 | + set_fs(oldfs); | |
33002 | + return r; | |
33003 | +} | |
33004 | + | |
33005 | +/* For numa with replicated code/data, the platform must supply its own | |
33006 | + * kdba_putarea_size and kdba_getarea_size routines. Without replication kdb | |
33007 | + * uses the standard architecture routines. | |
33008 | + */ | |
33009 | +#ifdef CONFIG_NUMA_REPLICATE | |
33010 | +extern int kdba_putarea_size(unsigned long to_xxx, void *from, size_t size); | |
33011 | +extern int kdba_getarea_size(void *to, unsigned long from_xxx, size_t size); | |
33012 | +#else | |
33013 | +#define kdba_putarea_size __kdba_putarea_size | |
33014 | +#define kdba_getarea_size __kdba_getarea_size | |
33015 | +#endif | |
33016 | + | |
33017 | +static inline int | |
33018 | +kdba_verify_rw(unsigned long addr, size_t size) | |
33019 | +{ | |
33020 | + unsigned char data[size]; | |
33021 | + return(kdba_getarea_size(data, addr, size) || kdba_putarea_size(addr, data, size)); | |
33022 | +} | |
33023 | + | |
33024 | +#endif /* !CONFIG_X86_32 */ | |
33025 | + | |
33026 | +static inline unsigned long | |
33027 | +kdba_funcptr_value(void *fp) | |
33028 | +{ | |
33029 | + return (unsigned long)fp; | |
33030 | +} | |
33031 | + | |
33032 | +#endif /* !_ASM_KDB_H */ | |
33033 | --- /dev/null | |
33034 | +++ b/include/asm-x86/kdbprivate.h | |
33035 | @@ -0,0 +1,241 @@ | |
33036 | +#ifndef _ASM_KDBPRIVATE_H | |
33037 | +#define _ASM_KDBPRIVATE_H | |
33038 | + | |
33039 | +/* | |
33040 | + * Kernel Debugger Architecture Dependent (x86) Private Headers | |
33041 | + * | |
33042 | + * This file is subject to the terms and conditions of the GNU General Public | |
33043 | + * License. See the file "COPYING" in the main directory of this archive | |
33044 | + * for more details. | |
33045 | + * | |
33046 | + * Copyright (c) 1999-2008 Silicon Graphics, Inc. All Rights Reserved. | |
33047 | + */ | |
33048 | + | |
33049 | +typedef unsigned char kdb_machinst_t; | |
33050 | + | |
33051 | +/* | |
33052 | + * KDB_MAXBPT describes the total number of breakpoints | |
33053 | + * supported by this architecure. | |
33054 | + */ | |
33055 | +#define KDB_MAXBPT 16 | |
33056 | + | |
33057 | +/* | |
33058 | + * KDB_MAXHARDBPT describes the total number of hardware | |
33059 | + * breakpoint registers that exist. | |
33060 | + */ | |
33061 | +#define KDB_MAXHARDBPT 4 | |
33062 | + | |
33063 | +/* Maximum number of arguments to a function */ | |
33064 | +#define KDBA_MAXARGS 16 | |
33065 | + | |
33066 | +/* | |
33067 | + * Support for ia32 debug registers | |
33068 | + */ | |
33069 | +typedef struct _kdbhard_bp { | |
33070 | + kdb_machreg_t bph_reg; /* Register this breakpoint uses */ | |
33071 | + | |
33072 | + unsigned int bph_free:1; /* Register available for use */ | |
33073 | + unsigned int bph_data:1; /* Data Access breakpoint */ | |
33074 | + | |
33075 | + unsigned int bph_write:1; /* Write Data breakpoint */ | |
33076 | + unsigned int bph_mode:2; /* 0=inst, 1=write, 2=io, 3=read */ | |
33077 | + unsigned int bph_length:2; /* 0=1, 1=2, 2=BAD, 3=4 (bytes) */ | |
33078 | + unsigned int bph_installed; /* flag: hw bp is installed */ | |
33079 | +} kdbhard_bp_t; | |
33080 | + | |
33081 | +#define IA32_BREAKPOINT_INSTRUCTION 0xcc | |
33082 | + | |
33083 | +#define DR6_BT 0x00008000 | |
33084 | +#define DR6_BS 0x00004000 | |
33085 | +#define DR6_BD 0x00002000 | |
33086 | + | |
33087 | +#define DR6_B3 0x00000008 | |
33088 | +#define DR6_B2 0x00000004 | |
33089 | +#define DR6_B1 0x00000002 | |
33090 | +#define DR6_B0 0x00000001 | |
33091 | +#define DR6_DR_MASK 0x0000000F | |
33092 | + | |
33093 | +#define DR7_RW_VAL(dr, drnum) \ | |
33094 | + (((dr) >> (16 + (4 * (drnum)))) & 0x3) | |
33095 | + | |
33096 | +#define DR7_RW_SET(dr, drnum, rw) \ | |
33097 | + do { \ | |
33098 | + (dr) &= ~(0x3 << (16 + (4 * (drnum)))); \ | |
33099 | + (dr) |= (((rw) & 0x3) << (16 + (4 * (drnum)))); \ | |
33100 | + } while (0) | |
33101 | + | |
33102 | +#define DR7_RW0(dr) DR7_RW_VAL(dr, 0) | |
33103 | +#define DR7_RW0SET(dr,rw) DR7_RW_SET(dr, 0, rw) | |
33104 | +#define DR7_RW1(dr) DR7_RW_VAL(dr, 1) | |
33105 | +#define DR7_RW1SET(dr,rw) DR7_RW_SET(dr, 1, rw) | |
33106 | +#define DR7_RW2(dr) DR7_RW_VAL(dr, 2) | |
33107 | +#define DR7_RW2SET(dr,rw) DR7_RW_SET(dr, 2, rw) | |
33108 | +#define DR7_RW3(dr) DR7_RW_VAL(dr, 3) | |
33109 | +#define DR7_RW3SET(dr,rw) DR7_RW_SET(dr, 3, rw) | |
33110 | + | |
33111 | + | |
33112 | +#define DR7_LEN_VAL(dr, drnum) \ | |
33113 | + (((dr) >> (18 + (4 * (drnum)))) & 0x3) | |
33114 | + | |
33115 | +#define DR7_LEN_SET(dr, drnum, rw) \ | |
33116 | + do { \ | |
33117 | + (dr) &= ~(0x3 << (18 + (4 * (drnum)))); \ | |
33118 | + (dr) |= (((rw) & 0x3) << (18 + (4 * (drnum)))); \ | |
33119 | + } while (0) | |
33120 | + | |
33121 | +#define DR7_LEN0(dr) DR7_LEN_VAL(dr, 0) | |
33122 | +#define DR7_LEN0SET(dr,len) DR7_LEN_SET(dr, 0, len) | |
33123 | +#define DR7_LEN1(dr) DR7_LEN_VAL(dr, 1) | |
33124 | +#define DR7_LEN1SET(dr,len) DR7_LEN_SET(dr, 1, len) | |
33125 | +#define DR7_LEN2(dr) DR7_LEN_VAL(dr, 2) | |
33126 | +#define DR7_LEN2SET(dr,len) DR7_LEN_SET(dr, 2, len) | |
33127 | +#define DR7_LEN3(dr) DR7_LEN_VAL(dr, 3) | |
33128 | +#define DR7_LEN3SET(dr,len) DR7_LEN_SET(dr, 3, len) | |
33129 | + | |
33130 | +#define DR7_G0(dr) (((dr)>>1)&0x1) | |
33131 | +#define DR7_G0SET(dr) ((dr) |= 0x2) | |
33132 | +#define DR7_G0CLR(dr) ((dr) &= ~0x2) | |
33133 | +#define DR7_G1(dr) (((dr)>>3)&0x1) | |
33134 | +#define DR7_G1SET(dr) ((dr) |= 0x8) | |
33135 | +#define DR7_G1CLR(dr) ((dr) &= ~0x8) | |
33136 | +#define DR7_G2(dr) (((dr)>>5)&0x1) | |
33137 | +#define DR7_G2SET(dr) ((dr) |= 0x20) | |
33138 | +#define DR7_G2CLR(dr) ((dr) &= ~0x20) | |
33139 | +#define DR7_G3(dr) (((dr)>>7)&0x1) | |
33140 | +#define DR7_G3SET(dr) ((dr) |= 0x80) | |
33141 | +#define DR7_G3CLR(dr) ((dr) &= ~0x80) | |
33142 | + | |
33143 | +#define DR7_L0(dr) (((dr))&0x1) | |
33144 | +#define DR7_L0SET(dr) ((dr) |= 0x1) | |
33145 | +#define DR7_L0CLR(dr) ((dr) &= ~0x1) | |
33146 | +#define DR7_L1(dr) (((dr)>>2)&0x1) | |
33147 | +#define DR7_L1SET(dr) ((dr) |= 0x4) | |
33148 | +#define DR7_L1CLR(dr) ((dr) &= ~0x4) | |
33149 | +#define DR7_L2(dr) (((dr)>>4)&0x1) | |
33150 | +#define DR7_L2SET(dr) ((dr) |= 0x10) | |
33151 | +#define DR7_L2CLR(dr) ((dr) &= ~0x10) | |
33152 | +#define DR7_L3(dr) (((dr)>>6)&0x1) | |
33153 | +#define DR7_L3SET(dr) ((dr) |= 0x40) | |
33154 | +#define DR7_L3CLR(dr) ((dr) &= ~0x40) | |
33155 | + | |
33156 | +#define DR7_GD 0x00002000 /* General Detect Enable */ | |
33157 | +#define DR7_GE 0x00000200 /* Global exact */ | |
33158 | +#define DR7_LE 0x00000100 /* Local exact */ | |
33159 | + | |
33160 | +extern kdb_machreg_t kdba_getdr6(void); | |
33161 | +extern void kdba_putdr6(kdb_machreg_t); | |
33162 | + | |
33163 | +extern kdb_machreg_t kdba_getdr7(void); | |
33164 | + | |
33165 | +struct kdba_running_process { | |
33166 | + long sp; /* KDB may be on a different stack */ | |
33167 | + long ip; /* eip when esp was set */ | |
33168 | +}; | |
33169 | + | |
33170 | +static inline | |
33171 | +void kdba_unsave_running(struct kdba_running_process *k, struct pt_regs *regs) | |
33172 | +{ | |
33173 | +} | |
33174 | + | |
33175 | +struct kdb_activation_record; | |
33176 | +extern void kdba_get_stack_info_alternate(kdb_machreg_t addr, int cpu, | |
33177 | + struct kdb_activation_record *ar); | |
33178 | + | |
33179 | +extern void kdba_wait_for_cpus(void); | |
33180 | + | |
33181 | + | |
33182 | +#ifdef CONFIG_X86_32 | |
33183 | + | |
33184 | +#define DR_TYPE_EXECUTE 0x0 | |
33185 | +#define DR_TYPE_WRITE 0x1 | |
33186 | +#define DR_TYPE_IO 0x2 | |
33187 | +#define DR_TYPE_RW 0x3 | |
33188 | + | |
33189 | +/* | |
33190 | + * Platform specific environment entries | |
33191 | + */ | |
33192 | +#define KDB_PLATFORM_ENV "IDMODE=x86", "BYTESPERWORD=4", "IDCOUNT=16" | |
33193 | + | |
33194 | +/* | |
33195 | + * Support for setjmp/longjmp | |
33196 | + */ | |
33197 | +#define JB_BX 0 | |
33198 | +#define JB_SI 1 | |
33199 | +#define JB_DI 2 | |
33200 | +#define JB_BP 3 | |
33201 | +#define JB_SP 4 | |
33202 | +#define JB_PC 5 | |
33203 | + | |
33204 | +typedef struct __kdb_jmp_buf { | |
33205 | + unsigned long regs[6]; /* kdba_setjmp assumes fixed offsets here */ | |
33206 | +} kdb_jmp_buf; | |
33207 | + | |
33208 | +extern int asmlinkage kdba_setjmp(kdb_jmp_buf *); | |
33209 | +extern void asmlinkage kdba_longjmp(kdb_jmp_buf *, int); | |
33210 | +#define kdba_setjmp kdba_setjmp | |
33211 | + | |
33212 | +extern kdb_jmp_buf *kdbjmpbuf; | |
33213 | + | |
33214 | +/* Arch specific data saved for running processes */ | |
33215 | +static inline | |
33216 | +void kdba_save_running(struct kdba_running_process *k, struct pt_regs *regs) | |
33217 | +{ | |
33218 | + k->sp = current_stack_pointer; | |
33219 | + __asm__ __volatile__ ( " lea 1f,%%eax; movl %%eax,%0 ; 1: " : "=r"(k->ip) : : "eax" ); | |
33220 | +} | |
33221 | + | |
33222 | +extern void kdb_interrupt(void); | |
33223 | + | |
33224 | +#define KDB_INT_REGISTERS 8 | |
33225 | + | |
33226 | +#else /* CONFIG_X86_32 */ | |
33227 | + | |
33228 | +extern kdb_machreg_t kdba_getdr(int); | |
33229 | +extern void kdba_putdr(int, kdb_machreg_t); | |
33230 | + | |
33231 | +extern kdb_machreg_t kdb_getcr(int); | |
33232 | + | |
33233 | +/* | |
33234 | + * Platform specific environment entries | |
33235 | + */ | |
33236 | +#define KDB_PLATFORM_ENV "IDMODE=x86_64", "BYTESPERWORD=8", "IDCOUNT=16" | |
33237 | + | |
33238 | +/* | |
33239 | + * reg indicies for x86_64 setjmp/longjmp | |
33240 | + */ | |
33241 | +#define JB_RBX 0 | |
33242 | +#define JB_RBP 1 | |
33243 | +#define JB_R12 2 | |
33244 | +#define JB_R13 3 | |
33245 | +#define JB_R14 4 | |
33246 | +#define JB_R15 5 | |
33247 | +#define JB_RSP 6 | |
33248 | +#define JB_PC 7 | |
33249 | + | |
33250 | +typedef struct __kdb_jmp_buf { | |
33251 | + unsigned long regs[8]; /* kdba_setjmp assumes fixed offsets here */ | |
33252 | +} kdb_jmp_buf; | |
33253 | + | |
33254 | +extern int asmlinkage kdba_setjmp(kdb_jmp_buf *); | |
33255 | +extern void asmlinkage kdba_longjmp(kdb_jmp_buf *, int); | |
33256 | +#define kdba_setjmp kdba_setjmp | |
33257 | + | |
33258 | +extern kdb_jmp_buf *kdbjmpbuf; | |
33259 | + | |
33260 | +/* Arch specific data saved for running processes */ | |
33261 | +register unsigned long current_stack_pointer asm("rsp") __used; | |
33262 | + | |
33263 | +static inline | |
33264 | +void kdba_save_running(struct kdba_running_process *k, struct pt_regs *regs) | |
33265 | +{ | |
33266 | + k->sp = current_stack_pointer; | |
33267 | + __asm__ __volatile__ ( " lea 0(%%rip),%%rax; movq %%rax,%0 ; " : "=r"(k->ip) : : "rax" ); | |
33268 | +} | |
33269 | + | |
33270 | +extern asmlinkage void kdb_interrupt(void); | |
33271 | + | |
33272 | +#define KDB_INT_REGISTERS 16 | |
33273 | + | |
33274 | +#endif /* !CONFIG_X86_32 */ | |
33275 | + | |
33276 | +#endif /* !_ASM_KDBPRIVATE_H */ | |
33277 | --- a/include/asm-x86/kdebug.h | |
33278 | +++ b/include/asm-x86/kdebug.h | |
33279 | @@ -15,6 +15,8 @@ enum die_val { | |
33280 | DIE_DIE, | |
33281 | DIE_NMIWATCHDOG, | |
33282 | DIE_KERNELDEBUG, | |
33283 | + DIE_KDEBUG_ENTER, | |
33284 | + DIE_KDEBUG_LEAVE, | |
33285 | DIE_TRAP, | |
33286 | DIE_GPF, | |
33287 | DIE_CALL, | |
33288 | --- a/include/asm-x86/kmap_types.h | |
33289 | +++ b/include/asm-x86/kmap_types.h | |
33290 | @@ -21,7 +21,8 @@ D(9) KM_IRQ0, | |
33291 | D(10) KM_IRQ1, | |
33292 | D(11) KM_SOFTIRQ0, | |
33293 | D(12) KM_SOFTIRQ1, | |
33294 | -D(13) KM_TYPE_NR | |
33295 | +D(13) KM_KDB, | |
33296 | +D(14) KM_TYPE_NR | |
33297 | }; | |
33298 | ||
33299 | #undef D | |
33300 | --- a/include/asm-x86/ptrace.h | |
33301 | +++ b/include/asm-x86/ptrace.h | |
33302 | @@ -16,6 +16,29 @@ | |
33303 | /* this struct defines the way the registers are stored on the | |
33304 | stack during a system call. */ | |
33305 | ||
33306 | +enum EFLAGS { | |
33307 | + EF_CF = 0x00000001, | |
33308 | + EF_PF = 0x00000004, | |
33309 | + EF_AF = 0x00000010, | |
33310 | + EF_ZF = 0x00000040, | |
33311 | + EF_SF = 0x00000080, | |
33312 | + EF_TF = 0x00000100, | |
33313 | + EF_IE = 0x00000200, | |
33314 | + EF_DF = 0x00000400, | |
33315 | + EF_OF = 0x00000800, | |
33316 | + EF_IOPL = 0x00003000, | |
33317 | + EF_IOPL_RING0 = 0x00000000, | |
33318 | + EF_IOPL_RING1 = 0x00001000, | |
33319 | + EF_IOPL_RING2 = 0x00002000, | |
33320 | + EF_NT = 0x00004000, /* nested task */ | |
33321 | + EF_RF = 0x00010000, /* resume */ | |
33322 | + EF_VM = 0x00020000, /* virtual mode */ | |
33323 | + EF_AC = 0x00040000, /* alignment */ | |
33324 | + EF_VIF = 0x00080000, /* virtual interrupt */ | |
33325 | + EF_VIP = 0x00100000, /* virtual interrupt pending */ | |
33326 | + EF_ID = 0x00200000, /* id */ | |
33327 | +}; | |
33328 | + | |
33329 | #ifndef __KERNEL__ | |
33330 | ||
33331 | struct pt_regs { |