123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 |
- --- gdb-7.8.2.orig/gdb/microblaze-tdep.c 2015-01-15 11:58:12.000000000 +0100
- +++ gdb-7.8.2/gdb/microblaze-tdep.c 2016-09-21 10:34:30.029222319 +0200
- @@ -1,6 +1,6 @@
- /* Target-dependent code for Xilinx MicroBlaze.
-
- - Copyright (C) 2009-2014 Free Software Foundation, Inc.
- + Copyright (C) 2009-2013 Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- @@ -29,13 +29,13 @@
- #include "inferior.h"
- #include "regcache.h"
- #include "target.h"
- +#include "frame.h"
- #include "frame-base.h"
- #include "frame-unwind.h"
- #include "dwarf2-frame.h"
- #include "osabi.h"
-
- #include "gdb_assert.h"
- -#include <string.h>
- #include "target-descriptions.h"
- #include "opcodes/microblaze-opcm.h"
- #include "opcodes/microblaze-dis.h"
- @@ -73,7 +73,8 @@ static const char *microblaze_register_n
- "rpc", "rmsr", "rear", "resr", "rfsr", "rbtr",
- "rpvr0", "rpvr1", "rpvr2", "rpvr3", "rpvr4", "rpvr5", "rpvr6",
- "rpvr7", "rpvr8", "rpvr9", "rpvr10", "rpvr11",
- - "redr", "rpid", "rzpr", "rtlbx", "rtlbsx", "rtlblo", "rtlbhi"
- + "redr", "rpid", "rzpr", "rtlbx", "rtlbsx", "rtlblo", "rtlbhi",
- + "rslr", "rshr"
- };
-
- #define MICROBLAZE_NUM_REGS ARRAY_SIZE (microblaze_register_names)
- @@ -145,6 +146,14 @@ microblaze_push_dummy_code (struct gdbar
- return sp;
- }
-
- +static CORE_ADDR
- +microblaze_store_arguments (struct regcache *regcache, int nargs,
- + struct value **args, CORE_ADDR sp,
- + int struct_return, CORE_ADDR struct_addr)
- +{
- + error (_("store_arguments not implemented"));
- + return sp;
- +}
-
- static CORE_ADDR
- microblaze_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
- @@ -156,14 +165,52 @@ microblaze_push_dummy_call (struct gdbar
- return sp;
- }
-
- +static int
- +microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
- + struct bp_target_info *bp_tgt)
- +{
- + CORE_ADDR addr = bp_tgt->placed_address;
- + const unsigned char *bp;
- + int val;
- + int bplen;
- + gdb_byte old_contents[BREAKPOINT_MAX];
- + struct cleanup *cleanup;
- +
- + /* Determine appropriate breakpoint contents and size for this address. */
- + bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
- + if (bp == NULL)
- + error (_("Software breakpoints not implemented for this target."));
- +
- + /* Make sure we see the memory breakpoints. */
- + cleanup = make_show_memory_breakpoints_cleanup (1);
- + val = target_read_memory (addr, old_contents, bplen);
- +
- + /* If our breakpoint is no longer at the address, this means that the
- + program modified the code on us, so it is wrong to put back the
- + old value. */
- + if (val == 0 && memcmp (bp, old_contents, bplen) == 0)
- + {
- + val = target_write_raw_memory (addr, bp_tgt->shadow_contents, bplen);
- + microblaze_debug ("microblaze_linux_memory_remove_breakpoint writing back to memory at addr 0x%lx\n", addr);
- + }
- +
- + do_cleanups (cleanup);
- + return val;
- +}
- +
- static const gdb_byte *
- microblaze_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc,
- int *len)
- {
- + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- static gdb_byte break_insn[] = MICROBLAZE_BREAKPOINT;
- + static gdb_byte break_insn_le[] = MICROBLAZE_BREAKPOINT_LE;
-
- *len = sizeof (break_insn);
- - return break_insn;
- + if (byte_order == BFD_ENDIAN_BIG)
- + return break_insn;
- + else
- + return break_insn_le;
- }
-
- /* Allocate and initialize a frame cache. */
- @@ -178,6 +225,7 @@ microblaze_alloc_frame_cache (void)
- /* Base address. */
- cache->base = 0;
- cache->pc = 0;
- + cache->saved_sp = 0;
-
- /* Frameless until proven otherwise. */
- cache->frameless_p = 1;
- @@ -234,6 +282,8 @@ microblaze_analyze_prologue (struct gdba
- int flags = 0;
- int save_hidden_pointer_found = 0;
- int non_stack_instruction_found = 0;
- + int n_insns;
- + unsigned int *insn_block;
-
- /* Find the start of this function. */
- find_pc_partial_function (pc, &name, &func_addr, &func_end);
- @@ -273,11 +323,18 @@ microblaze_analyze_prologue (struct gdba
- name, paddress (gdbarch, func_addr),
- paddress (gdbarch, stop));
-
- +/* Do a block read to minimize the transaction with the Debug Agent */
- + n_insns = (stop == func_addr) ? 1 : ((stop - func_addr) / INST_WORD_SIZE);
- + insn_block = calloc(n_insns, sizeof(unsigned long));
- +
- + target_read_memory (func_addr, (void*) insn_block, n_insns * INST_WORD_SIZE );
- +
- for (addr = func_addr; addr < stop; addr += INST_WORD_SIZE)
- {
- insn = microblaze_fetch_instruction (addr);
- + //insn = insn_block[(addr - func_addr) / INST_WORD_SIZE];
- op = microblaze_decode_insn (insn, &rd, &ra, &rb, &imm);
- - microblaze_debug ("%s %08lx\n", paddress (gdbarch, pc), insn);
- + microblaze_debug ("%s %08lx op=%x r%d r%d imm=%d\n", paddress (gdbarch, addr), insn, op, rd, ra, imm);
-
- /* This code is very sensitive to what functions are present in the
- prologue. It assumes that the (addi, addik, swi, sw) can be the
- @@ -291,6 +348,7 @@ microblaze_analyze_prologue (struct gdba
- cache->frameless_p = 0; /* Frame found. */
- save_hidden_pointer_found = 0;
- non_stack_instruction_found = 0;
- + cache->register_offsets[rd] = -imm;
- continue;
- }
- else if (IS_SPILL_SP(op, rd, ra))
- @@ -401,8 +459,8 @@ microblaze_analyze_prologue (struct gdba
- part of the prologue. */
- if (save_hidden_pointer_found)
- prologue_end_addr -= INST_WORD_SIZE;
- -
- - return prologue_end_addr;
- + free(insn_block);
- + return prologue_end_addr;
- }
-
- static CORE_ADDR
- @@ -452,6 +510,7 @@ microblaze_skip_prologue (struct gdbarch
- return start_pc;
- }
-
- +enum { REG_UNAVAIL = (CORE_ADDR) -1 };
- /* Normal frames. */
-
- static struct microblaze_frame_cache *
- @@ -459,7 +518,7 @@ microblaze_frame_cache (struct frame_inf
- {
- struct microblaze_frame_cache *cache;
- struct gdbarch *gdbarch = get_frame_arch (next_frame);
- - CORE_ADDR func;
- + CORE_ADDR current_pc;
- int rn;
-
- if (*this_cache)
- @@ -473,9 +532,18 @@ microblaze_frame_cache (struct frame_inf
- for (rn = 0; rn < gdbarch_num_regs (gdbarch); rn++)
- cache->register_offsets[rn] = -1;
-
- - func = get_frame_func (next_frame);
- + cache->pc = get_frame_func (next_frame);
- + current_pc = get_frame_pc (next_frame);
-
- - cache->pc = get_frame_address_in_block (next_frame);
- + if (cache->pc)
- + microblaze_analyze_prologue (gdbarch, cache->pc, current_pc,
- + cache);
- +
- + cache->base = get_frame_register_unsigned (next_frame, gdbarch_sp_regnum (gdbarch));
- + cache->saved_sp = cache->base + cache->framesize;
- +
- + cache->register_offsets[MICROBLAZE_PREV_PC_REGNUM] = cache->base;
- + cache->register_offsets[MICROBLAZE_SP_REGNUM] = cache->saved_sp;
-
- return cache;
- }
- @@ -501,6 +569,14 @@ microblaze_frame_prev_register (struct f
- struct microblaze_frame_cache *cache =
- microblaze_frame_cache (this_frame, this_cache);
-
- + if ((regnum == MICROBLAZE_SP_REGNUM &&
- + cache->register_offsets[MICROBLAZE_SP_REGNUM])
- + || (regnum == MICROBLAZE_FP_REGNUM &&
- + cache->register_offsets[MICROBLAZE_SP_REGNUM]))
- +
- + return frame_unwind_got_constant (this_frame, regnum,
- + cache->register_offsets[MICROBLAZE_SP_REGNUM]);
- +
- if (cache->frameless_p)
- {
- if (regnum == MICROBLAZE_PC_REGNUM)
- @@ -508,11 +584,18 @@ microblaze_frame_prev_register (struct f
- if (regnum == MICROBLAZE_SP_REGNUM)
- regnum = 1;
- return trad_frame_get_prev_register (this_frame,
- - cache->saved_regs, regnum);
- + cache->saved_regs, regnum);
- }
- - else
- - return trad_frame_get_prev_register (this_frame, cache->saved_regs,
- - regnum);
- +
- + if (regnum == MICROBLAZE_PC_REGNUM)
- + {
- + regnum = 15;
- + return frame_unwind_got_memory (this_frame, regnum,
- + cache->register_offsets[MICROBLAZE_PREV_PC_REGNUM]);
- + }
- +
- + return trad_frame_get_prev_register (this_frame, cache->saved_regs,
- + regnum);
-
- }
-
- @@ -536,6 +619,12 @@ microblaze_frame_base_address (struct fr
- return cache->base;
- }
-
- +static const struct frame_unwind *
- +microblaze_frame_sniffer (struct frame_info *next_frame)
- +{
- + return µblaze_frame_unwind;
- +}
- +
- static const struct frame_base microblaze_frame_base =
- {
- µblaze_frame_unwind,
- @@ -628,6 +717,109 @@ microblaze_stabs_argument_has_addr (stru
- return (TYPE_LENGTH (type) == 16);
- }
-
- +int
- +microblaze_software_single_step (struct frame_info *frame)
- +{
- + struct gdbarch *arch = get_frame_arch (frame);
- + struct address_space *aspace = get_frame_address_space (frame);
- + struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
- + static char le_breakp[] = MICROBLAZE_BREAKPOINT_LE;
- + static char be_breakp[] = MICROBLAZE_BREAKPOINT;
- + enum bfd_endian byte_order = gdbarch_byte_order (arch);
- + char *breakp = byte_order == BFD_ENDIAN_BIG ? be_breakp : le_breakp;
- + int ret = 0;
- +
- + /* Save the address and the values of the next_pc and the target */
- + static struct sstep_breaks
- + {
- + CORE_ADDR address;
- + bfd_boolean valid;
- + /* Shadow contents. */
- + char data[INST_WORD_SIZE];
- + } stepbreaks[2];
- + int ii;
- +
- + if (1)
- + {
- + CORE_ADDR pc;
- + long insn;
- + enum microblaze_instr minstr;
- + bfd_boolean isunsignednum;
- + enum microblaze_instr_type insn_type;
- + short delay_slots;
- + int imm;
- + bfd_boolean immfound = FALSE;
- +
- + /* Set a breakpoint at the next instruction */
- + /* If the current instruction is an imm, set it at the inst after */
- + /* If the instruction has a delay slot, skip the delay slot */
- + pc = get_frame_pc (frame);
- + insn = microblaze_fetch_instruction (pc);
- + minstr = get_insn_microblaze (insn, &isunsignednum, &insn_type, &delay_slots);
- + if (insn_type == immediate_inst)
- + {
- + int rd, ra, rb;
- + immfound = TRUE;
- + minstr = microblaze_decode_insn (insn, &rd, &ra, &rb, &imm);
- + pc = pc + INST_WORD_SIZE;
- + insn = microblaze_fetch_instruction (pc);
- + minstr = get_insn_microblaze (insn, &isunsignednum, &insn_type, &delay_slots);
- + }
- + stepbreaks[0].address = pc + (delay_slots * INST_WORD_SIZE) + INST_WORD_SIZE;
- + if (insn_type != return_inst) {
- + stepbreaks[0].valid = TRUE;
- + } else {
- + stepbreaks[0].valid = FALSE;
- + }
- +
- + microblaze_debug ("single-step insn_type=%x insn=%x\n", insn_type, insn);
- + /* Now check for branch or return instructions */
- + if (insn_type == branch_inst || insn_type == return_inst) {
- + int limm;
- + int lrd, lra, lrb;
- + int ra, rb;
- + bfd_boolean targetvalid;
- + bfd_boolean unconditionalbranch;
- + microblaze_decode_insn(insn, &lrd, &lra, &lrb, &limm);
- + if (lra >= 0 && lra < MICROBLAZE_NUM_REGS)
- + ra = get_frame_register_unsigned (frame, lra);
- + else
- + ra = 0;
- + if (lrb >= 0 && lrb < MICROBLAZE_NUM_REGS)
- + rb = get_frame_register_unsigned (frame, lrb);
- + else
- + rb = 0;
- +
- + stepbreaks[1].address = microblaze_get_target_address (insn, immfound, imm, pc, ra, rb, &targetvalid, &unconditionalbranch);
- + microblaze_debug ("single-step uncondbr=%d targetvalid=%d target=%x\n", unconditionalbranch, targetvalid, stepbreaks[1].address);
- +
- + if (unconditionalbranch)
- + stepbreaks[0].valid = FALSE; /* This is a unconditional branch: will not come to the next address */
- + if (targetvalid && (stepbreaks[0].valid == FALSE ||
- + (stepbreaks[0].address != stepbreaks[1].address))
- + && (stepbreaks[1].address != pc)) {
- + stepbreaks[1].valid = TRUE;
- + } else {
- + stepbreaks[1].valid = FALSE;
- + }
- + } else {
- + stepbreaks[1].valid = FALSE;
- + }
- +
- + /* Insert the breakpoints */
- + for (ii = 0; ii < 2; ++ii)
- + {
- +
- + /* ignore invalid breakpoint. */
- + if (stepbreaks[ii].valid) {
- + insert_single_step_breakpoint (arch, aspace, stepbreaks[ii].address);
- + ret = 1;
- + }
- + }
- + }
- + return ret;
- +}
- +
- static void
- microblaze_write_pc (struct regcache *regcache, CORE_ADDR pc)
- {
- @@ -664,6 +856,70 @@ microblaze_dwarf2_reg_to_regnum (struct
- return dwarf2_to_reg_map[reg];
- }
-
- +
- +void
- +microblaze_supply_gregset (const struct microblaze_gregset *gregset,
- + struct regcache *regcache,
- + int regnum, const void *gregs)
- +{
- + unsigned int *regs = gregs;
- + if (regnum >= 0)
- + regcache_raw_supply (regcache, regnum, regs + regnum);
- +
- + if (regnum == -1) {
- + int i;
- +
- + for (i = 0; i < 50; i++) {
- + regcache_raw_supply (regcache, i, regs + i);
- + }
- + }
- +}
- +
- +
- +void
- +microblaze_collect_gregset (const struct microblaze_gregset *gregset,
- + const struct regcache *regcache,
- + int regnum, void *gregs)
- +{
- + /* FIXME. */
- +}
- +
- +void
- +microblaze_supply_fpregset (struct regcache *regcache,
- + int regnum, const void *fpregs)
- +{
- + /* FIXME. */
- +}
- +
- +void
- +microblaze_collect_fpregset (const struct regcache *regcache,
- + int regnum, void *fpregs)
- +{
- + /* FIXME. */
- +}
- +
- +
- +/* Return the appropriate register set for the core section identified
- + by SECT_NAME and SECT_SIZE. */
- +
- +const struct regset *
- +microblaze_regset_from_core_section (struct gdbarch *gdbarch,
- + const char *sect_name, size_t sect_size)
- +{
- + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- +
- + microblaze_debug ("microblaze_regset_from_core_section, sect_name = %s\n", sect_name);
- +
- + if (strcmp (sect_name, ".reg") == 0 && sect_size >= tdep->sizeof_gregset)
- + return tdep->gregset;
- +
- + if (strcmp (sect_name, ".reg2") == 0 && sect_size >= tdep->sizeof_fpregset)
- + return tdep->fpregset;
- +
- + microblaze_debug ("microblaze_regset_from_core_section returning null :-( \n");
- + return NULL;
- +}
- +
- static struct gdbarch *
- microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
- {
- @@ -679,6 +935,11 @@ microblaze_gdbarch_init (struct gdbarch_
- tdep = XNEW (struct gdbarch_tdep);
- gdbarch = gdbarch_alloc (&info, tdep);
-
- + tdep->gregset = NULL;
- + tdep->sizeof_gregset = 0;
- + tdep->fpregset = NULL;
- + tdep->sizeof_fpregset = 0;
- +
- set_gdbarch_long_double_bit (gdbarch, 128);
-
- set_gdbarch_num_regs (gdbarch, MICROBLAZE_NUM_REGS);
- @@ -706,7 +967,10 @@ microblaze_gdbarch_init (struct gdbarch_
- /* Stack grows downward. */
- set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
-
- + set_gdbarch_memory_remove_breakpoint (gdbarch, microblaze_linux_memory_remove_breakpoint);
- +
- set_gdbarch_breakpoint_from_pc (gdbarch, microblaze_breakpoint_from_pc);
- + set_gdbarch_software_single_step (gdbarch, microblaze_software_single_step);
-
- set_gdbarch_frame_args_skip (gdbarch, 8);
-
- @@ -725,6 +989,13 @@ microblaze_gdbarch_init (struct gdbarch_
- dwarf2_append_unwinders (gdbarch);
- frame_unwind_append_unwinder (gdbarch, µblaze_frame_unwind);
- frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
- + //frame_base_append_sniffer (gdbarch, microblaze_frame_sniffer);
- +
- + /* If we have register sets, enable the generic core file support. */
- + if (tdep->gregset) {
- + set_gdbarch_regset_from_core_section (gdbarch,
- + microblaze_regset_from_core_section);
- + }
-
- return gdbarch;
- }
|