ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_disass.cpp
Revision: 1.10
Committed: 2004-06-14T14:23:59Z (19 years, 10 months ago) by gbeauche
Branch: MAIN
CVS Tags: release_3-2
Changes since 1.9: +4 -1 lines
Log Message:
Fix m68k disassembler with 64-bit vma.

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * mon_disass.cpp - Disassemblers
3     *
4 cebix 1.9 * cxmon (C) 1997-2004 Christian Bauer, Marc Hellwig
5 cebix 1.1 *
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 gbeauche 1.6 int buffer_read_memory(bfd_vma from, bfd_byte *to, unsigned int length, struct disassemble_info *info)
44 cebix 1.1 {
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 gbeauche 1.10 if (addr >= UVAL64(0x100000000))
88     info->fprintf_func(info->stream, "$%08x%08x", (uint32)(addr >> 32), (uint32)addr);
89     else
90     info->fprintf_func(info->stream, "$%08x", (uint32)addr);
91 cebix 1.1 }
92    
93     int generic_symbol_at_address(bfd_vma addr, struct disassemble_info *info)
94     {
95     return 0;
96     }
97    
98 cebix 1.2 void print_68k_invalid_opcode(unsigned long opcode, struct disassemble_info *info)
99     {
100     if (mon_macos_mode) {
101     // Look for MacOS A-Trap
102     const atrap_info *p = atraps;
103     while (p->word) {
104     if (p->word == opcode) {
105     info->fprintf_func(info->stream, p->name);
106     return;
107     }
108     p++;
109     }
110     }
111     info->fprintf_func(info->stream, "?");
112     }
113    
114 cebix 1.1 };
115    
116    
117     /*
118     * sprintf into a "stream"
119     */
120    
121     struct SFILE {
122     char *buffer;
123     char *current;
124     };
125    
126     static int mon_sprintf(SFILE *f, const char *format, ...)
127     {
128     int n;
129     va_list args;
130     va_start(args, format);
131     vsprintf(f->current, format, args);
132     f->current += n = strlen(f->current);
133     va_end(args);
134     return n;
135     }
136    
137    
138     /*
139     * Disassemble one instruction, return number of bytes
140     */
141    
142     int disass_68k(FILE *f, uint32 adr)
143     {
144     // Initialize info for GDB disassembler
145     disassemble_info info;
146     char buf[1024];
147     SFILE sfile = {buf, buf};
148     sfile.buffer = buf;
149     sfile.current = buf;
150     INIT_DISASSEMBLE_INFO(info, (FILE *)&sfile, (fprintf_ftype)mon_sprintf);
151    
152     // Disassemble instruction
153 cebix 1.2 lookup_lowmem = mon_macos_mode;
154 cebix 1.1 int num = print_insn_m68k(adr, &info);
155 cebix 1.2
156     for (int i=0; i<6; i+=2) {
157     if (num > i)
158     fprintf(f, "%04x ", mon_read_half(adr + i));
159     else
160     fprintf(f, " ");
161     }
162 cebix 1.1 if (num == 8)
163     fprintf(f, "%04x\t%s\n", mon_read_half(adr + 6), buf);
164 cebix 1.2 else if (num > 8)
165 cebix 1.1 fprintf(f, "...\t%s\n", buf);
166     else
167     fprintf(f, " \t%s\n", buf);
168 cebix 1.2
169 cebix 1.1 return num;
170     }
171    
172 gbeauche 1.6 int disass_x86(FILE *f, uint32 adr, uint32 bits)
173 cebix 1.1 {
174     // Initialize info for GDB disassembler
175     disassemble_info info;
176     char buf[1024];
177     SFILE sfile = {buf, buf};
178     sfile.buffer = buf;
179     sfile.current = buf;
180     INIT_DISASSEMBLE_INFO(info, (FILE *)&sfile, (fprintf_ftype)mon_sprintf);
181 gbeauche 1.6 if (bits == 16)
182 cebix 1.3 info.mach = bfd_mach_i386_i8086;
183 gbeauche 1.6 else if (bits == 64)
184     info.mach = bfd_mach_x86_64;
185 cebix 1.1
186     // Disassemble instruction
187     lookup_lowmem = false;
188 gbeauche 1.7 int num = print_insn_i386_att(adr, &info);
189 cebix 1.2
190     for (int i=0; i<6; i++) {
191     if (num > i)
192     fprintf(f, "%02x ", mon_read_byte(adr + i));
193     else
194     fprintf(f, " ");
195     }
196     if (num == 7)
197     fprintf(f, "%02x\t%s\n", mon_read_byte(adr + 7), buf);
198     else if (num > 7)
199     fprintf(f, "..\t%s\n", buf);
200     else
201     fprintf(f, " \t%s\n", buf);
202    
203 cebix 1.1 return num;
204     }