ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_disass.cpp
Revision: 1.3
Committed: 2000-10-06T00:04:22Z (24 years, 1 month ago) by cebix
Branch: MAIN
Changes since 1.2: +3 -1 lines
Log Message:
new command "d8086" for disassembling 16-bit x86 code

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * mon_disass.cpp - Disassemblers
3     *
4     * mon (C) 1997-2000 Christian Bauer, Marc Hellwig
5     *
6     * This program is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19     */
20    
21     #include "sysdeps.h"
22    
23     #include <stdarg.h>
24    
25     #include "mon.h"
26     #include "mon_disass.h"
27 cebix 1.2
28     #include "mon_atraps.h"
29 cebix 1.1 #include "mon_lowmem.h"
30    
31    
32 cebix 1.2 // Flag: enable MacOS A-Trap and LM globals lookup in 68k disassembler
33     bool mon_macos_mode = false;
34    
35    
36 cebix 1.1 /*
37     * GNU disassembler callbacks
38     */
39    
40     extern "C" {
41     #include "disass/dis-asm.h"
42    
43     int buffer_read_memory(bfd_vma from, bfd_byte *to, int length, struct disassemble_info *info)
44     {
45     while (length--)
46     *to++ = mon_read_byte(from++);
47     return 0;
48     }
49    
50     void perror_memory(int status, bfd_vma memaddr, struct disassemble_info *info)
51     {
52     info->fprintf_func(info->stream, "Unknown error %d\n", status);
53     }
54    
55     bool lookup_lowmem;
56    
57     void generic_print_address(bfd_vma addr, struct disassemble_info *info)
58     {
59 cebix 1.2 if (lookup_lowmem && addr >= 0x100 && addr < 0x3000) {
60     if (((addr >= 0x400 && addr < 0x800) || (addr >= 0xe00 && addr < 0x1e00)) && ((addr & 3) == 0)) {
61     // Look for address in A-Trap table
62     uint16 opcode = (addr < 0xe00 ? 0xa000 + (addr - 0x400) / 4 : 0xa800 + (addr - 0xe00) / 4);
63     uint16 mask = (addr < 0xe00 ? 0xf8ff : 0xffff);
64     const atrap_info *p = atraps;
65     while (p->word) {
66     if ((p->word & mask) == opcode) {
67     info->fprintf_func(info->stream, p->name);
68     return;
69     }
70     p++;
71     }
72     } else {
73     // Look for address in low memory globals table
74     const lowmem_info *p = lowmem;
75     while (p->name) {
76     if (addr >= p[0].addr && addr < p[1].addr) {
77     if (addr == p[0].addr)
78     info->fprintf_func(info->stream, "%s", p->name);
79     else
80     info->fprintf_func(info->stream, "%s+%d", p->name, addr - p->addr);
81     return;
82     }
83     p++;
84 cebix 1.1 }
85     }
86     }
87     info->fprintf_func(info->stream, "$%08x", addr);
88     }
89    
90     int generic_symbol_at_address(bfd_vma addr, struct disassemble_info *info)
91     {
92     return 0;
93     }
94    
95 cebix 1.2 void print_68k_invalid_opcode(unsigned long opcode, struct disassemble_info *info)
96     {
97     if (mon_macos_mode) {
98     // Look for MacOS A-Trap
99     const atrap_info *p = atraps;
100     while (p->word) {
101     if (p->word == opcode) {
102     info->fprintf_func(info->stream, p->name);
103     return;
104     }
105     p++;
106     }
107     }
108     info->fprintf_func(info->stream, "?");
109     }
110    
111 cebix 1.1 };
112    
113    
114     /*
115     * sprintf into a "stream"
116     */
117    
118     struct SFILE {
119     char *buffer;
120     char *current;
121     };
122    
123     static int mon_sprintf(SFILE *f, const char *format, ...)
124     {
125     int n;
126     va_list args;
127     va_start(args, format);
128     vsprintf(f->current, format, args);
129     f->current += n = strlen(f->current);
130     va_end(args);
131     return n;
132     }
133    
134    
135     /*
136     * Disassemble one instruction, return number of bytes
137     */
138    
139     int disass_68k(FILE *f, uint32 adr)
140     {
141     // Initialize info for GDB disassembler
142     disassemble_info info;
143     char buf[1024];
144     SFILE sfile = {buf, buf};
145     sfile.buffer = buf;
146     sfile.current = buf;
147     INIT_DISASSEMBLE_INFO(info, (FILE *)&sfile, (fprintf_ftype)mon_sprintf);
148    
149     // Disassemble instruction
150 cebix 1.2 lookup_lowmem = mon_macos_mode;
151 cebix 1.1 int num = print_insn_m68k(adr, &info);
152 cebix 1.2
153     for (int i=0; i<6; i+=2) {
154     if (num > i)
155     fprintf(f, "%04x ", mon_read_half(adr + i));
156     else
157     fprintf(f, " ");
158     }
159 cebix 1.1 if (num == 8)
160     fprintf(f, "%04x\t%s\n", mon_read_half(adr + 6), buf);
161 cebix 1.2 else if (num > 8)
162 cebix 1.1 fprintf(f, "...\t%s\n", buf);
163     else
164     fprintf(f, " \t%s\n", buf);
165 cebix 1.2
166 cebix 1.1 return num;
167     }
168    
169 cebix 1.3 int disass_x86(FILE *f, uint32 adr, bool i8086)
170 cebix 1.1 {
171     // Initialize info for GDB disassembler
172     disassemble_info info;
173     char buf[1024];
174     SFILE sfile = {buf, buf};
175     sfile.buffer = buf;
176     sfile.current = buf;
177     INIT_DISASSEMBLE_INFO(info, (FILE *)&sfile, (fprintf_ftype)mon_sprintf);
178 cebix 1.3 if (i8086)
179     info.mach = bfd_mach_i386_i8086;
180 cebix 1.1
181     // Disassemble instruction
182     lookup_lowmem = false;
183     int num = print_insn_i386(adr, &info);
184 cebix 1.2
185     for (int i=0; i<6; i++) {
186     if (num > i)
187     fprintf(f, "%02x ", mon_read_byte(adr + i));
188     else
189     fprintf(f, " ");
190     }
191     if (num == 7)
192     fprintf(f, "%02x\t%s\n", mon_read_byte(adr + 7), buf);
193     else if (num > 7)
194     fprintf(f, "..\t%s\n", buf);
195     else
196     fprintf(f, " \t%s\n", buf);
197    
198 cebix 1.1 return num;
199     }