diff options
-rw-r--r-- | gdb/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/arm-tdep.c | 231 |
2 files changed, 145 insertions, 95 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a12240f7c85..1891b3925b4 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2000-02-16 Fernando Nasser <fnasser@totem.to.cygnus.com> + + * arm-tdep.c (set_disassembly_flavor, arm_othernames, + _initialize_arm_tdep): Allows the user to choose between any of + the flavors available for the disassembly to be used in the "info + reg" command and elsewhere in gdb. It prevents having to maintain + this information in two places by using the data kept in the + opcodes directory. + 2000-02-09 Mark Kettenis <kettenis@gnu.org> * configure.in: Check for lwpid_t, psaddr_t, prgregset_t and diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 725b07a5214..24f54667f2c 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -30,56 +30,41 @@ extern void _initialize_arm_tdep (void); -/* - The following macros are actually wrong. Neither arm nor thumb can - or should set the lsb on addr. - The thumb addresses are mod 2, so (addr & 2) would be a good heuristic - to use when checking for thumb (see arm_pc_is_thumb() below). - Unfortunately, something else depends on these (incorrect) macros, so - fixing them actually breaks gdb. I didn't have time to investigate. Z.R. - */ -/* Thumb function addresses are odd (bit 0 is set). Here are some - macros to test, set, or clear bit 0 of addresses. */ -#define IS_THUMB_ADDR(addr) ((addr) & 1) -#define MAKE_THUMB_ADDR(addr) ((addr) | 1) -#define UNMAKE_THUMB_ADDR(addr) ((addr) & ~1) +/* From opcodes/arm-dis.c */ + +extern int get_arm_regname_num_options (void); + +extern int set_arm_regname_option (int option); -/* Default register names as specified by APCS. */ -static char * atpcs_register_names[] = -{"a1", "a2", "a3", "a4", /* 0 1 2 3 */ - "v1", "v2", "v3", "v4", /* 4 5 6 7 */ - "v5", "v6", "v7", "v8", /* 8 9 10 11 */ - "IP", "SP", "LR", "PC", /* 12 13 14 15 */ - "f0", "f1", "f2", "f3", /* 16 17 18 19 */ - "f4", "f5", "f6", "f7", /* 20 21 22 23 */ - "FPS", "PS" }; /* 24 25 */ - -/* Alternate set of registers names used by GCC. */ -static char * additional_register_names[] = +extern int get_arm_regnames (int option, const char **setname, + const char **setdescription, + const char ***regnames); + +/* Number of different reg name sets (options). */ +static int num_flavor_options; + +/* We have more registers than the disassembler as gdb can print the value + of special registers as well. + The general register names are overwritten by whatever is being used by + the disassembler at the moment. We also adjust the case of cpsr and fps. */ + +/* Initial value: Register names used in ARM's ISA documentation. */ +static char * arm_register_name_strings[] = {"r0", "r1", "r2", "r3", /* 0 1 2 3 */ "r4", "r5", "r6", "r7", /* 4 5 6 7 */ "r8", "r9", "r10", "r11", /* 8 9 10 11 */ "r12", "sp", "lr", "pc", /* 12 13 14 15 */ "f0", "f1", "f2", "f3", /* 16 17 18 19 */ "f4", "f5", "f6", "f7", /* 20 21 22 23 */ - "fps", "ps" }; /* 24 25 */ + "fps", "cpsr" }; /* 24 25 */ +char **arm_register_names = arm_register_name_strings; -/* This is the variable that is set with "set disassembly-flavor". - By default use the APCS registers names. */ -char ** arm_register_names = atpcs_register_names; - -/* Valid register name flavours. */ -static char apcs_flavor[] = "apcs"; -static char r_prefix_flavor[] = "r-prefix"; -static char * valid_flavors[] = -{ - apcs_flavor, - r_prefix_flavor, - NULL -}; +/* Valid register name flavors. */ +static char **valid_flavors; -/* Disassembly flavor to use. */ -static char *disassembly_flavor = apcs_flavor; +/* Disassembly flavor to use. Default to "std" register names. */ +static char *disassembly_flavor; +static int current_option; /* Index to that option in the opcodes table. */ /* This is used to keep the bfd arch_info in sync with the disassembly flavor. */ @@ -103,6 +88,12 @@ struct frame_extra_info int framereg; }; +/* Addresses for calling Thumb functions have the bit 0 set. + Here are some macros to test, set, or clear bit 0 of addresses. */ +#define IS_THUMB_ADDR(addr) ((addr) & 1) +#define MAKE_THUMB_ADDR(addr) ((addr) | 1) +#define UNMAKE_THUMB_ADDR(addr) ((addr) & ~1) + #define SWAP_TARGET_AND_HOST(buffer,len) \ do \ { \ @@ -1388,52 +1379,6 @@ arm_float_info (void) print_fpu_flags (status); } -/* If the disassembly mode is APCS, we have to also switch the - bfd mach_type. This function is run in the set disassembly_flavor - command, and does that. */ - -static void -set_disassembly_flavor_sfunc (char *args, int from_tty, - struct cmd_list_element *c) -{ - set_disassembly_flavor (); -} - -static void -set_disassembly_flavor (void) -{ - if (disassembly_flavor == apcs_flavor) - { - parse_arm_disassembler_option ("reg-names-atpcs"); - arm_register_names = atpcs_register_names; - } - else if (disassembly_flavor == r_prefix_flavor) - { - parse_arm_disassembler_option ("reg-names-std"); - arm_register_names = additional_register_names; - } -} - -/* arm_othernames implements the "othernames" command. This is kind - of hacky, and I prefer the set-show disassembly-flavor which is - also used for the x86 gdb. I will keep this around, however, in - case anyone is actually using it. */ - -static void -arm_othernames (char *names, int n) -{ - if (disassembly_flavor == r_prefix_flavor) - { - disassembly_flavor = apcs_flavor; - set_disassembly_flavor (); - } - else - { - disassembly_flavor = r_prefix_flavor; - set_disassembly_flavor (); - } -} - #if 0 /* FIXME: The generated assembler works but sucks. Instead of using r0, r1 it pushes them on the stack, then loads them into r3, r4 and @@ -2033,29 +1978,121 @@ arm_skip_stub (CORE_ADDR pc) return 0; /* not a stub */ } +/* If the user changes the register disassembly flavor used for info register + and other commands, we have to also switch the flavor used in opcodes + for disassembly output. + This function is run in the set disassembly_flavor command, and does that. */ + +static void +set_disassembly_flavor_sfunc (char *args, int from_tty, + struct cmd_list_element *c) +{ + set_disassembly_flavor (); +} + +static void +set_disassembly_flavor (void) +{ + const char *setname, *setdesc, **regnames; + int numregs, j; + + /* Find the flavor that the user wants in the opcodes table. */ + int current = 0; + numregs = get_arm_regnames (current, &setname, &setdesc, ®names); + while ((disassembly_flavor != setname) + && (current < num_flavor_options)) + get_arm_regnames (++current, &setname, &setdesc, ®names); + current_option = current; + + /* Fill our copy. */ + for (j = 0; j < numregs; j++) + arm_register_names[j] = (char *) regnames[j]; + + /* Adjust case. */ + if (isupper (*regnames[PC_REGNUM])) + { + arm_register_names[FPS_REGNUM] = "FPS"; + arm_register_names[PS_REGNUM] = "CPSR"; + } + else + { + arm_register_names[FPS_REGNUM] = "fps"; + arm_register_names[PS_REGNUM] = "cpsr"; + } + + /* Synchronize the disassembler. */ + set_arm_regname_option (current); +} + +/* arm_othernames implements the "othernames" command. This is kind + of hacky, and I prefer the set-show disassembly-flavor which is + also used for the x86 gdb. I will keep this around, however, in + case anyone is actually using it. */ + +static void +arm_othernames (char *names, int n) +{ + /* Circle through the various flavors. */ + current_option = (current_option + 1) % num_flavor_options; + + disassembly_flavor = valid_flavors[current_option]; + set_disassembly_flavor (); +} + void _initialize_arm_tdep (void) { + struct ui_file *stb; + long length; struct cmd_list_element *new_cmd; + const char *setname, *setdesc, **regnames; + int numregs, i, j; + static char *helptext; tm_print_insn = gdb_print_insn_arm; + /* Get the number of possible sets of register names defined in opcodes. */ + num_flavor_options = get_arm_regname_num_options (); + /* Sync the opcode insn printer with our register viewer: */ - parse_arm_disassembler_option ("reg-names-atpcs"); + parse_arm_disassembler_option ("reg-names-std"); - /* Add the deprecated "othernames" command */ + /* Begin creating the help text. */ + stb = mem_fileopen (); + fprintf_unfiltered (stb, "Set the disassembly flavor.\n\ +The valid values are:\n"); - add_com ("othernames", class_obscure, arm_othernames, - "Switch to the other set of register names."); + /* Initialize the array that will be passed to add_set_enum_cmd(). */ + valid_flavors = xmalloc ((num_flavor_options + 1) * sizeof (char *)); + for (i = 0; i < num_flavor_options; i++) + { + numregs = get_arm_regnames (i, &setname, &setdesc, ®names); + valid_flavors[i] = (char *) setname; + fprintf_unfiltered (stb, "%s - %s\n", setname, + setdesc); + /* Copy the default names (if found) and synchronize disassembler. */ + if (!strcmp (setname, "std")) + { + disassembly_flavor = (char *) setname; + current_option = i; + for (j = 0; j < numregs; j++) + arm_register_names[j] = (char *) regnames[j]; + set_arm_regname_option (i); + } + } + /* Mark the end of valid options. */ + valid_flavors[num_flavor_options] = NULL; - /* Add the disassembly-flavor command */ + /* Finish the creation of the help text. */ + fprintf_unfiltered (stb, "The default is \"std\"."); + helptext = ui_file_xstrdup (stb, &length); + ui_file_delete (stb); + /* Add the disassembly-flavor command */ new_cmd = add_set_enum_cmd ("disassembly-flavor", no_class, valid_flavors, (char *) &disassembly_flavor, - "Set the disassembly flavor, \ -the valid values are \"apcs\" and \"r-prefix\", \ -and the default value is \"apcs\".", + helptext, &setlist); new_cmd->function.sfunc = set_disassembly_flavor_sfunc; add_show_from_set (new_cmd, &showlist); @@ -2066,6 +2103,10 @@ and the default value is \"apcs\".", "Set usage of ARM 32-bit mode.\n", &setlist), &showlist); + /* Add the deprecated "othernames" command */ + + add_com ("othernames", class_obscure, arm_othernames, + "Switch to the next set of register names."); } /* Test whether the coff symbol specific value corresponds to a Thumb |