gdb/lm32-tdep.c - gdb
Global variables defined
Data types defined
Functions defined
Macros defined
Source code
- #include "defs.h"
- #include "frame.h"
- #include "frame-unwind.h"
- #include "frame-base.h"
- #include "inferior.h"
- #include "dis-asm.h"
- #include "symfile.h"
- #include "remote.h"
- #include "gdbcore.h"
- #include "gdb/sim-lm32.h"
- #include "gdb/callback.h"
- #include "gdb/remote-sim.h"
- #include "sim-regno.h"
- #include "arch-utils.h"
- #include "regcache.h"
- #include "trad-frame.h"
- #include "reggroups.h"
- #include "opcodes/lm32-desc.h"
- #define LM32_OPCODE(insn) ((insn >> 26) & 0x3f)
- #define LM32_REG0(insn) ((insn >> 21) & 0x1f)
- #define LM32_REG1(insn) ((insn >> 16) & 0x1f)
- #define LM32_REG2(insn) ((insn >> 11) & 0x1f)
- #define LM32_IMM16(insn) ((((long)insn & 0xffff) << 16) >> 16)
- struct gdbarch_tdep
- {
-
- };
- struct lm32_frame_cache
- {
-
- CORE_ADDR base;
- CORE_ADDR pc;
-
- int size;
-
- struct trad_frame_saved_reg *saved_regs;
- };
- static void
- lm32_add_reggroups (struct gdbarch *gdbarch)
- {
- reggroup_add (gdbarch, general_reggroup);
- reggroup_add (gdbarch, all_reggroup);
- reggroup_add (gdbarch, system_reggroup);
- }
- static int
- lm32_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
- struct reggroup *group)
- {
- if (group == general_reggroup)
- return ((regnum >= SIM_LM32_R0_REGNUM) && (regnum <= SIM_LM32_RA_REGNUM))
- || (regnum == SIM_LM32_PC_REGNUM);
- else if (group == system_reggroup)
- return ((regnum >= SIM_LM32_EA_REGNUM) && (regnum <= SIM_LM32_BA_REGNUM))
- || ((regnum >= SIM_LM32_EID_REGNUM) && (regnum <= SIM_LM32_IP_REGNUM));
- return default_register_reggroup_p (gdbarch, regnum, group);
- }
- static const char *
- lm32_register_name (struct gdbarch *gdbarch, int reg_nr)
- {
- static char *register_names[] = {
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
- "r24", "r25", "gp", "fp", "sp", "ra", "ea", "ba",
- "PC", "EID", "EBA", "DEBA", "IE", "IM", "IP"
- };
- if ((reg_nr < 0) || (reg_nr >= ARRAY_SIZE (register_names)))
- return NULL;
- else
- return register_names[reg_nr];
- }
- static struct type *
- lm32_register_type (struct gdbarch *gdbarch, int reg_nr)
- {
- return builtin_type (gdbarch)->builtin_int32;
- }
- static int
- lm32_cannot_store_register (struct gdbarch *gdbarch, int regno)
- {
- return (regno == SIM_LM32_R0_REGNUM) || (regno == SIM_LM32_EID_REGNUM);
- }
- static CORE_ADDR
- lm32_analyze_prologue (struct gdbarch *gdbarch,
- CORE_ADDR pc, CORE_ADDR limit,
- struct lm32_frame_cache *info)
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- unsigned long instruction;
-
- info->size = 0;
- for (; pc < limit; pc += 4)
- {
-
- instruction = read_memory_integer (pc, 4, byte_order);
- if ((LM32_OPCODE (instruction) == OP_SW)
- && (LM32_REG0 (instruction) == SIM_LM32_SP_REGNUM))
- {
-
- info->saved_regs[LM32_REG1 (instruction)].addr =
- LM32_IMM16 (instruction);
- }
- else if ((LM32_OPCODE (instruction) == OP_ADDI)
- && (LM32_REG1 (instruction) == SIM_LM32_SP_REGNUM))
- {
-
- info->size -= LM32_IMM16 (instruction);
- }
- else if (
- ((LM32_OPCODE (instruction) == OP_ADD)
- && (LM32_REG2 (instruction) == SIM_LM32_FP_REGNUM)
- && (LM32_REG0 (instruction) == SIM_LM32_FP_REGNUM)
- && (LM32_REG1 (instruction) == SIM_LM32_SP_REGNUM))
-
- || ((LM32_OPCODE (instruction) == OP_ADDI)
- && (LM32_REG1 (instruction) == SIM_LM32_FP_REGNUM)
- && (LM32_REG0 (instruction) == SIM_LM32_R0_REGNUM)))
- {
-
- }
- else
- {
-
- break;
- }
- }
- return pc;
- }
- static CORE_ADDR
- lm32_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
- {
- CORE_ADDR func_addr, limit_pc;
- struct lm32_frame_cache frame_info;
- struct trad_frame_saved_reg saved_regs[SIM_LM32_NUM_REGS];
-
- if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
- {
- CORE_ADDR post_prologue_pc
- = skip_prologue_using_sal (gdbarch, func_addr);
- if (post_prologue_pc != 0)
- return max (pc, post_prologue_pc);
- }
-
-
- limit_pc = skip_prologue_using_sal (gdbarch, pc);
- if (limit_pc == 0)
- limit_pc = pc + 100;
- frame_info.saved_regs = saved_regs;
- return lm32_analyze_prologue (gdbarch, pc, limit_pc, &frame_info);
- }
- static const gdb_byte *
- lm32_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
- int *lenptr)
- {
- static const gdb_byte breakpoint[4] = { OP_RAISE << 2, 0, 0, 2 };
- *lenptr = sizeof (breakpoint);
- return breakpoint;
- }
- static CORE_ADDR
- lm32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
- struct regcache *regcache, CORE_ADDR bp_addr,
- int nargs, struct value **args, CORE_ADDR sp,
- int struct_return, CORE_ADDR struct_addr)
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- int first_arg_reg = SIM_LM32_R1_REGNUM;
- int num_arg_regs = 8;
- int i;
-
- regcache_cooked_write_signed (regcache, SIM_LM32_RA_REGNUM, bp_addr);
-
- if (struct_return)
- {
- regcache_cooked_write_unsigned (regcache, first_arg_reg, struct_addr);
- first_arg_reg++;
- num_arg_regs--;
- sp -= 4;
- }
-
- for (i = 0; i < nargs; i++)
- {
- struct value *arg = args[i];
- struct type *arg_type = check_typedef (value_type (arg));
- gdb_byte *contents;
- ULONGEST val;
-
- switch (TYPE_CODE (arg_type))
- {
- case TYPE_CODE_INT:
- case TYPE_CODE_BOOL:
- case TYPE_CODE_CHAR:
- case TYPE_CODE_RANGE:
- case TYPE_CODE_ENUM:
- if (TYPE_LENGTH (arg_type) < 4)
- {
- arg_type = builtin_type (gdbarch)->builtin_int32;
- arg = value_cast (arg_type, arg);
- }
- break;
- }
- FIXME
- contents = (gdb_byte *) value_contents (arg);
- val = extract_unsigned_integer (contents, TYPE_LENGTH (arg_type),
- byte_order);
-
- if (i < num_arg_regs)
- regcache_cooked_write_unsigned (regcache, first_arg_reg + i, val);
- else
- {
- write_memory (sp, (void *) &val, TYPE_LENGTH (arg_type));
- sp -= 4;
- }
- }
-
- regcache_cooked_write_signed (regcache, SIM_LM32_SP_REGNUM, sp);
-
- return sp;
- }
- static void
- lm32_extract_return_value (struct type *type, struct regcache *regcache,
- gdb_byte *valbuf)
- {
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- ULONGEST l;
- CORE_ADDR return_buffer;
- if (TYPE_CODE (type) != TYPE_CODE_STRUCT
- && TYPE_CODE (type) != TYPE_CODE_UNION
- && TYPE_CODE (type) != TYPE_CODE_ARRAY && TYPE_LENGTH (type) <= 4)
- {
-
- regcache_cooked_read_unsigned (regcache, SIM_LM32_R1_REGNUM, &l);
- store_unsigned_integer (valbuf, TYPE_LENGTH (type), byte_order, l);
- }
- else if ((TYPE_CODE (type) == TYPE_CODE_INT) && (TYPE_LENGTH (type) == 8))
- {
-
- regcache_cooked_read_unsigned (regcache, SIM_LM32_R1_REGNUM, &l);
- memcpy (valbuf, &l, 4);
- regcache_cooked_read_unsigned (regcache, SIM_LM32_R2_REGNUM, &l);
- memcpy (valbuf + 4, &l, 4);
- }
- else
- {
-
- FIXME
- regcache_cooked_read_unsigned (regcache, SIM_LM32_R1_REGNUM, &l);
- return_buffer = l;
- read_memory (return_buffer, valbuf, TYPE_LENGTH (type));
- }
- }
- static void
- lm32_store_return_value (struct type *type, struct regcache *regcache,
- const gdb_byte *valbuf)
- {
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- ULONGEST val;
- int len = TYPE_LENGTH (type);
- if (len <= 4)
- {
- val = extract_unsigned_integer (valbuf, len, byte_order);
- regcache_cooked_write_unsigned (regcache, SIM_LM32_R1_REGNUM, val);
- }
- else if (len <= 8)
- {
- val = extract_unsigned_integer (valbuf, 4, byte_order);
- regcache_cooked_write_unsigned (regcache, SIM_LM32_R1_REGNUM, val);
- val = extract_unsigned_integer (valbuf + 4, len - 4, byte_order);
- regcache_cooked_write_unsigned (regcache, SIM_LM32_R2_REGNUM, val);
- }
- else
- error (_("lm32_store_return_value: type length too large."));
- }
- static enum return_value_convention
- lm32_return_value (struct gdbarch *gdbarch, struct value *function,
- struct type *valtype, struct regcache *regcache,
- gdb_byte *readbuf, const gdb_byte *writebuf)
- {
- enum type_code code = TYPE_CODE (valtype);
- if (code == TYPE_CODE_STRUCT
- || code == TYPE_CODE_UNION
- || code == TYPE_CODE_ARRAY || TYPE_LENGTH (valtype) > 8)
- return RETURN_VALUE_STRUCT_CONVENTION;
- if (readbuf)
- lm32_extract_return_value (valtype, regcache, readbuf);
- if (writebuf)
- lm32_store_return_value (valtype, regcache, writebuf);
- return RETURN_VALUE_REGISTER_CONVENTION;
- }
- static CORE_ADDR
- lm32_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
- {
- return frame_unwind_register_unsigned (next_frame, SIM_LM32_PC_REGNUM);
- }
- static CORE_ADDR
- lm32_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
- {
- return frame_unwind_register_unsigned (next_frame, SIM_LM32_SP_REGNUM);
- }
- static struct frame_id
- lm32_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
- {
- CORE_ADDR sp = get_frame_register_unsigned (this_frame, SIM_LM32_SP_REGNUM);
- return frame_id_build (sp, get_frame_pc (this_frame));
- }
- static struct lm32_frame_cache *
- lm32_frame_cache (struct frame_info *this_frame, void **this_prologue_cache)
- {
- CORE_ADDR current_pc;
- ULONGEST prev_sp;
- ULONGEST this_base;
- struct lm32_frame_cache *info;
- int i;
- if ((*this_prologue_cache))
- return (*this_prologue_cache);
- info = FRAME_OBSTACK_ZALLOC (struct lm32_frame_cache);
- (*this_prologue_cache) = info;
- info->saved_regs = trad_frame_alloc_saved_regs (this_frame);
- info->pc = get_frame_func (this_frame);
- current_pc = get_frame_pc (this_frame);
- lm32_analyze_prologue (get_frame_arch (this_frame),
- info->pc, current_pc, info);
-
- this_base = get_frame_register_unsigned (this_frame, SIM_LM32_SP_REGNUM);
- prev_sp = this_base + info->size;
- info->base = this_base;
-
- for (i = 0; i < gdbarch_num_regs (get_frame_arch (this_frame)) - 1; i++)
- {
- if (trad_frame_addr_p (info->saved_regs, i))
- info->saved_regs[i].addr = this_base + info->saved_regs[i].addr;
- }
-
- info->saved_regs[SIM_LM32_PC_REGNUM] = info->saved_regs[SIM_LM32_RA_REGNUM];
-
- trad_frame_set_value (info->saved_regs, SIM_LM32_SP_REGNUM, prev_sp);
- return info;
- }
- static void
- lm32_frame_this_id (struct frame_info *this_frame, void **this_cache,
- struct frame_id *this_id)
- {
- struct lm32_frame_cache *cache = lm32_frame_cache (this_frame, this_cache);
-
- if (cache->base == 0)
- return;
- (*this_id) = frame_id_build (cache->base, cache->pc);
- }
- static struct value *
- lm32_frame_prev_register (struct frame_info *this_frame,
- void **this_prologue_cache, int regnum)
- {
- struct lm32_frame_cache *info;
- info = lm32_frame_cache (this_frame, this_prologue_cache);
- return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
- }
- static const struct frame_unwind lm32_frame_unwind = {
- NORMAL_FRAME,
- default_frame_unwind_stop_reason,
- lm32_frame_this_id,
- lm32_frame_prev_register,
- NULL,
- default_frame_sniffer
- };
- static CORE_ADDR
- lm32_frame_base_address (struct frame_info *this_frame, void **this_cache)
- {
- struct lm32_frame_cache *info = lm32_frame_cache (this_frame, this_cache);
- return info->base;
- }
- static const struct frame_base lm32_frame_base = {
- &lm32_frame_unwind,
- lm32_frame_base_address,
- lm32_frame_base_address,
- lm32_frame_base_address
- };
- static CORE_ADDR
- lm32_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
- {
-
- return sp & ~3;
- }
- static struct gdbarch *
- lm32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
- {
- struct gdbarch *gdbarch;
- struct gdbarch_tdep *tdep;
-
- arches = gdbarch_list_lookup_by_info (arches, &info);
- if (arches != NULL)
- return arches->gdbarch;
-
- tdep = XNEW (struct gdbarch_tdep);
- gdbarch = gdbarch_alloc (&info, tdep);
-
- set_gdbarch_short_bit (gdbarch, 16);
- set_gdbarch_int_bit (gdbarch, 32);
- set_gdbarch_long_bit (gdbarch, 32);
- set_gdbarch_long_long_bit (gdbarch, 64);
- set_gdbarch_float_bit (gdbarch, 32);
- set_gdbarch_double_bit (gdbarch, 64);
- set_gdbarch_long_double_bit (gdbarch, 64);
- set_gdbarch_ptr_bit (gdbarch, 32);
-
- set_gdbarch_num_regs (gdbarch, SIM_LM32_NUM_REGS);
- set_gdbarch_sp_regnum (gdbarch, SIM_LM32_SP_REGNUM);
- set_gdbarch_pc_regnum (gdbarch, SIM_LM32_PC_REGNUM);
- set_gdbarch_register_name (gdbarch, lm32_register_name);
- set_gdbarch_register_type (gdbarch, lm32_register_type);
- set_gdbarch_cannot_store_register (gdbarch, lm32_cannot_store_register);
-
- set_gdbarch_skip_prologue (gdbarch, lm32_skip_prologue);
- set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_decr_pc_after_break (gdbarch, 0);
- set_gdbarch_frame_args_skip (gdbarch, 0);
-
- set_gdbarch_frame_align (gdbarch, lm32_frame_align);
- frame_base_set_default (gdbarch, &lm32_frame_base);
- set_gdbarch_unwind_pc (gdbarch, lm32_unwind_pc);
- set_gdbarch_unwind_sp (gdbarch, lm32_unwind_sp);
- set_gdbarch_dummy_id (gdbarch, lm32_dummy_id);
- frame_unwind_append_unwinder (gdbarch, &lm32_frame_unwind);
-
- set_gdbarch_breakpoint_from_pc (gdbarch, lm32_breakpoint_from_pc);
- set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
-
- set_gdbarch_push_dummy_call (gdbarch, lm32_push_dummy_call);
- set_gdbarch_return_value (gdbarch, lm32_return_value);
-
- set_gdbarch_print_insn (gdbarch, print_insn_lm32);
- lm32_add_reggroups (gdbarch);
- set_gdbarch_register_reggroup_p (gdbarch, lm32_register_reggroup_p);
- return gdbarch;
- }
- extern initialize_file_ftype _initialize_lm32_tdep;
- void
- _initialize_lm32_tdep (void)
- {
- register_gdbarch_init (bfd_arch_lm32, lm32_gdbarch_init);
- }