From b8176214a5bb9810bf6d5244815e9a49c5055dce Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 6 Oct 1994 16:47:32 +0000 Subject: [PATCH] * defs.h: If TARGET_BYTE_ORDER_SELECTABLE is defined by tm.h, define TARGET_BYTE_ORDER as target_byte_order, and declare target_byte_order as an extern int, and define BITS_BIG_ENDIAN as a test of TARGET_BYTE_ORDER. * top.c: Several additions if TARGET_BYTE_ORDER_SELECTABLE is defined: (endianlist, target_byte_order): New variables. (set_endian, set_endian_big, set_endian_little): New functions. (show_endian): New function. (init_cmd_lists): Initialize endianlist. (init_main): Add commands ``set endian big'', ``set endian little'', and ``show endian''. * a29k-pinsn.c: Rewrite uses of TARGET_BYTE_ORDER and BITS_BIG_ENDIAN to switch at run time rather than at compile time. * coffread.c, dwarfread.c, findvar.c, mips-tdep.c: Likewise. * remote-os9k.c, stabsread.c, valarith.c, valprint.c: Likewise. * values.c: Likewise. * mips-tdep.c: Rewrite uses of GDB_TARGET_IS_MIPS64 to switch at run time rather than at compile time. --- gdb/a29k-pinsn.c | 9 +++-- gdb/dwarfread.c | 72 +++++++++++++++++++++------------------ gdb/remote-os9k.c | 36 +++++++++----------- gdb/stabsread.c | 13 ++++---- gdb/top.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++ gdb/values.c | 14 ++++---- 6 files changed, 156 insertions(+), 73 deletions(-) diff --git a/gdb/a29k-pinsn.c b/gdb/a29k-pinsn.c index a90cdc0cc7..70e8e5bd00 100644 --- a/gdb/a29k-pinsn.c +++ b/gdb/a29k-pinsn.c @@ -33,9 +33,8 @@ print_insn (memaddr, stream) GDB_INIT_DISASSEMBLE_INFO(info, stream); -#if TARGET_BYTE_ORDER == BIG_ENDIAN - return print_insn_big_a29k (memaddr, &info); -#else - return print_insn_little_a29k (memaddr, &info); -#endif + if (TARGET_BYTE_ORDER == BIG_ENDIAN) + return print_insn_big_a29k (memaddr, &info); + else + return print_insn_little_a29k (memaddr, &info); } diff --git a/gdb/dwarfread.c b/gdb/dwarfread.c index 150e1d8166..aebe6bffeb 100644 --- a/gdb/dwarfread.c +++ b/gdb/dwarfread.c @@ -985,9 +985,7 @@ struct_type (dip, thisdie, enddie, objfile) int n; struct dieinfo mbr; char *nextdie; -#if !BITS_BIG_ENDIAN int anonymous_size; -#endif if ((type = lookup_utype (dip -> die_ref)) == NULL) { @@ -1060,39 +1058,47 @@ struct_type (dip, thisdie, enddie, objfile) list -> field.bitpos = 8 * locval (mbr.at_location); /* Handle bit fields. */ list -> field.bitsize = mbr.at_bit_size; -#if BITS_BIG_ENDIAN - /* For big endian bits, the at_bit_offset gives the additional - bit offset from the MSB of the containing anonymous object to - the MSB of the field. We don't have to do anything special - since we don't need to know the size of the anonymous object. */ - list -> field.bitpos += mbr.at_bit_offset; -#else - /* For little endian bits, we need to have a non-zero at_bit_size, - so that we know we are in fact dealing with a bitfield. Compute - the bit offset to the MSB of the anonymous object, subtract off - the number of bits from the MSB of the field to the MSB of the - object, and then subtract off the number of bits of the field - itself. The result is the bit offset of the LSB of the field. */ - if (mbr.at_bit_size > 0) + if (BITS_BIG_ENDIAN) { - if (mbr.has_at_byte_size) - { - /* The size of the anonymous object containing the bit field - is explicit, so use the indicated size (in bytes). */ - anonymous_size = mbr.at_byte_size; - } - else - { - /* The size of the anonymous object containing the bit field - matches the size of an object of the bit field's type. - DWARF allows at_byte_size to be left out in such cases, - as a debug information size optimization. */ - anonymous_size = TYPE_LENGTH (list -> field.type); - } - list -> field.bitpos += - anonymous_size * 8 - mbr.at_bit_offset - mbr.at_bit_size; + /* For big endian bits, the at_bit_offset gives the + additional bit offset from the MSB of the containing + anonymous object to the MSB of the field. We don't + have to do anything special since we don't need to + know the size of the anonymous object. */ + list -> field.bitpos += mbr.at_bit_offset; + } + else + { + /* For little endian bits, we need to have a non-zero + at_bit_size, so that we know we are in fact dealing + with a bitfield. Compute the bit offset to the MSB + of the anonymous object, subtract off the number of + bits from the MSB of the field to the MSB of the + object, and then subtract off the number of bits of + the field itself. The result is the bit offset of + the LSB of the field. */ + if (mbr.at_bit_size > 0) + { + if (mbr.has_at_byte_size) + { + /* The size of the anonymous object containing + the bit field is explicit, so use the + indicated size (in bytes). */ + anonymous_size = mbr.at_byte_size; + } + else + { + /* The size of the anonymous object containing + the bit field matches the size of an object + of the bit field's type. DWARF allows + at_byte_size to be left out in such cases, as + a debug information size optimization. */ + anonymous_size = TYPE_LENGTH (list -> field.type); + } + list -> field.bitpos += + anonymous_size * 8 - mbr.at_bit_offset - mbr.at_bit_size; + } } -#endif nfields++; break; default: diff --git a/gdb/remote-os9k.c b/gdb/remote-os9k.c index cf4cd9b7d3..a3f67745aa 100644 --- a/gdb/remote-os9k.c +++ b/gdb/remote-os9k.c @@ -270,13 +270,11 @@ get_hex_regs (n, regno) val = 0; for (j = 0; j < 4; j++) { -#if TARGET_BYTE_ORDER == BIG_ENDIAN - get_hex_byte(&b); - val = (val << 8) + b; -#else - get_hex_byte(&b); - val = val + (b << (j*8)); -#endif + get_hex_byte (&b); + if (TARGET_BYTE_ORDER == BIG_ENDIAN) + val = (val << 8) + b; + else + val = val + (b << (j*8)); } supply_register (regno++, (char *) &val); } @@ -577,13 +575,11 @@ rombug_fetch_registers () val = 0; for (j = 0; j < 2; j++) { -#if TARGET_BYTE_ORDER == BIG_ENDIAN - get_hex_byte(&b); - val = (val << 8) + b; -#else - get_hex_byte(&b); - val = val + (b << (j*8)); -#endif + get_hex_byte (&b); + if (TARGET_BYTE_ORDER == BIG_ENDIAN) + val = (val << 8) + b; + else + val = val + (b << (j*8)); } if (regno == 8) i = 10; @@ -640,13 +636,11 @@ rombug_fetch_register (regno) val = 0; for (j = 0; j < 2; j++) { -#if TARGET_BYTE_ORDER == BIG_ENDIAN - get_hex_byte(&b); - val = (val << 8) + b; -#else - get_hex_byte(&b); - val = val + (b << (j*8)); -#endif + get_hex_byte (&b); + if (TARGET_BYTE_ORDER == BIG_ENDIAN) + val = (val << 8) + b; + else + val = val + (b << (j*8)); } supply_register (regno, (char *) &val); } diff --git a/gdb/stabsread.c b/gdb/stabsread.c index 5b5fee572d..042d450f62 100644 --- a/gdb/stabsread.c +++ b/gdb/stabsread.c @@ -867,11 +867,13 @@ define_symbol (valu, string, desc, type, objfile) #endif add_symbol_to_list (sym, &local_symbols); -#if TARGET_BYTE_ORDER == LITTLE_ENDIAN - /* On little-endian machines, this crud is never necessary, and, - if the extra bytes contain garbage, is harmful. */ - break; -#else /* Big endian. */ + if (TARGET_BYTE_ORDER != BIG_ENDIAN) + { + /* On little-endian machines, this crud is never necessary, + and, if the extra bytes contain garbage, is harmful. */ + break; + } + /* If it's gcc-compiled, if it says `short', believe it. */ if (processing_gcc_compilation || BELIEVE_PCC_PROMOTION) break; @@ -950,7 +952,6 @@ define_symbol (valu, string, desc, type, objfile) #endif /* no BELIEVE_PCC_PROMOTION_TYPE. */ } #endif /* !BELIEVE_PCC_PROMOTION. */ -#endif /* Big endian. */ case 'P': /* acc seems to use P to delare the prototypes of functions that diff --git a/gdb/top.c b/gdb/top.c index c052302f2f..113c8bbb6a 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -92,6 +92,18 @@ static void init_signals PARAMS ((void)); static void set_verbose PARAMS ((char *, int, struct cmd_list_element *)); +#ifdef TARGET_BYTE_ORDER_SELECTABLE + +static void set_endian PARAMS ((char *, int)); + +static void set_endian_big PARAMS ((char *, int)); + +static void set_endian_little PARAMS ((char *, int)); + +static void show_endian PARAMS ((char *, int)); + +#endif + static void show_history PARAMS ((char *, int)); static void set_history PARAMS ((char *, int)); @@ -205,6 +217,12 @@ struct cmd_list_element *unsetlist; struct cmd_list_element *showlist; +#ifdef TARGET_BYTE_ORDER_SELECTABLE +/* Chain containing the \"set endian\" commands. */ + +struct cmd_list_element *endianlist; +#endif + /* Chain containing all defined \"set history\". */ struct cmd_list_element *sethistlist; @@ -2625,6 +2643,56 @@ echo_command (text, from_tty) gdb_flush (gdb_stdout); } + +#ifdef TARGET_BYTE_ORDER_SELECTABLE + +/* Functions to manipulate the endianness of the target. */ + +#ifndef TARGET_BYTE_ORDER_DEFAULT +#define TARGET_BYTE_ORDER_DEFAULT BIG_ENDIAN +#endif + +int target_byte_order = TARGET_BYTE_ORDER_DEFAULT; + +/* Called if the user enters ``set endian'' without an argument. */ +static void +set_endian (args, from_tty) + char *args; + int from_tty; +{ + printf_unfiltered ("\"set endian\" must be followed by \"big\" or \"little\".\n"); + show_endian (args, from_tty); +} + +/* Called by ``set endian big''. */ +static void +set_endian_big (args, from_tty) + char *args; + int from_tty; +{ + target_byte_order = BIG_ENDIAN; +} + +/* Called by ``set endian little''. */ +static void +set_endian_little (args, from_tty) + char *args; + int from_tty; +{ + target_byte_order = LITTLE_ENDIAN; +} + +/* Called by ``show endian''. */ +static void +show_endian (args, from_tty) + char *args; + int from_tty; +{ + printf_unfiltered ("The target is assumed to be %s endian.\n", + TARGET_BYTE_ORDER == BIG_ENDIAN ? "big" : "little"); +} + +#endif /* defined (TARGET_BYTE_ORDER_SELECTABLE) */ /* Functions to manipulate command line editing control variables. */ @@ -2795,6 +2863,9 @@ init_cmd_lists () setlist = NULL; unsetlist = NULL; showlist = NULL; +#ifdef TARGET_BYTE_ORDER_SELECTABLE + endianlist = NULL; +#endif sethistlist = NULL; showhistlist = NULL; unsethistlist = NULL; @@ -2845,6 +2916,20 @@ init_main () { struct cmd_list_element *c; +#ifdef TARGET_BYTE_ORDER_SELECTABLE + + add_prefix_cmd ("endian", class_support, set_endian, + "Set endianness of target.", + &endianlist, "set endian ", 0, &setlist); + add_cmd ("big", class_support, set_endian_big, + "Set target as being big endian.", &endianlist); + add_cmd ("little", class_support, set_endian_little, + "Set target as being little endian.", &endianlist); + add_cmd ("endian", class_support, show_endian, + "Show endianness of target.", &showlist); + +#endif /* defined (TARGET_BYTE_ORDER_SELECTABLE) */ + #ifdef DEFAULT_PROMPT prompt = savestring (DEFAULT_PROMPT, strlen(DEFAULT_PROMPT)); #else diff --git a/gdb/values.c b/gdb/values.c index 81fa4e7fc0..916bf6f27a 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -1249,11 +1249,10 @@ unpack_field_as_long (type, valaddr, fieldno) /* Extract bits. See comment above. */ -#if BITS_BIG_ENDIAN - lsbcount = (sizeof val * 8 - bitpos % 8 - bitsize); -#else - lsbcount = (bitpos % 8); -#endif + if (BITS_BIG_ENDIAN) + lsbcount = (sizeof val * 8 - bitpos % 8 - bitsize); + else + lsbcount = (bitpos % 8); val >>= lsbcount; /* If the field does not entirely fill a LONGEST, then zero the sign bits. @@ -1300,9 +1299,8 @@ modify_field (addr, fieldval, bitpos, bitsize) oword = extract_signed_integer (addr, sizeof oword); /* Shifting for bit field depends on endianness of the target machine. */ -#if BITS_BIG_ENDIAN - bitpos = sizeof (oword) * 8 - bitpos - bitsize; -#endif + if (BITS_BIG_ENDIAN) + bitpos = sizeof (oword) * 8 - bitpos - bitsize; /* Mask out old value, while avoiding shifts >= size of oword */ if (bitsize < 8 * sizeof (oword))