/* Select disassembly routine for specified architecture.
- Copyright (C) 1994-2015 Free Software Foundation, Inc.
+ Copyright (C) 1994-2017 Free Software Foundation, Inc.
This file is part of the GNU opcodes library.
MA 02110-1301, USA. */
#include "sysdep.h"
-#include "dis-asm.h"
+#include "disassemble.h"
+#include "safe-ctype.h"
+#include <assert.h>
#ifdef ARCH_all
#define ARCH_aarch64
#define ARCH_pdp11
#define ARCH_pj
#define ARCH_powerpc
+#define ARCH_pru
#define ARCH_rs6000
#define ARCH_rl78
#define ARCH_rx
#define ARCH_vax
#define ARCH_visium
#define ARCH_w65
+#define ARCH_wasm32
#define ARCH_xstormy16
#define ARCH_xc16x
#define ARCH_xgate
#endif
disassembler_ftype
-disassembler (abfd)
- bfd *abfd;
+disassembler (enum bfd_architecture a, bfd_boolean big, unsigned long mach,
+ bfd *abfd)
{
- enum bfd_architecture a = bfd_get_arch (abfd);
disassembler_ftype disassemble;
+ if (abfd != NULL)
+ {
+ /* Do some asserts that the first three parameters should equal
+ to what we can get from ABFD. On the other hand, these
+ asserts help removing some compiler errors on unused
+ parameter. */
+ assert (a == bfd_get_arch (abfd));
+ assert (big == bfd_big_endian (abfd));
+ assert (mach == bfd_get_mach (abfd));
+ }
+
switch (a)
{
/* If you add a case to this table, also add it to the
#endif
#ifdef ARCH_arm
case bfd_arch_arm:
- if (bfd_big_endian (abfd))
+ if (big)
disassemble = print_insn_big_arm;
else
disassemble = print_insn_little_arm;
#endif
#ifdef ARCH_h8300
case bfd_arch_h8300:
- if (bfd_get_mach (abfd) == bfd_mach_h8300h
- || bfd_get_mach (abfd) == bfd_mach_h8300hn)
+ if (mach == bfd_mach_h8300h || mach == bfd_mach_h8300hn)
disassemble = print_insn_h8300h;
- else if (bfd_get_mach (abfd) == bfd_mach_h8300s
- || bfd_get_mach (abfd) == bfd_mach_h8300sn
- || bfd_get_mach (abfd) == bfd_mach_h8300sx
- || bfd_get_mach (abfd) == bfd_mach_h8300sxn)
+ else if (mach == bfd_mach_h8300s
+ || mach == bfd_mach_h8300sn
+ || mach == bfd_mach_h8300sx
+ || mach == bfd_mach_h8300sxn)
disassemble = print_insn_h8300s;
else
disassemble = print_insn_h8300;
#endif
#ifdef ARCH_i386
case bfd_arch_i386:
+ case bfd_arch_iamcu:
case bfd_arch_l1om:
case bfd_arch_k1om:
disassemble = print_insn_i386;
#endif
#ifdef ARCH_mips
case bfd_arch_mips:
- if (bfd_big_endian (abfd))
+ if (big)
disassemble = print_insn_big_mips;
else
disassemble = print_insn_little_mips;
#endif
#ifdef ARCH_nios2
case bfd_arch_nios2:
- if (bfd_big_endian (abfd))
+ if (big)
disassemble = print_insn_big_nios2;
else
disassemble = print_insn_little_nios2;
#endif
#ifdef ARCH_powerpc
case bfd_arch_powerpc:
- if (bfd_big_endian (abfd))
+ if (big)
disassemble = print_insn_big_powerpc;
else
disassemble = print_insn_little_powerpc;
break;
#endif
+#ifdef ARCH_pru
+ case bfd_arch_pru:
+ disassemble = print_insn_pru;
+ break;
+#endif
+#ifdef ARCH_riscv
+ case bfd_arch_riscv:
+ disassemble = print_insn_riscv;
+ break;
+#endif
#ifdef ARCH_rs6000
case bfd_arch_rs6000:
- if (bfd_get_mach (abfd) == bfd_mach_ppc_620)
+ if (mach == bfd_mach_ppc_620)
disassemble = print_insn_big_powerpc;
else
disassemble = print_insn_rs6000;
#endif
#ifdef ARCH_rl78
case bfd_arch_rl78:
- disassemble = print_insn_rl78;
+ disassemble = rl78_get_disassembler (abfd);
break;
#endif
#ifdef ARCH_rx
#endif
#ifdef ARCH_score
case bfd_arch_score:
- if (bfd_big_endian (abfd))
+ if (big)
disassemble = print_insn_big_score;
else
disassemble = print_insn_little_score;
disassemble = print_insn_w65;
break;
#endif
+#ifdef ARCH_wasm32
+ case bfd_arch_wasm32:
+ disassemble = print_insn_wasm32;
+ break;
+#endif
#ifdef ARCH_xgate
case bfd_arch_xgate:
disassemble = print_insn_xgate;
#endif
#ifdef ARCH_z8k
case bfd_arch_z8k:
- if (bfd_get_mach(abfd) == bfd_mach_z8001)
+ if (mach == bfd_mach_z8001)
disassemble = print_insn_z8001;
else
disassemble = print_insn_z8002;
}
void
-disassembler_usage (stream)
- FILE * stream ATTRIBUTE_UNUSED;
+disassembler_usage (FILE *stream ATTRIBUTE_UNUSED)
{
#ifdef ARCH_aarch64
print_aarch64_disassembler_options (stream);
#endif
+#ifdef ARCH_arc
+ print_arc_disassembler_options (stream);
+#endif
#ifdef ARCH_arm
print_arm_disassembler_options (stream);
#endif
#ifdef ARCH_powerpc
print_ppc_disassembler_options (stream);
#endif
+#ifdef ARCH_riscv
+ print_riscv_disassembler_options (stream);
+#endif
#ifdef ARCH_i386
print_i386_disassembler_options (stream);
#endif
#ifdef ARCH_s390
print_s390_disassembler_options (stream);
#endif
+#ifdef ARCH_wasm32
+ print_wasm32_disassembler_options (stream);
+#endif
return;
}
disassemble_init_powerpc (info);
break;
#endif
+#ifdef ARCH_wasm32
+ case bfd_arch_wasm32:
+ disassemble_init_wasm32 (info);
+ break;
+#endif
+#ifdef ARCH_s390
+ case bfd_arch_s390:
+ disassemble_init_s390 (info);
+ break;
+#endif
default:
break;
}
}
+
+/* Remove whitespace and consecutive commas from OPTIONS. */
+
+char *
+remove_whitespace_and_extra_commas (char *options)
+{
+ char *str;
+ size_t i, len;
+
+ if (options == NULL)
+ return NULL;
+
+ /* Strip off all trailing whitespace and commas. */
+ for (len = strlen (options); len > 0; len--)
+ {
+ if (!ISSPACE (options[len - 1]) && options[len - 1] != ',')
+ break;
+ options[len - 1] = '\0';
+ }
+
+ /* Convert all remaining whitespace to commas. */
+ for (i = 0; options[i] != '\0'; i++)
+ if (ISSPACE (options[i]))
+ options[i] = ',';
+
+ /* Remove consecutive commas. */
+ for (str = options; *str != '\0'; str++)
+ if (*str == ',' && (*(str + 1) == ',' || str == options))
+ {
+ char *next = str + 1;
+ while (*next == ',')
+ next++;
+ len = strlen (next);
+ if (str != options)
+ str++;
+ memmove (str, next, len);
+ next[len - (size_t)(next - str)] = '\0';
+ }
+ return (strlen (options) != 0) ? options : NULL;
+}
+
+/* Like STRCMP, but treat ',' the same as '\0' so that we match
+ strings like "foobar" against "foobar,xxyyzz,...". */
+
+int
+disassembler_options_cmp (const char *s1, const char *s2)
+{
+ unsigned char c1, c2;
+
+ do
+ {
+ c1 = (unsigned char) *s1++;
+ if (c1 == ',')
+ c1 = '\0';
+ c2 = (unsigned char) *s2++;
+ if (c2 == ',')
+ c2 = '\0';
+ if (c1 == '\0')
+ return c1 - c2;
+ }
+ while (c1 == c2);
+
+ return c1 - c2;
+}