From dd92f6397700e5478ae02b7dfad416181d04ef22 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Wed, 16 Jun 1999 02:24:36 +0000 Subject: [PATCH] Add -M command line switch to objdump - text of switch is passed on to disassembler Add support for register name set selection ot ARM disassembler. --- binutils/ChangeLog | 14 ++++++++ binutils/NEWS | 5 +++ binutils/binutils.texi | 16 ++++++++++ binutils/objdump.c | 14 ++++++-- include/ChangeLog | 5 +++ include/dis-asm.h | 5 +++ opcodes/ChangeLog | 19 +++++++++++ opcodes/arm-dis.c | 72 ++++++++++++++++++++++++++++++++++++++++-- opcodes/disassemble.c | 1 - 9 files changed, 145 insertions(+), 6 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index d3e1ba36064..83feb18d8c4 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,17 @@ +1999-06-14 Nick Clifton + + * objdump.c (disassembler_options): New variable. + (usage): Document new -M/--disassembler-options option. + (long_options): Add --disassembler-options. + (disassemble_data): Initialise disassembler_options field of + disassembler_info structure. + (main): Add parsing of -M option. + + * binutils.texi: Document new command line switch to objdump. + + * NEWS: Describe new command line switch to objdump. + + Mon Jun 14 10:27:54 1999 Andreas Schwab * binutils.texi: Fix typos. diff --git a/binutils/NEWS b/binutils/NEWS index 7c395010861..eb27ad54476 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -2,6 +2,11 @@ Changes in binutils 2.10: +* New command line switch to objdump -M (or --disassembler-options) which takes + a parameter which can then be interpreted on a per-target basis by the + disassembler. Used by ARM targets to select register name sets, ISA, APCS or + raw verions. + * objdump support for -mi386:intel which causes disassembly to be displayed with intel syntax. diff --git a/binutils/binutils.texi b/binutils/binutils.texi index 73bba55742b..535df3f6b8a 100644 --- a/binutils/binutils.texi +++ b/binutils/binutils.texi @@ -1137,6 +1137,7 @@ objdump [ -a | --archive-headers ] [ -j @var{section} | --section=@var{section} ] [ -l | --line-numbers ] [ -S | --source ] [ -m @var{machine} | --architecture=@var{machine} ] + [ -M @var{options} | --disassembler-options=@var{options}] [ -p | --private-headers ] [ -r | --reloc ] [ -R | --dynamic-reloc ] [ -s | --full-contents ] [ --stabs ] @@ -1295,6 +1296,21 @@ can be useful when disassembling object files which do not describe architecture information, such as S-records. You can list the available architectures with the @samp{-i} option. +@item -M @var{options} +@itemx --disassembler-options=@var{options} +Pass target specific information to the disassembler. Only supported on +some targets. + +If the target is an ARM architecture then this switch can be used to +select which register name set is used during disassembler. Specifying +@samp{--disassembler-options=reg-name-std} (the default) will select the +register names as used in ARM's instruction set documentation, but with +register 13 called 'sp', register 14 called 'lr' and register 15 called +'pc'. Specifying @samp{--disassembler-options=reg-names-apcs} will +select the name set used by the ARM Procedure Call Standard, whilst +specifying @samp{--disassembler-options=reg-names-raw} will just use +@samp{r} followed by the register number. + @item -p @itemx --private-headers Print information that is specific to the object file format. The exact diff --git a/binutils/objdump.c b/binutils/objdump.c index 40c68cc3b33..b7ee5d6283a 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -83,6 +83,9 @@ struct objdump_disasm_info { /* Architecture to disassemble for, or default if NULL. */ static char *machine = (char *) NULL; +/* Target specific options to the disassembler. */ +static char *disassembler_options = (char *) NULL; + /* Endianness to disassemble for, or default if BFD_ENDIAN_UNKNOWN. */ static enum bfd_endian endian = BFD_ENDIAN_UNKNOWN; @@ -217,7 +220,8 @@ usage (stream, status) int status; { fprintf (stream, _("\ -Usage: %s [-ahifCdDprRtTxsSlw] [-b bfdname] [-m machine] [-j section-name]\n\ +Usage: %s [-ahifCdDprRtTxsSlw] [-b bfdname] [-m machine] \n\ + [-j section-name] [-M disassembler-options]\n\ [--archive-headers] [--target=bfdname] [--debugging] [--disassemble]\n\ [--disassemble-all] [--disassemble-zeroes] [--file-headers]\n\ [--section-headers] [--headers]\n\ @@ -255,6 +259,7 @@ static struct option long_options[]= {"demangle", no_argument, &do_demangle, 1}, {"disassemble", no_argument, NULL, 'd'}, {"disassemble-all", no_argument, NULL, 'D'}, + {"disassembler-options", required_argument, NULL, 'M'}, {"disassemble-zeroes", no_argument, &disassemble_zeroes, 1}, {"dynamic-reloc", no_argument, NULL, 'R'}, {"dynamic-syms", no_argument, NULL, 'T'}, @@ -1564,6 +1569,8 @@ disassemble_data (abfd) disasm_info.flavour = bfd_get_flavour (abfd); disasm_info.arch = bfd_get_arch (abfd); disasm_info.mach = bfd_get_mach (abfd); + disasm_info.disassembler_options = disassembler_options; + if (bfd_big_endian (abfd)) disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_BIG; else if (bfd_little_endian (abfd)) @@ -2694,7 +2701,7 @@ main (argc, argv) bfd_init (); set_default_bfd_target (); - while ((c = getopt_long (argc, argv, "pib:m:VCdDlfahrRtTxsSj:wE:", + while ((c = getopt_long (argc, argv, "pib:m:M:VCdDlfahrRtTxsSj:wE:", long_options, (int *) 0)) != EOF) { @@ -2707,6 +2714,9 @@ main (argc, argv) case 'm': machine = optarg; break; + case 'M': + disassembler_options = optarg; + break; case 'j': only = optarg; break; diff --git a/include/ChangeLog b/include/ChangeLog index fbadf92fdf4..d318d969ee4 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +1999-06-14 Nick Clifton + + * dis-asm.h (arm_toggle_regnames): New prototype. + (struct diassemble_info): New field: disassembler_options. + 1999-04-11 Richard Henderson * bfdlink.h (bfd_elf_version_expr): Rename `match' to `pattern'. diff --git a/include/dis-asm.h b/include/dis-asm.h index 666ed690152..b42a5ca1dfa 100644 --- a/include/dis-asm.h +++ b/include/dis-asm.h @@ -133,6 +133,9 @@ typedef struct disassemble_info { zero if unknown. */ bfd_vma target2; /* Second target address for dref2 */ + /* Command line options specific to the target disassembler. */ + char * disassembler_options; + } disassemble_info; @@ -181,6 +184,8 @@ extern int print_insn_tic30 PARAMS ((bfd_vma, disassemble_info*)); extern int print_insn_vax PARAMS ((bfd_vma, disassemble_info*)); extern int print_insn_tic80 PARAMS ((bfd_vma, disassemble_info*)); +extern int arm_toggle_regnames PARAMS ((void)); + /* Fetch the disassembler for a given BFD, if that support is available. */ extern disassembler_ftype disassembler PARAMS ((bfd *)); diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 777ddea7e07..09a76dc0714 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,22 @@ +1999-06-14 Nick Clifton & Drew Mosley + + * arm-dis.c (arm_regnames): Turn into a pointer to a register + name set. + (arm_regnames_standard): New variable: Array of ARM register + names according to ARM instruction set nomenclature. + (arm_regnames_apcs): New variable: Array of ARM register names + according to ARM Procedure Call Standard. + (arm_regnames_raw): New variable: Array of ARM register names + using just 'r' and the register number. + (arm_toggle_regnames): New function: Toggle the chosen register set + naming scheme. + (parse_disassembler_options): New function: Parse any target + disassembler command line options. + (print_insn_big_arm): Call parse_disassembler_options if any + are defined. + (print_insn_little_arm): Call parse_disassembler_options if any + are defined. + 1999-06-13 Ian Lance Taylor * i386-dis.c (FWAIT_OPCODE): Define. diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index 5bc1350eb41..ba03b9baef1 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -1,5 +1,5 @@ /* Instruction printing code for the ARM - Copyright (C) 1994, 95, 96, 97, 1998 Free Software Foundation, Inc. + Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) Modification by James G. Smith (jsmith@cygnus.co.uk) @@ -35,9 +35,20 @@ static char *arm_conditional[] = {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", "hi", "ls", "ge", "lt", "gt", "le", "", "nv"}; -static char *arm_regnames[] = +static char *arm_regnames_raw[] = {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc"}; + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}; + +static char *arm_regnames_standard[] = +{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc"}; + +static char *arm_regnames_apcs[] = +{"a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", + "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc"}; + +/* Choose which register name set to use. */ +static char **arm_regnames = arm_regnames_standard; static char *arm_fp_const[] = {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"}; @@ -742,6 +753,45 @@ print_insn_thumb (pc, info, given) abort (); } +/* Select a different register name set. + Returns true if the name set selected is the APCS name set. */ +int +arm_toggle_regnames () +{ + if (arm_regnames == arm_regnames_standard) + arm_regnames = arm_regnames_apcs; + else + arm_regnames = arm_regnames_standard; + + return arm_regnames == arm_regnames_apcs; +} + +static void +parse_disassembler_options (options) + char * options; +{ + if (options == NULL) + return; + + if (strncmp (options, "reg-names-", 10) == 0) + { + options += 10; + + if (strcmp (options, "std") == 0) + arm_regnames = arm_regnames_standard; + else if (strcmp (options, "apcs") == 0) + arm_regnames = arm_regnames_apcs; + else if (strcmp (options, "raw") == 0) + arm_regnames = arm_regnames_raw; + else + fprintf (stderr, "Unrecognised register name set: %s\n", options); + } + else + fprintf (stderr, "Unrecognised disassembler option: %s\n", options); + + return; +} + /* NOTE: There are no checks in these routines that the relevant number of data bytes exist */ int @@ -756,6 +806,14 @@ print_insn_big_arm (pc, info) elf_symbol_type *es; int is_thumb; + if (info->disassembler_options) + { + parse_disassembler_options (info->disassembler_options); + + /* To avoid repeated parsing of this option, we remove it here. */ + info->disassembler_options = NULL; + } + is_thumb = false; if (info->symbols != NULL) { @@ -838,6 +896,14 @@ print_insn_little_arm (pc, info) elf_symbol_type *es; int is_thumb; + if (info->disassembler_options) + { + parse_disassembler_options (info->disassembler_options); + + /* To avoid repeated parsing of this option, we remove it here. */ + info->disassembler_options = NULL; + } + is_thumb = false; if (info->symbols != NULL) { diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c index 4898b42458d..da6d5d5712c 100644 --- a/opcodes/disassemble.c +++ b/opcodes/disassemble.c @@ -245,4 +245,3 @@ disassembler (abfd) } return disassemble; } - -- 2.30.2