X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fhppa-tdep.c;h=866e6cf6dea3dc5cc8e9fb7a4dd2dc9cbb75b7c8;hb=be6d4f74c77c6f521afc873d226480e001cb99c2;hp=d5798cffbd6f4bad8577ebfe329545e7e7ae2340;hpb=8f8a23a2c397294ab562c6cf7020679f85b921ec;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c index d5798cffbd..866e6cf6de 100644 --- a/gdb/hppa-tdep.c +++ b/gdb/hppa-tdep.c @@ -1,7 +1,6 @@ /* Target-dependent code for the HP PA-RISC architecture. - Copyright (C) 1986-1987, 1989-1996, 1998-2005, 2007-2012 Free - Software Foundation, Inc. + Copyright (C) 1986-2019 Free Software Foundation, Inc. Contributed by the Center for Software Science at the University of Utah (pa-gdb-bugs@cs.utah.edu). @@ -27,7 +26,6 @@ #include "regcache.h" #include "completer.h" #include "osabi.h" -#include "gdb_assert.h" #include "arch-utils.h" /* For argument passing to the inferior. */ #include "symtab.h" @@ -41,6 +39,7 @@ #include "gdbtypes.h" #include "objfiles.h" #include "hppa-tdep.h" +#include static int hppa_debug = 0; @@ -48,13 +47,44 @@ static int hppa_debug = 0; static const int hppa32_num_regs = 128; static const int hppa64_num_regs = 96; +/* We use the objfile->obj_private pointer for two things: + * 1. An unwind table; + * + * 2. A pointer to any associated shared library object. + * + * #defines are used to help refer to these objects. + */ + +/* Info about the unwind table associated with an object file. + * This is hung off of the "objfile->obj_private" pointer, and + * is allocated in the objfile's psymbol obstack. This allows + * us to have unique unwind info for each executable and shared + * library that we are debugging. + */ +struct hppa_unwind_info + { + struct unwind_table_entry *table; /* Pointer to unwind info */ + struct unwind_table_entry *cache; /* Pointer to last entry we found */ + int last; /* Index of last entry */ + }; + +struct hppa_objfile_private + { + struct hppa_unwind_info *unwind_info; /* a pointer */ + struct so_list *so_info; /* a pointer */ + CORE_ADDR dp; + + int dummy_call_sequence_reg; + CORE_ADDR dummy_call_sequence_addr; + }; + /* hppa-specific object data -- unwind and solib info. TODO/maybe: think about splitting this into two parts; the unwind data is common to all hppa targets, but is only used in this file; we can register that separately and make this static. The solib data is probably hpux- specific, so we can create a separate extern objfile_data that is registered by hppa-hpux-tdep.c and shared with pa64solib.c and somsolib.c. */ -const struct objfile_data *hppa_objfile_priv_data = NULL; +static const struct objfile_data *hppa_objfile_priv_data = NULL; /* Get at various relevent fields of an instruction word. */ #define MASK_5 0x1f @@ -75,7 +105,7 @@ const struct objfile_data *hppa_objfile_priv_data = NULL; static int hppa_sign_extend (unsigned val, unsigned bits) { - return (int) (val >> (bits - 1) ? (-1 << bits) | val : val); + return (int) (val >> (bits - 1) ? (-(1 << bits)) | val : val); } /* For many immediate values the sign bit is the low bit! */ @@ -83,7 +113,7 @@ hppa_sign_extend (unsigned val, unsigned bits) static int hppa_low_hppa_sign_extend (unsigned val, unsigned bits) { - return (int) ((val & 0x1 ? (-1 << (bits - 1)) : 0) | val >> 1); + return (int) ((val & 0x1 ? (-(1 << (bits - 1))) : 0) | val >> 1); } /* Extract the bits at positions between FROM and TO, using HP's numbering @@ -163,25 +193,22 @@ hppa_extract_17 (unsigned word) CORE_ADDR hppa_symbol_address(const char *sym) { - struct minimal_symbol *minsym; + struct bound_minimal_symbol minsym; minsym = lookup_minimal_symbol (sym, NULL, NULL); - if (minsym) - return SYMBOL_VALUE_ADDRESS (minsym); + if (minsym.minsym) + return BMSYMBOL_VALUE_ADDRESS (minsym); else return (CORE_ADDR)-1; } -struct hppa_objfile_private * +static struct hppa_objfile_private * hppa_init_objfile_priv_data (struct objfile *objfile) { - struct hppa_objfile_private *priv; + hppa_objfile_private *priv + = OBSTACK_ZALLOC (&objfile->objfile_obstack, hppa_objfile_private); - priv = (struct hppa_objfile_private *) - obstack_alloc (&objfile->objfile_obstack, - sizeof (struct hppa_objfile_private)); set_objfile_data (objfile, hppa_objfile_priv_data, priv); - memset (priv, 0, sizeof (*priv)); return priv; } @@ -194,8 +221,8 @@ hppa_init_objfile_priv_data (struct objfile *objfile) static int compare_unwind_entries (const void *arg1, const void *arg2) { - const struct unwind_table_entry *a = arg1; - const struct unwind_table_entry *b = arg2; + const struct unwind_table_entry *a = (const struct unwind_table_entry *) arg1; + const struct unwind_table_entry *b = (const struct unwind_table_entry *) arg2; if (a->region_start > b->region_start) return 1; @@ -222,7 +249,7 @@ record_text_segment_lowaddr (bfd *abfd, asection *section, void *data) static void internalize_unwinds (struct objfile *objfile, struct unwind_table_entry *table, asection *section, unsigned int entries, - unsigned int size, CORE_ADDR text_offset) + size_t size, CORE_ADDR text_offset) { /* We will read the unwind entries into temporary memory, then fill in the actual unwind table. */ @@ -232,7 +259,7 @@ internalize_unwinds (struct objfile *objfile, struct unwind_table_entry *table, struct gdbarch *gdbarch = get_objfile_arch (objfile); unsigned long tmp; unsigned i; - char *buf = alloca (size); + char *buf = (char *) alloca (size); CORE_ADDR low_text_segment_address; /* For ELF targets, then unwinds are supposed to @@ -321,14 +348,14 @@ static void read_unwind_info (struct objfile *objfile) { asection *unwind_sec, *stub_unwind_sec; - unsigned unwind_size, stub_unwind_size, total_size; + size_t unwind_size, stub_unwind_size, total_size; unsigned index, unwind_entries; unsigned stub_entries, total_entries; CORE_ADDR text_offset; struct hppa_unwind_info *ui; struct hppa_objfile_private *obj_private; - text_offset = ANOFFSET (objfile->section_offsets, 0); + text_offset = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); ui = (struct hppa_unwind_info *) obstack_alloc (&objfile->objfile_obstack, sizeof (struct hppa_unwind_info)); @@ -405,7 +432,7 @@ read_unwind_info (struct objfile *objfile) if (stub_unwind_size > 0) { unsigned int i; - char *buf = alloca (stub_unwind_size); + char *buf = (char *) alloca (stub_unwind_size); /* Read in the stub unwind entries. */ bfd_get_section_contents (objfile->obfd, stub_unwind_sec, buf, @@ -456,7 +483,6 @@ struct unwind_table_entry * find_unwind_entry (CORE_ADDR pc) { int first, middle, last; - struct objfile *objfile; struct hppa_objfile_private *priv; if (hppa_debug) @@ -471,59 +497,61 @@ find_unwind_entry (CORE_ADDR pc) return NULL; } - ALL_OBJFILES (objfile) - { - struct hppa_unwind_info *ui; - ui = NULL; - priv = objfile_data (objfile, hppa_objfile_priv_data); - if (priv) - ui = ((struct hppa_objfile_private *) priv)->unwind_info; - - if (!ui) - { - read_unwind_info (objfile); - priv = objfile_data (objfile, hppa_objfile_priv_data); - if (priv == NULL) - error (_("Internal error reading unwind information.")); - ui = ((struct hppa_objfile_private *) priv)->unwind_info; - } + for (objfile *objfile : current_program_space->objfiles ()) + { + struct hppa_unwind_info *ui; + ui = NULL; + priv = ((struct hppa_objfile_private *) + objfile_data (objfile, hppa_objfile_priv_data)); + if (priv) + ui = ((struct hppa_objfile_private *) priv)->unwind_info; + + if (!ui) + { + read_unwind_info (objfile); + priv = ((struct hppa_objfile_private *) + objfile_data (objfile, hppa_objfile_priv_data)); + if (priv == NULL) + error (_("Internal error reading unwind information.")); + ui = ((struct hppa_objfile_private *) priv)->unwind_info; + } - /* First, check the cache. */ + /* First, check the cache. */ - if (ui->cache - && pc >= ui->cache->region_start - && pc <= ui->cache->region_end) - { - if (hppa_debug) - fprintf_unfiltered (gdb_stdlog, "%s (cached) }\n", - hex_string ((uintptr_t) ui->cache)); - return ui->cache; - } + if (ui->cache + && pc >= ui->cache->region_start + && pc <= ui->cache->region_end) + { + if (hppa_debug) + fprintf_unfiltered (gdb_stdlog, "%s (cached) }\n", + hex_string ((uintptr_t) ui->cache)); + return ui->cache; + } - /* Not in the cache, do a binary search. */ + /* Not in the cache, do a binary search. */ - first = 0; - last = ui->last; + first = 0; + last = ui->last; - while (first <= last) - { - middle = (first + last) / 2; - if (pc >= ui->table[middle].region_start - && pc <= ui->table[middle].region_end) - { - ui->cache = &ui->table[middle]; - if (hppa_debug) - fprintf_unfiltered (gdb_stdlog, "%s }\n", - hex_string ((uintptr_t) ui->cache)); - return &ui->table[middle]; - } + while (first <= last) + { + middle = (first + last) / 2; + if (pc >= ui->table[middle].region_start + && pc <= ui->table[middle].region_end) + { + ui->cache = &ui->table[middle]; + if (hppa_debug) + fprintf_unfiltered (gdb_stdlog, "%s }\n", + hex_string ((uintptr_t) ui->cache)); + return &ui->table[middle]; + } - if (pc < ui->table[middle].region_start) - last = middle - 1; - else - first = middle + 1; - } - } /* ALL_OBJFILES() */ + if (pc < ui->table[middle].region_start) + last = middle - 1; + else + first = middle + 1; + } + } if (hppa_debug) fprintf_unfiltered (gdb_stdlog, "NULL (not found) }\n"); @@ -531,18 +559,21 @@ find_unwind_entry (CORE_ADDR pc) return NULL; } -/* The epilogue is defined here as the area either on the `bv' instruction +/* Implement the stack_frame_destroyed_p gdbarch method. + + The epilogue is defined here as the area either on the `bv' instruction itself or an instruction which destroys the function's stack frame. We do not assume that the epilogue is at the end of a function as we can also have return sequences in the middle of a function. */ + static int -hppa_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) +hppa_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); unsigned long status; unsigned int inst; - char buf[4]; + gdb_byte buf[4]; status = target_read_memory (pc, buf, 4); if (status != 0) @@ -569,20 +600,16 @@ hppa_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) return 0; } -static const unsigned char * -hppa_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, int *len) -{ - static const unsigned char breakpoint[] = {0x00, 0x01, 0x00, 0x04}; - (*len) = sizeof (breakpoint); - return breakpoint; -} +constexpr gdb_byte hppa_break_insn[] = {0x00, 0x01, 0x00, 0x04}; + +typedef BP_MANIPULATION (hppa_break_insn) hppa_breakpoint; /* Return the name of a register. */ static const char * hppa32_register_name (struct gdbarch *gdbarch, int i) { - static char *names[] = { + static const char *names[] = { "flags", "r1", "rp", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", @@ -625,7 +652,7 @@ hppa32_register_name (struct gdbarch *gdbarch, int i) static const char * hppa64_register_name (struct gdbarch *gdbarch, int i) { - static char *names[] = { + static const char *names[] = { "flags", "r1", "rp", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", @@ -662,14 +689,13 @@ static int hppa64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) { /* The general registers and the sar are the same in both sets. */ - if (reg <= 32) + if (reg >= 0 && reg <= 32) return reg; /* fr4-fr31 are mapped from 72 in steps of 2. */ if (reg >= 72 && reg < 72 + 28 * 2 && !(reg & 1)) return HPPA64_FP4_REGNUM + (reg - 72) / 2; - warning (_("Unmapped DWARF DBX Register #%d encountered."), reg); return -1; } @@ -687,7 +713,8 @@ static CORE_ADDR hppa32_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr) + function_call_return_method return_method, + CORE_ADDR struct_addr) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); @@ -697,10 +724,6 @@ hppa32_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* Stack base address at which the first parameter is stored. */ CORE_ADDR param_end = 0; - /* The inner most end of the stack after all the parameters have - been pushed. */ - CORE_ADDR new_sp = 0; - /* Two passes. First pass computes the location of everything, second pass writes the bytes out. */ int write_pass; @@ -726,7 +749,7 @@ hppa32_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct type *type = check_typedef (value_type (arg)); /* The corresponding parameter that is pushed onto the stack, and [possibly] passed in a register. */ - char param_val[8]; + gdb_byte param_val[8]; int param_len; memset (param_val, 0, sizeof param_val); if (TYPE_LENGTH (type) > 8) @@ -797,17 +820,15 @@ hppa32_push_dummy_call (struct gdbarch *gdbarch, struct value *function, int fpLreg = 72 + (param_ptr - 36) / 4 * 2; int fpreg = 74 + (param_ptr - 32) / 8 * 4; - regcache_cooked_write (regcache, grreg, param_val); - regcache_cooked_write (regcache, fpLreg, param_val); + regcache->cooked_write (grreg, param_val); + regcache->cooked_write (fpLreg, param_val); if (param_len > 4) { - regcache_cooked_write (regcache, grreg + 1, - param_val + 4); + regcache->cooked_write (grreg + 1, param_val + 4); - regcache_cooked_write (regcache, fpreg, param_val); - regcache_cooked_write (regcache, fpreg + 1, - param_val + 4); + regcache->cooked_write (fpreg, param_val); + regcache->cooked_write (fpreg + 1, param_val + 4); } } } @@ -828,7 +849,7 @@ hppa32_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* If a structure has to be returned, set up register 28 to hold its address. */ - if (struct_return) + if (return_method == return_method_struct) regcache_cooked_write_unsigned (regcache, 28, struct_addr); gp = tdep->find_global_pointer (gdbarch, function); @@ -869,6 +890,7 @@ hppa64_integral_or_pointer_p (const struct type *type) } case TYPE_CODE_PTR: case TYPE_CODE_REF: + case TYPE_CODE_RVALUE_REF: return (TYPE_LENGTH (type) == 8); default: break; @@ -929,7 +951,7 @@ hppa64_convert_code_addr_to_fptr (struct gdbarch *gdbarch, CORE_ADDR code) addr += 2 * 8) { ULONGEST opdaddr; - char tmp[8]; + gdb_byte tmp[8]; if (target_read_memory (addr, tmp, sizeof (tmp))) break; @@ -947,7 +969,8 @@ static CORE_ADDR hppa64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr) + function_call_return_method return_method, + CORE_ADDR struct_addr) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); @@ -1022,8 +1045,8 @@ hppa64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, passed in floating-point registers, are passed in the right halves of the floating point registers; the left halves are unused." */ - regcache_cooked_write_part (regcache, regnum, offset % 8, - len, value_contents (arg)); + regcache->cooked_write_part (regnum, offset % 8, len, + value_contents (arg)); } } } @@ -1064,11 +1087,11 @@ hppa64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, regnum = HPPA_ARG0_REGNUM - offset / 8; while (regnum > HPPA_ARG0_REGNUM - 8 && len > 0) { - regcache_cooked_write_part (regcache, regnum, - offset % 8, min (len, 8), valbuf); - offset += min (len, 8); - valbuf += min (len, 8); - len -= min (len, 8); + regcache->cooked_write_part (regnum, offset % 8, std::min (len, 8), + valbuf); + offset += std::min (len, 8); + valbuf += std::min (len, 8); + len -= std::min (len, 8); regnum--; } @@ -1080,7 +1103,7 @@ hppa64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* Allocate the outgoing parameter area. Make sure the outgoing parameter area is multiple of 16 bytes in length. */ - sp += max (align_up (offset, 16), 64); + sp += std::max (align_up (offset, 16), (ULONGEST) 64); /* Allocate 32-bytes of scratch space. The documentation doesn't mention this, but it seems to be needed. */ @@ -1091,7 +1114,7 @@ hppa64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* If a structure has to be returned, set up GR 28 (%ret0) to hold its address. */ - if (struct_return) + if (return_method == return_method_struct) regcache_cooked_write_unsigned (regcache, HPPA_RET0_REGNUM, struct_addr); /* Set up GR27 (%dp) to hold the global pointer (gp). */ @@ -1130,20 +1153,18 @@ hppa32_return_value (struct gdbarch *gdbarch, struct value *function, if (part > 0) { if (readbuf != NULL) - regcache_cooked_read_part (regcache, reg, 4 - part, - part, readbuf); + regcache->cooked_read_part (reg, 4 - part, part, readbuf); if (writebuf != NULL) - regcache_cooked_write_part (regcache, reg, 4 - part, - part, writebuf); + regcache->cooked_write_part (reg, 4 - part, part, writebuf); reg++; } /* Now transfer the remaining register values. */ for (b = part; b < TYPE_LENGTH (type); b += 4) { if (readbuf != NULL) - regcache_cooked_read (regcache, reg, readbuf + b); + regcache->cooked_read (reg, readbuf + b); if (writebuf != NULL) - regcache_cooked_write (regcache, reg, writebuf + b); + regcache->cooked_write (reg, writebuf + b); reg++; } return RETURN_VALUE_REGISTER_CONVENTION; @@ -1160,7 +1181,7 @@ hppa64_return_value (struct gdbarch *gdbarch, struct value *function, int len = TYPE_LENGTH (type); int regnum, offset; - if (TYPE_LENGTH (type) > 16) + if (len > 16) { /* All return values larget than 128 bits must be aggregate return values. */ @@ -1221,10 +1242,10 @@ hppa64_return_value (struct gdbarch *gdbarch, struct value *function, { while (len > 0) { - regcache_cooked_read_part (regcache, regnum, offset, - min (len, 8), readbuf); - readbuf += min (len, 8); - len -= min (len, 8); + regcache->cooked_read_part (regnum, offset, std::min (len, 8), + readbuf); + readbuf += std::min (len, 8); + len -= std::min (len, 8); regnum++; } } @@ -1233,10 +1254,10 @@ hppa64_return_value (struct gdbarch *gdbarch, struct value *function, { while (len > 0) { - regcache_cooked_write_part (regcache, regnum, offset, - min (len, 8), writebuf); - writebuf += min (len, 8); - len -= min (len, 8); + regcache->cooked_write_part (regnum, offset, std::min (len, 8), + writebuf); + writebuf += std::min (len, 8); + len -= std::min (len, 8); regnum++; } } @@ -1277,13 +1298,13 @@ hppa64_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr) } CORE_ADDR -hppa_read_pc (struct regcache *regcache) +hppa_read_pc (readable_regcache *regcache) { ULONGEST ipsw; ULONGEST pc; - regcache_cooked_read_unsigned (regcache, HPPA_IPSW_REGNUM, &ipsw); - regcache_cooked_read_unsigned (regcache, HPPA_PCOQ_HEAD_REGNUM, &pc); + regcache->cooked_read (HPPA_IPSW_REGNUM, &ipsw); + regcache->cooked_read (HPPA_PCOQ_HEAD_REGNUM, &pc); /* If the current instruction is nullified, then we are effectively still executing the previous instruction. Pretend we are still @@ -1324,7 +1345,7 @@ prologue_inst_adjust_sp (unsigned long inst) /* std,ma X,D(sp) */ if ((inst & 0xffe00008) == 0x73c00008) - return (inst & 0x1 ? -1 << 13 : 0) | (((inst >> 4) & 0x3ff) << 3); + return (inst & 0x1 ? -(1 << 13) : 0) | (((inst >> 4) & 0x3ff) << 3); /* addil high21,%r30; ldo low11,(%r1),%r30) save high bits in save_high21 for later use. */ @@ -1378,37 +1399,106 @@ is_branch (unsigned long inst) } /* Return the register number for a GR which is saved by INST or - zero it INST does not save a GR. */ + zero if INST does not save a GR. -static int -inst_saves_gr (unsigned long inst) -{ - /* Does it look like a stw? */ - if ((inst >> 26) == 0x1a || (inst >> 26) == 0x1b - || (inst >> 26) == 0x1f - || ((inst >> 26) == 0x1f - && ((inst >> 6) == 0xa))) - return hppa_extract_5R_store (inst); + Referenced from: - /* Does it look like a std? */ - if ((inst >> 26) == 0x1c - || ((inst >> 26) == 0x03 - && ((inst >> 6) & 0xf) == 0xb)) - return hppa_extract_5R_store (inst); + parisc 1.1: + https://parisc.wiki.kernel.org/images-parisc/6/68/Pa11_acd.pdf - /* Does it look like a stwm? GCC & HPC may use this in prologues. */ - if ((inst >> 26) == 0x1b) - return hppa_extract_5R_store (inst); + parisc 2.0: + https://parisc.wiki.kernel.org/images-parisc/7/73/Parisc2.0.pdf - /* Does it look like sth or stb? HPC versions 9.0 and later use these - too. */ - if ((inst >> 26) == 0x19 || (inst >> 26) == 0x18 - || ((inst >> 26) == 0x3 - && (((inst >> 6) & 0xf) == 0x8 - || (inst >> 6) & 0xf) == 0x9)) - return hppa_extract_5R_store (inst); + According to Table 6-5 of Chapter 6 (Memory Reference Instructions) + on page 106 in parisc 2.0, all instructions for storing values from + the general registers are: - return 0; + Store: stb, sth, stw, std (according to Chapter 7, they + are only in both "inst >> 26" and "inst >> 6". + Store Absolute: stwa, stda (according to Chapter 7, they are only + in "inst >> 6". + Store Bytes: stby, stdby (according to Chapter 7, they are + only in "inst >> 6"). + + For (inst >> 26), according to Chapter 7: + + The effective memory reference address is formed by the addition + of an immediate displacement to a base value. + + - stb: 0x18, store a byte from a general register. + + - sth: 0x19, store a halfword from a general register. + + - stw: 0x1a, store a word from a general register. + + - stwm: 0x1b, store a word from a general register and perform base + register modification (2.0 will still treate it as stw). + + - std: 0x1c, store a doubleword from a general register (2.0 only). + + - stw: 0x1f, store a word from a general register (2.0 only). + + For (inst >> 6) when ((inst >> 26) == 0x03), according to Chapter 7: + + The effective memory reference address is formed by the addition + of an index value to a base value specified in the instruction. + + - stb: 0x08, store a byte from a general register (1.1 calls stbs). + + - sth: 0x09, store a halfword from a general register (1.1 calls + sths). + + - stw: 0x0a, store a word from a general register (1.1 calls stws). + + - std: 0x0b: store a doubleword from a general register (2.0 only) + + Implement fast byte moves (stores) to unaligned word or doubleword + destination. + + - stby: 0x0c, for unaligned word (1.1 calls stbys). + + - stdby: 0x0d for unaligned doubleword (2.0 only). + + Store a word or doubleword using an absolute memory address formed + using short or long displacement or indexed + + - stwa: 0x0e, store a word from a general register to an absolute + address (1.0 calls stwas). + + - stda: 0x0f, store a doubleword from a general register to an + absolute address (2.0 only). */ + +static int +inst_saves_gr (unsigned long inst) +{ + switch ((inst >> 26) & 0x0f) + { + case 0x03: + switch ((inst >> 6) & 0x0f) + { + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + return hppa_extract_5R_store (inst); + default: + return 0; + } + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + case 0x1c: + /* no 0x1d or 0x1e -- according to parisc 2.0 document */ + case 0x1f: + return hppa_extract_5R_store (inst); + default: + return 0; + } } /* Return the register number for a FR which is saved by INST or @@ -1447,7 +1537,7 @@ skip_prologue_hard_way (struct gdbarch *gdbarch, CORE_ADDR pc, int stop_before_branch) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - char buf[4]; + gdb_byte buf[4]; CORE_ADDR orig_pc = pc; unsigned long inst, stack_remaining, save_gr, save_fr, save_rp, save_sp; unsigned long args_stored, status, i, restart_gr, restart_fr; @@ -1751,7 +1841,7 @@ hppa_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) may be the first instruction of the prologue. If that happens, then the instruction skipping code has a bug that needs to be fixed. */ if (post_prologue_pc != 0) - return max (pc, post_prologue_pc); + return std::max (pc, post_prologue_pc); else return (skip_prologue_hard_way (gdbarch, pc, 1)); } @@ -1803,7 +1893,7 @@ hppa_frame_cache (struct frame_info *this_frame, void **this_cache) if (hppa_debug) fprintf_unfiltered (gdb_stdlog, "base=%s (cached) }", paddress (gdbarch, ((struct hppa_frame_cache *)*this_cache)->base)); - return (*this_cache); + return (struct hppa_frame_cache *) (*this_cache); } cache = FRAME_OBSTACK_ZALLOC (struct hppa_frame_cache); (*this_cache) = cache; @@ -1815,7 +1905,7 @@ hppa_frame_cache (struct frame_info *this_frame, void **this_cache) { if (hppa_debug) fprintf_unfiltered (gdb_stdlog, "base=NULL (no unwind entry) }"); - return (*this_cache); + return (struct hppa_frame_cache *) (*this_cache); } /* Turn the Entry_GR field into a bitmask. */ @@ -1898,14 +1988,14 @@ hppa_frame_cache (struct frame_info *this_frame, void **this_cache) pc += 4) { int reg; - char buf4[4]; + gdb_byte buf4[4]; long inst; if (!safe_frame_unwind_memory (this_frame, pc, buf4, sizeof buf4)) { error (_("Cannot read instruction at %s."), paddress (gdbarch, pc)); - return (*this_cache); + return (struct hppa_frame_cache *) (*this_cache); } inst = extract_unsigned_integer (buf4, sizeof buf4, byte_order); @@ -1964,7 +2054,7 @@ hppa_frame_cache (struct frame_info *this_frame, void **this_cache) CORE_ADDR offset; if ((inst >> 26) == 0x1c) - offset = (inst & 0x1 ? -1 << 13 : 0) + offset = (inst & 0x1 ? -(1 << 13) : 0) | (((inst >> 4) & 0x3ff) << 3); else if ((inst >> 26) == 0x03) offset = hppa_low_hppa_sign_extend (inst & 0x1f, 5); @@ -2178,7 +2268,7 @@ hppa_frame_cache (struct frame_info *this_frame, void **this_cache) if (hppa_debug) fprintf_unfiltered (gdb_stdlog, "base=%s }", paddress (gdbarch, ((struct hppa_frame_cache *)*this_cache)->base)); - return (*this_cache); + return (struct hppa_frame_cache *) (*this_cache); } static void @@ -2186,7 +2276,6 @@ hppa_frame_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) { struct hppa_frame_cache *info; - CORE_ADDR pc = get_frame_pc (this_frame); struct unwind_table_entry *u; info = hppa_frame_cache (this_frame, this_cache); @@ -2347,12 +2436,10 @@ static struct hppa_stub_unwind_cache * hppa_stub_frame_unwind_cache (struct frame_info *this_frame, void **this_cache) { - struct gdbarch *gdbarch = get_frame_arch (this_frame); struct hppa_stub_unwind_cache *info; - struct unwind_table_entry *u; if (*this_cache) - return *this_cache; + return (struct hppa_stub_unwind_cache *) *this_cache; info = FRAME_OBSTACK_ZALLOC (struct hppa_stub_unwind_cache); *this_cache = info; @@ -2360,21 +2447,6 @@ hppa_stub_frame_unwind_cache (struct frame_info *this_frame, info->base = get_frame_register_unsigned (this_frame, HPPA_SP_REGNUM); - if (gdbarch_osabi (gdbarch) == GDB_OSABI_HPUX_SOM) - { - /* HPUX uses export stubs in function calls; the export stub clobbers - the return value of the caller, and, later restores it from the - stack. */ - u = find_unwind_entry (get_frame_pc (this_frame)); - - if (u && u->stub_unwind.stub_type == EXPORT) - { - info->saved_regs[HPPA_PCOQ_HEAD_REGNUM].addr = info->base - 24; - - return info; - } - } - /* By default we assume that stubs do not change the rp. */ info->saved_regs[HPPA_PCOQ_HEAD_REGNUM].realreg = HPPA_RP_REGNUM; @@ -2418,7 +2490,7 @@ hppa_stub_unwind_sniffer (const struct frame_unwind *self, if (pc == 0 || (tdep->in_solib_call_trampoline != NULL - && tdep->in_solib_call_trampoline (gdbarch, pc, NULL)) + && tdep->in_solib_call_trampoline (gdbarch, pc)) || gdbarch_in_solib_return_trampoline (gdbarch, pc, NULL)) return 1; return 0; @@ -2464,30 +2536,36 @@ hppa_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) /* Return the minimal symbol whose name is NAME and stub type is STUB_TYPE. Return NULL if no such symbol was found. */ -struct minimal_symbol * +struct bound_minimal_symbol hppa_lookup_stub_minimal_symbol (const char *name, enum unwind_stub_types stub_type) { - struct objfile *objfile; - struct minimal_symbol *msym; + struct bound_minimal_symbol result = { NULL, NULL }; - ALL_MSYMBOLS (objfile, msym) + for (objfile *objfile : current_program_space->objfiles ()) { - if (strcmp (SYMBOL_LINKAGE_NAME (msym), name) == 0) - { - struct unwind_table_entry *u; + for (minimal_symbol *msym : objfile->msymbols ()) + { + if (strcmp (MSYMBOL_LINKAGE_NAME (msym), name) == 0) + { + struct unwind_table_entry *u; - u = find_unwind_entry (SYMBOL_VALUE (msym)); - if (u != NULL && u->stub_unwind.stub_type == stub_type) - return msym; - } + u = find_unwind_entry (MSYMBOL_VALUE (msym)); + if (u != NULL && u->stub_unwind.stub_type == stub_type) + { + result.objfile = objfile; + result.minsym = msym; + return result; + } + } + } } - return NULL; + return result; } static void -unwind_command (char *exp, int from_tty) +unwind_command (const char *exp, int from_tty) { CORE_ADDR address; struct unwind_table_entry *u; @@ -2640,7 +2718,7 @@ hppa64_cannot_fetch_register (struct gdbarch *gdbarch, int regnum) } static CORE_ADDR -hppa_smash_text_address (struct gdbarch *gdbarch, CORE_ADDR addr) +hppa_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr) { /* The low two bits of the PC on the PA contain the privilege level. Some genius implementing a (non-GCC) compiler apparently decided @@ -2662,14 +2740,14 @@ hppa_fetch_pointer_argument (struct frame_info *frame, int argi, } static enum register_status -hppa_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, +hppa_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache, int regnum, gdb_byte *buf) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ULONGEST tmp; enum register_status status; - status = regcache_raw_read_unsigned (regcache, regnum, &tmp); + status = regcache->raw_read (regnum, &tmp); if (status == REG_VALID) { if (regnum == HPPA_PCOQ_HEAD_REGNUM || regnum == HPPA_PCOQ_TAIL_REGNUM) @@ -2706,14 +2784,6 @@ hppa_frame_prev_register_helper (struct frame_info *this_frame, return frame_unwind_got_constant (this_frame, regnum, pc + 4); } - /* Make sure the "flags" register is zero in all unwound frames. - The "flags" registers is a HP-UX specific wart, and only the code - in hppa-hpux-tdep.c depends on it. However, it is easier to deal - with it here. This shouldn't affect other systems since those - should provide zero for the "flags" register anyway. */ - if (regnum == HPPA_FLAGS_REGNUM) - return frame_unwind_got_constant (this_frame, regnum, 0); - return trad_frame_get_prev_register (this_frame, saved_regs, regnum); } @@ -2776,18 +2846,6 @@ static struct insn_pattern hppa_plt_stub[] = { { 0, 0 } }; -static struct insn_pattern hppa_sigtramp[] = { - /* ldi 0, %r25 or ldi 1, %r25 */ - { 0x34190000, 0xfffffffd }, - /* ldi __NR_rt_sigreturn, %r20 */ - { 0x3414015a, 0xffffffff }, - /* be,l 0x100(%sr2, %r0), %sr0, %r31 */ - { 0xe4008200, 0xffffffff }, - /* nop */ - { 0x08000240, 0xffffffff }, - { 0, 0 } -}; - /* Maximum number of instructions on the patterns above. */ #define HPPA_MAX_INSN_PATTERN_LEN 4 @@ -2856,13 +2914,12 @@ hppa_in_dyncall (CORE_ADDR pc) } int -hppa_in_solib_call_trampoline (struct gdbarch *gdbarch, - CORE_ADDR pc, char *name) +hppa_in_solib_call_trampoline (struct gdbarch *gdbarch, CORE_ADDR pc) { unsigned int insn[HPPA_MAX_INSN_PATTERN_LEN]; struct unwind_table_entry *u; - if (in_plt_section (pc, name) || hppa_in_dyncall (pc)) + if (in_plt_section (pc) || hppa_in_dyncall (pc)) return 1; /* The GNU toolchain produces linker stubs without unwind @@ -2919,13 +2976,13 @@ hppa_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) /* fallthrough */ } - if (in_plt_section (pc, NULL)) + if (in_plt_section (pc)) { pc = read_memory_typed_address (pc, func_ptr_type); /* If the PLT slot has not yet been resolved, the target will be the PLT stub. */ - if (in_plt_section (pc, NULL)) + if (in_plt_section (pc)) { /* Sanity check: are we pointing to the PLT stub? */ if (!hppa_match_insns (gdbarch, pc, hppa_plt_stub, insn)) @@ -2984,14 +3041,6 @@ hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { struct gdbarch_tdep *tdep; struct gdbarch *gdbarch; - - /* Try to determine the ABI of the object we are loading. */ - if (info.abfd != NULL && info.osabi == GDB_OSABI_UNKNOWN) - { - /* If it's a SOM file, assume it's HP/UX SOM. */ - if (bfd_get_flavour (info.abfd) == bfd_target_som_flavour) - info.osabi = GDB_OSABI_HPUX_SOM; - } /* find a candidate among the list of pre-declared architectures. */ arches = gdbarch_list_lookup_by_info (arches, &info); @@ -2999,7 +3048,7 @@ hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) return (arches->gdbarch); /* If none found, then allocate and initialize one. */ - tdep = XZALLOC (struct gdbarch_tdep); + tdep = XCNEW (struct gdbarch_tdep); gdbarch = gdbarch_alloc (&info, tdep); /* Determine from the bfd_arch_info structure if we are dealing with @@ -3053,13 +3102,12 @@ hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* The following gdbarch vector elements do not depend on the address size, or in any other gdbarch element previously set. */ set_gdbarch_skip_prologue (gdbarch, hppa_skip_prologue); - set_gdbarch_in_function_epilogue_p (gdbarch, - hppa_in_function_epilogue_p); + set_gdbarch_stack_frame_destroyed_p (gdbarch, + hppa_stack_frame_destroyed_p); set_gdbarch_inner_than (gdbarch, core_addr_greaterthan); set_gdbarch_sp_regnum (gdbarch, HPPA_SP_REGNUM); set_gdbarch_fp0_regnum (gdbarch, HPPA_FP0_REGNUM); - set_gdbarch_addr_bits_remove (gdbarch, hppa_smash_text_address); - set_gdbarch_smash_text_address (gdbarch, hppa_smash_text_address); + set_gdbarch_addr_bits_remove (gdbarch, hppa_addr_bits_remove); set_gdbarch_believe_pcc_promotion (gdbarch, 1); set_gdbarch_read_pc (gdbarch, hppa_read_pc); set_gdbarch_write_pc (gdbarch, hppa_write_pc); @@ -3067,8 +3115,6 @@ hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Helper for function argument information. */ set_gdbarch_fetch_pointer_argument (gdbarch, hppa_fetch_pointer_argument); - set_gdbarch_print_insn (gdbarch, print_insn_hppa); - /* When a hardware watchpoint triggers, we'll move the inferior past it by removing all eventpoints; stepping past the instruction that caused the trigger; reinserting eventpoints; and checking @@ -3105,7 +3151,8 @@ hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) internal_error (__FILE__, __LINE__, _("bad switch")); } - set_gdbarch_breakpoint_from_pc (gdbarch, hppa_breakpoint_from_pc); + set_gdbarch_breakpoint_kind_from_pc (gdbarch, hppa_breakpoint::kind_from_pc); + set_gdbarch_sw_breakpoint_from_kind (gdbarch, hppa_breakpoint::bp_from_kind); set_gdbarch_pseudo_register_read (gdbarch, hppa_pseudo_register_read); /* Frame unwind methods. */ @@ -3133,14 +3180,9 @@ hppa_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) fprintf_unfiltered (file, "elf = %s\n", tdep->is_elf ? "yes" : "no"); } -/* Provide a prototype to silence -Wmissing-prototypes. */ -extern initialize_file_ftype _initialize_hppa_tdep; - void _initialize_hppa_tdep (void) { - struct cmd_list_element *c; - gdbarch_register (bfd_arch_hppa, hppa_gdbarch_init, hppa_dump_tdep); hppa_objfile_priv_data = register_objfile_data ();