- struct gdbarch *gdbarch;
- struct gdbarch_tdep *tdep;
-
- static LONGEST call_dummy_32[] =
- { 0xbc100001, 0x9de38000, 0xbc100002, 0xbe100003,
- 0xda03a058, 0xd803a054, 0xd603a050, 0xd403a04c,
- 0xd203a048, 0x40000000, 0xd003a044, 0x01000000,
- 0x91d02001, 0x01000000
- };
- static LONGEST call_dummy_64[] =
- { 0x9de3bec0fd3fa7f7LL, 0xf93fa7eff53fa7e7LL,
- 0xf13fa7dfed3fa7d7LL, 0xe93fa7cfe53fa7c7LL,
- 0xe13fa7bfdd3fa7b7LL, 0xd93fa7afd53fa7a7LL,
- 0xd13fa79fcd3fa797LL, 0xc93fa78fc53fa787LL,
- 0xc13fa77fcc3fa777LL, 0xc83fa76fc43fa767LL,
- 0xc03fa75ffc3fa757LL, 0xf83fa74ff43fa747LL,
- 0xf03fa73f01000000LL, 0x0100000001000000LL,
- 0x0100000091580000LL, 0xd027a72b93500000LL,
- 0xd027a72791480000LL, 0xd027a72391400000LL,
- 0xd027a71fda5ba8a7LL, 0xd85ba89fd65ba897LL,
- 0xd45ba88fd25ba887LL, 0x9fc02000d05ba87fLL,
- 0x0100000091d02001LL, 0x0100000001000000LL
- };
- static LONGEST call_dummy_nil[] = {0};
-
- /* Try to determine the OS ABI of the object we are loading. */
-
- if (info.abfd != NULL
- && info.osabi == GDB_OSABI_UNKNOWN)
- {
- /* If it's an ELF file, assume it's Solaris. */
- if (bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
- info.osabi = GDB_OSABI_SOLARIS;
- }
-
- /* First see if there is already a gdbarch that can satisfy the request. */
- arches = gdbarch_list_lookup_by_info (arches, &info);
- if (arches != NULL)
- return arches->gdbarch;
-
- /* None found: is the request for a sparc architecture? */
- if (info.bfd_arch_info->arch != bfd_arch_sparc)
- return NULL; /* No; then it's not for us. */
-
- /* Yes: create a new gdbarch for the specified machine type. */
- tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
- gdbarch = gdbarch_alloc (&info, tdep);
-
- /* First set settings that are common for all sparc architectures. */
- set_gdbarch_believe_pcc_promotion (gdbarch, 1);
- set_gdbarch_breakpoint_from_pc (gdbarch, sparc_breakpoint_from_pc);
- set_gdbarch_decr_pc_after_break (gdbarch, 0);
- set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
- set_gdbarch_extract_struct_value_address (gdbarch,
- sparc_extract_struct_value_address);
- set_gdbarch_deprecated_fix_call_dummy (gdbarch, sparc_gdbarch_fix_call_dummy);
- set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_deprecated_fp_regnum (gdbarch, SPARC_FP_REGNUM);
- set_gdbarch_fp0_regnum (gdbarch, SPARC_FP0_REGNUM);
- set_gdbarch_deprecated_frame_chain (gdbarch, sparc_frame_chain);
- set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sparc_frame_init_saved_regs);
- set_gdbarch_deprecated_frame_saved_pc (gdbarch, sparc_frame_saved_pc);
- set_gdbarch_frameless_function_invocation (gdbarch,
- frameless_look_for_prologue);
- set_gdbarch_deprecated_get_saved_register (gdbarch, sparc_get_saved_register);
- set_gdbarch_deprecated_init_extra_frame_info (gdbarch, sparc_init_extra_frame_info);
- set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_long_double_bit (gdbarch, 16 * TARGET_CHAR_BIT);
- set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
- set_gdbarch_deprecated_max_register_raw_size (gdbarch, 8);
- set_gdbarch_deprecated_max_register_virtual_size (gdbarch, 8);
- set_gdbarch_deprecated_pop_frame (gdbarch, sparc_pop_frame);
- set_gdbarch_deprecated_push_return_address (gdbarch, sparc_push_return_address);
- set_gdbarch_deprecated_push_dummy_frame (gdbarch, sparc_push_dummy_frame);
- set_gdbarch_deprecated_reg_struct_has_addr
- (gdbarch, sparc_reg_struct_has_addr);
- set_gdbarch_return_value_on_stack (gdbarch, sparc_return_value_on_stack);
- set_gdbarch_deprecated_saved_pc_after_call (gdbarch, sparc_saved_pc_after_call);
- set_gdbarch_prologue_frameless_p (gdbarch, sparc_prologue_frameless_p);
- set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
- set_gdbarch_skip_prologue (gdbarch, sparc_skip_prologue);
- set_gdbarch_sp_regnum (gdbarch, SPARC_SP_REGNUM);
- set_gdbarch_deprecated_use_generic_dummy_frames (gdbarch, 0);
- set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
-
- /* Helper for function argument information. */
- set_gdbarch_fetch_pointer_argument (gdbarch, sparc_fetch_pointer_argument);
-
- /*
- * Settings that depend only on 32/64 bit word size
- */
-
- switch (info.bfd_arch_info->mach)
- {
- case bfd_mach_sparc:
- case bfd_mach_sparc_v8plus:
- case bfd_mach_sparc_v8plusa:
- /* 32-bit machine types: */
-
-#ifdef SPARC32_CALL_DUMMY_ON_STACK
- set_gdbarch_deprecated_pc_in_call_dummy (gdbarch, deprecated_pc_in_call_dummy_on_stack);
- set_gdbarch_deprecated_call_dummy_address (gdbarch, sparc_call_dummy_address);
- set_gdbarch_deprecated_call_dummy_breakpoint_offset (gdbarch, 0x30);
- set_gdbarch_deprecated_call_dummy_length (gdbarch, 0x38);
-
- /* NOTE: cagney/2003-05-01: Using the just added push_dummy_code
- architecture method, it is now possible to implement a
- generic dummy frames based inferior function call that stores
- the breakpoint (and struct info) on the stack. Further, by
- treating a SIGSEG at a breakpoint as equivalent to a SIGTRAP
- it is even possible to make this work when the stack is
- no-execute.
-
- NOTE: cagney/2002-04-26: Based from info posted by Peter
- Schauer around Oct '99. Briefly, due to aspects of the SPARC
- ABI, it isn't possible to use ON_STACK with a strictly
- compliant compiler.
-
- Peter Schauer writes ...
-
- No, any call from GDB to a user function returning a
- struct/union will fail miserably. Try this:
-
- *NOINDENT*
- struct x
- {
- int a[4];
- };
-
- struct x gx;
-
- struct x
- sret ()
- {
- return gx;
- }
-
- main ()
- {
- int i;
- for (i = 0; i < 4; i++)
- gx.a[i] = i + 1;
- gx = sret ();
- }
- *INDENT*
-
- Set a breakpoint at the gx = sret () statement, run to it and
- issue a `print sret()'. It will not succed with your
- approach, and I doubt that continuing the program will work
- as well.
-
- For details of the ABI see the Sparc Architecture Manual. I
- have Version 8 (Prentice Hall ISBN 0-13-825001-4) and the
- calling conventions for functions returning aggregate values
- are explained in Appendix D.3. */
-
- set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
- set_gdbarch_deprecated_call_dummy_words (gdbarch, call_dummy_32);
-#else
- set_gdbarch_deprecated_pc_in_call_dummy (gdbarch, deprecated_pc_in_call_dummy_at_entry_point);
- set_gdbarch_deprecated_call_dummy_words (gdbarch, call_dummy_nil);
-#endif
- set_gdbarch_deprecated_call_dummy_stack_adjust (gdbarch, 68);
- set_gdbarch_frame_args_skip (gdbarch, 68);
- set_gdbarch_function_start_offset (gdbarch, 0);
- set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_deprecated_npc_regnum (gdbarch, SPARC32_NPC_REGNUM);
- set_gdbarch_pc_regnum (gdbarch, SPARC32_PC_REGNUM);
- set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_deprecated_push_arguments (gdbarch, sparc32_push_arguments);
-
- set_gdbarch_deprecated_register_byte (gdbarch, sparc32_register_byte);
- set_gdbarch_deprecated_register_raw_size (gdbarch, sparc32_register_size);
- set_gdbarch_deprecated_register_size (gdbarch, 4);
- set_gdbarch_deprecated_register_virtual_size (gdbarch, sparc32_register_size);
- set_gdbarch_deprecated_register_virtual_type (gdbarch, sparc32_register_virtual_type);
-#ifdef SPARC32_CALL_DUMMY_ON_STACK
- set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, sizeof (call_dummy_32));
-#else
- set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, 0);
-#endif
- set_gdbarch_deprecated_stack_align (gdbarch, sparc32_stack_align);
- set_gdbarch_deprecated_extra_stack_alignment_needed (gdbarch, 1);
- set_gdbarch_deprecated_store_struct_return (gdbarch, sparc32_store_struct_return);
- set_gdbarch_use_struct_convention (gdbarch,
- generic_use_struct_convention);
- set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp);
- tdep->y_regnum = SPARC32_Y_REGNUM;
- tdep->fp_max_regnum = SPARC_FP0_REGNUM + 32;
- tdep->intreg_size = 4;
- tdep->reg_save_offset = 0x60;
- tdep->call_dummy_call_offset = 0x24;
- break;
-
- case bfd_mach_sparc_v9:
- case bfd_mach_sparc_v9a:
- /* 64-bit machine types: */
- default: /* Any new machine type is likely to be 64-bit. */
-
-#ifdef SPARC64_CALL_DUMMY_ON_STACK
- set_gdbarch_deprecated_pc_in_call_dummy (gdbarch, deprecated_pc_in_call_dummy_on_stack);
- set_gdbarch_deprecated_call_dummy_address (gdbarch, sparc_call_dummy_address);
- set_gdbarch_deprecated_call_dummy_breakpoint_offset (gdbarch, 8 * 4);
- set_gdbarch_deprecated_call_dummy_length (gdbarch, 192);
- set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
- set_gdbarch_deprecated_call_dummy_start_offset (gdbarch, 148);
- set_gdbarch_deprecated_call_dummy_words (gdbarch, call_dummy_64);
-#else
- set_gdbarch_deprecated_pc_in_call_dummy (gdbarch, deprecated_pc_in_call_dummy_at_entry_point);
- set_gdbarch_deprecated_call_dummy_words (gdbarch, call_dummy_nil);
-#endif
- set_gdbarch_deprecated_call_dummy_stack_adjust (gdbarch, 128);
- set_gdbarch_frame_args_skip (gdbarch, 136);
- set_gdbarch_function_start_offset (gdbarch, 0);
- set_gdbarch_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
- set_gdbarch_deprecated_npc_regnum (gdbarch, SPARC64_NPC_REGNUM);
- set_gdbarch_pc_regnum (gdbarch, SPARC64_PC_REGNUM);
- set_gdbarch_ptr_bit (gdbarch, 8 * TARGET_CHAR_BIT);
- set_gdbarch_deprecated_push_arguments (gdbarch, sparc64_push_arguments);
- /* NOTE different for at_entry */
- set_gdbarch_deprecated_target_read_fp (gdbarch, sparc64_read_fp);
- set_gdbarch_read_sp (gdbarch, sparc64_read_sp);
- /* Some of the registers aren't 64 bits, but it's a lot simpler just
- to assume they all are (since most of them are). */
- set_gdbarch_deprecated_register_byte (gdbarch, sparc64_register_byte);
- set_gdbarch_deprecated_register_raw_size (gdbarch, sparc64_register_size);
- set_gdbarch_deprecated_register_size (gdbarch, 8);
- set_gdbarch_deprecated_register_virtual_size (gdbarch, sparc64_register_size);
- set_gdbarch_deprecated_register_virtual_type (gdbarch, sparc64_register_virtual_type);
-#ifdef SPARC64_CALL_DUMMY_ON_STACK
- set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, sizeof (call_dummy_64));
-#else
- set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, 0);
-#endif
- set_gdbarch_deprecated_stack_align (gdbarch, sparc64_stack_align);
- set_gdbarch_deprecated_extra_stack_alignment_needed (gdbarch, 1);
- set_gdbarch_deprecated_store_struct_return (gdbarch, sparc64_store_struct_return);
- set_gdbarch_use_struct_convention (gdbarch,
- sparc64_use_struct_convention);
- set_gdbarch_deprecated_dummy_write_sp (gdbarch, sparc64_write_sp);
- tdep->y_regnum = SPARC64_Y_REGNUM;
- tdep->fp_max_regnum = SPARC_FP0_REGNUM + 48;
- tdep->intreg_size = 8;
- tdep->reg_save_offset = 0x90;
- tdep->call_dummy_call_offset = 148 + 4 * 5;
- break;
- }
-
- /*
- * Settings that vary per-architecture:
- */
-
- switch (info.bfd_arch_info->mach)
- {
- case bfd_mach_sparc:
- set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value);
- set_gdbarch_store_return_value (gdbarch, sparc32_store_return_value);
- set_gdbarch_num_regs (gdbarch, 72);
- set_gdbarch_deprecated_register_bytes (gdbarch, 32*4 + 32*4 + 8*4);
- set_gdbarch_register_name (gdbarch, sparc32_register_name);
- tdep->fp_register_bytes = 32 * 4;
- tdep->print_insn_mach = bfd_mach_sparc;
- break;
- case bfd_mach_sparc_v8plus:
- set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value);
- set_gdbarch_store_return_value (gdbarch, sparc32_store_return_value);
- set_gdbarch_num_regs (gdbarch, 72);
- set_gdbarch_deprecated_register_bytes (gdbarch, 32*4 + 32*4 + 8*4);
- set_gdbarch_register_name (gdbarch, sparc32_register_name);
- tdep->print_insn_mach = bfd_mach_sparc;
- tdep->fp_register_bytes = 32 * 4;
- break;
- case bfd_mach_sparc_v8plusa:
- set_gdbarch_extract_return_value (gdbarch, sparc32_extract_return_value);
- set_gdbarch_store_return_value (gdbarch, sparc32_store_return_value);
- set_gdbarch_num_regs (gdbarch, 72);
- set_gdbarch_deprecated_register_bytes (gdbarch, 32*4 + 32*4 + 8*4);
- set_gdbarch_register_name (gdbarch, sparc32_register_name);
- tdep->fp_register_bytes = 32 * 4;
- tdep->print_insn_mach = bfd_mach_sparc;
- break;
- case bfd_mach_sparc_v9:
- set_gdbarch_deprecated_extract_return_value (gdbarch, sparc64_extract_return_value);
- set_gdbarch_num_regs (gdbarch, 125);
- set_gdbarch_deprecated_register_bytes (gdbarch, 32*8 + 32*8 + 45*8);
- set_gdbarch_register_name (gdbarch, sparc64_register_name);
- set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value);
- tdep->fp_register_bytes = 64 * 4;
- tdep->print_insn_mach = bfd_mach_sparc_v9a;
- break;
- case bfd_mach_sparc_v9a:
- set_gdbarch_deprecated_extract_return_value (gdbarch, sparc64_extract_return_value);
- set_gdbarch_num_regs (gdbarch, 125);
- set_gdbarch_deprecated_register_bytes (gdbarch, 32*8 + 32*8 + 45*8);
- set_gdbarch_register_name (gdbarch, sparc64_register_name);
- set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value);
- tdep->fp_register_bytes = 64 * 4;
- tdep->print_insn_mach = bfd_mach_sparc_v9a;
- break;
- }
-
- set_gdbarch_print_insn (gdbarch, print_insn_sparc);
-
- /* Hook in OS ABI-specific overrides, if they have been registered. */
- gdbarch_init_osabi (info, gdbarch);