|  | /* Target-dependent code for the HP PA-RISC architecture. | 
|  |  | 
|  | Copyright (C) 1986-2022 Free Software Foundation, Inc. | 
|  |  | 
|  | Contributed by the Center for Software Science at the | 
|  | University of Utah (pa-gdb-bugs@cs.utah.edu). | 
|  |  | 
|  | This file is part of GDB. | 
|  |  | 
|  | This program is free software; you can redistribute it and/or modify | 
|  | it under the terms of the GNU General Public License as published by | 
|  | the Free Software Foundation; either version 3 of the License, or | 
|  | (at your option) any later version. | 
|  |  | 
|  | This program is distributed in the hope that it will be useful, | 
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | GNU General Public License for more details. | 
|  |  | 
|  | You should have received a copy of the GNU General Public License | 
|  | along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ | 
|  |  | 
|  | #include "defs.h" | 
|  | #include "bfd.h" | 
|  | #include "inferior.h" | 
|  | #include "regcache.h" | 
|  | #include "completer.h" | 
|  | #include "osabi.h" | 
|  | #include "arch-utils.h" | 
|  | /* For argument passing to the inferior.  */ | 
|  | #include "symtab.h" | 
|  | #include "dis-asm.h" | 
|  | #include "trad-frame.h" | 
|  | #include "frame-unwind.h" | 
|  | #include "frame-base.h" | 
|  |  | 
|  | #include "gdbcore.h" | 
|  | #include "gdbcmd.h" | 
|  | #include "gdbtypes.h" | 
|  | #include "objfiles.h" | 
|  | #include "hppa-tdep.h" | 
|  | #include <algorithm> | 
|  |  | 
|  | static bool hppa_debug = false; | 
|  |  | 
|  | /* Some local constants.  */ | 
|  | 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 = nullptr;	/* a pointer */ | 
|  | struct so_list *so_info = nullptr;			/* a pointer  */ | 
|  | CORE_ADDR dp = 0; | 
|  |  | 
|  | int dummy_call_sequence_reg = 0; | 
|  | CORE_ADDR dummy_call_sequence_addr = 0; | 
|  | }; | 
|  |  | 
|  | /* 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.  */ | 
|  | static const struct objfile_key<hppa_objfile_private> hppa_objfile_priv_data; | 
|  |  | 
|  | /* Get at various relevant fields of an instruction word.  */ | 
|  | #define MASK_5 0x1f | 
|  | #define MASK_11 0x7ff | 
|  | #define MASK_14 0x3fff | 
|  | #define MASK_21 0x1fffff | 
|  |  | 
|  | /* Sizes (in bytes) of the native unwind entries.  */ | 
|  | #define UNWIND_ENTRY_SIZE 16 | 
|  | #define STUB_UNWIND_ENTRY_SIZE 8 | 
|  |  | 
|  | /* Routines to extract various sized constants out of hppa | 
|  | instructions.  */ | 
|  |  | 
|  | /* This assumes that no garbage lies outside of the lower bits of | 
|  | value.  */ | 
|  |  | 
|  | static int | 
|  | hppa_sign_extend (unsigned val, unsigned bits) | 
|  | { | 
|  | return (int) (val >> (bits - 1) ? (-(1 << bits)) | val : val); | 
|  | } | 
|  |  | 
|  | /* For many immediate values the sign bit is the low bit!  */ | 
|  |  | 
|  | static int | 
|  | hppa_low_hppa_sign_extend (unsigned val, unsigned bits) | 
|  | { | 
|  | return (int) ((val & 0x1 ? (-(1 << (bits - 1))) : 0) | val >> 1); | 
|  | } | 
|  |  | 
|  | /* Extract the bits at positions between FROM and TO, using HP's numbering | 
|  | (MSB = 0).  */ | 
|  |  | 
|  | int | 
|  | hppa_get_field (unsigned word, int from, int to) | 
|  | { | 
|  | return ((word) >> (31 - (to)) & ((1 << ((to) - (from) + 1)) - 1)); | 
|  | } | 
|  |  | 
|  | /* Extract the immediate field from a ld{bhw}s instruction.  */ | 
|  |  | 
|  | int | 
|  | hppa_extract_5_load (unsigned word) | 
|  | { | 
|  | return hppa_low_hppa_sign_extend (word >> 16 & MASK_5, 5); | 
|  | } | 
|  |  | 
|  | /* Extract the immediate field from a break instruction.  */ | 
|  |  | 
|  | unsigned | 
|  | hppa_extract_5r_store (unsigned word) | 
|  | { | 
|  | return (word & MASK_5); | 
|  | } | 
|  |  | 
|  | /* Extract the immediate field from a {sr}sm instruction.  */ | 
|  |  | 
|  | unsigned | 
|  | hppa_extract_5R_store (unsigned word) | 
|  | { | 
|  | return (word >> 16 & MASK_5); | 
|  | } | 
|  |  | 
|  | /* Extract a 14 bit immediate field.  */ | 
|  |  | 
|  | int | 
|  | hppa_extract_14 (unsigned word) | 
|  | { | 
|  | return hppa_low_hppa_sign_extend (word & MASK_14, 14); | 
|  | } | 
|  |  | 
|  | /* Extract a 21 bit constant.  */ | 
|  |  | 
|  | int | 
|  | hppa_extract_21 (unsigned word) | 
|  | { | 
|  | int val; | 
|  |  | 
|  | word &= MASK_21; | 
|  | word <<= 11; | 
|  | val = hppa_get_field (word, 20, 20); | 
|  | val <<= 11; | 
|  | val |= hppa_get_field (word, 9, 19); | 
|  | val <<= 2; | 
|  | val |= hppa_get_field (word, 5, 6); | 
|  | val <<= 5; | 
|  | val |= hppa_get_field (word, 0, 4); | 
|  | val <<= 2; | 
|  | val |= hppa_get_field (word, 7, 8); | 
|  | return hppa_sign_extend (val, 21) << 11; | 
|  | } | 
|  |  | 
|  | /* extract a 17 bit constant from branch instructions, returning the | 
|  | 19 bit signed value.  */ | 
|  |  | 
|  | int | 
|  | hppa_extract_17 (unsigned word) | 
|  | { | 
|  | return hppa_sign_extend (hppa_get_field (word, 19, 28) | | 
|  | hppa_get_field (word, 29, 29) << 10 | | 
|  | hppa_get_field (word, 11, 15) << 11 | | 
|  | (word & 0x1) << 16, 17) << 2; | 
|  | } | 
|  |  | 
|  | CORE_ADDR | 
|  | hppa_symbol_address(const char *sym) | 
|  | { | 
|  | struct bound_minimal_symbol minsym; | 
|  |  | 
|  | minsym = lookup_minimal_symbol (sym, NULL, NULL); | 
|  | if (minsym.minsym) | 
|  | return BMSYMBOL_VALUE_ADDRESS (minsym); | 
|  | else | 
|  | return (CORE_ADDR)-1; | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  | /* Compare the start address for two unwind entries returning 1 if | 
|  | the first address is larger than the second, -1 if the second is | 
|  | larger than the first, and zero if they are equal.  */ | 
|  |  | 
|  | static int | 
|  | compare_unwind_entries (const void *arg1, const void *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; | 
|  | else if (a->region_start < b->region_start) | 
|  | return -1; | 
|  | else | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static void | 
|  | record_text_segment_lowaddr (bfd *abfd, asection *section, void *data) | 
|  | { | 
|  | if ((section->flags & (SEC_ALLOC | SEC_LOAD | SEC_READONLY)) | 
|  | == (SEC_ALLOC | SEC_LOAD | SEC_READONLY)) | 
|  | { | 
|  | bfd_vma value = section->vma - section->filepos; | 
|  | CORE_ADDR *low_text_segment_address = (CORE_ADDR *)data; | 
|  |  | 
|  | if (value < *low_text_segment_address) | 
|  | *low_text_segment_address = value; | 
|  | } | 
|  | } | 
|  |  | 
|  | static void | 
|  | internalize_unwinds (struct objfile *objfile, struct unwind_table_entry *table, | 
|  | asection *section, unsigned int entries, | 
|  | size_t size, CORE_ADDR text_offset) | 
|  | { | 
|  | /* We will read the unwind entries into temporary memory, then | 
|  | fill in the actual unwind table.  */ | 
|  |  | 
|  | if (size > 0) | 
|  | { | 
|  | struct gdbarch *gdbarch = objfile->arch (); | 
|  | hppa_gdbarch_tdep *tdep = (hppa_gdbarch_tdep *) gdbarch_tdep (gdbarch); | 
|  | unsigned long tmp; | 
|  | unsigned i; | 
|  | char *buf = (char *) alloca (size); | 
|  | CORE_ADDR low_text_segment_address; | 
|  |  | 
|  | /* For ELF targets, then unwinds are supposed to | 
|  | be segment relative offsets instead of absolute addresses. | 
|  |  | 
|  | Note that when loading a shared library (text_offset != 0) the | 
|  | unwinds are already relative to the text_offset that will be | 
|  | passed in.  */ | 
|  | if (tdep->is_elf && text_offset == 0) | 
|  | { | 
|  | low_text_segment_address = -1; | 
|  |  | 
|  | bfd_map_over_sections (objfile->obfd, | 
|  | record_text_segment_lowaddr, | 
|  | &low_text_segment_address); | 
|  |  | 
|  | text_offset = low_text_segment_address; | 
|  | } | 
|  | else if (tdep->solib_get_text_base) | 
|  | { | 
|  | text_offset = tdep->solib_get_text_base (objfile); | 
|  | } | 
|  |  | 
|  | bfd_get_section_contents (objfile->obfd, section, buf, 0, size); | 
|  |  | 
|  | /* Now internalize the information being careful to handle host/target | 
|  | endian issues.  */ | 
|  | for (i = 0; i < entries; i++) | 
|  | { | 
|  | table[i].region_start = bfd_get_32 (objfile->obfd, | 
|  | (bfd_byte *) buf); | 
|  | table[i].region_start += text_offset; | 
|  | buf += 4; | 
|  | table[i].region_end = bfd_get_32 (objfile->obfd, (bfd_byte *) buf); | 
|  | table[i].region_end += text_offset; | 
|  | buf += 4; | 
|  | tmp = bfd_get_32 (objfile->obfd, (bfd_byte *) buf); | 
|  | buf += 4; | 
|  | table[i].Cannot_unwind = (tmp >> 31) & 0x1; | 
|  | table[i].Millicode = (tmp >> 30) & 0x1; | 
|  | table[i].Millicode_save_sr0 = (tmp >> 29) & 0x1; | 
|  | table[i].Region_description = (tmp >> 27) & 0x3; | 
|  | table[i].reserved = (tmp >> 26) & 0x1; | 
|  | table[i].Entry_SR = (tmp >> 25) & 0x1; | 
|  | table[i].Entry_FR = (tmp >> 21) & 0xf; | 
|  | table[i].Entry_GR = (tmp >> 16) & 0x1f; | 
|  | table[i].Args_stored = (tmp >> 15) & 0x1; | 
|  | table[i].Variable_Frame = (tmp >> 14) & 0x1; | 
|  | table[i].Separate_Package_Body = (tmp >> 13) & 0x1; | 
|  | table[i].Frame_Extension_Millicode = (tmp >> 12) & 0x1; | 
|  | table[i].Stack_Overflow_Check = (tmp >> 11) & 0x1; | 
|  | table[i].Two_Instruction_SP_Increment = (tmp >> 10) & 0x1; | 
|  | table[i].sr4export = (tmp >> 9) & 0x1; | 
|  | table[i].cxx_info = (tmp >> 8) & 0x1; | 
|  | table[i].cxx_try_catch = (tmp >> 7) & 0x1; | 
|  | table[i].sched_entry_seq = (tmp >> 6) & 0x1; | 
|  | table[i].reserved1 = (tmp >> 5) & 0x1; | 
|  | table[i].Save_SP = (tmp >> 4) & 0x1; | 
|  | table[i].Save_RP = (tmp >> 3) & 0x1; | 
|  | table[i].Save_MRP_in_frame = (tmp >> 2) & 0x1; | 
|  | table[i].save_r19 = (tmp >> 1) & 0x1; | 
|  | table[i].Cleanup_defined = tmp & 0x1; | 
|  | tmp = bfd_get_32 (objfile->obfd, (bfd_byte *) buf); | 
|  | buf += 4; | 
|  | table[i].MPE_XL_interrupt_marker = (tmp >> 31) & 0x1; | 
|  | table[i].HP_UX_interrupt_marker = (tmp >> 30) & 0x1; | 
|  | table[i].Large_frame = (tmp >> 29) & 0x1; | 
|  | table[i].alloca_frame = (tmp >> 28) & 0x1; | 
|  | table[i].reserved2 = (tmp >> 27) & 0x1; | 
|  | table[i].Total_frame_size = tmp & 0x7ffffff; | 
|  |  | 
|  | /* Stub unwinds are handled elsewhere.  */ | 
|  | table[i].stub_unwind.stub_type = 0; | 
|  | table[i].stub_unwind.padding = 0; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Read in the backtrace information stored in the `$UNWIND_START$' section of | 
|  | the object file.  This info is used mainly by find_unwind_entry() to find | 
|  | out the stack frame size and frame pointer used by procedures.  We put | 
|  | everything on the psymbol obstack in the objfile so that it automatically | 
|  | gets freed when the objfile is destroyed.  */ | 
|  |  | 
|  | static void | 
|  | read_unwind_info (struct objfile *objfile) | 
|  | { | 
|  | asection *unwind_sec, *stub_unwind_sec; | 
|  | 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 = objfile->text_section_offset (); | 
|  | ui = (struct hppa_unwind_info *) obstack_alloc (&objfile->objfile_obstack, | 
|  | sizeof (struct hppa_unwind_info)); | 
|  |  | 
|  | ui->table = NULL; | 
|  | ui->cache = NULL; | 
|  | ui->last = -1; | 
|  |  | 
|  | /* For reasons unknown the HP PA64 tools generate multiple unwinder | 
|  | sections in a single executable.  So we just iterate over every | 
|  | section in the BFD looking for unwinder sections instead of trying | 
|  | to do a lookup with bfd_get_section_by_name. | 
|  |  | 
|  | First determine the total size of the unwind tables so that we | 
|  | can allocate memory in a nice big hunk.  */ | 
|  | total_entries = 0; | 
|  | for (unwind_sec = objfile->obfd->sections; | 
|  | unwind_sec; | 
|  | unwind_sec = unwind_sec->next) | 
|  | { | 
|  | if (strcmp (unwind_sec->name, "$UNWIND_START$") == 0 | 
|  | || strcmp (unwind_sec->name, ".PARISC.unwind") == 0) | 
|  | { | 
|  | unwind_size = bfd_section_size (unwind_sec); | 
|  | unwind_entries = unwind_size / UNWIND_ENTRY_SIZE; | 
|  |  | 
|  | total_entries += unwind_entries; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Now compute the size of the stub unwinds.  Note the ELF tools do not | 
|  | use stub unwinds at the current time.  */ | 
|  | stub_unwind_sec = bfd_get_section_by_name (objfile->obfd, "$UNWIND_END$"); | 
|  |  | 
|  | if (stub_unwind_sec) | 
|  | { | 
|  | stub_unwind_size = bfd_section_size (stub_unwind_sec); | 
|  | stub_entries = stub_unwind_size / STUB_UNWIND_ENTRY_SIZE; | 
|  | } | 
|  | else | 
|  | { | 
|  | stub_unwind_size = 0; | 
|  | stub_entries = 0; | 
|  | } | 
|  |  | 
|  | /* Compute total number of unwind entries and their total size.  */ | 
|  | total_entries += stub_entries; | 
|  | total_size = total_entries * sizeof (struct unwind_table_entry); | 
|  |  | 
|  | /* Allocate memory for the unwind table.  */ | 
|  | ui->table = (struct unwind_table_entry *) | 
|  | obstack_alloc (&objfile->objfile_obstack, total_size); | 
|  | ui->last = total_entries - 1; | 
|  |  | 
|  | /* Now read in each unwind section and internalize the standard unwind | 
|  | entries.  */ | 
|  | index = 0; | 
|  | for (unwind_sec = objfile->obfd->sections; | 
|  | unwind_sec; | 
|  | unwind_sec = unwind_sec->next) | 
|  | { | 
|  | if (strcmp (unwind_sec->name, "$UNWIND_START$") == 0 | 
|  | || strcmp (unwind_sec->name, ".PARISC.unwind") == 0) | 
|  | { | 
|  | unwind_size = bfd_section_size (unwind_sec); | 
|  | unwind_entries = unwind_size / UNWIND_ENTRY_SIZE; | 
|  |  | 
|  | internalize_unwinds (objfile, &ui->table[index], unwind_sec, | 
|  | unwind_entries, unwind_size, text_offset); | 
|  | index += unwind_entries; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Now read in and internalize the stub unwind entries.  */ | 
|  | if (stub_unwind_size > 0) | 
|  | { | 
|  | unsigned int i; | 
|  | char *buf = (char *) alloca (stub_unwind_size); | 
|  |  | 
|  | /* Read in the stub unwind entries.  */ | 
|  | bfd_get_section_contents (objfile->obfd, stub_unwind_sec, buf, | 
|  | 0, stub_unwind_size); | 
|  |  | 
|  | /* Now convert them into regular unwind entries.  */ | 
|  | for (i = 0; i < stub_entries; i++, index++) | 
|  | { | 
|  | /* Clear out the next unwind entry.  */ | 
|  | memset (&ui->table[index], 0, sizeof (struct unwind_table_entry)); | 
|  |  | 
|  | /* Convert offset & size into region_start and region_end. | 
|  | Stuff away the stub type into "reserved" fields.  */ | 
|  | ui->table[index].region_start = bfd_get_32 (objfile->obfd, | 
|  | (bfd_byte *) buf); | 
|  | ui->table[index].region_start += text_offset; | 
|  | buf += 4; | 
|  | ui->table[index].stub_unwind.stub_type = bfd_get_8 (objfile->obfd, | 
|  | (bfd_byte *) buf); | 
|  | buf += 2; | 
|  | ui->table[index].region_end | 
|  | = ui->table[index].region_start + 4 * | 
|  | (bfd_get_16 (objfile->obfd, (bfd_byte *) buf) - 1); | 
|  | buf += 2; | 
|  | } | 
|  |  | 
|  | } | 
|  |  | 
|  | /* Unwind table needs to be kept sorted.  */ | 
|  | qsort (ui->table, total_entries, sizeof (struct unwind_table_entry), | 
|  | compare_unwind_entries); | 
|  |  | 
|  | /* Keep a pointer to the unwind information.  */ | 
|  | obj_private = hppa_objfile_priv_data.get (objfile); | 
|  | if (obj_private == NULL) | 
|  | obj_private = hppa_objfile_priv_data.emplace (objfile); | 
|  |  | 
|  | obj_private->unwind_info = ui; | 
|  | } | 
|  |  | 
|  | /* Lookup the unwind (stack backtrace) info for the given PC.  We search all | 
|  | of the objfiles seeking the unwind table entry for this PC.  Each objfile | 
|  | contains a sorted list of struct unwind_table_entry.  Since we do a binary | 
|  | search of the unwind tables, we depend upon them to be sorted.  */ | 
|  |  | 
|  | struct unwind_table_entry * | 
|  | find_unwind_entry (CORE_ADDR pc) | 
|  | { | 
|  | int first, middle, last; | 
|  |  | 
|  | if (hppa_debug) | 
|  | fprintf_unfiltered (gdb_stdlog, "{ find_unwind_entry %s -> ", | 
|  | hex_string (pc)); | 
|  |  | 
|  | /* A function at address 0?  Not in HP-UX!  */ | 
|  | if (pc == (CORE_ADDR) 0) | 
|  | { | 
|  | if (hppa_debug) | 
|  | fprintf_unfiltered (gdb_stdlog, "NULL }\n"); | 
|  | return NULL; | 
|  | } | 
|  |  | 
|  | for (objfile *objfile : current_program_space->objfiles ()) | 
|  | { | 
|  | struct hppa_unwind_info *ui; | 
|  | ui = NULL; | 
|  | struct hppa_objfile_private *priv = hppa_objfile_priv_data.get (objfile); | 
|  | if (priv) | 
|  | ui = priv->unwind_info; | 
|  |  | 
|  | if (!ui) | 
|  | { | 
|  | read_unwind_info (objfile); | 
|  | priv = hppa_objfile_priv_data.get (objfile); | 
|  | if (priv == NULL) | 
|  | error (_("Internal error reading unwind information.")); | 
|  | ui = priv->unwind_info; | 
|  | } | 
|  |  | 
|  | /* 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; | 
|  | } | 
|  |  | 
|  | /* Not in the cache, do a binary search.  */ | 
|  |  | 
|  | 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]; | 
|  | } | 
|  |  | 
|  | 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"); | 
|  |  | 
|  | return NULL; | 
|  | } | 
|  |  | 
|  | /* 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_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; | 
|  | gdb_byte buf[4]; | 
|  |  | 
|  | status = target_read_memory (pc, buf, 4); | 
|  | if (status != 0) | 
|  | return 0; | 
|  |  | 
|  | inst = extract_unsigned_integer (buf, 4, byte_order); | 
|  |  | 
|  | /* The most common way to perform a stack adjustment ldo X(sp),sp | 
|  | We are destroying a stack frame if the offset is negative.  */ | 
|  | if ((inst & 0xffffc000) == 0x37de0000 | 
|  | && hppa_extract_14 (inst) < 0) | 
|  | return 1; | 
|  |  | 
|  | /* ldw,mb D(sp),X or ldd,mb D(sp),X */ | 
|  | if (((inst & 0x0fc010e0) == 0x0fc010e0 | 
|  | || (inst & 0x0fc010e0) == 0x0fc010e0) | 
|  | && hppa_extract_14 (inst) < 0) | 
|  | return 1; | 
|  |  | 
|  | /* bv %r0(%rp) or bv,n %r0(%rp) */ | 
|  | if (inst == 0xe840c000 || inst == 0xe840c002) | 
|  | return 1; | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | 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 const char *names[] = { | 
|  | "flags",  "r1",      "rp",     "r3", | 
|  | "r4",     "r5",      "r6",     "r7", | 
|  | "r8",     "r9",      "r10",    "r11", | 
|  | "r12",    "r13",     "r14",    "r15", | 
|  | "r16",    "r17",     "r18",    "r19", | 
|  | "r20",    "r21",     "r22",    "r23", | 
|  | "r24",    "r25",     "r26",    "dp", | 
|  | "ret0",   "ret1",    "sp",     "r31", | 
|  | "sar",    "pcoqh",   "pcsqh",  "pcoqt", | 
|  | "pcsqt",  "eiem",    "iir",    "isr", | 
|  | "ior",    "ipsw",    "goto",   "sr4", | 
|  | "sr0",    "sr1",     "sr2",    "sr3", | 
|  | "sr5",    "sr6",     "sr7",    "cr0", | 
|  | "cr8",    "cr9",     "ccr",    "cr12", | 
|  | "cr13",   "cr24",    "cr25",   "cr26", | 
|  | "mpsfu_high","mpsfu_low","mpsfu_ovflo","pad", | 
|  | "fpsr",    "fpe1",   "fpe2",   "fpe3", | 
|  | "fpe4",   "fpe5",    "fpe6",   "fpe7", | 
|  | "fr4",     "fr4R",   "fr5",    "fr5R", | 
|  | "fr6",    "fr6R",    "fr7",    "fr7R", | 
|  | "fr8",     "fr8R",   "fr9",    "fr9R", | 
|  | "fr10",   "fr10R",   "fr11",   "fr11R", | 
|  | "fr12",    "fr12R",  "fr13",   "fr13R", | 
|  | "fr14",   "fr14R",   "fr15",   "fr15R", | 
|  | "fr16",    "fr16R",  "fr17",   "fr17R", | 
|  | "fr18",   "fr18R",   "fr19",   "fr19R", | 
|  | "fr20",    "fr20R",  "fr21",   "fr21R", | 
|  | "fr22",   "fr22R",   "fr23",   "fr23R", | 
|  | "fr24",    "fr24R",  "fr25",   "fr25R", | 
|  | "fr26",   "fr26R",   "fr27",   "fr27R", | 
|  | "fr28",    "fr28R",  "fr29",   "fr29R", | 
|  | "fr30",   "fr30R",   "fr31",   "fr31R" | 
|  | }; | 
|  | if (i < 0 || i >= (sizeof (names) / sizeof (*names))) | 
|  | return NULL; | 
|  | else | 
|  | return names[i]; | 
|  | } | 
|  |  | 
|  | static const char * | 
|  | hppa64_register_name (struct gdbarch *gdbarch, int i) | 
|  | { | 
|  | static const char *names[] = { | 
|  | "flags",  "r1",      "rp",     "r3", | 
|  | "r4",     "r5",      "r6",     "r7", | 
|  | "r8",     "r9",      "r10",    "r11", | 
|  | "r12",    "r13",     "r14",    "r15", | 
|  | "r16",    "r17",     "r18",    "r19", | 
|  | "r20",    "r21",     "r22",    "r23", | 
|  | "r24",    "r25",     "r26",    "dp", | 
|  | "ret0",   "ret1",    "sp",     "r31", | 
|  | "sar",    "pcoqh",   "pcsqh",  "pcoqt", | 
|  | "pcsqt",  "eiem",    "iir",    "isr", | 
|  | "ior",    "ipsw",    "goto",   "sr4", | 
|  | "sr0",    "sr1",     "sr2",    "sr3", | 
|  | "sr5",    "sr6",     "sr7",    "cr0", | 
|  | "cr8",    "cr9",     "ccr",    "cr12", | 
|  | "cr13",   "cr24",    "cr25",   "cr26", | 
|  | "mpsfu_high","mpsfu_low","mpsfu_ovflo","pad", | 
|  | "fpsr",    "fpe1",   "fpe2",   "fpe3", | 
|  | "fr4",    "fr5",     "fr6",    "fr7", | 
|  | "fr8",     "fr9",    "fr10",   "fr11", | 
|  | "fr12",   "fr13",    "fr14",   "fr15", | 
|  | "fr16",    "fr17",   "fr18",   "fr19", | 
|  | "fr20",   "fr21",    "fr22",   "fr23", | 
|  | "fr24",    "fr25",   "fr26",   "fr27", | 
|  | "fr28",  "fr29",    "fr30",   "fr31" | 
|  | }; | 
|  | if (i < 0 || i >= (sizeof (names) / sizeof (*names))) | 
|  | return NULL; | 
|  | else | 
|  | return names[i]; | 
|  | } | 
|  |  | 
|  | /* Map dwarf DBX register numbers to GDB register numbers.  */ | 
|  | 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 >= 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; | 
|  |  | 
|  | return -1; | 
|  | } | 
|  |  | 
|  | /* This function pushes a stack frame with arguments as part of the | 
|  | inferior function calling mechanism. | 
|  |  | 
|  | This is the version of the function for the 32-bit PA machines, in | 
|  | which later arguments appear at lower addresses.  (The stack always | 
|  | grows towards higher addresses.) | 
|  |  | 
|  | We simply allocate the appropriate amount of stack space and put | 
|  | arguments into their proper slots.  */ | 
|  |  | 
|  | 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, | 
|  | function_call_return_method return_method, | 
|  | CORE_ADDR struct_addr) | 
|  | { | 
|  | enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | 
|  |  | 
|  | /* Stack base address at which any pass-by-reference parameters are | 
|  | stored.  */ | 
|  | CORE_ADDR struct_end = 0; | 
|  | /* Stack base address at which the first parameter is stored.  */ | 
|  | CORE_ADDR param_end = 0; | 
|  |  | 
|  | /* Two passes.  First pass computes the location of everything, | 
|  | second pass writes the bytes out.  */ | 
|  | int write_pass; | 
|  |  | 
|  | /* Global pointer (r19) of the function we are trying to call.  */ | 
|  | CORE_ADDR gp; | 
|  |  | 
|  | hppa_gdbarch_tdep *tdep = (hppa_gdbarch_tdep *) gdbarch_tdep (gdbarch); | 
|  |  | 
|  | for (write_pass = 0; write_pass < 2; write_pass++) | 
|  | { | 
|  | CORE_ADDR struct_ptr = 0; | 
|  | /* The first parameter goes into sp-36, each stack slot is 4-bytes. | 
|  | struct_ptr is adjusted for each argument below, so the first | 
|  | argument will end up at sp-36.  */ | 
|  | CORE_ADDR param_ptr = 32; | 
|  | int i; | 
|  | int small_struct = 0; | 
|  |  | 
|  | for (i = 0; i < nargs; i++) | 
|  | { | 
|  | struct value *arg = args[i]; | 
|  | struct type *type = check_typedef (value_type (arg)); | 
|  | /* The corresponding parameter that is pushed onto the | 
|  | stack, and [possibly] passed in a register.  */ | 
|  | gdb_byte param_val[8]; | 
|  | int param_len; | 
|  | memset (param_val, 0, sizeof param_val); | 
|  | if (TYPE_LENGTH (type) > 8) | 
|  | { | 
|  | /* Large parameter, pass by reference.  Store the value | 
|  | in "struct" area and then pass its address.  */ | 
|  | param_len = 4; | 
|  | struct_ptr += align_up (TYPE_LENGTH (type), 8); | 
|  | if (write_pass) | 
|  | write_memory (struct_end - struct_ptr, | 
|  | value_contents (arg).data (), TYPE_LENGTH (type)); | 
|  | store_unsigned_integer (param_val, 4, byte_order, | 
|  | struct_end - struct_ptr); | 
|  | } | 
|  | else if (type->code () == TYPE_CODE_INT | 
|  | || type->code () == TYPE_CODE_ENUM) | 
|  | { | 
|  | /* Integer value store, right aligned.  "unpack_long" | 
|  | takes care of any sign-extension problems.  */ | 
|  | param_len = align_up (TYPE_LENGTH (type), 4); | 
|  | store_unsigned_integer | 
|  | (param_val, param_len, byte_order, | 
|  | unpack_long (type, value_contents (arg).data ())); | 
|  | } | 
|  | else if (type->code () == TYPE_CODE_FLT) | 
|  | { | 
|  | /* Floating point value store, right aligned.  */ | 
|  | param_len = align_up (TYPE_LENGTH (type), 4); | 
|  | memcpy (param_val, value_contents (arg).data (), param_len); | 
|  | } | 
|  | else | 
|  | { | 
|  | param_len = align_up (TYPE_LENGTH (type), 4); | 
|  |  | 
|  | /* Small struct value are stored right-aligned.  */ | 
|  | memcpy (param_val + param_len - TYPE_LENGTH (type), | 
|  | value_contents (arg).data (), TYPE_LENGTH (type)); | 
|  |  | 
|  | /* Structures of size 5, 6 and 7 bytes are special in that | 
|  | the higher-ordered word is stored in the lower-ordered | 
|  | argument, and even though it is a 8-byte quantity the | 
|  | registers need not be 8-byte aligned.  */ | 
|  | if (param_len > 4 && param_len < 8) | 
|  | small_struct = 1; | 
|  | } | 
|  |  | 
|  | param_ptr += param_len; | 
|  | if (param_len == 8 && !small_struct) | 
|  | param_ptr = align_up (param_ptr, 8); | 
|  |  | 
|  | /* First 4 non-FP arguments are passed in gr26-gr23. | 
|  | First 4 32-bit FP arguments are passed in fr4L-fr7L. | 
|  | First 2 64-bit FP arguments are passed in fr5 and fr7. | 
|  |  | 
|  | The rest go on the stack, starting at sp-36, towards lower | 
|  | addresses.  8-byte arguments must be aligned to a 8-byte | 
|  | stack boundary.  */ | 
|  | if (write_pass) | 
|  | { | 
|  | write_memory (param_end - param_ptr, param_val, param_len); | 
|  |  | 
|  | /* There are some cases when we don't know the type | 
|  | expected by the callee (e.g. for variadic functions), so | 
|  | pass the parameters in both general and fp regs.  */ | 
|  | if (param_ptr <= 48) | 
|  | { | 
|  | int grreg = 26 - (param_ptr - 36) / 4; | 
|  | int fpLreg = 72 + (param_ptr - 36) / 4 * 2; | 
|  | int fpreg = 74 + (param_ptr - 32) / 8 * 4; | 
|  |  | 
|  | regcache->cooked_write (grreg, param_val); | 
|  | regcache->cooked_write (fpLreg, param_val); | 
|  |  | 
|  | if (param_len > 4) | 
|  | { | 
|  | regcache->cooked_write (grreg + 1, param_val + 4); | 
|  |  | 
|  | regcache->cooked_write (fpreg, param_val); | 
|  | regcache->cooked_write (fpreg + 1, param_val + 4); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Update the various stack pointers.  */ | 
|  | if (!write_pass) | 
|  | { | 
|  | struct_end = sp + align_up (struct_ptr, 64); | 
|  | /* PARAM_PTR already accounts for all the arguments passed | 
|  | by the user.  However, the ABI mandates minimum stack | 
|  | space allocations for outgoing arguments.  The ABI also | 
|  | mandates minimum stack alignments which we must | 
|  | preserve.  */ | 
|  | param_end = struct_end + align_up (param_ptr, 64); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* If a structure has to be returned, set up register 28 to hold its | 
|  | address.  */ | 
|  | if (return_method == return_method_struct) | 
|  | regcache_cooked_write_unsigned (regcache, 28, struct_addr); | 
|  |  | 
|  | gp = tdep->find_global_pointer (gdbarch, function); | 
|  |  | 
|  | if (gp != 0) | 
|  | regcache_cooked_write_unsigned (regcache, 19, gp); | 
|  |  | 
|  | /* Set the return address.  */ | 
|  | if (!gdbarch_push_dummy_code_p (gdbarch)) | 
|  | regcache_cooked_write_unsigned (regcache, HPPA_RP_REGNUM, bp_addr); | 
|  |  | 
|  | /* Update the Stack Pointer.  */ | 
|  | regcache_cooked_write_unsigned (regcache, HPPA_SP_REGNUM, param_end); | 
|  |  | 
|  | return param_end; | 
|  | } | 
|  |  | 
|  | /* The 64-bit PA-RISC calling conventions are documented in "64-Bit | 
|  | Runtime Architecture for PA-RISC 2.0", which is distributed as part | 
|  | as of the HP-UX Software Transition Kit (STK).  This implementation | 
|  | is based on version 3.3, dated October 6, 1997.  */ | 
|  |  | 
|  | /* Check whether TYPE is an "Integral or Pointer Scalar Type".  */ | 
|  |  | 
|  | static int | 
|  | hppa64_integral_or_pointer_p (const struct type *type) | 
|  | { | 
|  | switch (type->code ()) | 
|  | { | 
|  | case TYPE_CODE_INT: | 
|  | case TYPE_CODE_BOOL: | 
|  | case TYPE_CODE_CHAR: | 
|  | case TYPE_CODE_ENUM: | 
|  | case TYPE_CODE_RANGE: | 
|  | { | 
|  | int len = TYPE_LENGTH (type); | 
|  | return (len == 1 || len == 2 || len == 4 || len == 8); | 
|  | } | 
|  | case TYPE_CODE_PTR: | 
|  | case TYPE_CODE_REF: | 
|  | case TYPE_CODE_RVALUE_REF: | 
|  | return (TYPE_LENGTH (type) == 8); | 
|  | default: | 
|  | break; | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* Check whether TYPE is a "Floating Scalar Type".  */ | 
|  |  | 
|  | static int | 
|  | hppa64_floating_p (const struct type *type) | 
|  | { | 
|  | switch (type->code ()) | 
|  | { | 
|  | case TYPE_CODE_FLT: | 
|  | { | 
|  | int len = TYPE_LENGTH (type); | 
|  | return (len == 4 || len == 8 || len == 16); | 
|  | } | 
|  | default: | 
|  | break; | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* If CODE points to a function entry address, try to look up the corresponding | 
|  | function descriptor and return its address instead.  If CODE is not a | 
|  | function entry address, then just return it unchanged.  */ | 
|  | static CORE_ADDR | 
|  | hppa64_convert_code_addr_to_fptr (struct gdbarch *gdbarch, CORE_ADDR code) | 
|  | { | 
|  | enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | 
|  | struct obj_section *sec, *opd; | 
|  |  | 
|  | sec = find_pc_section (code); | 
|  |  | 
|  | if (!sec) | 
|  | return code; | 
|  |  | 
|  | /* If CODE is in a data section, assume it's already a fptr.  */ | 
|  | if (!(sec->the_bfd_section->flags & SEC_CODE)) | 
|  | return code; | 
|  |  | 
|  | ALL_OBJFILE_OSECTIONS (sec->objfile, opd) | 
|  | { | 
|  | if (strcmp (opd->the_bfd_section->name, ".opd") == 0) | 
|  | break; | 
|  | } | 
|  |  | 
|  | if (opd < sec->objfile->sections_end) | 
|  | { | 
|  | for (CORE_ADDR addr = opd->addr (); addr < opd->endaddr (); addr += 2 * 8) | 
|  | { | 
|  | ULONGEST opdaddr; | 
|  | gdb_byte tmp[8]; | 
|  |  | 
|  | if (target_read_memory (addr, tmp, sizeof (tmp))) | 
|  | break; | 
|  | opdaddr = extract_unsigned_integer (tmp, sizeof (tmp), byte_order); | 
|  |  | 
|  | if (opdaddr == code) | 
|  | return addr - 16; | 
|  | } | 
|  | } | 
|  |  | 
|  | return code; | 
|  | } | 
|  |  | 
|  | 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, | 
|  | function_call_return_method return_method, | 
|  | CORE_ADDR struct_addr) | 
|  | { | 
|  | hppa_gdbarch_tdep *tdep = (hppa_gdbarch_tdep *) gdbarch_tdep (gdbarch); | 
|  | enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | 
|  | int i, offset = 0; | 
|  | CORE_ADDR gp; | 
|  |  | 
|  | /* "The outgoing parameter area [...] must be aligned at a 16-byte | 
|  | boundary."  */ | 
|  | sp = align_up (sp, 16); | 
|  |  | 
|  | for (i = 0; i < nargs; i++) | 
|  | { | 
|  | struct value *arg = args[i]; | 
|  | struct type *type = value_type (arg); | 
|  | int len = TYPE_LENGTH (type); | 
|  | const bfd_byte *valbuf; | 
|  | bfd_byte fptrbuf[8]; | 
|  | int regnum; | 
|  |  | 
|  | /* "Each parameter begins on a 64-bit (8-byte) boundary."  */ | 
|  | offset = align_up (offset, 8); | 
|  |  | 
|  | if (hppa64_integral_or_pointer_p (type)) | 
|  | { | 
|  | /* "Integral scalar parameters smaller than 64 bits are | 
|  | padded on the left (i.e., the value is in the | 
|  | least-significant bits of the 64-bit storage unit, and | 
|  | the high-order bits are undefined)."  Therefore we can | 
|  | safely sign-extend them.  */ | 
|  | if (len < 8) | 
|  | { | 
|  | arg = value_cast (builtin_type (gdbarch)->builtin_int64, arg); | 
|  | len = 8; | 
|  | } | 
|  | } | 
|  | else if (hppa64_floating_p (type)) | 
|  | { | 
|  | if (len > 8) | 
|  | { | 
|  | /* "Quad-precision (128-bit) floating-point scalar | 
|  | parameters are aligned on a 16-byte boundary."  */ | 
|  | offset = align_up (offset, 16); | 
|  |  | 
|  | /* "Double-extended- and quad-precision floating-point | 
|  | parameters within the first 64 bytes of the parameter | 
|  | list are always passed in general registers."  */ | 
|  | } | 
|  | else | 
|  | { | 
|  | if (len == 4) | 
|  | { | 
|  | /* "Single-precision (32-bit) floating-point scalar | 
|  | parameters are padded on the left with 32 bits of | 
|  | garbage (i.e., the floating-point value is in the | 
|  | least-significant 32 bits of a 64-bit storage | 
|  | unit)."  */ | 
|  | offset += 4; | 
|  | } | 
|  |  | 
|  | /* "Single- and double-precision floating-point | 
|  | parameters in this area are passed according to the | 
|  | available formal parameter information in a function | 
|  | prototype.  [...]  If no prototype is in scope, | 
|  | floating-point parameters must be passed both in the | 
|  | corresponding general registers and in the | 
|  | corresponding floating-point registers."  */ | 
|  | regnum = HPPA64_FP4_REGNUM + offset / 8; | 
|  |  | 
|  | if (regnum < HPPA64_FP4_REGNUM + 8) | 
|  | { | 
|  | /* "Single-precision floating-point parameters, when | 
|  | 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 (regnum, offset % 8, len, | 
|  | value_contents (arg).data ()); | 
|  | } | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | if (len > 8) | 
|  | { | 
|  | /* "Aggregates larger than 8 bytes are aligned on a | 
|  | 16-byte boundary, possibly leaving an unused argument | 
|  | slot, which is filled with garbage.  If necessary, | 
|  | they are padded on the right (with garbage), to a | 
|  | multiple of 8 bytes."  */ | 
|  | offset = align_up (offset, 16); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* If we are passing a function pointer, make sure we pass a function | 
|  | descriptor instead of the function entry address.  */ | 
|  | if (type->code () == TYPE_CODE_PTR | 
|  | && TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_FUNC) | 
|  | { | 
|  | ULONGEST codeptr, fptr; | 
|  |  | 
|  | codeptr = unpack_long (type, value_contents (arg).data ()); | 
|  | fptr = hppa64_convert_code_addr_to_fptr (gdbarch, codeptr); | 
|  | store_unsigned_integer (fptrbuf, TYPE_LENGTH (type), byte_order, | 
|  | fptr); | 
|  | valbuf = fptrbuf; | 
|  | } | 
|  | else | 
|  | { | 
|  | valbuf = value_contents (arg).data (); | 
|  | } | 
|  |  | 
|  | /* Always store the argument in memory.  */ | 
|  | write_memory (sp + offset, valbuf, len); | 
|  |  | 
|  | regnum = HPPA_ARG0_REGNUM - offset / 8; | 
|  | while (regnum > HPPA_ARG0_REGNUM - 8 && len > 0) | 
|  | { | 
|  | 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--; | 
|  | } | 
|  |  | 
|  | offset += len; | 
|  | } | 
|  |  | 
|  | /* Set up GR29 (%ret1) to hold the argument pointer (ap).  */ | 
|  | regcache_cooked_write_unsigned (regcache, HPPA_RET1_REGNUM, sp + 64); | 
|  |  | 
|  | /* Allocate the outgoing parameter area.  Make sure the outgoing | 
|  | parameter area is multiple of 16 bytes in length.  */ | 
|  | 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.  */ | 
|  | sp += 32; | 
|  |  | 
|  | /* Allocate the frame marker area.  */ | 
|  | sp += 16; | 
|  |  | 
|  | /* If a structure has to be returned, set up GR 28 (%ret0) to hold | 
|  | its address.  */ | 
|  | 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).  */ | 
|  | gp = tdep->find_global_pointer (gdbarch, function); | 
|  | if (gp != 0) | 
|  | regcache_cooked_write_unsigned (regcache, HPPA_DP_REGNUM, gp); | 
|  |  | 
|  | /* Set up GR2 (%rp) to hold the return pointer (rp).  */ | 
|  | if (!gdbarch_push_dummy_code_p (gdbarch)) | 
|  | regcache_cooked_write_unsigned (regcache, HPPA_RP_REGNUM, bp_addr); | 
|  |  | 
|  | /* Set up GR30 to hold the stack pointer (sp).  */ | 
|  | regcache_cooked_write_unsigned (regcache, HPPA_SP_REGNUM, sp); | 
|  |  | 
|  | return sp; | 
|  | } | 
|  |  | 
|  |  | 
|  | /* Handle 32/64-bit struct return conventions.  */ | 
|  |  | 
|  | static enum return_value_convention | 
|  | hppa32_return_value (struct gdbarch *gdbarch, struct value *function, | 
|  | struct type *type, struct regcache *regcache, | 
|  | gdb_byte *readbuf, const gdb_byte *writebuf) | 
|  | { | 
|  | if (TYPE_LENGTH (type) <= 2 * 4) | 
|  | { | 
|  | /* The value always lives in the right hand end of the register | 
|  | (or register pair)?  */ | 
|  | int b; | 
|  | int reg = type->code () == TYPE_CODE_FLT ? HPPA_FP4_REGNUM : 28; | 
|  | int part = TYPE_LENGTH (type) % 4; | 
|  | /* The left hand register contains only part of the value, | 
|  | transfer that first so that the rest can be xfered as entire | 
|  | 4-byte registers.  */ | 
|  | if (part > 0) | 
|  | { | 
|  | if (readbuf != NULL) | 
|  | regcache->cooked_read_part (reg, 4 - part, part, readbuf); | 
|  | if (writebuf != NULL) | 
|  | 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 (reg, readbuf + b); | 
|  | if (writebuf != NULL) | 
|  | regcache->cooked_write (reg, writebuf + b); | 
|  | reg++; | 
|  | } | 
|  | return RETURN_VALUE_REGISTER_CONVENTION; | 
|  | } | 
|  | else | 
|  | return RETURN_VALUE_STRUCT_CONVENTION; | 
|  | } | 
|  |  | 
|  | static enum return_value_convention | 
|  | hppa64_return_value (struct gdbarch *gdbarch, struct value *function, | 
|  | struct type *type, struct regcache *regcache, | 
|  | gdb_byte *readbuf, const gdb_byte *writebuf) | 
|  | { | 
|  | int len = TYPE_LENGTH (type); | 
|  | int regnum, offset; | 
|  |  | 
|  | if (len > 16) | 
|  | { | 
|  | /* All return values larger than 128 bits must be aggregate | 
|  | return values.  */ | 
|  | gdb_assert (!hppa64_integral_or_pointer_p (type)); | 
|  | gdb_assert (!hppa64_floating_p (type)); | 
|  |  | 
|  | /* "Aggregate return values larger than 128 bits are returned in | 
|  | a buffer allocated by the caller.  The address of the buffer | 
|  | must be passed in GR 28."  */ | 
|  | return RETURN_VALUE_STRUCT_CONVENTION; | 
|  | } | 
|  |  | 
|  | if (hppa64_integral_or_pointer_p (type)) | 
|  | { | 
|  | /* "Integral return values are returned in GR 28.  Values | 
|  | smaller than 64 bits are padded on the left (with garbage)."  */ | 
|  | regnum = HPPA_RET0_REGNUM; | 
|  | offset = 8 - len; | 
|  | } | 
|  | else if (hppa64_floating_p (type)) | 
|  | { | 
|  | if (len > 8) | 
|  | { | 
|  | /* "Double-extended- and quad-precision floating-point | 
|  | values are returned in GRs 28 and 29.  The sign, | 
|  | exponent, and most-significant bits of the mantissa are | 
|  | returned in GR 28; the least-significant bits of the | 
|  | mantissa are passed in GR 29.  For double-extended | 
|  | precision values, GR 29 is padded on the right with 48 | 
|  | bits of garbage."  */ | 
|  | regnum = HPPA_RET0_REGNUM; | 
|  | offset = 0; | 
|  | } | 
|  | else | 
|  | { | 
|  | /* "Single-precision and double-precision floating-point | 
|  | return values are returned in FR 4R (single precision) or | 
|  | FR 4 (double-precision)."  */ | 
|  | regnum = HPPA64_FP4_REGNUM; | 
|  | offset = 8 - len; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | /* "Aggregate return values up to 64 bits in size are returned | 
|  | in GR 28.  Aggregates smaller than 64 bits are left aligned | 
|  | in the register; the pad bits on the right are undefined." | 
|  |  | 
|  | "Aggregate return values between 65 and 128 bits are returned | 
|  | in GRs 28 and 29.  The first 64 bits are placed in GR 28, and | 
|  | the remaining bits are placed, left aligned, in GR 29.  The | 
|  | pad bits on the right of GR 29 (if any) are undefined."  */ | 
|  | regnum = HPPA_RET0_REGNUM; | 
|  | offset = 0; | 
|  | } | 
|  |  | 
|  | if (readbuf) | 
|  | { | 
|  | while (len > 0) | 
|  | { | 
|  | regcache->cooked_read_part (regnum, offset, std::min (len, 8), | 
|  | readbuf); | 
|  | readbuf += std::min (len, 8); | 
|  | len -= std::min (len, 8); | 
|  | regnum++; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (writebuf) | 
|  | { | 
|  | while (len > 0) | 
|  | { | 
|  | regcache->cooked_write_part (regnum, offset, std::min (len, 8), | 
|  | writebuf); | 
|  | writebuf += std::min (len, 8); | 
|  | len -= std::min (len, 8); | 
|  | regnum++; | 
|  | } | 
|  | } | 
|  |  | 
|  | return RETURN_VALUE_REGISTER_CONVENTION; | 
|  | } | 
|  |  | 
|  |  | 
|  | static CORE_ADDR | 
|  | hppa32_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr, | 
|  | struct target_ops *targ) | 
|  | { | 
|  | if (addr & 2) | 
|  | { | 
|  | struct type *func_ptr_type = builtin_type (gdbarch)->builtin_func_ptr; | 
|  | CORE_ADDR plabel = addr & ~3; | 
|  | return read_memory_typed_address (plabel, func_ptr_type); | 
|  | } | 
|  |  | 
|  | return addr; | 
|  | } | 
|  |  | 
|  | static CORE_ADDR | 
|  | hppa32_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr) | 
|  | { | 
|  | /* HP frames are 64-byte (or cache line) aligned (yes that's _byte_ | 
|  | and not _bit_)!  */ | 
|  | return align_up (addr, 64); | 
|  | } | 
|  |  | 
|  | /* Force all frames to 16-byte alignment.  Better safe than sorry.  */ | 
|  |  | 
|  | static CORE_ADDR | 
|  | hppa64_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr) | 
|  | { | 
|  | /* Just always 16-byte align.  */ | 
|  | return align_up (addr, 16); | 
|  | } | 
|  |  | 
|  | static CORE_ADDR | 
|  | hppa_read_pc (readable_regcache *regcache) | 
|  | { | 
|  | ULONGEST ipsw; | 
|  | ULONGEST 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 | 
|  | there.  This is needed when single stepping; if the nullified | 
|  | instruction is on a different line, we don't want GDB to think | 
|  | we've stepped onto that line.  */ | 
|  | if (ipsw & 0x00200000) | 
|  | pc -= 4; | 
|  |  | 
|  | return pc & ~0x3; | 
|  | } | 
|  |  | 
|  | void | 
|  | hppa_write_pc (struct regcache *regcache, CORE_ADDR pc) | 
|  | { | 
|  | regcache_cooked_write_unsigned (regcache, HPPA_PCOQ_HEAD_REGNUM, pc); | 
|  | regcache_cooked_write_unsigned (regcache, HPPA_PCOQ_TAIL_REGNUM, pc + 4); | 
|  | } | 
|  |  | 
|  | /* For the given instruction (INST), return any adjustment it makes | 
|  | to the stack pointer or zero for no adjustment. | 
|  |  | 
|  | This only handles instructions commonly found in prologues.  */ | 
|  |  | 
|  | static int | 
|  | prologue_inst_adjust_sp (unsigned long inst) | 
|  | { | 
|  | /* This must persist across calls.  */ | 
|  | static int save_high21; | 
|  |  | 
|  | /* The most common way to perform a stack adjustment ldo X(sp),sp */ | 
|  | if ((inst & 0xffffc000) == 0x37de0000) | 
|  | return hppa_extract_14 (inst); | 
|  |  | 
|  | /* stwm X,D(sp) */ | 
|  | if ((inst & 0xffe00000) == 0x6fc00000) | 
|  | return hppa_extract_14 (inst); | 
|  |  | 
|  | /* std,ma X,D(sp) */ | 
|  | if ((inst & 0xffe00008) == 0x73c00008) | 
|  | 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.  */ | 
|  | if ((inst & 0xffe00000) == 0x2bc00000) | 
|  | { | 
|  | save_high21 = hppa_extract_21 (inst); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | if ((inst & 0xffff0000) == 0x343e0000) | 
|  | return save_high21 + hppa_extract_14 (inst); | 
|  |  | 
|  | /* fstws as used by the HP compilers.  */ | 
|  | if ((inst & 0xffffffe0) == 0x2fd01220) | 
|  | return hppa_extract_5_load (inst); | 
|  |  | 
|  | /* No adjustment.  */ | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* Return nonzero if INST is a branch of some kind, else return zero.  */ | 
|  |  | 
|  | static int | 
|  | is_branch (unsigned long inst) | 
|  | { | 
|  | switch (inst >> 26) | 
|  | { | 
|  | case 0x20: | 
|  | case 0x21: | 
|  | case 0x22: | 
|  | case 0x23: | 
|  | case 0x27: | 
|  | case 0x28: | 
|  | case 0x29: | 
|  | case 0x2a: | 
|  | case 0x2b: | 
|  | case 0x2f: | 
|  | case 0x30: | 
|  | case 0x31: | 
|  | case 0x32: | 
|  | case 0x33: | 
|  | case 0x38: | 
|  | case 0x39: | 
|  | case 0x3a: | 
|  | case 0x3b: | 
|  | return 1; | 
|  |  | 
|  | default: | 
|  | return 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Return the register number for a GR which is saved by INST or | 
|  | zero if INST does not save a GR. | 
|  |  | 
|  | Referenced from: | 
|  |  | 
|  | parisc 1.1: | 
|  | https://parisc.wiki.kernel.org/images-parisc/6/68/Pa11_acd.pdf | 
|  |  | 
|  | parisc 2.0: | 
|  | https://parisc.wiki.kernel.org/images-parisc/7/73/Parisc2.0.pdf | 
|  |  | 
|  | 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: | 
|  |  | 
|  | 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 treat 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 | 
|  | zero it INST does not save a FR. | 
|  |  | 
|  | Note we only care about full 64bit register stores (that's the only | 
|  | kind of stores the prologue will use). | 
|  |  | 
|  | FIXME: What about argument stores with the HP compiler in ANSI mode? */ | 
|  |  | 
|  | static int | 
|  | inst_saves_fr (unsigned long inst) | 
|  | { | 
|  | /* Is this an FSTD?  */ | 
|  | if ((inst & 0xfc00dfc0) == 0x2c001200) | 
|  | return hppa_extract_5r_store (inst); | 
|  | if ((inst & 0xfc000002) == 0x70000002) | 
|  | return hppa_extract_5R_store (inst); | 
|  | /* Is this an FSTW?  */ | 
|  | if ((inst & 0xfc00df80) == 0x24001200) | 
|  | return hppa_extract_5r_store (inst); | 
|  | if ((inst & 0xfc000002) == 0x7c000000) | 
|  | return hppa_extract_5R_store (inst); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* Advance PC across any function entry prologue instructions | 
|  | to reach some "real" code. | 
|  |  | 
|  | Use information in the unwind table to determine what exactly should | 
|  | be in the prologue.  */ | 
|  |  | 
|  |  | 
|  | static CORE_ADDR | 
|  | skip_prologue_hard_way (struct gdbarch *gdbarch, CORE_ADDR pc, | 
|  | int stop_before_branch) | 
|  | { | 
|  | enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | 
|  | 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; | 
|  | struct unwind_table_entry *u; | 
|  | int final_iteration; | 
|  |  | 
|  | restart_gr = 0; | 
|  | restart_fr = 0; | 
|  |  | 
|  | restart: | 
|  | u = find_unwind_entry (pc); | 
|  | if (!u) | 
|  | return pc; | 
|  |  | 
|  | /* If we are not at the beginning of a function, then return now.  */ | 
|  | if ((pc & ~0x3) != u->region_start) | 
|  | return pc; | 
|  |  | 
|  | /* This is how much of a frame adjustment we need to account for.  */ | 
|  | stack_remaining = u->Total_frame_size << 3; | 
|  |  | 
|  | /* Magic register saves we want to know about.  */ | 
|  | save_rp = u->Save_RP; | 
|  | save_sp = u->Save_SP; | 
|  |  | 
|  | /* An indication that args may be stored into the stack.  Unfortunately | 
|  | the HPUX compilers tend to set this in cases where no args were | 
|  | stored too!.  */ | 
|  | args_stored = 1; | 
|  |  | 
|  | /* Turn the Entry_GR field into a bitmask.  */ | 
|  | save_gr = 0; | 
|  | for (i = 3; i < u->Entry_GR + 3; i++) | 
|  | { | 
|  | /* Frame pointer gets saved into a special location.  */ | 
|  | if (u->Save_SP && i == HPPA_FP_REGNUM) | 
|  | continue; | 
|  |  | 
|  | save_gr |= (1 << i); | 
|  | } | 
|  | save_gr &= ~restart_gr; | 
|  |  | 
|  | /* Turn the Entry_FR field into a bitmask too.  */ | 
|  | save_fr = 0; | 
|  | for (i = 12; i < u->Entry_FR + 12; i++) | 
|  | save_fr |= (1 << i); | 
|  | save_fr &= ~restart_fr; | 
|  |  | 
|  | final_iteration = 0; | 
|  |  | 
|  | /* Loop until we find everything of interest or hit a branch. | 
|  |  | 
|  | For unoptimized GCC code and for any HP CC code this will never ever | 
|  | examine any user instructions. | 
|  |  | 
|  | For optimized GCC code we're faced with problems.  GCC will schedule | 
|  | its prologue and make prologue instructions available for delay slot | 
|  | filling.  The end result is user code gets mixed in with the prologue | 
|  | and a prologue instruction may be in the delay slot of the first branch | 
|  | or call. | 
|  |  | 
|  | Some unexpected things are expected with debugging optimized code, so | 
|  | we allow this routine to walk past user instructions in optimized | 
|  | GCC code.  */ | 
|  | while (save_gr || save_fr || save_rp || save_sp || stack_remaining > 0 | 
|  | || args_stored) | 
|  | { | 
|  | unsigned int reg_num; | 
|  | unsigned long old_stack_remaining, old_save_gr, old_save_fr; | 
|  | unsigned long old_save_rp, old_save_sp, next_inst; | 
|  |  | 
|  | /* Save copies of all the triggers so we can compare them later | 
|  | (only for HPC).  */ | 
|  | old_save_gr = save_gr; | 
|  | old_save_fr = save_fr; | 
|  | old_save_rp = save_rp; | 
|  | old_save_sp = save_sp; | 
|  | old_stack_remaining = stack_remaining; | 
|  |  | 
|  | status = target_read_memory (pc, buf, 4); | 
|  | inst = extract_unsigned_integer (buf, 4, byte_order); | 
|  |  | 
|  | /* Yow! */ | 
|  | if (status != 0) | 
|  | return pc; | 
|  |  | 
|  | /* Note the interesting effects of this instruction.  */ | 
|  | stack_remaining -= prologue_inst_adjust_sp (inst); | 
|  |  | 
|  | /* There are limited ways to store the return pointer into the | 
|  | stack.  */ | 
|  | if (inst == 0x6bc23fd9 || inst == 0x0fc212c1 || inst == 0x73c23fe1) | 
|  | save_rp = 0; | 
|  |  | 
|  | /* These are the only ways we save SP into the stack.  At this time | 
|  | the HP compilers never bother to save SP into the stack.  */ | 
|  | if ((inst & 0xffffc000) == 0x6fc10000 | 
|  | || (inst & 0xffffc00c) == 0x73c10008) | 
|  | save_sp = 0; | 
|  |  | 
|  | /* Are we loading some register with an offset from the argument | 
|  | pointer?  */ | 
|  | if ((inst & 0xffe00000) == 0x37a00000 | 
|  | || (inst & 0xffffffe0) == 0x081d0240) | 
|  | { | 
|  | pc += 4; | 
|  | continue; | 
|  | } | 
|  |  | 
|  | /* Account for general and floating-point register saves.  */ | 
|  | reg_num = inst_saves_gr (inst); | 
|  | save_gr &= ~(1 << reg_num); | 
|  |  | 
|  | /* Ugh.  Also account for argument stores into the stack. | 
|  | Unfortunately args_stored only tells us that some arguments | 
|  | where stored into the stack.  Not how many or what kind! | 
|  |  | 
|  | This is a kludge as on the HP compiler sets this bit and it | 
|  | never does prologue scheduling.  So once we see one, skip past | 
|  | all of them.   We have similar code for the fp arg stores below. | 
|  |  | 
|  | FIXME.  Can still die if we have a mix of GR and FR argument | 
|  | stores!  */ | 
|  | if (reg_num >= (gdbarch_ptr_bit (gdbarch) == 64 ? 19 : 23) | 
|  | && reg_num <= 26) | 
|  | { | 
|  | while (reg_num >= (gdbarch_ptr_bit (gdbarch) == 64 ? 19 : 23) | 
|  | && reg_num <= 26) | 
|  | { | 
|  | pc += 4; | 
|  | status = target_read_memory (pc, buf, 4); | 
|  | inst = extract_unsigned_integer (buf, 4, byte_order); | 
|  | if (status != 0) | 
|  | return pc; | 
|  | reg_num = inst_saves_gr (inst); | 
|  | } | 
|  | args_stored = 0; | 
|  | continue; | 
|  | } | 
|  |  | 
|  | reg_num = inst_saves_fr (inst); | 
|  | save_fr &= ~(1 << reg_num); | 
|  |  | 
|  | status = target_read_memory (pc + 4, buf, 4); | 
|  | next_inst = extract_unsigned_integer (buf, 4, byte_order); | 
|  |  | 
|  | /* Yow! */ | 
|  | if (status != 0) | 
|  | return pc; | 
|  |  | 
|  | /* We've got to be read to handle the ldo before the fp register | 
|  | save.  */ | 
|  | if ((inst & 0xfc000000) == 0x34000000 | 
|  | && inst_saves_fr (next_inst) >= 4 | 
|  | && inst_saves_fr (next_inst) | 
|  | <= (gdbarch_ptr_bit (gdbarch) == 64 ? 11 : 7)) | 
|  | { | 
|  | /* So we drop into the code below in a reasonable state.  */ | 
|  | reg_num = inst_saves_fr (next_inst); | 
|  | pc -= 4; | 
|  | } | 
|  |  | 
|  | /* Ugh.  Also account for argument stores into the stack. | 
|  | This is a kludge as on the HP compiler sets this bit and it | 
|  | never does prologue scheduling.  So once we see one, skip past | 
|  | all of them.  */ | 
|  | if (reg_num >= 4 | 
|  | && reg_num <= (gdbarch_ptr_bit (gdbarch) == 64 ? 11 : 7)) | 
|  | { | 
|  | while (reg_num >= 4 | 
|  | && reg_num | 
|  | <= (gdbarch_ptr_bit (gdbarch) == 64 ? 11 : 7)) | 
|  | { | 
|  | pc += 8; | 
|  | status = target_read_memory (pc, buf, 4); | 
|  | inst = extract_unsigned_integer (buf, 4, byte_order); | 
|  | if (status != 0) | 
|  | return pc; | 
|  | if ((inst & 0xfc000000) != 0x34000000) | 
|  | break; | 
|  | status = target_read_memory (pc + 4, buf, 4); | 
|  | next_inst = extract_unsigned_integer (buf, 4, byte_order); | 
|  | if (status != 0) | 
|  | return pc; | 
|  | reg_num = inst_saves_fr (next_inst); | 
|  | } | 
|  | args_stored = 0; | 
|  | continue; | 
|  | } | 
|  |  | 
|  | /* Quit if we hit any kind of branch.  This can happen if a prologue | 
|  | instruction is in the delay slot of the first call/branch.  */ | 
|  | if (is_branch (inst) && stop_before_branch) | 
|  | break; | 
|  |  | 
|  | /* What a crock.  The HP compilers set args_stored even if no | 
|  | arguments were stored into the stack (boo hiss).  This could | 
|  | cause this code to then skip a bunch of user insns (up to the | 
|  | first branch). | 
|  |  | 
|  | To combat this we try to identify when args_stored was bogusly | 
|  | set and clear it.   We only do this when args_stored is nonzero, | 
|  | all other resources are accounted for, and nothing changed on | 
|  | this pass.  */ | 
|  | if (args_stored | 
|  | && !(save_gr || save_fr || save_rp || save_sp || stack_remaining > 0) | 
|  | && old_save_gr == save_gr && old_save_fr == save_fr | 
|  | && old_save_rp == save_rp && old_save_sp == save_sp | 
|  | && old_stack_remaining == stack_remaining) | 
|  | break; | 
|  |  | 
|  | /* Bump the PC.  */ | 
|  | pc += 4; | 
|  |  | 
|  | /* !stop_before_branch, so also look at the insn in the delay slot | 
|  | of the branch.  */ | 
|  | if (final_iteration) | 
|  | break; | 
|  | if (is_branch (inst)) | 
|  | final_iteration = 1; | 
|  | } | 
|  |  | 
|  | /* We've got a tentative location for the end of the prologue.  However | 
|  | because of limitations in the unwind descriptor mechanism we may | 
|  | have went too far into user code looking for the save of a register | 
|  | that does not exist.  So, if there registers we expected to be saved | 
|  | but never were, mask them out and restart. | 
|  |  | 
|  | This should only happen in optimized code, and should be very rare.  */ | 
|  | if (save_gr || (save_fr && !(restart_fr || restart_gr))) | 
|  | { | 
|  | pc = orig_pc; | 
|  | restart_gr = save_gr; | 
|  | restart_fr = save_fr; | 
|  | goto restart; | 
|  | } | 
|  |  | 
|  | return pc; | 
|  | } | 
|  |  | 
|  |  | 
|  | /* Return the address of the PC after the last prologue instruction if | 
|  | we can determine it from the debug symbols.  Else return zero.  */ | 
|  |  | 
|  | static CORE_ADDR | 
|  | after_prologue (CORE_ADDR pc) | 
|  | { | 
|  | struct symtab_and_line sal; | 
|  | CORE_ADDR func_addr, func_end; | 
|  |  | 
|  | /* If we can not find the symbol in the partial symbol table, then | 
|  | there is no hope we can determine the function's start address | 
|  | with this code.  */ | 
|  | if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end)) | 
|  | return 0; | 
|  |  | 
|  | /* Get the line associated with FUNC_ADDR.  */ | 
|  | sal = find_pc_line (func_addr, 0); | 
|  |  | 
|  | /* There are only two cases to consider.  First, the end of the source line | 
|  | is within the function bounds.  In that case we return the end of the | 
|  | source line.  Second is the end of the source line extends beyond the | 
|  | bounds of the current function.  We need to use the slow code to | 
|  | examine instructions in that case. | 
|  |  | 
|  | Anything else is simply a bug elsewhere.  Fixing it here is absolutely | 
|  | the wrong thing to do.  In fact, it should be entirely possible for this | 
|  | function to always return zero since the slow instruction scanning code | 
|  | is supposed to *always* work.  If it does not, then it is a bug.  */ | 
|  | if (sal.end < func_end) | 
|  | return sal.end; | 
|  | else | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* To skip prologues, I use this predicate.  Returns either PC itself | 
|  | if the code at PC does not look like a function prologue; otherwise | 
|  | returns an address that (if we're lucky) follows the prologue. | 
|  |  | 
|  | hppa_skip_prologue is called by gdb to place a breakpoint in a function. | 
|  | It doesn't necessarily skips all the insns in the prologue.  In fact | 
|  | we might not want to skip all the insns because a prologue insn may | 
|  | appear in the delay slot of the first branch, and we don't want to | 
|  | skip over the branch in that case.  */ | 
|  |  | 
|  | static CORE_ADDR | 
|  | hppa_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) | 
|  | { | 
|  | CORE_ADDR post_prologue_pc; | 
|  |  | 
|  | /* See if we can determine the end of the prologue via the symbol table. | 
|  | If so, then return either PC, or the PC after the prologue, whichever | 
|  | is greater.  */ | 
|  |  | 
|  | post_prologue_pc = after_prologue (pc); | 
|  |  | 
|  | /* If after_prologue returned a useful address, then use it.  Else | 
|  | fall back on the instruction skipping code. | 
|  |  | 
|  | Some folks have claimed this causes problems because the breakpoint | 
|  | 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 std::max (pc, post_prologue_pc); | 
|  | else | 
|  | return (skip_prologue_hard_way (gdbarch, pc, 1)); | 
|  | } | 
|  |  | 
|  | /* Return an unwind entry that falls within the frame's code block.  */ | 
|  |  | 
|  | static struct unwind_table_entry * | 
|  | hppa_find_unwind_entry_in_block (struct frame_info *this_frame) | 
|  | { | 
|  | CORE_ADDR pc = get_frame_address_in_block (this_frame); | 
|  |  | 
|  | /* FIXME drow/20070101: Calling gdbarch_addr_bits_remove on the | 
|  | result of get_frame_address_in_block implies a problem. | 
|  | The bits should have been removed earlier, before the return | 
|  | value of gdbarch_unwind_pc.  That might be happening already; | 
|  | if it isn't, it should be fixed.  Then this call can be | 
|  | removed.  */ | 
|  | pc = gdbarch_addr_bits_remove (get_frame_arch (this_frame), pc); | 
|  | return find_unwind_entry (pc); | 
|  | } | 
|  |  | 
|  | struct hppa_frame_cache | 
|  | { | 
|  | CORE_ADDR base; | 
|  | trad_frame_saved_reg *saved_regs; | 
|  | }; | 
|  |  | 
|  | static struct hppa_frame_cache * | 
|  | hppa_frame_cache (struct frame_info *this_frame, void **this_cache) | 
|  | { | 
|  | struct gdbarch *gdbarch = get_frame_arch (this_frame); | 
|  | enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | 
|  | int word_size = gdbarch_ptr_bit (gdbarch) / 8; | 
|  | struct hppa_frame_cache *cache; | 
|  | long saved_gr_mask; | 
|  | long saved_fr_mask; | 
|  | long frame_size; | 
|  | struct unwind_table_entry *u; | 
|  | CORE_ADDR prologue_end; | 
|  | int fp_in_r1 = 0; | 
|  | int i; | 
|  |  | 
|  | if (hppa_debug) | 
|  | fprintf_unfiltered (gdb_stdlog, "{ hppa_frame_cache (frame=%d) -> ", | 
|  | frame_relative_level(this_frame)); | 
|  |  | 
|  | if ((*this_cache) != NULL) | 
|  | { | 
|  | if (hppa_debug) | 
|  | fprintf_unfiltered (gdb_stdlog, "base=%s (cached) }", | 
|  | paddress (gdbarch, ((struct hppa_frame_cache *)*this_cache)->base)); | 
|  | return (struct hppa_frame_cache *) (*this_cache); | 
|  | } | 
|  | cache = FRAME_OBSTACK_ZALLOC (struct hppa_frame_cache); | 
|  | (*this_cache) = cache; | 
|  | cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); | 
|  |  | 
|  | /* Yow! */ | 
|  | u = hppa_find_unwind_entry_in_block (this_frame); | 
|  | if (!u) | 
|  | { | 
|  | if (hppa_debug) | 
|  | fprintf_unfiltered (gdb_stdlog, "base=NULL (no unwind entry) }"); | 
|  | return (struct hppa_frame_cache *) (*this_cache); | 
|  | } | 
|  |  | 
|  | /* Turn the Entry_GR field into a bitmask.  */ | 
|  | saved_gr_mask = 0; | 
|  | for (i = 3; i < u->Entry_GR + 3; i++) | 
|  | { | 
|  | /* Frame pointer gets saved into a special location.  */ | 
|  | if (u->Save_SP && i == HPPA_FP_REGNUM) | 
|  | continue; | 
|  |  | 
|  | saved_gr_mask |= (1 << i); | 
|  | } | 
|  |  | 
|  | /* Turn the Entry_FR field into a bitmask too.  */ | 
|  | saved_fr_mask = 0; | 
|  | for (i = 12; i < u->Entry_FR + 12; i++) | 
|  | saved_fr_mask |= (1 << i); | 
|  |  | 
|  | /* Loop until we find everything of interest or hit a branch. | 
|  |  | 
|  | For unoptimized GCC code and for any HP CC code this will never ever | 
|  | examine any user instructions. | 
|  |  | 
|  | For optimized GCC code we're faced with problems.  GCC will schedule | 
|  | its prologue and make prologue instructions available for delay slot | 
|  | filling.  The end result is user code gets mixed in with the prologue | 
|  | and a prologue instruction may be in the delay slot of the first branch | 
|  | or call. | 
|  |  | 
|  | Some unexpected things are expected with debugging optimized code, so | 
|  | we allow this routine to walk past user instructions in optimized | 
|  | GCC code.  */ | 
|  | { | 
|  | int final_iteration = 0; | 
|  | CORE_ADDR pc, start_pc, end_pc; | 
|  | int looking_for_sp = u->Save_SP; | 
|  | int looking_for_rp = u->Save_RP; | 
|  | int fp_loc = -1; | 
|  |  | 
|  | /* We have to use skip_prologue_hard_way instead of just | 
|  | skip_prologue_using_sal, in case we stepped into a function without | 
|  | symbol information.  hppa_skip_prologue also bounds the returned | 
|  | pc by the passed in pc, so it will not return a pc in the next | 
|  | function. | 
|  |  | 
|  | We used to call hppa_skip_prologue to find the end of the prologue, | 
|  | but if some non-prologue instructions get scheduled into the prologue, | 
|  | and the program is compiled with debug information, the "easy" way | 
|  | in hppa_skip_prologue will return a prologue end that is too early | 
|  | for us to notice any potential frame adjustments.  */ | 
|  |  | 
|  | /* We used to use get_frame_func to locate the beginning of the | 
|  | function to pass to skip_prologue.  However, when objects are | 
|  | compiled without debug symbols, get_frame_func can return the wrong | 
|  | function (or 0).  We can do better than that by using unwind records. | 
|  | This only works if the Region_description of the unwind record | 
|  | indicates that it includes the entry point of the function. | 
|  | HP compilers sometimes generate unwind records for regions that | 
|  | do not include the entry or exit point of a function.  GNU tools | 
|  | do not do this.  */ | 
|  |  | 
|  | if ((u->Region_description & 0x2) == 0) | 
|  | start_pc = u->region_start; | 
|  | else | 
|  | start_pc = get_frame_func (this_frame); | 
|  |  | 
|  | prologue_end = skip_prologue_hard_way (gdbarch, start_pc, 0); | 
|  | end_pc = get_frame_pc (this_frame); | 
|  |  | 
|  | if (prologue_end != 0 && end_pc > prologue_end) | 
|  | end_pc = prologue_end; | 
|  |  | 
|  | frame_size = 0; | 
|  |  | 
|  | for (pc = start_pc; | 
|  | ((saved_gr_mask || saved_fr_mask | 
|  | || looking_for_sp || looking_for_rp | 
|  | || frame_size < (u->Total_frame_size << 3)) | 
|  | && pc < end_pc); | 
|  | pc += 4) | 
|  | { | 
|  | int reg; | 
|  | gdb_byte buf4[4]; | 
|  | long inst; | 
|  |  | 
|  | if (!safe_frame_unwind_memory (this_frame, pc, buf4)) | 
|  | { | 
|  | error (_("Cannot read instruction at %s."), | 
|  | paddress (gdbarch, pc)); | 
|  | return (struct hppa_frame_cache *) (*this_cache); | 
|  | } | 
|  |  | 
|  | inst = extract_unsigned_integer (buf4, sizeof buf4, byte_order); | 
|  |  | 
|  | /* Note the interesting effects of this instruction.  */ | 
|  | frame_size += prologue_inst_adjust_sp (inst); | 
|  |  | 
|  | /* There are limited ways to store the return pointer into the | 
|  | stack.  */ | 
|  | if (inst == 0x6bc23fd9) /* stw rp,-0x14(sr0,sp) */ | 
|  | { | 
|  | looking_for_rp = 0; | 
|  | cache->saved_regs[HPPA_RP_REGNUM].set_addr (-20); | 
|  | } | 
|  | else if (inst == 0x6bc23fd1) /* stw rp,-0x18(sr0,sp) */ | 
|  | { | 
|  | looking_for_rp = 0; | 
|  | cache->saved_regs[HPPA_RP_REGNUM].set_addr (-24); | 
|  | } | 
|  | else if (inst == 0x0fc212c1 | 
|  | || inst == 0x73c23fe1) /* std rp,-0x10(sr0,sp) */ | 
|  | { | 
|  | looking_for_rp = 0; | 
|  | cache->saved_regs[HPPA_RP_REGNUM].set_addr (-16); | 
|  | } | 
|  |  | 
|  | /* Check to see if we saved SP into the stack.  This also | 
|  | happens to indicate the location of the saved frame | 
|  | pointer.  */ | 
|  | if ((inst & 0xffffc000) == 0x6fc10000  /* stw,ma r1,N(sr0,sp) */ | 
|  | || (inst & 0xffffc00c) == 0x73c10008) /* std,ma r1,N(sr0,sp) */ | 
|  | { | 
|  | looking_for_sp = 0; | 
|  | cache->saved_regs[HPPA_FP_REGNUM].set_addr (0); | 
|  | } | 
|  | else if (inst == 0x08030241) /* copy %r3, %r1 */ | 
|  | { | 
|  | fp_in_r1 = 1; | 
|  | } | 
|  |  | 
|  | /* Account for general and floating-point register saves.  */ | 
|  | reg = inst_saves_gr (inst); | 
|  | if (reg >= 3 && reg <= 18 | 
|  | && (!u->Save_SP || reg != HPPA_FP_REGNUM)) | 
|  | { | 
|  | saved_gr_mask &= ~(1 << reg); | 
|  | if ((inst >> 26) == 0x1b && hppa_extract_14 (inst) >= 0) | 
|  | /* stwm with a positive displacement is a _post_ | 
|  | _modify_.  */ | 
|  | cache->saved_regs[reg].set_addr (0); | 
|  | else if ((inst & 0xfc00000c) == 0x70000008) | 
|  | /* A std has explicit post_modify forms.  */ | 
|  | cache->saved_regs[reg].set_addr (0); | 
|  | else | 
|  | { | 
|  | CORE_ADDR offset; | 
|  |  | 
|  | if ((inst >> 26) == 0x1c) | 
|  | offset = (inst & 0x1 ? -(1 << 13) : 0) | 
|  | | (((inst >> 4) & 0x3ff) << 3); | 
|  | else if ((inst >> 26) == 0x03) | 
|  | offset = hppa_low_hppa_sign_extend (inst & 0x1f, 5); | 
|  | else | 
|  | offset = hppa_extract_14 (inst); | 
|  |  | 
|  | /* Handle code with and without frame pointers.  */ | 
|  | if (u->Save_SP) | 
|  | cache->saved_regs[reg].set_addr (offset); | 
|  | else | 
|  | cache->saved_regs[reg].set_addr ((u->Total_frame_size << 3) | 
|  | + offset); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* GCC handles callee saved FP regs a little differently. | 
|  |  | 
|  | It emits an instruction to put the value of the start of | 
|  | the FP store area into %r1.  It then uses fstds,ma with a | 
|  | basereg of %r1 for the stores. | 
|  |  | 
|  | HP CC emits them at the current stack pointer modifying the | 
|  | stack pointer as it stores each register.  */ | 
|  |  | 
|  | /* ldo X(%r3),%r1 or ldo X(%r30),%r1.  */ | 
|  | if ((inst & 0xffffc000) == 0x34610000 | 
|  | || (inst & 0xffffc000) == 0x37c10000) | 
|  | fp_loc = hppa_extract_14 (inst); | 
|  |  | 
|  | reg = inst_saves_fr (inst); | 
|  | if (reg >= 12 && reg <= 21) | 
|  | { | 
|  | /* Note +4 braindamage below is necessary because the FP | 
|  | status registers are internally 8 registers rather than | 
|  | the expected 4 registers.  */ | 
|  | saved_fr_mask &= ~(1 << reg); | 
|  | if (fp_loc == -1) | 
|  | { | 
|  | /* 1st HP CC FP register store.  After this | 
|  | instruction we've set enough state that the GCC and | 
|  | HPCC code are both handled in the same manner.  */ | 
|  | cache->saved_regs[reg + HPPA_FP4_REGNUM + 4].set_addr (0); | 
|  | fp_loc = 8; | 
|  | } | 
|  | else | 
|  | { | 
|  | cache->saved_regs[reg + HPPA_FP0_REGNUM + 4].set_addr (fp_loc); | 
|  | fp_loc += 8; | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Quit if we hit any kind of branch the previous iteration.  */ | 
|  | if (final_iteration) | 
|  | break; | 
|  | /* We want to look precisely one instruction beyond the branch | 
|  | if we have not found everything yet.  */ | 
|  | if (is_branch (inst)) | 
|  | final_iteration = 1; | 
|  | } | 
|  | } | 
|  |  | 
|  | { | 
|  | /* The frame base always represents the value of %sp at entry to | 
|  | the current function (and is thus equivalent to the "saved" | 
|  | stack pointer.  */ | 
|  | CORE_ADDR this_sp = get_frame_register_unsigned (this_frame, | 
|  | HPPA_SP_REGNUM); | 
|  | CORE_ADDR fp; | 
|  |  | 
|  | if (hppa_debug) | 
|  | fprintf_unfiltered (gdb_stdlog, " (this_sp=%s, pc=%s, " | 
|  | "prologue_end=%s) ", | 
|  | paddress (gdbarch, this_sp), | 
|  | paddress (gdbarch, get_frame_pc (this_frame)), | 
|  | paddress (gdbarch, prologue_end)); | 
|  |  | 
|  | /* Check to see if a frame pointer is available, and use it for | 
|  | frame unwinding if it is. | 
|  |  | 
|  | There are some situations where we need to rely on the frame | 
|  | pointer to do stack unwinding.  For example, if a function calls | 
|  | alloca (), the stack pointer can get adjusted inside the body of | 
|  | the function.  In this case, the ABI requires that the compiler | 
|  | maintain a frame pointer for the function. | 
|  |  | 
|  | The unwind record has a flag (alloca_frame) that indicates that | 
|  | a function has a variable frame; unfortunately, gcc/binutils | 
|  | does not set this flag.  Instead, whenever a frame pointer is used | 
|  | and saved on the stack, the Save_SP flag is set.  We use this to | 
|  | decide whether to use the frame pointer for unwinding. | 
|  |  | 
|  | TODO: For the HP compiler, maybe we should use the alloca_frame flag | 
|  | instead of Save_SP.  */ | 
|  |  | 
|  | fp = get_frame_register_unsigned (this_frame, HPPA_FP_REGNUM); | 
|  |  | 
|  | if (u->alloca_frame) | 
|  | fp -= u->Total_frame_size << 3; | 
|  |  | 
|  | if (get_frame_pc (this_frame) >= prologue_end | 
|  | && (u->Save_SP || u->alloca_frame) && fp != 0) | 
|  | { | 
|  | cache->base = fp; | 
|  |  | 
|  | if (hppa_debug) | 
|  | fprintf_unfiltered (gdb_stdlog, " (base=%s) [frame pointer]", | 
|  | paddress (gdbarch, cache->base)); | 
|  | } | 
|  | else if (u->Save_SP | 
|  | && cache->saved_regs[HPPA_SP_REGNUM].is_addr ()) | 
|  | { | 
|  | /* Both we're expecting the SP to be saved and the SP has been | 
|  | saved.  The entry SP value is saved at this frame's SP | 
|  | address.  */ | 
|  | cache->base = read_memory_integer (this_sp, word_size, byte_order); | 
|  |  | 
|  | if (hppa_debug) | 
|  | fprintf_unfiltered (gdb_stdlog, " (base=%s) [saved]", | 
|  | paddress (gdbarch, cache->base)); | 
|  | } | 
|  | else | 
|  | { | 
|  | /* The prologue has been slowly allocating stack space.  Adjust | 
|  | the SP back.  */ | 
|  | cache->base = this_sp - frame_size; | 
|  | if (hppa_debug) | 
|  | fprintf_unfiltered (gdb_stdlog, " (base=%s) [unwind adjust]", | 
|  | paddress (gdbarch, cache->base)); | 
|  |  | 
|  | } | 
|  | cache->saved_regs[HPPA_SP_REGNUM].set_value (cache->base); | 
|  | } | 
|  |  | 
|  | /* The PC is found in the "return register", "Millicode" uses "r31" | 
|  | as the return register while normal code uses "rp".  */ | 
|  | if (u->Millicode) | 
|  | { | 
|  | if (cache->saved_regs[31].is_addr ()) | 
|  | { | 
|  | cache->saved_regs[HPPA_PCOQ_HEAD_REGNUM] = cache->saved_regs[31]; | 
|  | if (hppa_debug) | 
|  | fprintf_unfiltered (gdb_stdlog, " (pc=r31) [stack] } "); | 
|  | } | 
|  | else | 
|  | { | 
|  | ULONGEST r31 = get_frame_register_unsigned (this_frame, 31); | 
|  | cache->saved_regs[HPPA_PCOQ_HEAD_REGNUM].set_value (r31); | 
|  | if (hppa_debug) | 
|  | fprintf_unfiltered (gdb_stdlog, " (pc=r31) [frame] } "); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | if (cache->saved_regs[HPPA_RP_REGNUM].is_addr ()) | 
|  | { | 
|  | cache->saved_regs[HPPA_PCOQ_HEAD_REGNUM] = | 
|  | cache->saved_regs[HPPA_RP_REGNUM]; | 
|  | if (hppa_debug) | 
|  | fprintf_unfiltered (gdb_stdlog, " (pc=rp) [stack] } "); | 
|  | } | 
|  | else | 
|  | { | 
|  | ULONGEST rp = get_frame_register_unsigned (this_frame, | 
|  | HPPA_RP_REGNUM); | 
|  | cache->saved_regs[HPPA_PCOQ_HEAD_REGNUM].set_value (rp); | 
|  | if (hppa_debug) | 
|  | fprintf_unfiltered (gdb_stdlog, " (pc=rp) [frame] } "); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* If Save_SP is set, then we expect the frame pointer to be saved in the | 
|  | frame.  However, there is a one-insn window where we haven't saved it | 
|  | yet, but we've already clobbered it.  Detect this case and fix it up. | 
|  |  | 
|  | The prologue sequence for frame-pointer functions is: | 
|  | 0: stw %rp, -20(%sp) | 
|  | 4: copy %r3, %r1 | 
|  | 8: copy %sp, %r3 | 
|  | c: stw,ma %r1, XX(%sp) | 
|  |  | 
|  | So if we are at offset c, the r3 value that we want is not yet saved | 
|  | on the stack, but it's been overwritten.  The prologue analyzer will | 
|  | set fp_in_r1 when it sees the copy insn so we know to get the value | 
|  | from r1 instead.  */ | 
|  | if (u->Save_SP && !cache->saved_regs[HPPA_FP_REGNUM].is_addr () | 
|  | && fp_in_r1) | 
|  | { | 
|  | ULONGEST r1 = get_frame_register_unsigned (this_frame, 1); | 
|  | cache->saved_regs[HPPA_FP_REGNUM].set_value (r1); | 
|  | } | 
|  |  | 
|  | { | 
|  | /* Convert all the offsets into addresses.  */ | 
|  | int reg; | 
|  | for (reg = 0; reg < gdbarch_num_regs (gdbarch); reg++) | 
|  | { | 
|  | if (cache->saved_regs[reg].is_addr ()) | 
|  | cache->saved_regs[reg].set_addr (cache->saved_regs[reg].addr () | 
|  | + cache->base); | 
|  | } | 
|  | } | 
|  |  | 
|  | { | 
|  | hppa_gdbarch_tdep *tdep = (hppa_gdbarch_tdep *) gdbarch_tdep (gdbarch); | 
|  |  | 
|  | if (tdep->unwind_adjust_stub) | 
|  | tdep->unwind_adjust_stub (this_frame, cache->base, cache->saved_regs); | 
|  | } | 
|  |  | 
|  | if (hppa_debug) | 
|  | fprintf_unfiltered (gdb_stdlog, "base=%s }", | 
|  | paddress (gdbarch, ((struct hppa_frame_cache *)*this_cache)->base)); | 
|  | return (struct hppa_frame_cache *) (*this_cache); | 
|  | } | 
|  |  | 
|  | static void | 
|  | hppa_frame_this_id (struct frame_info *this_frame, void **this_cache, | 
|  | struct frame_id *this_id) | 
|  | { | 
|  | struct hppa_frame_cache *info; | 
|  | struct unwind_table_entry *u; | 
|  |  | 
|  | info = hppa_frame_cache (this_frame, this_cache); | 
|  | u = hppa_find_unwind_entry_in_block (this_frame); | 
|  |  | 
|  | (*this_id) = frame_id_build (info->base, u->region_start); | 
|  | } | 
|  |  | 
|  | static struct value * | 
|  | hppa_frame_prev_register (struct frame_info *this_frame, | 
|  | void **this_cache, int regnum) | 
|  | { | 
|  | struct hppa_frame_cache *info = hppa_frame_cache (this_frame, this_cache); | 
|  |  | 
|  | return hppa_frame_prev_register_helper (this_frame, | 
|  | info->saved_regs, regnum); | 
|  | } | 
|  |  | 
|  | static int | 
|  | hppa_frame_unwind_sniffer (const struct frame_unwind *self, | 
|  | struct frame_info *this_frame, void **this_cache) | 
|  | { | 
|  | if (hppa_find_unwind_entry_in_block (this_frame)) | 
|  | return 1; | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static const struct frame_unwind hppa_frame_unwind = | 
|  | { | 
|  | "hppa unwind table", | 
|  | NORMAL_FRAME, | 
|  | default_frame_unwind_stop_reason, | 
|  | hppa_frame_this_id, | 
|  | hppa_frame_prev_register, | 
|  | NULL, | 
|  | hppa_frame_unwind_sniffer | 
|  | }; | 
|  |  | 
|  | /* This is a generic fallback frame unwinder that kicks in if we fail all | 
|  | the other ones.  Normally we would expect the stub and regular unwinder | 
|  | to work, but in some cases we might hit a function that just doesn't | 
|  | have any unwind information available.  In this case we try to do | 
|  | unwinding solely based on code reading.  This is obviously going to be | 
|  | slow, so only use this as a last resort.  Currently this will only | 
|  | identify the stack and pc for the frame.  */ | 
|  |  | 
|  | static struct hppa_frame_cache * | 
|  | hppa_fallback_frame_cache (struct frame_info *this_frame, void **this_cache) | 
|  | { | 
|  | struct gdbarch *gdbarch = get_frame_arch (this_frame); | 
|  | enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | 
|  | struct hppa_frame_cache *cache; | 
|  | unsigned int frame_size = 0; | 
|  | int found_rp = 0; | 
|  | CORE_ADDR start_pc; | 
|  |  | 
|  | if (hppa_debug) | 
|  | fprintf_unfiltered (gdb_stdlog, | 
|  | "{ hppa_fallback_frame_cache (frame=%d) -> ", | 
|  | frame_relative_level (this_frame)); | 
|  |  | 
|  | cache = FRAME_OBSTACK_ZALLOC (struct hppa_frame_cache); | 
|  | (*this_cache) = cache; | 
|  | cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); | 
|  |  | 
|  | start_pc = get_frame_func (this_frame); | 
|  | if (start_pc) | 
|  | { | 
|  | CORE_ADDR cur_pc = get_frame_pc (this_frame); | 
|  | CORE_ADDR pc; | 
|  |  | 
|  | for (pc = start_pc; pc < cur_pc; pc += 4) | 
|  | { | 
|  | unsigned int insn; | 
|  |  | 
|  | insn = read_memory_unsigned_integer (pc, 4, byte_order); | 
|  | frame_size += prologue_inst_adjust_sp (insn); | 
|  |  | 
|  | /* There are limited ways to store the return pointer into the | 
|  | stack.  */ | 
|  | if (insn == 0x6bc23fd9) /* stw rp,-0x14(sr0,sp) */ | 
|  | { | 
|  | cache->saved_regs[HPPA_RP_REGNUM].set_addr (-20); | 
|  | found_rp = 1; | 
|  | } | 
|  | else if (insn == 0x0fc212c1 | 
|  | || insn == 0x73c23fe1) /* std rp,-0x10(sr0,sp) */ | 
|  | { | 
|  | cache->saved_regs[HPPA_RP_REGNUM].set_addr (-16); | 
|  | found_rp = 1; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | if (hppa_debug) | 
|  | fprintf_unfiltered (gdb_stdlog, " frame_size=%d, found_rp=%d }\n", | 
|  | frame_size, found_rp); | 
|  |  | 
|  | cache->base = get_frame_register_unsigned (this_frame, HPPA_SP_REGNUM); | 
|  | cache->base -= frame_size; | 
|  | cache->saved_regs[HPPA_SP_REGNUM].set_value (cache->base); | 
|  |  | 
|  | if (cache->saved_regs[HPPA_RP_REGNUM].is_addr ()) | 
|  | { | 
|  | cache->saved_regs[HPPA_RP_REGNUM].set_addr (cache->saved_regs[HPPA_RP_REGNUM].addr () | 
|  | + cache->base); | 
|  | cache->saved_regs[HPPA_PCOQ_HEAD_REGNUM] = | 
|  | cache->saved_regs[HPPA_RP_REGNUM]; | 
|  | } | 
|  | else | 
|  | { | 
|  | ULONGEST rp; | 
|  | rp = get_frame_register_unsigned (this_frame, HPPA_RP_REGNUM); | 
|  | cache->saved_regs[HPPA_PCOQ_HEAD_REGNUM].set_value (rp); | 
|  | } | 
|  |  | 
|  | return cache; | 
|  | } | 
|  |  | 
|  | static void | 
|  | hppa_fallback_frame_this_id (struct frame_info *this_frame, void **this_cache, | 
|  | struct frame_id *this_id) | 
|  | { | 
|  | struct hppa_frame_cache *info = | 
|  | hppa_fallback_frame_cache (this_frame, this_cache); | 
|  |  | 
|  | (*this_id) = frame_id_build (info->base, get_frame_func (this_frame)); | 
|  | } | 
|  |  | 
|  | static struct value * | 
|  | hppa_fallback_frame_prev_register (struct frame_info *this_frame, | 
|  | void **this_cache, int regnum) | 
|  | { | 
|  | struct hppa_frame_cache *info | 
|  | = hppa_fallback_frame_cache (this_frame, this_cache); | 
|  |  | 
|  | return hppa_frame_prev_register_helper (this_frame, | 
|  | info->saved_regs, regnum); | 
|  | } | 
|  |  | 
|  | static const struct frame_unwind hppa_fallback_frame_unwind = | 
|  | { | 
|  | "hppa prologue", | 
|  | NORMAL_FRAME, | 
|  | default_frame_unwind_stop_reason, | 
|  | hppa_fallback_frame_this_id, | 
|  | hppa_fallback_frame_prev_register, | 
|  | NULL, | 
|  | default_frame_sniffer | 
|  | }; | 
|  |  | 
|  | /* Stub frames, used for all kinds of call stubs.  */ | 
|  | struct hppa_stub_unwind_cache | 
|  | { | 
|  | CORE_ADDR base; | 
|  | trad_frame_saved_reg *saved_regs; | 
|  | }; | 
|  |  | 
|  | static struct hppa_stub_unwind_cache * | 
|  | hppa_stub_frame_unwind_cache (struct frame_info *this_frame, | 
|  | void **this_cache) | 
|  | { | 
|  | struct hppa_stub_unwind_cache *info; | 
|  |  | 
|  | if (*this_cache) | 
|  | return (struct hppa_stub_unwind_cache *) *this_cache; | 
|  |  | 
|  | info = FRAME_OBSTACK_ZALLOC (struct hppa_stub_unwind_cache); | 
|  | *this_cache = info; | 
|  | info->saved_regs = trad_frame_alloc_saved_regs (this_frame); | 
|  |  | 
|  | info->base = get_frame_register_unsigned (this_frame, HPPA_SP_REGNUM); | 
|  |  | 
|  | /* By default we assume that stubs do not change the rp.  */ | 
|  | info->saved_regs[HPPA_PCOQ_HEAD_REGNUM].set_realreg (HPPA_RP_REGNUM); | 
|  |  | 
|  | return info; | 
|  | } | 
|  |  | 
|  | static void | 
|  | hppa_stub_frame_this_id (struct frame_info *this_frame, | 
|  | void **this_prologue_cache, | 
|  | struct frame_id *this_id) | 
|  | { | 
|  | struct hppa_stub_unwind_cache *info | 
|  | = hppa_stub_frame_unwind_cache (this_frame, this_prologue_cache); | 
|  |  | 
|  | if (info) | 
|  | *this_id = frame_id_build (info->base, get_frame_func (this_frame)); | 
|  | } | 
|  |  | 
|  | static struct value * | 
|  | hppa_stub_frame_prev_register (struct frame_info *this_frame, | 
|  | void **this_prologue_cache, int regnum) | 
|  | { | 
|  | struct hppa_stub_unwind_cache *info | 
|  | = hppa_stub_frame_unwind_cache (this_frame, this_prologue_cache); | 
|  |  | 
|  | if (info == NULL) | 
|  | error (_("Requesting registers from null frame.")); | 
|  |  | 
|  | return hppa_frame_prev_register_helper (this_frame, | 
|  | info->saved_regs, regnum); | 
|  | } | 
|  |  | 
|  | static int | 
|  | hppa_stub_unwind_sniffer (const struct frame_unwind *self, | 
|  | struct frame_info *this_frame, | 
|  | void **this_cache) | 
|  | { | 
|  | CORE_ADDR pc = get_frame_address_in_block (this_frame); | 
|  | struct gdbarch *gdbarch = get_frame_arch (this_frame); | 
|  | hppa_gdbarch_tdep *tdep = (hppa_gdbarch_tdep *) gdbarch_tdep (gdbarch); | 
|  |  | 
|  | if (pc == 0 | 
|  | || (tdep->in_solib_call_trampoline != NULL | 
|  | && tdep->in_solib_call_trampoline (gdbarch, pc)) | 
|  | || gdbarch_in_solib_return_trampoline (gdbarch, pc, NULL)) | 
|  | return 1; | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static const struct frame_unwind hppa_stub_frame_unwind = { | 
|  | "hppa stub", | 
|  | NORMAL_FRAME, | 
|  | default_frame_unwind_stop_reason, | 
|  | hppa_stub_frame_this_id, | 
|  | hppa_stub_frame_prev_register, | 
|  | NULL, | 
|  | hppa_stub_unwind_sniffer | 
|  | }; | 
|  |  | 
|  | CORE_ADDR | 
|  | hppa_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) | 
|  | { | 
|  | ULONGEST ipsw; | 
|  | CORE_ADDR pc; | 
|  |  | 
|  | ipsw = frame_unwind_register_unsigned (next_frame, HPPA_IPSW_REGNUM); | 
|  | pc = frame_unwind_register_unsigned (next_frame, HPPA_PCOQ_HEAD_REGNUM); | 
|  |  | 
|  | /* If the current instruction is nullified, then we are effectively | 
|  | still executing the previous instruction.  Pretend we are still | 
|  | there.  This is needed when single stepping; if the nullified | 
|  | instruction is on a different line, we don't want GDB to think | 
|  | we've stepped onto that line.  */ | 
|  | if (ipsw & 0x00200000) | 
|  | pc -= 4; | 
|  |  | 
|  | return pc & ~0x3; | 
|  | } | 
|  |  | 
|  | /* Return the minimal symbol whose name is NAME and stub type is STUB_TYPE. | 
|  | Return NULL if no such symbol was found.  */ | 
|  |  | 
|  | struct bound_minimal_symbol | 
|  | hppa_lookup_stub_minimal_symbol (const char *name, | 
|  | enum unwind_stub_types stub_type) | 
|  | { | 
|  | struct bound_minimal_symbol result; | 
|  |  | 
|  | for (objfile *objfile : current_program_space->objfiles ()) | 
|  | { | 
|  | for (minimal_symbol *msym : objfile->msymbols ()) | 
|  | { | 
|  | if (strcmp (msym->linkage_name (), name) == 0) | 
|  | { | 
|  | struct unwind_table_entry *u; | 
|  |  | 
|  | 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 result; | 
|  | } | 
|  |  | 
|  | static void | 
|  | unwind_command (const char *exp, int from_tty) | 
|  | { | 
|  | CORE_ADDR address; | 
|  | struct unwind_table_entry *u; | 
|  |  | 
|  | /* If we have an expression, evaluate it and use it as the address.  */ | 
|  |  | 
|  | if (exp != 0 && *exp != 0) | 
|  | address = parse_and_eval_address (exp); | 
|  | else | 
|  | return; | 
|  |  | 
|  | u = find_unwind_entry (address); | 
|  |  | 
|  | if (!u) | 
|  | { | 
|  | printf_filtered ("Can't find unwind table entry for %s\n", exp); | 
|  | return; | 
|  | } | 
|  |  | 
|  | printf_filtered ("unwind_table_entry (%s):\n", host_address_to_string (u)); | 
|  |  | 
|  | printf_filtered ("\tregion_start = %s\n", hex_string (u->region_start)); | 
|  |  | 
|  | printf_filtered ("\tregion_end = %s\n", hex_string (u->region_end)); | 
|  |  | 
|  | #define pif(FLD) if (u->FLD) printf_filtered (" "#FLD); | 
|  |  | 
|  | printf_filtered ("\n\tflags ="); | 
|  | pif (Cannot_unwind); | 
|  | pif (Millicode); | 
|  | pif (Millicode_save_sr0); | 
|  | pif (Entry_SR); | 
|  | pif (Args_stored); | 
|  | pif (Variable_Frame); | 
|  | pif (Separate_Package_Body); | 
|  | pif (Frame_Extension_Millicode); | 
|  | pif (Stack_Overflow_Check); | 
|  | pif (Two_Instruction_SP_Increment); | 
|  | pif (sr4export); | 
|  | pif (cxx_info); | 
|  | pif (cxx_try_catch); | 
|  | pif (sched_entry_seq); | 
|  | pif (Save_SP); | 
|  | pif (Save_RP); | 
|  | pif (Save_MRP_in_frame); | 
|  | pif (save_r19); | 
|  | pif (Cleanup_defined); | 
|  | pif (MPE_XL_interrupt_marker); | 
|  | pif (HP_UX_interrupt_marker); | 
|  | pif (Large_frame); | 
|  | pif (alloca_frame); | 
|  |  | 
|  | putchar_filtered ('\n'); | 
|  |  | 
|  | #define pin(FLD) printf_filtered ("\t"#FLD" = 0x%x\n", u->FLD); | 
|  |  | 
|  | pin (Region_description); | 
|  | pin (Entry_FR); | 
|  | pin (Entry_GR); | 
|  | pin (Total_frame_size); | 
|  |  | 
|  | if (u->stub_unwind.stub_type) | 
|  | { | 
|  | printf_filtered ("\tstub type = "); | 
|  | switch (u->stub_unwind.stub_type) | 
|  | { | 
|  | case LONG_BRANCH: | 
|  | printf_filtered ("long branch\n"); | 
|  | break; | 
|  | case PARAMETER_RELOCATION: | 
|  | printf_filtered ("parameter relocation\n"); | 
|  | break; | 
|  | case EXPORT: | 
|  | printf_filtered ("export\n"); | 
|  | break; | 
|  | case IMPORT: | 
|  | printf_filtered ("import\n"); | 
|  | break; | 
|  | case IMPORT_SHLIB: | 
|  | printf_filtered ("import shlib\n"); | 
|  | break; | 
|  | default: | 
|  | printf_filtered ("unknown (%d)\n", u->stub_unwind.stub_type); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Return the GDB type object for the "standard" data type of data in | 
|  | register REGNUM.  */ | 
|  |  | 
|  | static struct type * | 
|  | hppa32_register_type (struct gdbarch *gdbarch, int regnum) | 
|  | { | 
|  | if (regnum < HPPA_FP4_REGNUM) | 
|  | return builtin_type (gdbarch)->builtin_uint32; | 
|  | else | 
|  | return builtin_type (gdbarch)->builtin_float; | 
|  | } | 
|  |  | 
|  | static struct type * | 
|  | hppa64_register_type (struct gdbarch *gdbarch, int regnum) | 
|  | { | 
|  | if (regnum < HPPA64_FP4_REGNUM) | 
|  | return builtin_type (gdbarch)->builtin_uint64; | 
|  | else | 
|  | return builtin_type (gdbarch)->builtin_double; | 
|  | } | 
|  |  | 
|  | /* Return non-zero if REGNUM is not a register available to the user | 
|  | through ptrace/ttrace.  */ | 
|  |  | 
|  | static int | 
|  | hppa32_cannot_store_register (struct gdbarch *gdbarch, int regnum) | 
|  | { | 
|  | return (regnum == 0 | 
|  | || regnum == HPPA_PCSQ_HEAD_REGNUM | 
|  | || (regnum >= HPPA_PCSQ_TAIL_REGNUM && regnum < HPPA_IPSW_REGNUM) | 
|  | || (regnum > HPPA_IPSW_REGNUM && regnum < HPPA_FP4_REGNUM)); | 
|  | } | 
|  |  | 
|  | static int | 
|  | hppa32_cannot_fetch_register (struct gdbarch *gdbarch, int regnum) | 
|  | { | 
|  | /* cr26 and cr27 are readable (but not writable) from userspace.  */ | 
|  | if (regnum == HPPA_CR26_REGNUM || regnum == HPPA_CR27_REGNUM) | 
|  | return 0; | 
|  | else | 
|  | return hppa32_cannot_store_register (gdbarch, regnum); | 
|  | } | 
|  |  | 
|  | static int | 
|  | hppa64_cannot_store_register (struct gdbarch *gdbarch, int regnum) | 
|  | { | 
|  | return (regnum == 0 | 
|  | || regnum == HPPA_PCSQ_HEAD_REGNUM | 
|  | || (regnum >= HPPA_PCSQ_TAIL_REGNUM && regnum < HPPA_IPSW_REGNUM) | 
|  | || (regnum > HPPA_IPSW_REGNUM && regnum < HPPA64_FP4_REGNUM)); | 
|  | } | 
|  |  | 
|  | static int | 
|  | hppa64_cannot_fetch_register (struct gdbarch *gdbarch, int regnum) | 
|  | { | 
|  | /* cr26 and cr27 are readable (but not writable) from userspace.  */ | 
|  | if (regnum == HPPA_CR26_REGNUM || regnum == HPPA_CR27_REGNUM) | 
|  | return 0; | 
|  | else | 
|  | return hppa64_cannot_store_register (gdbarch, regnum); | 
|  | } | 
|  |  | 
|  | static CORE_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 | 
|  | this means that "addresses" in a text section therefore include a | 
|  | privilege level, and thus symbol tables should contain these bits. | 
|  | This seems like a bonehead thing to do--anyway, it seems to work | 
|  | for our purposes to just ignore those bits.  */ | 
|  |  | 
|  | return (addr &= ~0x3); | 
|  | } | 
|  |  | 
|  | /* Get the ARGIth function argument for the current function.  */ | 
|  |  | 
|  | static CORE_ADDR | 
|  | hppa_fetch_pointer_argument (struct frame_info *frame, int argi, | 
|  | struct type *type) | 
|  | { | 
|  | return get_frame_register_unsigned (frame, HPPA_R0_REGNUM + 26 - argi); | 
|  | } | 
|  |  | 
|  | static enum register_status | 
|  | 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 (regnum, &tmp); | 
|  | if (status == REG_VALID) | 
|  | { | 
|  | if (regnum == HPPA_PCOQ_HEAD_REGNUM || regnum == HPPA_PCOQ_TAIL_REGNUM) | 
|  | tmp &= ~0x3; | 
|  | store_unsigned_integer (buf, sizeof tmp, byte_order, tmp); | 
|  | } | 
|  | return status; | 
|  | } | 
|  |  | 
|  | static CORE_ADDR | 
|  | hppa_find_global_pointer (struct gdbarch *gdbarch, struct value *function) | 
|  | { | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | struct value * | 
|  | hppa_frame_prev_register_helper (struct frame_info *this_frame, | 
|  | trad_frame_saved_reg saved_regs[], | 
|  | int regnum) | 
|  | { | 
|  | struct gdbarch *arch = get_frame_arch (this_frame); | 
|  | enum bfd_endian byte_order = gdbarch_byte_order (arch); | 
|  |  | 
|  | if (regnum == HPPA_PCOQ_TAIL_REGNUM) | 
|  | { | 
|  | int size = register_size (arch, HPPA_PCOQ_HEAD_REGNUM); | 
|  | CORE_ADDR pc; | 
|  | struct value *pcoq_val = | 
|  | trad_frame_get_prev_register (this_frame, saved_regs, | 
|  | HPPA_PCOQ_HEAD_REGNUM); | 
|  |  | 
|  | pc = extract_unsigned_integer (value_contents_all (pcoq_val).data (), | 
|  | size, byte_order); | 
|  | return frame_unwind_got_constant (this_frame, regnum, pc + 4); | 
|  | } | 
|  |  | 
|  | return trad_frame_get_prev_register (this_frame, saved_regs, regnum); | 
|  | } | 
|  |  | 
|  |  | 
|  | /* An instruction to match.  */ | 
|  | struct insn_pattern | 
|  | { | 
|  | unsigned int data;            /* See if it matches this....  */ | 
|  | unsigned int mask;            /* ... with this mask.  */ | 
|  | }; | 
|  |  | 
|  | /* See bfd/elf32-hppa.c */ | 
|  | static struct insn_pattern hppa_long_branch_stub[] = { | 
|  | /* ldil LR'xxx,%r1 */ | 
|  | { 0x20200000, 0xffe00000 }, | 
|  | /* be,n RR'xxx(%sr4,%r1) */ | 
|  | { 0xe0202002, 0xffe02002 }, | 
|  | { 0, 0 } | 
|  | }; | 
|  |  | 
|  | static struct insn_pattern hppa_long_branch_pic_stub[] = { | 
|  | /* b,l .+8, %r1 */ | 
|  | { 0xe8200000, 0xffe00000 }, | 
|  | /* addil LR'xxx - ($PIC_pcrel$0 - 4), %r1 */ | 
|  | { 0x28200000, 0xffe00000 }, | 
|  | /* be,n RR'xxxx - ($PIC_pcrel$0 - 8)(%sr4, %r1) */ | 
|  | { 0xe0202002, 0xffe02002 }, | 
|  | { 0, 0 } | 
|  | }; | 
|  |  | 
|  | static struct insn_pattern hppa_import_stub[] = { | 
|  | /* addil LR'xxx, %dp */ | 
|  | { 0x2b600000, 0xffe00000 }, | 
|  | /* ldw RR'xxx(%r1), %r21 */ | 
|  | { 0x48350000, 0xffffb000 }, | 
|  | /* bv %r0(%r21) */ | 
|  | { 0xeaa0c000, 0xffffffff }, | 
|  | /* ldw RR'xxx+4(%r1), %r19 */ | 
|  | { 0x48330000, 0xffffb000 }, | 
|  | { 0, 0 } | 
|  | }; | 
|  |  | 
|  | static struct insn_pattern hppa_import_pic_stub[] = { | 
|  | /* addil LR'xxx,%r19 */ | 
|  | { 0x2a600000, 0xffe00000 }, | 
|  | /* ldw RR'xxx(%r1),%r21 */ | 
|  | { 0x48350000, 0xffffb000 }, | 
|  | /* bv %r0(%r21) */ | 
|  | { 0xeaa0c000, 0xffffffff }, | 
|  | /* ldw RR'xxx+4(%r1),%r19 */ | 
|  | { 0x48330000, 0xffffb000 }, | 
|  | { 0, 0 }, | 
|  | }; | 
|  |  | 
|  | static struct insn_pattern hppa_plt_stub[] = { | 
|  | /* b,l 1b, %r20 - 1b is 3 insns before here */ | 
|  | { 0xea9f1fdd, 0xffffffff }, | 
|  | /* depi 0,31,2,%r20 */ | 
|  | { 0xd6801c1e, 0xffffffff }, | 
|  | { 0, 0 } | 
|  | }; | 
|  |  | 
|  | /* Maximum number of instructions on the patterns above.  */ | 
|  | #define HPPA_MAX_INSN_PATTERN_LEN	4 | 
|  |  | 
|  | /* Return non-zero if the instructions at PC match the series | 
|  | described in PATTERN, or zero otherwise.  PATTERN is an array of | 
|  | 'struct insn_pattern' objects, terminated by an entry whose mask is | 
|  | zero. | 
|  |  | 
|  | When the match is successful, fill INSN[i] with what PATTERN[i] | 
|  | matched.  */ | 
|  |  | 
|  | static int | 
|  | hppa_match_insns (struct gdbarch *gdbarch, CORE_ADDR pc, | 
|  | struct insn_pattern *pattern, unsigned int *insn) | 
|  | { | 
|  | enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); | 
|  | CORE_ADDR npc = pc; | 
|  | int i; | 
|  |  | 
|  | for (i = 0; pattern[i].mask; i++) | 
|  | { | 
|  | gdb_byte buf[HPPA_INSN_SIZE]; | 
|  |  | 
|  | target_read_memory (npc, buf, HPPA_INSN_SIZE); | 
|  | insn[i] = extract_unsigned_integer (buf, HPPA_INSN_SIZE, byte_order); | 
|  | if ((insn[i] & pattern[i].mask) == pattern[i].data) | 
|  | npc += 4; | 
|  | else | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | /* This relaxed version of the instruction matcher allows us to match | 
|  | from somewhere inside the pattern, by looking backwards in the | 
|  | instruction scheme.  */ | 
|  |  | 
|  | static int | 
|  | hppa_match_insns_relaxed (struct gdbarch *gdbarch, CORE_ADDR pc, | 
|  | struct insn_pattern *pattern, unsigned int *insn) | 
|  | { | 
|  | int offset, len = 0; | 
|  |  | 
|  | while (pattern[len].mask) | 
|  | len++; | 
|  |  | 
|  | for (offset = 0; offset < len; offset++) | 
|  | if (hppa_match_insns (gdbarch, pc - offset * HPPA_INSN_SIZE, | 
|  | pattern, insn)) | 
|  | return 1; | 
|  |  | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | hppa_in_dyncall (CORE_ADDR pc) | 
|  | { | 
|  | struct unwind_table_entry *u; | 
|  |  | 
|  | u = find_unwind_entry (hppa_symbol_address ("$$dyncall")); | 
|  | if (!u) | 
|  | return 0; | 
|  |  | 
|  | return (pc >= u->region_start && pc <= u->region_end); | 
|  | } | 
|  |  | 
|  | int | 
|  | 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) || hppa_in_dyncall (pc)) | 
|  | return 1; | 
|  |  | 
|  | /* The GNU toolchain produces linker stubs without unwind | 
|  | information.  Since the pattern matching for linker stubs can be | 
|  | quite slow, so bail out if we do have an unwind entry.  */ | 
|  |  | 
|  | u = find_unwind_entry (pc); | 
|  | if (u != NULL) | 
|  | return 0; | 
|  |  | 
|  | return | 
|  | (hppa_match_insns_relaxed (gdbarch, pc, hppa_import_stub, insn) | 
|  | || hppa_match_insns_relaxed (gdbarch, pc, hppa_import_pic_stub, insn) | 
|  | || hppa_match_insns_relaxed (gdbarch, pc, hppa_long_branch_stub, insn) | 
|  | || hppa_match_insns_relaxed (gdbarch, pc, | 
|  | hppa_long_branch_pic_stub, insn)); | 
|  | } | 
|  |  | 
|  | /* This code skips several kind of "trampolines" used on PA-RISC | 
|  | systems: $$dyncall, import stubs and PLT stubs.  */ | 
|  |  | 
|  | CORE_ADDR | 
|  | hppa_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) | 
|  | { | 
|  | struct gdbarch *gdbarch = get_frame_arch (frame); | 
|  | struct type *func_ptr_type = builtin_type (gdbarch)->builtin_func_ptr; | 
|  |  | 
|  | unsigned int insn[HPPA_MAX_INSN_PATTERN_LEN]; | 
|  | int dp_rel; | 
|  |  | 
|  | /* $$dyncall handles both PLABELs and direct addresses.  */ | 
|  | if (hppa_in_dyncall (pc)) | 
|  | { | 
|  | pc = get_frame_register_unsigned (frame, HPPA_R0_REGNUM + 22); | 
|  |  | 
|  | /* PLABELs have bit 30 set; if it's a PLABEL, then dereference it.  */ | 
|  | if (pc & 0x2) | 
|  | pc = read_memory_typed_address (pc & ~0x3, func_ptr_type); | 
|  |  | 
|  | return pc; | 
|  | } | 
|  |  | 
|  | dp_rel = hppa_match_insns (gdbarch, pc, hppa_import_stub, insn); | 
|  | if (dp_rel || hppa_match_insns (gdbarch, pc, hppa_import_pic_stub, insn)) | 
|  | { | 
|  | /* Extract the target address from the addil/ldw sequence.  */ | 
|  | pc = hppa_extract_21 (insn[0]) + hppa_extract_14 (insn[1]); | 
|  |  | 
|  | if (dp_rel) | 
|  | pc += get_frame_register_unsigned (frame, HPPA_DP_REGNUM); | 
|  | else | 
|  | pc += get_frame_register_unsigned (frame, HPPA_R0_REGNUM + 19); | 
|  |  | 
|  | /* fallthrough */ | 
|  | } | 
|  |  | 
|  | 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)) | 
|  | { | 
|  | /* Sanity check: are we pointing to the PLT stub?  */ | 
|  | if (!hppa_match_insns (gdbarch, pc, hppa_plt_stub, insn)) | 
|  | { | 
|  | warning (_("Cannot resolve PLT stub at %s."), | 
|  | paddress (gdbarch, pc)); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* This should point to the fixup routine.  */ | 
|  | pc = read_memory_typed_address (pc + 8, func_ptr_type); | 
|  | } | 
|  | } | 
|  |  | 
|  | return pc; | 
|  | } | 
|  |  | 
|  |  | 
|  | /* Here is a table of C type sizes on hppa with various compiles | 
|  | and options.  I measured this on PA 9000/800 with HP-UX 11.11 | 
|  | and these compilers: | 
|  |  | 
|  | /usr/ccs/bin/cc    HP92453-01 A.11.01.21 | 
|  | /opt/ansic/bin/cc  HP92453-01 B.11.11.28706.GP | 
|  | /opt/aCC/bin/aCC   B3910B A.03.45 | 
|  | gcc                gcc 3.3.2 native hppa2.0w-hp-hpux11.11 | 
|  |  | 
|  | cc            : 1 2 4 4 8 : 4 8 -- : 4 4 | 
|  | ansic +DA1.1  : 1 2 4 4 8 : 4 8 16 : 4 4 | 
|  | ansic +DA2.0  : 1 2 4 4 8 : 4 8 16 : 4 4 | 
|  | ansic +DA2.0W : 1 2 4 8 8 : 4 8 16 : 8 8 | 
|  | acc   +DA1.1  : 1 2 4 4 8 : 4 8 16 : 4 4 | 
|  | acc   +DA2.0  : 1 2 4 4 8 : 4 8 16 : 4 4 | 
|  | acc   +DA2.0W : 1 2 4 8 8 : 4 8 16 : 8 8 | 
|  | gcc           : 1 2 4 4 8 : 4 8 16 : 4 4 | 
|  |  | 
|  | Each line is: | 
|  |  | 
|  | compiler and options | 
|  | char, short, int, long, long long | 
|  | float, double, long double | 
|  | char *, void (*)() | 
|  |  | 
|  | So all these compilers use either ILP32 or LP64 model. | 
|  | TODO: gcc has more options so it needs more investigation. | 
|  |  | 
|  | For floating point types, see: | 
|  |  | 
|  | http://docs.hp.com/hpux/pdf/B3906-90006.pdf | 
|  | HP-UX floating-point guide, hpux 11.00 | 
|  |  | 
|  | -- chastain 2003-12-18  */ | 
|  |  | 
|  | static struct gdbarch * | 
|  | hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) | 
|  | { | 
|  | struct gdbarch *gdbarch; | 
|  |  | 
|  | /* find a candidate among the list of pre-declared architectures.  */ | 
|  | arches = gdbarch_list_lookup_by_info (arches, &info); | 
|  | if (arches != NULL) | 
|  | return (arches->gdbarch); | 
|  |  | 
|  | /* If none found, then allocate and initialize one.  */ | 
|  | hppa_gdbarch_tdep *tdep = new hppa_gdbarch_tdep; | 
|  | gdbarch = gdbarch_alloc (&info, tdep); | 
|  |  | 
|  | /* Determine from the bfd_arch_info structure if we are dealing with | 
|  | a 32 or 64 bits architecture.  If the bfd_arch_info is not available, | 
|  | then default to a 32bit machine.  */ | 
|  | if (info.bfd_arch_info != NULL) | 
|  | tdep->bytes_per_address = | 
|  | info.bfd_arch_info->bits_per_address / info.bfd_arch_info->bits_per_byte; | 
|  | else | 
|  | tdep->bytes_per_address = 4; | 
|  |  | 
|  | tdep->find_global_pointer = hppa_find_global_pointer; | 
|  |  | 
|  | /* Some parts of the gdbarch vector depend on whether we are running | 
|  | on a 32 bits or 64 bits target.  */ | 
|  | switch (tdep->bytes_per_address) | 
|  | { | 
|  | case 4: | 
|  | set_gdbarch_num_regs (gdbarch, hppa32_num_regs); | 
|  | set_gdbarch_register_name (gdbarch, hppa32_register_name); | 
|  | set_gdbarch_register_type (gdbarch, hppa32_register_type); | 
|  | set_gdbarch_cannot_store_register (gdbarch, | 
|  | hppa32_cannot_store_register); | 
|  | set_gdbarch_cannot_fetch_register (gdbarch, | 
|  | hppa32_cannot_fetch_register); | 
|  | break; | 
|  | case 8: | 
|  | set_gdbarch_num_regs (gdbarch, hppa64_num_regs); | 
|  | set_gdbarch_register_name (gdbarch, hppa64_register_name); | 
|  | set_gdbarch_register_type (gdbarch, hppa64_register_type); | 
|  | set_gdbarch_dwarf2_reg_to_regnum (gdbarch, hppa64_dwarf_reg_to_regnum); | 
|  | set_gdbarch_cannot_store_register (gdbarch, | 
|  | hppa64_cannot_store_register); | 
|  | set_gdbarch_cannot_fetch_register (gdbarch, | 
|  | hppa64_cannot_fetch_register); | 
|  | break; | 
|  | default: | 
|  | internal_error (__FILE__, __LINE__, _("Unsupported address size: %d"), | 
|  | tdep->bytes_per_address); | 
|  | } | 
|  |  | 
|  | set_gdbarch_long_bit (gdbarch, tdep->bytes_per_address * TARGET_CHAR_BIT); | 
|  | set_gdbarch_ptr_bit (gdbarch, tdep->bytes_per_address * TARGET_CHAR_BIT); | 
|  |  | 
|  | /* The following gdbarch vector elements are the same in both ILP32 | 
|  | and LP64, but might show differences some day.  */ | 
|  | set_gdbarch_long_long_bit (gdbarch, 64); | 
|  | set_gdbarch_long_double_bit (gdbarch, 128); | 
|  | set_gdbarch_long_double_format (gdbarch, floatformats_ia64_quad); | 
|  |  | 
|  | /* 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_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_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); | 
|  |  | 
|  | /* Helper for function argument information.  */ | 
|  | set_gdbarch_fetch_pointer_argument (gdbarch, hppa_fetch_pointer_argument); | 
|  |  | 
|  | /* 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 | 
|  | whether any watched location changed.  */ | 
|  | set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1); | 
|  |  | 
|  | /* Inferior function call methods.  */ | 
|  | switch (tdep->bytes_per_address) | 
|  | { | 
|  | case 4: | 
|  | set_gdbarch_push_dummy_call (gdbarch, hppa32_push_dummy_call); | 
|  | set_gdbarch_frame_align (gdbarch, hppa32_frame_align); | 
|  | set_gdbarch_convert_from_func_ptr_addr | 
|  | (gdbarch, hppa32_convert_from_func_ptr_addr); | 
|  | break; | 
|  | case 8: | 
|  | set_gdbarch_push_dummy_call (gdbarch, hppa64_push_dummy_call); | 
|  | set_gdbarch_frame_align (gdbarch, hppa64_frame_align); | 
|  | break; | 
|  | default: | 
|  | internal_error (__FILE__, __LINE__, _("bad switch")); | 
|  | } | 
|  |  | 
|  | /* Struct return methods.  */ | 
|  | switch (tdep->bytes_per_address) | 
|  | { | 
|  | case 4: | 
|  | set_gdbarch_return_value (gdbarch, hppa32_return_value); | 
|  | break; | 
|  | case 8: | 
|  | set_gdbarch_return_value (gdbarch, hppa64_return_value); | 
|  | break; | 
|  | default: | 
|  | internal_error (__FILE__, __LINE__, _("bad switch")); | 
|  | } | 
|  |  | 
|  | 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.  */ | 
|  | set_gdbarch_unwind_pc (gdbarch, hppa_unwind_pc); | 
|  |  | 
|  | /* Hook in ABI-specific overrides, if they have been registered.  */ | 
|  | gdbarch_init_osabi (info, gdbarch); | 
|  |  | 
|  | /* Hook in the default unwinders.  */ | 
|  | frame_unwind_append_unwinder (gdbarch, &hppa_stub_frame_unwind); | 
|  | frame_unwind_append_unwinder (gdbarch, &hppa_frame_unwind); | 
|  | frame_unwind_append_unwinder (gdbarch, &hppa_fallback_frame_unwind); | 
|  |  | 
|  | return gdbarch; | 
|  | } | 
|  |  | 
|  | static void | 
|  | hppa_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) | 
|  | { | 
|  | hppa_gdbarch_tdep *tdep = (hppa_gdbarch_tdep *) gdbarch_tdep (gdbarch); | 
|  |  | 
|  | fprintf_filtered (file, "bytes_per_address = %d\n", | 
|  | tdep->bytes_per_address); | 
|  | fprintf_filtered (file, "elf = %s\n", tdep->is_elf ? "yes" : "no"); | 
|  | } | 
|  |  | 
|  | void _initialize_hppa_tdep (); | 
|  | void | 
|  | _initialize_hppa_tdep () | 
|  | { | 
|  | gdbarch_register (bfd_arch_hppa, hppa_gdbarch_init, hppa_dump_tdep); | 
|  |  | 
|  | add_cmd ("unwind", class_maintenance, unwind_command, | 
|  | _("Print unwind table entry at given address."), | 
|  | &maintenanceprintlist); | 
|  |  | 
|  | /* Debug this files internals.  */ | 
|  | add_setshow_boolean_cmd ("hppa", class_maintenance, &hppa_debug, _("\ | 
|  | Set whether hppa target specific debugging information should be displayed."), | 
|  | _("\ | 
|  | Show whether hppa target specific debugging information is displayed."), _("\ | 
|  | This flag controls whether hppa target specific debugging information is\n\ | 
|  | displayed.  This information is particularly useful for debugging frame\n\ | 
|  | unwinding problems."), | 
|  | NULL, | 
|  | NULL, /* FIXME: i18n: hppa debug flag is %s.  */ | 
|  | &setdebuglist, &showdebuglist); | 
|  | } |