* [PATCH] Support new target S+core 3, a variant of S+core
@ 2009-03-17 2:17 don.lee
2009-03-17 16:12 ` Joel Brobecker
0 siblings, 1 reply; 10+ messages in thread
From: don.lee @ 2009-03-17 2:17 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 995 bytes --]
Hello,
The S+core team in our company have ported GDB to S+core 3, a variant
of S+core, now we want to contribute some patch. So here it is (see
attachment).
Please review it, and any suggestions are most welcome.
At now, I'm quite new to GDB, so if you fond something I did wrong,
please point it out.
Thanks for your time,
Don
----
ChangLog
2009-03-04 Don Lee <don.lee@sunplusct.com>:
Support new target S+core 3, which is a variant of S+core
* gdb/score-tdep.c: support new target S+core 3
* gdb/score-tdep.c: Ditto.
patch for gdb/MAINTAINER
--- src/gdb/MAINTAINERS 2009-03-04 10:26:35.000000000 +0800
+++ src.mod/gdb/MAINTAINERS 2009-03-04 10:29:15.000000000 +0800
@@ -307,6 +307,7 @@
score --target=score-elf
Qinwei qinwei@sunnorth.com.cn
+ Don Lee don.lee@sunplusct.com
sh --target=sh-elf ,-Werror
--target=sh64-elf ,-Werror
[-- Attachment #2: gdb.patch --]
[-- Type: application/octet-stream, Size: 42384 bytes --]
Index: gdb/configure.tgt
===================================================================
RCS file: /cvs/src/src/gdb/configure.tgt,v
retrieving revision 1.213
diff -r1.213 configure.tgt
378c378,382
< gdb_target_obs="score-tdep.o"
---
> gdb_target_obs="score-tdep.o corelow.o"
> if test -f ../sim/score/Makefile; then
> gdb_sim=../sim/score/libsim.a
> fi
> build_gdbserver=yes
Index: gdb/score-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/score-tdep.c,v
retrieving revision 1.18
diff -r1.18 score-tdep.c
32a33
> #include "regset.h"
40,41c41
< #define G_FLD(_i,_ms,_ls) (((_i) << (31 - (_ms))) >> (31 - (_ms) + (_ls)))
< #define RM_PBITS(_raw) ((G_FLD(_raw, 31, 16) << 15) | G_FLD(_raw, 14, 0))
---
> #define G_FLD(_i,_ms,_ls) ((unsigned)((_i) << (31 - (_ms))) >> (31 - (_ms) + (_ls)))
44,46c44,46
< unsigned int v;
< unsigned int raw;
< char is15;
---
> unsigned long long v;
> unsigned long long raw;
> unsigned int len;
56,186c56
< #if 0
< /* If S+core GCC will generate these instructions in the prologue:
<
< lw rx, imm1
< addi rx, -imm2
< mv! r2, rx
<
< then .pdr section is used. */
<
< #define P_SIZE 8
< #define PI_SYM 0
< #define PI_R_MSK 1
< #define PI_R_OFF 2
< #define PI_R_LEF 4
< #define PI_F_OFF 5
< #define PI_F_REG 6
< #define PI_RAREG 7
<
< typedef struct frame_extra_info
< {
< CORE_ADDR p_frame;
< unsigned int pdr[P_SIZE];
< } extra_info_t;
<
< struct obj_priv
< {
< bfd_size_type size;
< char *contents;
< };
<
< static bfd *the_bfd;
<
< static int
< score_compare_pdr_entries (const void *a, const void *b)
< {
< CORE_ADDR lhs = bfd_get_32 (the_bfd, (bfd_byte *) a);
< CORE_ADDR rhs = bfd_get_32 (the_bfd, (bfd_byte *) b);
< if (lhs < rhs)
< return -1;
< else if (lhs == rhs)
< return 0;
< else
< return 1;
< }
<
< static void
< score_analyze_pdr_section (CORE_ADDR startaddr, CORE_ADDR pc,
< struct frame_info *this_frame,
< struct score_frame_cache *this_cache)
< {
< struct symbol *sym;
< struct obj_section *sec;
< extra_info_t *fci_ext;
< CORE_ADDR leaf_ra_stack_addr = -1;
<
< gdb_assert (startaddr <= pc);
< gdb_assert (this_cache != NULL);
<
< fci_ext = frame_obstack_zalloc (sizeof (extra_info_t));
< if ((sec = find_pc_section (pc)) == NULL)
< {
< error ("Error: Can't find section in file:%s, line:%d!",
< __FILE__, __LINE__);
< return;
< }
<
< /* Anylyze .pdr section and get coresponding fields. */
< {
< static struct obj_priv *priv = NULL;
<
< if (priv == NULL)
< {
< asection *bfdsec;
< priv = obstack_alloc (&sec->objfile->objfile_obstack,
< sizeof (struct obj_priv));
< if ((bfdsec = bfd_get_section_by_name (sec->objfile->obfd, ".pdr")))
< {
< priv->size = bfd_section_size (sec->objfile->obfd, bfdsec);
< priv->contents = obstack_alloc (&sec->objfile->objfile_obstack,
< priv->size);
< bfd_get_section_contents (sec->objfile->obfd, bfdsec,
< priv->contents, 0, priv->size);
< the_bfd = sec->objfile->obfd;
< qsort (priv->contents, priv->size / 32, 32,
< score_compare_pdr_entries);
< the_bfd = NULL;
< }
< else
< priv->size = 0;
< }
< if (priv->size != 0)
< {
< int low = 0, mid, high = priv->size / 32;
< char *ptr;
< do
< {
< CORE_ADDR pdr_pc;
< mid = (low + high) / 2;
< ptr = priv->contents + mid * 32;
< pdr_pc = bfd_get_signed_32 (sec->objfile->obfd, ptr);
< pdr_pc += ANOFFSET (sec->objfile->section_offsets,
< SECT_OFF_TEXT (sec->objfile));
< if (pdr_pc == startaddr)
< break;
< if (pdr_pc > startaddr)
< high = mid;
< else
< low = mid + 1;
< }
< while (low != high);
<
< if (low != high)
< {
< gdb_assert (bfd_get_32 (sec->objfile->obfd, ptr) == startaddr);
< #define EXT_PDR(_pi) bfd_get_32(sec->objfile->obfd, ptr+((_pi)<<2))
< fci_ext->pdr[PI_SYM] = EXT_PDR (PI_SYM);
< fci_ext->pdr[PI_R_MSK] = EXT_PDR (PI_R_MSK);
< fci_ext->pdr[PI_R_OFF] = EXT_PDR (PI_R_OFF);
< fci_ext->pdr[PI_R_LEF] = EXT_PDR (PI_R_LEF);
< fci_ext->pdr[PI_F_OFF] = EXT_PDR (PI_F_OFF);
< fci_ext->pdr[PI_F_REG] = EXT_PDR (PI_F_REG);
< fci_ext->pdr[PI_RAREG] = EXT_PDR (PI_RAREG);
< #undef EXT_PDR
< }
< }
< }
< }
< #endif
<
< #if 0
< /* Open these functions if build with simulator. */
---
> static int target_mach = bfd_mach_score7;
190a61
> #if WITH_SIM
195a67
> #endif
203a76
> #if WITH_SIM
208a82
> #endif
216a91
> #if WITH_SIM
221a97
> #endif
229a106
> #if WITH_SIM
234a112
> #endif
242a121
> #if WITH_SIM
247a127
> #endif
255a136
> #if WITH_SIM
260a142
> #endif
265d146
< #endif
270c151,152
< gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
---
> gdb_assert (regnum >= 0
> && regnum < ((target_mach == bfd_mach_score7) ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
274a157,162
> score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
> {
> return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
> }
>
> static CORE_ADDR
280,281c168,169
< static CORE_ADDR
< score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
---
> static const char *
> score7_register_name (struct gdbarch *gdbarch, int regnum)
283c171,185
< return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
---
> const char *score_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", "r26", "r27", "r28", "r29", "r30", "r31",
>
> "PSR", "COND", "ECR", "EXCPVEC", "CCR",
> "EPC", "EMA", "TLBLOCK", "TLBPT", "PEADDR",
> "TLBRPT", "PEVN", "PECTX", "LIMPFN", "LDMPFN",
> "PREV", "DREG", "PC", "DSAVE", "COUNTER",
> "LDCR", "STCR", "CEH", "CEL",
> };
>
> gdb_assert (regnum >= 0 && regnum < SCORE7_NUM_REGS);
> return score_register_names[regnum];
287c189
< score_register_name (struct gdbarch *gdbarch, int regnum)
---
> score3_register_name (struct gdbarch *gdbarch, int regnum)
295,300c197,200
< "PSR", "COND", "ECR", "EXCPVEC",
< "CCR", "EPC", "EMA", "TLBLOCK",
< "TLBPT", "PEADDR", "TLBRPT", "PEVN",
< "PECTX", "LIMPFN", "LDMPFN", "PREV",
< "DREG", "PC", "DSAVE", "COUNTER",
< "LDCR", "STCR", "CEH", "CEL",
---
> "PSR", "COND", "ECR", "EXCPVEC", "CCR",
> "EPC", "EMA", "PREV", "DREG", "DSAVE",
> "COUNTER", "LDCR", "STCR", "CEH", "CEL",
> "", "", "PC",
303c203
< gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
---
> gdb_assert (regnum >= 0 && regnum < SCORE3_NUM_REGS);
306a207
> #if WITH_SIM
310c211,212
< gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
---
> gdb_assert (regnum >= 0
> && regnum < ((target_mach == bfd_mach_score7) ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
312a215
> #endif
322a226,384
> static inst_t *
> score7_fetch_inst (struct gdbarch *gdbarch, CORE_ADDR addr, char *memblock)
> {
> static inst_t inst = { 0, 0, 0 };
> char buf[SCORE_INSTLEN] = { 0 };
> int big;
> int ret;
>
> if (target_has_execution && memblock != NULL)
> {
> /* Fetch instruction from local MEMBLOCK. */
> memcpy (buf, memblock, SCORE_INSTLEN);
> }
> else
> {
> /* Fetch instruction from target. */
> ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN);
> if (ret)
> {
> error ("Error: target_read_memory in file:%s, line:%d!",
> __FILE__, __LINE__);
> return 0;
> }
> }
>
> inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN);
> inst.len = (inst.raw & 0x80008000) ? 4 : 2;
> inst.v = ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF);
> big = (gdbarch_byte_order(gdbarch) == BFD_ENDIAN_BIG);
> if (inst.len == 2)
> {
> if (big ^ ((addr & 0x2) == 2))
> inst.v = G_FLD (inst.v, 29, 15);
> else
> inst.v = G_FLD (inst.v, 14, 0);
> }
> return &inst;
> }
>
> static inst_t *
> score3_adjust_pc_and_fetch_inst (CORE_ADDR *pcptr, int *lenptr)
> {
> static inst_t inst = { 0, 0, 0 };
>
> struct breakplace
> {
> int break_offset;
> int inst_len;
> };
> /* raw table 1 (column 2, 3, 4)
> * 0 1 0 * # 2
> * 0 1 1 0 # 3
> 0 1 1 0 * # 6
> table 2 (column 1, 2, 3)
> * 0 0 * * # 0, 4
> 0 1 0 * * # 2
> 1 1 0 * * # 6
> */
>
> static const struct breakplace bk_table[16] =
> {
> /* table 1 */
> {0, 0},
> {0, 0},
> {0, 4},
> {0, 6},
> {0, 0},
> {0, 0},
> {-2, 6},
> {0, 0},
> /* table 2 */
> {0, 2},
> {0, 0},
> {-2, 4},
> {0, 0},
> {0, 2},
> {0, 0},
> {-4, 6},
> {0, 0}
> };
>
> #define EXTRACT_LEN 2
> CORE_ADDR adjust_pc = *pcptr & ~0x1;
> int inst_len;
> gdb_byte buf[5][EXTRACT_LEN] = {{'\0', '\0'}, {'\0', '\0'}, {'\0', '\0'}, {'\0', '\0'}, {'\0', '\0'}};
> int ret;
> unsigned int raw;
> unsigned int cbits = 0;
> int bk_index;
> int i, count;
>
> inst.v = 0;
> inst.raw = 0;
> inst.len = 0;
>
> adjust_pc -= 4;
> for (i = 0; i < 5; i++)
> {
> ret = target_read_memory (adjust_pc + 2 * i, buf[i], EXTRACT_LEN);
> if (ret != 0)
> {
> buf[i][0] = '\0';
> buf[i][1] = '\0';
> if (i == 2)
> error ("Error: target_read_memory in file:%s, line:%d!", __FILE__, __LINE__);
> }
>
> raw = extract_unsigned_integer (buf[i], EXTRACT_LEN);
> cbits = (cbits << 1) | (raw >> 15);
> }
> adjust_pc += 4;
>
> if (cbits & 0x4)
> {
> /* table 1 */
> cbits = (cbits >> 1) & 0x7;
> bk_index = cbits;
> }
> else
> {
> /* table 2 */
> cbits = (cbits >> 2) & 0x7;
> bk_index = cbits + 8;
> }
>
> gdb_assert (!((bk_table[bk_index].break_offset == 0) && (bk_table[bk_index].inst_len == 0)));
>
> inst.len = bk_table[bk_index].inst_len;
>
> i = (bk_table[bk_index].break_offset + 4) / 2;
> count = inst.len / 2;
> for (; count > 0; i++, count--)
> {
> inst.raw = (inst.raw << 16) | extract_unsigned_integer (buf[i], EXTRACT_LEN);
> }
>
> switch (inst.len)
> {
> case 2:
> inst.v = inst.raw & 0x7FFF;
> break;
> case 4:
> inst.v = ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF);
> break;
> case 6:
> inst.v = ((inst.raw >> 32 & 0x7FFF) << 30) | ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF);
> break;
> }
>
> if (pcptr)
> *pcptr = adjust_pc + bk_table[bk_index].break_offset;
> if (lenptr)
> *lenptr = bk_table[bk_index].inst_len;
>
> #undef EXTRACT_LEN
>
> return &inst;
> }
>
324,325c386
< score_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
< int *lenptr)
---
> score7_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr)
377a439,480
> static const gdb_byte *
> score3_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr)
> {
> CORE_ADDR adjust_pc = *pcptr;
> int len;
> static gdb_byte score_break_insns[6][6] = {
> /* The following three instructions are big endian. */
> { 0x00, 0x20 },
> { 0x80, 0x00, 0x00, 0x06 },
> { 0x80, 0x00, 0x80, 0x00, 0x00, 0x00 },
> /* The following three instructions are little endian. */
> { 0x20, 0x00 },
> { 0x00, 0x80, 0x06, 0x00 },
> { 0x00, 0x80, 0x00, 0x80, 0x00, 0x00 }};
>
> gdb_byte *p = NULL;
> int index = 0;
>
> score3_adjust_pc_and_fetch_inst (&adjust_pc, &len);
>
> index = ((gdbarch_byte_order(gdbarch) == BFD_ENDIAN_BIG) ? 0 : 3) + (len / 2 - 1);
> p = score_break_insns[index];
>
> *pcptr = adjust_pc;
> *lenptr = len;
>
> return p;
> }
>
> static CORE_ADDR
> score_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
> {
> CORE_ADDR adjust_pc = bpaddr;
>
> if (target_mach == bfd_mach_score3)
> score3_adjust_pc_and_fetch_inst (&adjust_pc, NULL);
> else
> adjust_pc = align_down (adjust_pc, 2);
>
> return adjust_pc;
> }
>
390c493,494
< gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS);
---
> gdb_assert (regnum >= 0
> && regnum < ((target_mach == bfd_mach_score7) ? SCORE7_NUM_REGS : SCORE3_NUM_REGS));
418c522
< struct type *type, struct regcache *regcache,
---
> struct type *type, struct regcache *regcache,
436,437c540
< score_xfer_register (regcache, regnum, xfer,
< gdbarch_byte_order (gdbarch),
---
> score_xfer_register (regcache, regnum, xfer, gdbarch_byte_order(gdbarch),
546c649
< if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
---
> if (gdbarch_byte_order(gdbarch) == BFD_ENDIAN_BIG
560c663
< if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
---
> if (gdbarch_byte_order(gdbarch) == BFD_ENDIAN_BIG
589,680d691
< static char *
< score_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size)
< {
< int ret;
< char *memblock = NULL;
<
< if (size < 0)
< {
< error ("Error: malloc size < 0 in file:%s, line:%d!",
< __FILE__, __LINE__);
< return NULL;
< }
< else if (size == 0)
< return NULL;
<
< memblock = (char *) xmalloc (size);
< memset (memblock, 0, size);
< ret = target_read_memory (addr & ~0x3, memblock, size);
< if (ret)
< {
< error ("Error: target_read_memory in file:%s, line:%d!",
< __FILE__, __LINE__);
< return NULL;
< }
< return memblock;
< }
<
< static void
< score_free_memblock (char *memblock)
< {
< xfree (memblock);
< }
<
< static void
< score_adjust_memblock_ptr (char **memblock, CORE_ADDR prev_pc,
< CORE_ADDR cur_pc)
< {
< if (prev_pc == -1)
< {
< /* First time call this function, do nothing. */
< }
< else if (cur_pc - prev_pc == 2 && (cur_pc & 0x3) == 0)
< {
< /* First 16-bit instruction, then 32-bit instruction. */
< *memblock += SCORE_INSTLEN;
< }
< else if (cur_pc - prev_pc == 4)
< {
< /* Is 32-bit instruction, increase MEMBLOCK by 4. */
< *memblock += SCORE_INSTLEN;
< }
< }
<
< static inst_t *
< score_fetch_inst (struct gdbarch *gdbarch, CORE_ADDR addr, char *memblock)
< {
< static inst_t inst = { 0, 0 };
< char buf[SCORE_INSTLEN] = { 0 };
< int big;
< int ret;
<
< if (target_has_execution && memblock != NULL)
< {
< /* Fetch instruction from local MEMBLOCK. */
< memcpy (buf, memblock, SCORE_INSTLEN);
< }
< else
< {
< /* Fetch instruction from target. */
< ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN);
< if (ret)
< {
< error ("Error: target_read_memory in file:%s, line:%d!",
< __FILE__, __LINE__);
< return 0;
< }
< }
<
< inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN);
< inst.is15 = !(inst.raw & 0x80008000);
< inst.v = RM_PBITS (inst.raw);
< big = (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG);
< if (inst.is15)
< {
< if (big ^ ((addr & 0x2) == 2))
< inst.v = G_FLD (inst.v, 29, 15);
< else
< inst.v = G_FLD (inst.v, 14, 0);
< }
< return &inst;
< }
<
682c693
< score_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
---
> score7_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
688c699
< inst_t *inst = score_fetch_inst (gdbarch, cpc, NULL);
---
> inst_t *inst = score7_fetch_inst (gdbarch, cpc, NULL);
691c702
< if (!inst->is15 && !stack_sub
---
> if ((inst->len == 4) && !stack_sub
696c707,708
< pc = stack_sub = cpc + SCORE_INSTLEN;
---
> stack_sub = cpc + SCORE_INSTLEN;
> pc = cpc + SCORE_INSTLEN;
698,699c710,715
< else if (!inst->is15
< && inst->v == RM_PBITS (0x8040bc56))
---
> else if ((inst->len == 4)
> && (G_FLD (inst->v, 29, 25) == 0x0)
> && (G_FLD (inst->v, 24, 20) == 0x2)
> && (G_FLD (inst->v, 19, 15) == 0x0)
> && (G_FLD (inst->v, 14, 10) == 0xF)
> && (G_FLD (inst->v, 9, 0) == 0x56))
705,706c721,725
< else if (inst->is15
< && inst->v == RM_PBITS (0x0203))
---
> else if ((inst->len == 2)
> && (G_FLD (inst->v, 14, 12) == 0x0)
> && (G_FLD (inst->v, 11, 8) == 0x2)
> && (G_FLD (inst->v, 7, 4) == 0x0)
> && (G_FLD (inst->v, 3, 0) == 0x3))
712c731
< else if (inst->is15
---
> else if ((inst->len == 2)
718c737
< else if (!inst->is15
---
> else if ((inst->len == 4)
725c744,798
< cpc += inst->is15 ? SCORE16_INSTLEN : SCORE_INSTLEN;
---
> cpc += (inst->len == 2) ? SCORE16_INSTLEN : SCORE_INSTLEN;
> }
> return pc;
> }
>
> static CORE_ADDR
> score3_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
> {
> CORE_ADDR cpc = pc;
> int iscan = 32, stack_sub = 0;
> while (iscan-- > 0)
> {
> inst_t *inst = score3_adjust_pc_and_fetch_inst (&cpc, NULL);
> if (!inst)
> break;
> if (inst->len == 4 && !stack_sub
> && (G_FLD (inst->v, 29, 25) == 0x1)
> && (G_FLD (inst->v, 19, 17) == 0x0)
> && (G_FLD (inst->v, 24, 20) == 0x0))
> {
> /* addi r0, offset */
> stack_sub = cpc + inst->len;
> pc = cpc + inst->len;
> }
> else if (inst->len == 4
> && (G_FLD (inst->v, 29, 25) == 0x0)
> && (G_FLD (inst->v, 24, 20) == 0x2)
> && (G_FLD (inst->v, 19, 15) == 0x0)
> && (G_FLD (inst->v, 14, 10) == 0xF)
> && (G_FLD (inst->v, 9, 0) == 0x56))
> {
> /* mv r2, r0 */
> pc = cpc + inst->len;
> break;
> }
> else if ((inst->len == 2)
> && (G_FLD (inst->v, 14, 10) == 0x10)
> && (G_FLD (inst->v, 9, 5) == 0x2)
> && (G_FLD (inst->v, 4, 0) == 0x0))
> {
> /* mv! r2, r0 */
> pc = cpc + inst->len;
> break;
> }
> else if (inst->len == 2
> && ((G_FLD (inst->v, 14, 12) == 3) /* b15 form */
> || (G_FLD (inst->v, 14, 12) == 0x0
> && G_FLD (inst->v, 11, 5) == 0x4))) /* br! */
> break;
> else if (inst->len == 4
> && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */
> || (G_FLD (inst->v, 29, 25) == 4))) /* b32 form */
> break;
>
> cpc += inst->len;
731c804
< score_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
---
> score7_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
733c806
< inst_t *inst = score_fetch_inst (gdbarch, cur_pc, NULL);
---
> inst_t *inst = score7_fetch_inst (gdbarch, cur_pc, NULL);
753a827,902
> static int
> score3_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc)
> {
> CORE_ADDR pc = cur_pc;
> inst_t *inst = score3_adjust_pc_and_fetch_inst (&pc, NULL);
>
> if (inst->len == 2
> && (G_FLD (inst->v, 14, 10) == 0x10)
> && (G_FLD (inst->v, 9, 5) == 0x0)
> && (G_FLD (inst->v, 4, 0) == 0x2))
> return 1; /* mv! r0, r2 */
> else if (inst->len == 4
> && (G_FLD (inst->v, 29, 25) == 0x0)
> && (G_FLD (inst->v, 24, 20) == 0x2)
> && (G_FLD (inst->v, 19, 15) == 0x0)
> && (G_FLD (inst->v, 14, 10) == 0xF)
> && (G_FLD (inst->v, 9, 0) == 0x56))
> return 1; /* mv r0, r2 */
> else if (inst->len == 2
> && (G_FLD (inst->v, 14, 12) == 0x0)
> && (G_FLD (inst->v, 11, 5) == 0x2))
> return 1; /* pop! */
> else if (inst->len == 2
> && (G_FLD (inst->v, 14, 12) == 0x0)
> && (G_FLD (inst->v, 11, 7) == 0x0)
> && (G_FLD (inst->v, 6, 5) == 0x2))
> return 1; /* rpop! */
> else if (inst->len == 2
> && (G_FLD (inst->v, 14, 12) == 0x0)
> && (G_FLD (inst->v, 11, 5) == 0x4)
> && (G_FLD (inst->v, 4, 0) == 0x3))
> return 1; /* br! r3 */
> else if (inst->len == 4
> && (G_FLD (inst->v, 29, 25) == 0x0)
> && (G_FLD (inst->v, 24, 20) == 0x0)
> && (G_FLD (inst->v, 19, 15) == 0x3)
> && (G_FLD (inst->v, 14, 10) == 0xF)
> && (G_FLD (inst->v, 9, 0) == 0x8))
> return 1; /* br r3 */
> else
> return 0;
> }
>
> static char *
> score7_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size)
> {
> int ret;
> char *memblock = NULL;
>
> if (size < 0)
> {
> error ("Error: malloc size < 0 in file:%s, line:%d!",
> __FILE__, __LINE__);
> return NULL;
> }
> else if (size == 0)
> return NULL;
>
> memblock = (char *) xmalloc (size);
> memset (memblock, 0, size);
> ret = target_read_memory (addr & ~0x3, memblock, size);
> if (ret)
> {
> error ("Error: target_read_memory in file:%s, line:%d!",
> __FILE__, __LINE__);
> return NULL;
> }
> return memblock;
> }
>
> static void
> score7_free_memblock (char *memblock)
> {
> xfree (memblock);
> }
>
755c904,924
< score_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
---
> score7_adjust_memblock_ptr (char **memblock, CORE_ADDR prev_pc,
> CORE_ADDR cur_pc)
> {
> if (prev_pc == -1)
> {
> /* First time call this function, do nothing. */
> }
> else if (cur_pc - prev_pc == 2 && (cur_pc & 0x3) == 0)
> {
> /* First 16-bit instruction, then 32-bit instruction. */
> *memblock += SCORE_INSTLEN;
> }
> else if (cur_pc - prev_pc == 4)
> {
> /* Is 32-bit instruction, increase MEMBLOCK by 4. */
> *memblock += SCORE_INSTLEN;
> }
> }
>
> static void
> score7_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
777c946
< score_malloc_and_get_memblock (startaddr, pc - startaddr);
---
> score7_malloc_and_get_memblock (startaddr, pc - startaddr);
789,790c958,959
< score_adjust_memblock_ptr (&memblock, prev_pc, cur_pc);
< inst = score_fetch_inst (gdbarch, cur_pc, memblock);
---
> score7_adjust_memblock_ptr (&memblock, prev_pc, cur_pc);
> inst = score7_fetch_inst (gdbarch, cur_pc, memblock);
796c965
< inst = score_fetch_inst (gdbarch, cur_pc, NULL);
---
> inst = score7_fetch_inst (gdbarch, cur_pc, NULL);
799c968,969
< if (inst->is15 == 1)
---
> /* FIXME: make a full-power prologue analyzer */
> if (inst->len == 2)
847,848c1017,1019
< if (G_FLD (inst->v, 29, 15) == 0xc60
< && G_FLD (inst->v, 2, 0) == 0x4)
---
> if (G_FLD(inst->v, 29, 25) == 0x3
> && G_FLD(inst->v, 2, 0) == 0x4
> && G_FLD(inst->v, 19, 15) == 0)
850,856c1021,1041
< /* sw r3, [r0, offset]+ */
< sp_offset += SCORE_INSTLEN;
< if (ra_offset_p == 0)
< {
< ra_offset = sp_offset;
< ra_offset_p = 1;
< }
---
> /* sw rD, [r0, offset]+ */
> sp_offset += SCORE_INSTLEN;
>
> if (G_FLD(inst->v, 24, 20) == 0x3)
> {
> /* rD = r3 */
> if (ra_offset_p == 0)
> {
> ra_offset = sp_offset;
> ra_offset_p = 1;
> }
> }
> else if (G_FLD(inst->v, 24, 20) == 0x2)
> {
> /* rD = r2 */
> if (fp_offset_p == 0)
> {
> fp_offset = sp_offset;
> fp_offset_p = 1;
> }
> }
858,859c1043,1044
< if (G_FLD (inst->v, 29, 15) == 0xc40
< && G_FLD (inst->v, 2, 0) == 0x4)
---
> else if (G_FLD(inst->v, 29, 25) == 0x14
> && G_FLD(inst->v, 19,15) == 0)
861,867c1046,1058
< /* sw r2, [r0, offset]+ */
< sp_offset += SCORE_INSTLEN;
< if (fp_offset_p == 0)
< {
< fp_offset = sp_offset;
< fp_offset_p = 1;
< }
---
> /* sw rD, [r0, offset] */
> if (G_FLD(inst->v, 24, 20) == 0x3)
> {
> /* rD = r3 */
> ra_offset = sp_offset - G_FLD(inst->v, 14, 0);
> ra_offset_p = 1;
> }
> else if (G_FLD(inst->v, 24, 20) == 0x2)
> {
> /* rD = r2 */
> fp_offset = sp_offset - G_FLD(inst->v, 14, 0);
> fp_offset_p = 1;
> }
898c1089
< score_fetch_inst (gdbarch, cur_pc + SCORE_INSTLEN, NULL);
---
> score7_fetch_inst (gdbarch, cur_pc + SCORE_INSTLEN, NULL);
936c1127,1369
< score_free_memblock (memblock_ptr);
---
> score7_free_memblock (memblock_ptr);
> }
>
> static void
> score3_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
> struct frame_info *this_frame,
> struct score_frame_cache *this_cache)
> {
> CORE_ADDR sp;
> CORE_ADDR fp;
> CORE_ADDR cur_pc = startaddr;
>
> int sp_offset = 0;
> int ra_offset = 0;
> int fp_offset = 0;
> int ra_offset_p = 0;
> int fp_offset_p = 0;
> int inst_len = 0;
>
> CORE_ADDR prev_pc = -1;
>
> sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
> fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);
>
> for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len)
> {
> inst_t *inst = NULL;
>
> inst = score3_adjust_pc_and_fetch_inst (&cur_pc, &inst_len);
>
> /* FIXME: make a full-power prologue analyzer */
> if (inst->len == 2)
> {
> if (G_FLD (inst->v, 14, 12) == 0x0
> && G_FLD (inst->v, 11, 7) == 0x0
> && G_FLD (inst->v, 6, 5) == 0x3)
> {
> /* push! */
> sp_offset += 4;
>
> if (G_FLD (inst->v, 4, 0) == 0x3
> && ra_offset_p == 0)
> {
> /* push! r3, [r0] */
> ra_offset = sp_offset;
> ra_offset_p = 1;
> }
> else if (G_FLD (inst->v, 4, 0) == 0x2
> && fp_offset_p == 0)
> {
> /* push! r2, [r0] */
> fp_offset = sp_offset;
> fp_offset_p = 1;
> }
> }
> else if (G_FLD (inst->v, 14, 12) == 0x6
> && G_FLD (inst->v, 11, 10) == 0x3)
> {
> /* rpush! */
> int start_r = G_FLD (inst->v, 9, 5);
> int cnt = G_FLD (inst->v, 4, 0);
>
> if ((ra_offset_p == 0)
> && (start_r <= SCORE_RA_REGNUM)
> && (SCORE_RA_REGNUM < start_r + cnt))
> {
> /* rpush! contains r3 */
> ra_offset_p = 1;
> ra_offset = sp_offset + 4 * (SCORE_RA_REGNUM - start_r) + 4;
> }
>
> if ((fp_offset_p == 0)
> && (start_r <= SCORE_FP_REGNUM)
> && (SCORE_FP_REGNUM < start_r + cnt))
> {
> /* rpush! contains r2 */
> fp_offset_p = 1;
> fp_offset = sp_offset + 4 * (SCORE_FP_REGNUM - start_r) + 4;
> }
>
> sp_offset += 4 * cnt;
> }
> else if (G_FLD (inst->v, 14, 12) == 0x0
> && G_FLD (inst->v, 11, 7) == 0x0
> && G_FLD (inst->v, 6, 5) == 0x2)
> {
> /* pop! */
> sp_offset -= 4;
> }
> else if (G_FLD (inst->v, 14, 12) == 0x6
> && G_FLD (inst->v, 11, 10) == 0x2)
> {
> /* rpop! */
> sp_offset -= 4 * G_FLD (inst->v, 4, 0);
> }
> else if (G_FLD (inst->v, 14, 12) == 0x5
> && G_FLD (inst->v, 11, 10) == 0x3
> && G_FLD (inst->v, 9, 6) == 0x0)
> {
> /* addi! r0, -offset */
> int imm = G_FLD (inst->v, 5, 0);
> if (imm >> 5)
> imm = -(0x3F - imm + 1);
> sp_offset -= imm;
> }
> else if (G_FLD (inst->v, 14, 12) == 0x5
> && G_FLD (inst->v, 11, 10) == 0x3
> && G_FLD (inst->v, 9, 6) == 0x2)
> {
> /* addi! r2, offset */
> if (pc - cur_pc >= 2)
> {
> unsigned int save_v = inst->v;
> inst_t *inst2;
>
> cur_pc += inst->len;
> inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL);
>
> if (inst2->len == 2
> && G_FLD (inst2->v, 14, 10) == 0x10
> && G_FLD (inst2->v, 9, 5) == 0x0
> && G_FLD (inst2->v, 4, 0) == 0x2)
> {
> /* mv! r0, r2 */
> int imm = G_FLD (inst->v, 5, 0);
> if (imm >> 5)
> imm = -(0x3F - imm + 1);
> sp_offset -= imm;
> }
> }
> }
> }
> else if (inst->len == 4)
> {
> if (G_FLD (inst->v, 29, 25) == 0x3
> && G_FLD (inst->v, 2, 0) == 0x4
> && G_FLD (inst->v, 24, 20) == 0x3
> && G_FLD (inst->v, 19, 15) == 0x0)
> {
> /* sw r3, [r0, offset]+ */
> sp_offset += inst->len;
> if (ra_offset_p == 0)
> {
> ra_offset = sp_offset;
> ra_offset_p = 1;
> }
> }
> else if (G_FLD (inst->v, 29, 25) == 0x3
> && G_FLD (inst->v, 2, 0) == 0x4
> && G_FLD (inst->v, 24, 20) == 0x2
> && G_FLD (inst->v, 19, 15) == 0x0)
> {
> /* sw r2, [r0, offset]+ */
> sp_offset += inst->len;
> if (fp_offset_p == 0)
> {
> fp_offset = sp_offset;
> fp_offset_p = 1;
> }
> }
> else if (G_FLD (inst->v, 29, 25) == 0x7
> && G_FLD (inst->v, 2, 0) == 0x0
> && G_FLD (inst->v, 24, 20) == 0x3
> && G_FLD (inst->v, 19, 15) == 0x0)
> {
> /* lw r3, [r0]+, 4 */
> sp_offset -= inst->len;
> ra_offset_p = 1;
> }
> else if (G_FLD (inst->v, 29, 25) == 0x7
> && G_FLD (inst->v, 2, 0) == 0x0
> && G_FLD (inst->v, 24, 20) == 0x2
> && G_FLD (inst->v, 19, 15) == 0x0)
> {
> /* lw r2, [r0]+, 4 */
> sp_offset -= inst->len;
> fp_offset_p = 1;
> }
> else if (G_FLD (inst->v, 29, 25) == 0x1
> && G_FLD (inst->v, 19, 17) == 0x0
> && G_FLD (inst->v, 24, 20) == 0x0
> && G_FLD (inst->v, 0, 0) == 0x0)
> {
> /* addi r0, -offset */
> int imm = G_FLD (inst->v, 16, 1);
> if (imm >> 15)
> imm = -(0xFFFF - imm + 1);
> sp_offset -= imm;
> }
> else if (G_FLD (inst->v, 29, 25) == 0x1
> && G_FLD (inst->v, 19, 17) == 0x0
> && G_FLD (inst->v, 24, 20) == 0x2
> && G_FLD (inst->v, 0, 0) == 0x0)
> {
> /* addi r2, offset */
> if (pc - cur_pc >= 2)
> {
> unsigned int save_v = inst->v;
> inst_t *inst2;
>
> cur_pc += inst->len;
> inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL);
>
> if (inst2->len == 2
> && G_FLD (inst2->v, 14, 10) == 0x10
> && G_FLD (inst2->v, 9, 5) == 0x0
> && G_FLD (inst2->v, 4, 0) == 0x2)
> {
> /* mv! r0, r2 */
> int imm = G_FLD (inst->v, 16, 1);
> if (imm >> 15)
> imm = -(0xFFFF - imm + 1);
> sp_offset -= imm;
> }
> }
> }
> }
> }
>
> /* Save RA. */
> if (ra_offset_p == 1)
> {
> if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1)
> this_cache->saved_regs[SCORE_PC_REGNUM].addr =
> sp + sp_offset - ra_offset;
> }
> else
> {
> this_cache->saved_regs[SCORE_PC_REGNUM] =
> this_cache->saved_regs[SCORE_RA_REGNUM];
> }
>
> /* Save FP. */
> if (fp_offset_p == 1)
> {
> if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1)
> this_cache->saved_regs[SCORE_FP_REGNUM].addr =
> sp + sp_offset - fp_offset;
> }
>
> /* Save SP and FP. */
> this_cache->base = sp + sp_offset;
> this_cache->fp = fp;
959c1392,1396
< score_analyze_prologue (start_addr, pc, this_frame, *this_cache);
---
>
> if (target_mach == bfd_mach_score3)
> score3_analyze_prologue (start_addr, pc, this_frame, *this_cache);
> else
> score7_analyze_prologue (start_addr, pc, this_frame, *this_cache);
992c1429,1430
< default_frame_sniffer
---
> default_frame_sniffer,
> NULL
1017a1456,1527
> /* Core file support (dirty hack)
>
> The core file MUST be generated by GNU/Linux on S+core */
>
> static void
> score7_linux_supply_gregset(const struct regset *regset,
> struct regcache *regcache,
> int regnum, const void *gregs_buf, size_t len)
> {
> int regno;
> elf_gregset_t *gregs;
>
> gdb_assert (regset != NULL);
> gdb_assert ((regcache != NULL) && (gregs_buf != NULL));
>
> gregs = (elf_gregset_t *) gregs_buf;
>
> for (regno = 0; regno < 32; regno++)
> if (regnum == -1 || regnum == regno)
> regcache_raw_supply (regcache, regno, gregs->regs + regno);
>
> {
> struct sreg {
> int regnum;
> void *buf;
> } sregs [] = {
> { 55, &(gregs->cel) }, /* CEL */
> { 54, &(gregs->ceh) }, /* CEH */
> { 53, &(gregs->sr0) }, /* sr0, i.e. cnt or COUNTER */
> { 52, &(gregs->sr1) }, /* sr1, i.e. lcr or LDCR */
> { 51, &(gregs->sr1) }, /* sr2, i.e. scr or STCR */
>
> /* Exception occured at this address, exactly the PC we want */
> { 49, &(gregs->cp0_epc) }, /* PC */
>
> { 38, &(gregs->cp0_ema) }, /* EMA */
> { 37, &(gregs->cp0_epc) }, /* EPC */
> { 34, &(gregs->cp0_ecr) }, /* ECR */
> { 33, &(gregs->cp0_condition) }, /* COND */
> { 32, &(gregs->cp0_psr) }, /* PSR */
> };
>
> for (regno = 0; regno < sizeof(sregs)/sizeof(sregs[0]); regno++)
> if (regnum == -1 || regnum == sregs[regno].regnum)
> regcache_raw_supply (regcache, sregs[regno].regnum, sregs[regno].buf);
> }
> }
>
> /* Return the appropriate register set from the core section identified
> by SECT_NAME and SECT_SIZE. */
>
> static const struct regset *
> score7_linux_regset_from_core_section(struct gdbarch *gdbarch,
> const char *sect_name, size_t sect_size)
> {
> struct gdbarch_tdep *tdep;
>
> gdb_assert (gdbarch != NULL);
> gdb_assert (sect_name != NULL);
>
> tdep = gdbarch_tdep (gdbarch);
>
> if (strcmp(sect_name, ".reg") == 0 && sect_size == sizeof(elf_gregset_t))
> {
> if (tdep->gregset == NULL)
> tdep->gregset = regset_alloc (gdbarch, score7_linux_supply_gregset, NULL);
> return tdep->gregset;
> }
>
> return NULL;
> }
>
1021a1532,1533
> struct gdbarch_tdep *tdep;
> target_mach = info.bfd_arch_info->mach;
1028c1540,1541
< gdbarch = gdbarch_alloc (&info, 0);
---
> tdep = xcalloc(1, sizeof(struct gdbarch_tdep));
> gdbarch = gdbarch_alloc (&info, tdep);
1034a1548
> #if WITH_SIM
1035a1550
> #endif
1038,1040c1553
< set_gdbarch_num_regs (gdbarch, SCORE_NUM_REGS);
< set_gdbarch_register_name (gdbarch, score_register_name);
< set_gdbarch_breakpoint_from_pc (gdbarch, score_breakpoint_from_pc);
---
> set_gdbarch_adjust_breakpoint_address (gdbarch, score_adjust_breakpoint_address);
1044d1556
< set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
1045a1558
> set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
1047,1048c1560,1580
< set_gdbarch_skip_prologue (gdbarch, score_skip_prologue);
< set_gdbarch_in_function_epilogue_p (gdbarch, score_in_function_epilogue_p);
---
>
> switch (target_mach)
> {
> case bfd_mach_score7:
> set_gdbarch_breakpoint_from_pc (gdbarch, score7_breakpoint_from_pc);
> set_gdbarch_skip_prologue (gdbarch, score7_skip_prologue);
> set_gdbarch_in_function_epilogue_p (gdbarch, score7_in_function_epilogue_p);
> set_gdbarch_register_name (gdbarch, score7_register_name);
> set_gdbarch_num_regs (gdbarch, SCORE7_NUM_REGS);
> /* Core file support. */
> set_gdbarch_regset_from_core_section (gdbarch, score7_linux_regset_from_core_section);
> break;
>
> case bfd_mach_score3:
> set_gdbarch_breakpoint_from_pc (gdbarch, score3_breakpoint_from_pc);
> set_gdbarch_skip_prologue (gdbarch, score3_skip_prologue);
> set_gdbarch_in_function_epilogue_p (gdbarch, score3_in_function_epilogue_p);
> set_gdbarch_register_name (gdbarch, score3_register_name);
> set_gdbarch_num_regs (gdbarch, SCORE3_NUM_REGS);
> break;
> }
Index: gdb/score-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/score-tdep.h,v
retrieving revision 1.5
diff -r1.5 score-tdep.h
41c41,42
< #define SCORE_NUM_REGS 56
---
> #define SCORE7_NUM_REGS 56
> #define SCORE3_NUM_REGS 50
47a49,151
> /* Forward declarations. */
> struct regset;
>
> /* Target-dependent structure in gdbarch */
> struct gdbarch_tdep
> {
> /* Cached core file helpers. */
> struct regset *gregset;
> };
>
> /* Linux Core file support (dirty hack)
>
> S+core Linux register set definition, copy from S+core Linux */
> struct pt_regs {
> /* Pad bytes for argument save space on the stack. */
> unsigned long pad0[6]; /* may be 4,MIPS accept 6var,SCore accepts 4 Var--yuchen */
>
> /* Saved main processor registers. */
> unsigned long orig_r4;
> unsigned long regs[32];
>
> /* Other saved registers. */
> unsigned long cel;
> unsigned long ceh;
>
> unsigned long sr0; /*cnt*/
> unsigned long sr1; /*lcr*/
> unsigned long sr2; /*scr*/
>
> /* saved cp0 registers */
> unsigned long cp0_epc;
> unsigned long cp0_ema;
> unsigned long cp0_psr;
> unsigned long cp0_ecr;
> unsigned long cp0_condition;
> };
>
> typedef struct pt_regs elf_gregset_t;
>
> #ifdef WITH_SIM
>
> #include <breakpoint.h>
>
> int soc_gh_can_use_watch(int type, int cnt);
> int soc_gh_add_watch(unsigned int addr, int len, int type);
> int soc_gh_del_watch(unsigned int addr, int len, int type);
> int soc_gh_stopped_by_watch(void);
> int soc_gh_add_hardbp(unsigned int addr);
> int soc_gh_del_hardbp(unsigned int addr);
>
> int score_target_can_use_watch(int type, int cnt, int ot);
> int score_stopped_by_watch(void);
> int score_target_insert_watchpoint (CORE_ADDR addr, int len, int type);
> int score_target_remove_watchpoint (CORE_ADDR addr, int len, int type);
> int score_target_insert_hw_breakpoint (struct bp_target_info * bp_tgt);
> int score_target_remove_hw_breakpoint (struct bp_target_info * bp_tgt);
>
> #define TARGET_HAS_HARDWARE_WATCHPOINTS
>
> #ifdef TARGET_CAN_USE_HARDWARE_WATCHPOINT
> #undef TARGET_CAN_USE_HARDWARE_WATCHPOINT
>
> #define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) \
> score_target_can_use_watch(type, cnt, ot)
> #endif
>
> #ifdef STOPPED_BY_WATCHPOINT
> #undef STOPPED_BY_WATCHPOINT
>
> #define STOPPED_BY_WATCHPOINT(w) \
> score_stopped_by_watch()
> #endif
>
> #ifdef target_insert_watchpoint
> #undef target_insert_watchpoint
>
> #define target_insert_watchpoint(addr, len, type) \
> score_target_insert_watchpoint (addr, len, type)
> #endif
>
> #ifdef target_remove_watchpoint
> #undef target_remove_watchpoint
>
> #define target_remove_watchpoint(addr, len, type) \
> score_target_remove_watchpoint (addr, len, type)
> #endif
>
> #ifdef target_insert_hw_breakpoint
> #undef target_insert_hw_breakpoint
>
> #define target_insert_hw_breakpoint(bp_tgt) \
> score_target_insert_hw_breakpoint (bp_tgt)
> #endif
>
> #ifdef target_remove_hw_breakpoint
> #undef target_remove_hw_breakpoint
>
> #define target_remove_hw_breakpoint(bp_tgt) \
> score_target_remove_hw_breakpoint (bp_tgt)
> #endif
>
> #endif /* WITH_SIM */
>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] Support new target S+core 3, a variant of S+core 2009-03-17 2:17 [PATCH] Support new target S+core 3, a variant of S+core don.lee @ 2009-03-17 16:12 ` Joel Brobecker 2009-03-19 7:36 ` don.lee 0 siblings, 1 reply; 10+ messages in thread From: Joel Brobecker @ 2009-03-17 16:12 UTC (permalink / raw) To: don.lee; +Cc: gdb-patches > The S+core team in our company have ported GDB to S+core 3, a variant > of S+core, now we want to contribute some patch. So here it is (see > attachment). Thanks, Don. > Please review it, and any suggestions are most welcome. Note that Qinwei is also capable of reviewing your code. I can take a look, but it's better if Qinwei does it, because he has actual knowledge of the target. > At now, I'm quite new to GDB, so if you fond something I did wrong, > please point it out. If you haven't done so, the gdb/CONTRIBUTE file contains valuable information. You may also want to give gdb/MAINTAINERS a quick read. The first thing that struck me was the fact that the patch was produced in the wrong format, so "context" is missing. Could you resubmit your patch using the "-u" option? For instance "cvs diff -u ...". Also, it looks like you are submitting several changes in one patch, which we prefer not to. For instance, your change to gdb/configure.tgt can be submitted as is, as it is independent of the target; it just tells gdb about the the simulator. > --- src/gdb/MAINTAINERS 2009-03-04 10:26:35.000000000 +0800 > +++ src.mod/gdb/MAINTAINERS 2009-03-04 10:29:15.000000000 +0800 > @@ -307,6 +307,7 @@ > > score --target=score-elf > Qinwei qinwei@sunnorth.com.cn > + Don Lee don.lee@sunplusct.com > > sh --target=sh-elf ,-Werror > --target=sh64-elf ,-Werror As I said on the gdb@ mailing-list, I would prefer to hold off on that change, but others might have a different opinion. In any case, this is also an independent change, so this can be submitted separately from the rest. > Index: gdb/configure.tgt > =================================================================== > RCS file: /cvs/src/src/gdb/configure.tgt,v > retrieving revision 1.213 > diff -r1.213 configure.tgt > 378c378,382 > < gdb_target_obs="score-tdep.o" > --- > > gdb_target_obs="score-tdep.o corelow.o" > > if test -f ../sim/score/Makefile; then > > gdb_sim=../sim/score/libsim.a > > fi > > build_gdbserver=yes There is no score subdirectory in sim/. Are you going to submit a simulator for that target? The rest of the patch is very hard to read! Could you explain a little bit the actual changes you made? At first sight, what the patch says is that you replaced pretty much everything, which I doubt is the case. -- Joel ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] Support new target S+core 3, a variant of S+core 2009-03-17 16:12 ` Joel Brobecker @ 2009-03-19 7:36 ` don.lee 2009-03-19 13:59 ` Joel Brobecker 2009-03-20 2:37 ` Eli Zaretskii 0 siblings, 2 replies; 10+ messages in thread From: don.lee @ 2009-03-19 7:36 UTC (permalink / raw) To: Joel Brobecker; +Cc: gdb-patches [-- Attachment #1: Type: text/plain, Size: 2153 bytes --] gdb-patches-owner@sourceware.org 写于 2009-03-17 23:57:43: > > > Note that Qinwei is also capable of reviewing your code. > I can take a look, but it's better if Qinwei does it, because he has > actual knowledge of the target. These code have been reviewed by Qinwei. Actually, part of the codes are written by him. > > If you haven't done so, the gdb/CONTRIBUTE file contains valuable > information. You may also want to give gdb/MAINTAINERS a quick read. > > The first thing that struck me was the fact that the patch was produced > in the wrong format, so "context" is missing. Could you resubmit your > patch using the "-u" option? For instance "cvs diff -u ...". Sorry, forget that, my mistake. > > Also, it looks like you are submitting several changes in one patch, > which we prefer not to. For instance, your change to gdb/configure.tgt > can be submitted as is, as it is independent of the target; it just > tells gdb about the the simulator. These changes are parts of a logical change, so I think submit as a whole is OK. But this time, I put change about gdb/configure.tgt on another patch. > In any case, > this is also an independent change, so this can be submitted separately > from the rest. By now, leave them alone for a moment. > > There is no score subdirectory in sim/. Are you going to submit > a simulator for that target? We have a simulator for it, so put a check for simulator in gdb/configure.tgt may make our life a bit easy. But as far as I know, these is no plan to submit this simulator, even in binary form. > > The rest of the patch is very hard to read! Could you explain a little > bit the actual changes you made? At first sight, what the patch says > is that you replaced pretty much everything, which I doubt is the case. The original S+core have been renamed S+core 7, the new variant named S+core 3. So lots of functions in score-tdep.c have been rewritten or been renamed, that's why you see almost everything have changed. Attachments are my new patches, with context information. Thank you for your time, Don [-- Attachment #2: gdb-configure.patch --] [-- Type: application/octet-stream, Size: 396 bytes --] --- src/gdb/configure.tgt 2009-03-16 23:04:14.000000000 +0800 +++ src.mod/gdb/configure.tgt 2009-03-17 09:26:44.000000000 +0800 @@ -375,7 +375,11 @@ score-*-*) # Target: S+core embedded system - gdb_target_obs="score-tdep.o" + gdb_target_obs="score-tdep.o corelow.o" + if test -f ../sim/score/Makefile; then + gdb_sim=../sim/score/libsim.a + fi + build_gdbserver=yes ;; sh*-*-linux*) [-- Attachment #3: gdb-score.patch --] [-- Type: application/octet-stream, Size: 49520 bytes --] --- src/gdb/score-tdep.h 2009-01-03 13:57:53.000000000 +0800 +++ src.mod/gdb/score-tdep.h 2009-03-03 17:49:26.000000000 +0800 @@ -38,11 +38,115 @@ #define SCORE_A0_REGNUM 4 #define SCORE_A1_REGNUM 5 #define SCORE_REGSIZE 4 -#define SCORE_NUM_REGS 56 +#define SCORE7_NUM_REGS 56 +#define SCORE3_NUM_REGS 50 #define SCORE_BEGIN_ARG_REGNUM 4 #define SCORE_LAST_ARG_REGNUM 7 #define SCORE_INSTLEN 4 #define SCORE16_INSTLEN 2 +/* Forward declarations. */ +struct regset; + +/* Target-dependent structure in gdbarch */ +struct gdbarch_tdep +{ + /* Cached core file helpers. */ + struct regset *gregset; +}; + +/* Linux Core file support (dirty hack) + + S+core Linux register set definition, copy from S+core Linux */ +struct pt_regs { + /* Pad bytes for argument save space on the stack. */ + unsigned long pad0[6]; /* may be 4,MIPS accept 6var,SCore accepts 4 Var--yuchen */ + + /* Saved main processor registers. */ + unsigned long orig_r4; + unsigned long regs[32]; + + /* Other saved registers. */ + unsigned long cel; + unsigned long ceh; + + unsigned long sr0; /*cnt*/ + unsigned long sr1; /*lcr*/ + unsigned long sr2; /*scr*/ + + /* saved cp0 registers */ + unsigned long cp0_epc; + unsigned long cp0_ema; + unsigned long cp0_psr; + unsigned long cp0_ecr; + unsigned long cp0_condition; +}; + +typedef struct pt_regs elf_gregset_t; + +#ifdef WITH_SIM + +#include <breakpoint.h> + +int soc_gh_can_use_watch(int type, int cnt); +int soc_gh_add_watch(unsigned int addr, int len, int type); +int soc_gh_del_watch(unsigned int addr, int len, int type); +int soc_gh_stopped_by_watch(void); +int soc_gh_add_hardbp(unsigned int addr); +int soc_gh_del_hardbp(unsigned int addr); + +int score_target_can_use_watch(int type, int cnt, int ot); +int score_stopped_by_watch(void); +int score_target_insert_watchpoint (CORE_ADDR addr, int len, int type); +int score_target_remove_watchpoint (CORE_ADDR addr, int len, int type); +int score_target_insert_hw_breakpoint (struct bp_target_info * bp_tgt); +int score_target_remove_hw_breakpoint (struct bp_target_info * bp_tgt); + +#define TARGET_HAS_HARDWARE_WATCHPOINTS + +#ifdef TARGET_CAN_USE_HARDWARE_WATCHPOINT +#undef TARGET_CAN_USE_HARDWARE_WATCHPOINT + +#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) \ + score_target_can_use_watch(type, cnt, ot) +#endif + +#ifdef STOPPED_BY_WATCHPOINT +#undef STOPPED_BY_WATCHPOINT + +#define STOPPED_BY_WATCHPOINT(w) \ + score_stopped_by_watch() +#endif + +#ifdef target_insert_watchpoint +#undef target_insert_watchpoint + +#define target_insert_watchpoint(addr, len, type) \ + score_target_insert_watchpoint (addr, len, type) +#endif + +#ifdef target_remove_watchpoint +#undef target_remove_watchpoint + +#define target_remove_watchpoint(addr, len, type) \ + score_target_remove_watchpoint (addr, len, type) +#endif + +#ifdef target_insert_hw_breakpoint +#undef target_insert_hw_breakpoint + +#define target_insert_hw_breakpoint(bp_tgt) \ + score_target_insert_hw_breakpoint (bp_tgt) +#endif + +#ifdef target_remove_hw_breakpoint +#undef target_remove_hw_breakpoint + +#define target_remove_hw_breakpoint(bp_tgt) \ + score_target_remove_hw_breakpoint (bp_tgt) +#endif + +#endif /* WITH_SIM */ + #endif /* SCORE_TDEP_H */ --- src/gdb/score-tdep.c 2009-01-03 13:57:53.000000000 +0800 +++ src.mod/gdb/score-tdep.c 2009-03-19 14:29:54.000000000 +0800 @@ -30,6 +30,7 @@ #include "target.h" #include "arch-utils.h" #include "regcache.h" +#include "regset.h" #include "dis-asm.h" #include "frame-unwind.h" #include "frame-base.h" @@ -37,13 +38,12 @@ #include "dwarf2-frame.h" #include "score-tdep.h" -#define G_FLD(_i,_ms,_ls) (((_i) << (31 - (_ms))) >> (31 - (_ms) + (_ls))) -#define RM_PBITS(_raw) ((G_FLD(_raw, 31, 16) << 15) | G_FLD(_raw, 14, 0)) +#define G_FLD(_i,_ms,_ls) ((unsigned)((_i) << (31 - (_ms))) >> (31 - (_ms) + (_ls))) typedef struct{ - unsigned int v; - unsigned int raw; - char is15; + unsigned long long v; + unsigned long long raw; + unsigned int len; }inst_t; struct score_frame_cache @@ -53,238 +53,110 @@ struct trad_frame_saved_reg *saved_regs; }; -#if 0 -/* If S+core GCC will generate these instructions in the prologue: - - lw rx, imm1 - addi rx, -imm2 - mv! r2, rx - - then .pdr section is used. */ - -#define P_SIZE 8 -#define PI_SYM 0 -#define PI_R_MSK 1 -#define PI_R_OFF 2 -#define PI_R_LEF 4 -#define PI_F_OFF 5 -#define PI_F_REG 6 -#define PI_RAREG 7 - -typedef struct frame_extra_info -{ - CORE_ADDR p_frame; - unsigned int pdr[P_SIZE]; -} extra_info_t; - -struct obj_priv -{ - bfd_size_type size; - char *contents; -}; - -static bfd *the_bfd; - -static int -score_compare_pdr_entries (const void *a, const void *b) -{ - CORE_ADDR lhs = bfd_get_32 (the_bfd, (bfd_byte *) a); - CORE_ADDR rhs = bfd_get_32 (the_bfd, (bfd_byte *) b); - if (lhs < rhs) - return -1; - else if (lhs == rhs) - return 0; - else - return 1; -} - -static void -score_analyze_pdr_section (CORE_ADDR startaddr, CORE_ADDR pc, - struct frame_info *this_frame, - struct score_frame_cache *this_cache) -{ - struct symbol *sym; - struct obj_section *sec; - extra_info_t *fci_ext; - CORE_ADDR leaf_ra_stack_addr = -1; - - gdb_assert (startaddr <= pc); - gdb_assert (this_cache != NULL); - - fci_ext = frame_obstack_zalloc (sizeof (extra_info_t)); - if ((sec = find_pc_section (pc)) == NULL) - { - error ("Error: Can't find section in file:%s, line:%d!", - __FILE__, __LINE__); - return; - } - - /* Anylyze .pdr section and get coresponding fields. */ - { - static struct obj_priv *priv = NULL; - - if (priv == NULL) - { - asection *bfdsec; - priv = obstack_alloc (&sec->objfile->objfile_obstack, - sizeof (struct obj_priv)); - if ((bfdsec = bfd_get_section_by_name (sec->objfile->obfd, ".pdr"))) - { - priv->size = bfd_section_size (sec->objfile->obfd, bfdsec); - priv->contents = obstack_alloc (&sec->objfile->objfile_obstack, - priv->size); - bfd_get_section_contents (sec->objfile->obfd, bfdsec, - priv->contents, 0, priv->size); - the_bfd = sec->objfile->obfd; - qsort (priv->contents, priv->size / 32, 32, - score_compare_pdr_entries); - the_bfd = NULL; - } - else - priv->size = 0; - } - if (priv->size != 0) - { - int low = 0, mid, high = priv->size / 32; - char *ptr; - do - { - CORE_ADDR pdr_pc; - mid = (low + high) / 2; - ptr = priv->contents + mid * 32; - pdr_pc = bfd_get_signed_32 (sec->objfile->obfd, ptr); - pdr_pc += ANOFFSET (sec->objfile->section_offsets, - SECT_OFF_TEXT (sec->objfile)); - if (pdr_pc == startaddr) - break; - if (pdr_pc > startaddr) - high = mid; - else - low = mid + 1; - } - while (low != high); - - if (low != high) - { - gdb_assert (bfd_get_32 (sec->objfile->obfd, ptr) == startaddr); -#define EXT_PDR(_pi) bfd_get_32(sec->objfile->obfd, ptr+((_pi)<<2)) - fci_ext->pdr[PI_SYM] = EXT_PDR (PI_SYM); - fci_ext->pdr[PI_R_MSK] = EXT_PDR (PI_R_MSK); - fci_ext->pdr[PI_R_OFF] = EXT_PDR (PI_R_OFF); - fci_ext->pdr[PI_R_LEF] = EXT_PDR (PI_R_LEF); - fci_ext->pdr[PI_F_OFF] = EXT_PDR (PI_F_OFF); - fci_ext->pdr[PI_F_REG] = EXT_PDR (PI_F_REG); - fci_ext->pdr[PI_RAREG] = EXT_PDR (PI_RAREG); -#undef EXT_PDR - } - } - } -} -#endif - -#if 0 -/* Open these functions if build with simulator. */ +static int target_mach = bfd_mach_score7; int score_target_can_use_watch (int type, int cnt, int othertype) { +#if WITH_SIM if (strcmp (current_target.to_shortname, "sim") == 0) - { return soc_gh_can_use_watch (type, cnt); - } - else - { - return (*current_target.to_can_use_hw_breakpoint) (type, cnt, othertype); - } +#endif + return (*current_target.to_can_use_hw_breakpoint) (type, cnt, othertype); } int score_stopped_by_watch (void) { +#if WITH_SIM if (strcmp (current_target.to_shortname, "sim") == 0) - { return soc_gh_stopped_by_watch (); - } - else - { - return (*current_target.to_stopped_by_watchpoint) (); - } +#endif + return (*current_target.to_stopped_by_watchpoint) (); } int score_target_insert_watchpoint (CORE_ADDR addr, int len, int type) { +#if WITH_SIM if (strcmp (current_target.to_shortname, "sim") == 0) - { return soc_gh_add_watch (addr, len, type); - } - else - { - return (*current_target.to_insert_watchpoint) (addr, len, type); - } +#endif + return (*current_target.to_insert_watchpoint) (addr, len, type); } int score_target_remove_watchpoint (CORE_ADDR addr, int len, int type) { +#if WITH_SIM if (strcmp (current_target.to_shortname, "sim") == 0) - { return soc_gh_del_watch (addr, len, type); - } - else - { - return (*current_target.to_remove_watchpoint) (addr, len, type); - } +#endif + return (*current_target.to_remove_watchpoint) (addr, len, type); } int score_target_insert_hw_breakpoint (struct bp_target_info * bp_tgt) { +#if WITH_SIM if (strcmp (current_target.to_shortname, "sim") == 0) - { return soc_gh_add_hardbp (bp_tgt->placed_address); - } - else - { - return (*current_target.to_insert_hw_breakpoint) (bp_tgt); - } +#endif + return (*current_target.to_insert_hw_breakpoint) (bp_tgt); } int score_target_remove_hw_breakpoint (struct bp_target_info * bp_tgt) { +#if WITH_SIM if (strcmp (current_target.to_shortname, "sim") == 0) - { return soc_gh_del_hardbp (bp_tgt->placed_address); - } - else - { - return (*current_target.to_remove_hw_breakpoint) (bp_tgt); - } -} #endif + return (*current_target.to_remove_hw_breakpoint) (bp_tgt); +} static struct type * score_register_type (struct gdbarch *gdbarch, int regnum) { - gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS); + gdb_assert (regnum >= 0 + && regnum < ((target_mach == bfd_mach_score7) ? SCORE7_NUM_REGS : SCORE3_NUM_REGS)); return builtin_type_uint32; } static CORE_ADDR +score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM); +} + +static CORE_ADDR score_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) { return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM); } -static CORE_ADDR -score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame) +static const char * +score7_register_name (struct gdbarch *gdbarch, int regnum) { - return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM); + const char *score_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", "r26", "r27", "r28", "r29", "r30", "r31", + + "PSR", "COND", "ECR", "EXCPVEC", "CCR", + "EPC", "EMA", "TLBLOCK", "TLBPT", "PEADDR", + "TLBRPT", "PEVN", "PECTX", "LIMPFN", "LDMPFN", + "PREV", "DREG", "PC", "DSAVE", "COUNTER", + "LDCR", "STCR", "CEH", "CEL", + }; + + gdb_assert (regnum >= 0 && regnum < SCORE7_NUM_REGS); + return score_register_names[regnum]; } static const char * -score_register_name (struct gdbarch *gdbarch, int regnum) +score3_register_name (struct gdbarch *gdbarch, int regnum) { const char *score_register_names[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", @@ -292,24 +164,25 @@ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", - "PSR", "COND", "ECR", "EXCPVEC", - "CCR", "EPC", "EMA", "TLBLOCK", - "TLBPT", "PEADDR", "TLBRPT", "PEVN", - "PECTX", "LIMPFN", "LDMPFN", "PREV", - "DREG", "PC", "DSAVE", "COUNTER", - "LDCR", "STCR", "CEH", "CEL", + "PSR", "COND", "ECR", "EXCPVEC", "CCR", + "EPC", "EMA", "PREV", "DREG", "DSAVE", + "COUNTER", "LDCR", "STCR", "CEH", "CEL", + "", "", "PC", }; - gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS); + gdb_assert (regnum >= 0 && regnum < SCORE3_NUM_REGS); return score_register_names[regnum]; } +#if WITH_SIM static int score_register_sim_regno (struct gdbarch *gdbarch, int regnum) { - gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS); + gdb_assert (regnum >= 0 + && regnum < ((target_mach == bfd_mach_score7) ? SCORE7_NUM_REGS : SCORE3_NUM_REGS)); return regnum; } +#endif static int score_print_insn (bfd_vma memaddr, struct disassemble_info *info) @@ -320,9 +193,167 @@ return print_insn_little_score (memaddr, info); } +static inst_t * +score7_fetch_inst (struct gdbarch *gdbarch, CORE_ADDR addr, char *memblock) +{ + static inst_t inst = { 0, 0, 0 }; + char buf[SCORE_INSTLEN] = { 0 }; + int big; + int ret; + + if (target_has_execution && memblock != NULL) + { + /* Fetch instruction from local MEMBLOCK. */ + memcpy (buf, memblock, SCORE_INSTLEN); + } + else + { + /* Fetch instruction from target. */ + ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN); + if (ret) + { + error ("Error: target_read_memory in file:%s, line:%d!", + __FILE__, __LINE__); + return 0; + } + } + + inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN); + inst.len = (inst.raw & 0x80008000) ? 4 : 2; + inst.v = ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF); + big = (gdbarch_byte_order(gdbarch) == BFD_ENDIAN_BIG); + if (inst.len == 2) + { + if (big ^ ((addr & 0x2) == 2)) + inst.v = G_FLD (inst.v, 29, 15); + else + inst.v = G_FLD (inst.v, 14, 0); + } + return &inst; +} + +static inst_t * +score3_adjust_pc_and_fetch_inst (CORE_ADDR *pcptr, int *lenptr) +{ + static inst_t inst = { 0, 0, 0 }; + + struct breakplace + { + int break_offset; + int inst_len; + }; + /* raw table 1 (column 2, 3, 4) + * 0 1 0 * # 2 + * 0 1 1 0 # 3 + 0 1 1 0 * # 6 + table 2 (column 1, 2, 3) + * 0 0 * * # 0, 4 + 0 1 0 * * # 2 + 1 1 0 * * # 6 + */ + + static const struct breakplace bk_table[16] = + { + /* table 1 */ + {0, 0}, + {0, 0}, + {0, 4}, + {0, 6}, + {0, 0}, + {0, 0}, + {-2, 6}, + {0, 0}, + /* table 2 */ + {0, 2}, + {0, 0}, + {-2, 4}, + {0, 0}, + {0, 2}, + {0, 0}, + {-4, 6}, + {0, 0} + }; + +#define EXTRACT_LEN 2 + CORE_ADDR adjust_pc = *pcptr & ~0x1; + int inst_len; + gdb_byte buf[5][EXTRACT_LEN] = {{'\0', '\0'}, {'\0', '\0'}, {'\0', '\0'}, {'\0', '\0'}, {'\0', '\0'}}; + int ret; + unsigned int raw; + unsigned int cbits = 0; + int bk_index; + int i, count; + + inst.v = 0; + inst.raw = 0; + inst.len = 0; + + adjust_pc -= 4; + for (i = 0; i < 5; i++) + { + ret = target_read_memory (adjust_pc + 2 * i, buf[i], EXTRACT_LEN); + if (ret != 0) + { + buf[i][0] = '\0'; + buf[i][1] = '\0'; + if (i == 2) + error ("Error: target_read_memory in file:%s, line:%d!", __FILE__, __LINE__); + } + + raw = extract_unsigned_integer (buf[i], EXTRACT_LEN); + cbits = (cbits << 1) | (raw >> 15); + } + adjust_pc += 4; + + if (cbits & 0x4) + { + /* table 1 */ + cbits = (cbits >> 1) & 0x7; + bk_index = cbits; + } + else + { + /* table 2 */ + cbits = (cbits >> 2) & 0x7; + bk_index = cbits + 8; + } + + gdb_assert (!((bk_table[bk_index].break_offset == 0) && (bk_table[bk_index].inst_len == 0))); + + inst.len = bk_table[bk_index].inst_len; + + i = (bk_table[bk_index].break_offset + 4) / 2; + count = inst.len / 2; + for (; count > 0; i++, count--) + { + inst.raw = (inst.raw << 16) | extract_unsigned_integer (buf[i], EXTRACT_LEN); + } + + switch (inst.len) + { + case 2: + inst.v = inst.raw & 0x7FFF; + break; + case 4: + inst.v = ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF); + break; + case 6: + inst.v = ((inst.raw >> 32 & 0x7FFF) << 30) | ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF); + break; + } + + if (pcptr) + *pcptr = adjust_pc + bk_table[bk_index].break_offset; + if (lenptr) + *lenptr = bk_table[bk_index].inst_len; + +#undef EXTRACT_LEN + + return &inst; +} + static const gdb_byte * -score_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, - int *lenptr) +score7_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) { gdb_byte buf[SCORE_INSTLEN] = { 0 }; int ret; @@ -375,6 +406,48 @@ } } +static const gdb_byte * +score3_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) +{ + CORE_ADDR adjust_pc = *pcptr; + int len; + static gdb_byte score_break_insns[6][6] = { + /* The following three instructions are big endian. */ + { 0x00, 0x20 }, + { 0x80, 0x00, 0x00, 0x06 }, + { 0x80, 0x00, 0x80, 0x00, 0x00, 0x00 }, + /* The following three instructions are little endian. */ + { 0x20, 0x00 }, + { 0x00, 0x80, 0x06, 0x00 }, + { 0x00, 0x80, 0x00, 0x80, 0x00, 0x00 }}; + + gdb_byte *p = NULL; + int index = 0; + + score3_adjust_pc_and_fetch_inst (&adjust_pc, &len); + + index = ((gdbarch_byte_order(gdbarch) == BFD_ENDIAN_BIG) ? 0 : 3) + (len / 2 - 1); + p = score_break_insns[index]; + + *pcptr = adjust_pc; + *lenptr = len; + + return p; +} + +static CORE_ADDR +score_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr) +{ + CORE_ADDR adjust_pc = bpaddr; + + if (target_mach == bfd_mach_score3) + score3_adjust_pc_and_fetch_inst (&adjust_pc, NULL); + else + adjust_pc = align_down (adjust_pc, 2); + + return adjust_pc; +} + static CORE_ADDR score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr) { @@ -387,7 +460,8 @@ const gdb_byte *writebuf, int buf_offset) { int reg_offset = 0; - gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS); + gdb_assert (regnum >= 0 + && regnum < ((target_mach == bfd_mach_score7) ? SCORE7_NUM_REGS : SCORE3_NUM_REGS)); switch (endian) { @@ -415,7 +489,7 @@ static enum return_value_convention score_return_value (struct gdbarch *gdbarch, struct type *func_type, - struct type *type, struct regcache *regcache, + struct type *type, struct regcache *regcache, gdb_byte * readbuf, const gdb_byte * writebuf) { if (TYPE_CODE (type) == TYPE_CODE_STRUCT @@ -433,8 +507,7 @@ int xfer = SCORE_REGSIZE; if (offset + xfer > TYPE_LENGTH (type)) xfer = TYPE_LENGTH (type) - offset; - score_xfer_register (regcache, regnum, xfer, - gdbarch_byte_order (gdbarch), + score_xfer_register (regcache, regnum, xfer, gdbarch_byte_order(gdbarch), readbuf, writebuf, offset); } return RETURN_VALUE_REGISTER_CONVENTION; @@ -543,7 +616,7 @@ Where X is a hole. */ - if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG + if (gdbarch_byte_order(gdbarch) == BFD_ENDIAN_BIG && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION) && argreg > SCORE_LAST_ARG_REGNUM @@ -557,7 +630,7 @@ /* The last part of a arg should shift left when gdbarch_byte_order is BFD_ENDIAN_BIG. */ - if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG + if (gdbarch_byte_order(gdbarch) == BFD_ENDIAN_BIG && arg_last_part_p == 1 && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)) @@ -586,162 +659,132 @@ return sp; } -static char * -score_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size) -{ - int ret; - char *memblock = NULL; - - if (size < 0) - { - error ("Error: malloc size < 0 in file:%s, line:%d!", - __FILE__, __LINE__); - return NULL; - } - else if (size == 0) - return NULL; - - memblock = (char *) xmalloc (size); - memset (memblock, 0, size); - ret = target_read_memory (addr & ~0x3, memblock, size); - if (ret) - { - error ("Error: target_read_memory in file:%s, line:%d!", - __FILE__, __LINE__); - return NULL; - } - return memblock; -} - -static void -score_free_memblock (char *memblock) -{ - xfree (memblock); -} - -static void -score_adjust_memblock_ptr (char **memblock, CORE_ADDR prev_pc, - CORE_ADDR cur_pc) -{ - if (prev_pc == -1) - { - /* First time call this function, do nothing. */ - } - else if (cur_pc - prev_pc == 2 && (cur_pc & 0x3) == 0) - { - /* First 16-bit instruction, then 32-bit instruction. */ - *memblock += SCORE_INSTLEN; - } - else if (cur_pc - prev_pc == 4) - { - /* Is 32-bit instruction, increase MEMBLOCK by 4. */ - *memblock += SCORE_INSTLEN; - } -} - -static inst_t * -score_fetch_inst (struct gdbarch *gdbarch, CORE_ADDR addr, char *memblock) -{ - static inst_t inst = { 0, 0 }; - char buf[SCORE_INSTLEN] = { 0 }; - int big; - int ret; - - if (target_has_execution && memblock != NULL) - { - /* Fetch instruction from local MEMBLOCK. */ - memcpy (buf, memblock, SCORE_INSTLEN); - } - else - { - /* Fetch instruction from target. */ - ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN); - if (ret) - { - error ("Error: target_read_memory in file:%s, line:%d!", - __FILE__, __LINE__); - return 0; - } - } - - inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN); - inst.is15 = !(inst.raw & 0x80008000); - inst.v = RM_PBITS (inst.raw); - big = (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG); - if (inst.is15) - { - if (big ^ ((addr & 0x2) == 2)) - inst.v = G_FLD (inst.v, 29, 15); - else - inst.v = G_FLD (inst.v, 14, 0); - } - return &inst; -} - static CORE_ADDR -score_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) +score7_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) { CORE_ADDR cpc = pc; int iscan = 32, stack_sub = 0; while (iscan-- > 0) { - inst_t *inst = score_fetch_inst (gdbarch, cpc, NULL); + inst_t *inst = score7_fetch_inst (gdbarch, cpc, NULL); if (!inst) break; - if (!inst->is15 && !stack_sub + if ((inst->len == 4) && !stack_sub && (G_FLD (inst->v, 29, 25) == 0x1 && G_FLD (inst->v, 24, 20) == 0x0)) { /* addi r0, offset */ - pc = stack_sub = cpc + SCORE_INSTLEN; + stack_sub = cpc + SCORE_INSTLEN; + pc = cpc + SCORE_INSTLEN; } - else if (!inst->is15 - && inst->v == RM_PBITS (0x8040bc56)) + else if ((inst->len == 4) + && (G_FLD (inst->v, 29, 25) == 0x0) + && (G_FLD (inst->v, 24, 20) == 0x2) + && (G_FLD (inst->v, 19, 15) == 0x0) + && (G_FLD (inst->v, 14, 10) == 0xF) + && (G_FLD (inst->v, 9, 0) == 0x56)) { /* mv r2, r0 */ pc = cpc + SCORE_INSTLEN; break; } - else if (inst->is15 - && inst->v == RM_PBITS (0x0203)) + else if ((inst->len == 2) + && (G_FLD (inst->v, 14, 12) == 0x0) + && (G_FLD (inst->v, 11, 8) == 0x2) + && (G_FLD (inst->v, 7, 4) == 0x0) + && (G_FLD (inst->v, 3, 0) == 0x3)) { /* mv! r2, r0 */ pc = cpc + SCORE16_INSTLEN; break; } - else if (inst->is15 + else if ((inst->len == 2) && ((G_FLD (inst->v, 14, 12) == 3) /* j15 form */ || (G_FLD (inst->v, 14, 12) == 4) /* b15 form */ || (G_FLD (inst->v, 14, 12) == 0x0 && G_FLD (inst->v, 3, 0) == 0x4))) /* br! */ break; - else if (!inst->is15 + else if ((inst->len == 4) && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */ || (G_FLD (inst->v, 29, 25) == 4) /* b32 form */ || (G_FLD (inst->v, 29, 25) == 0x0 && G_FLD (inst->v, 6, 1) == 0x4))) /* br */ break; - cpc += inst->is15 ? SCORE16_INSTLEN : SCORE_INSTLEN; + cpc += (inst->len == 2) ? SCORE16_INSTLEN : SCORE_INSTLEN; } return pc; } -static int -score_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc) +static CORE_ADDR +score3_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) { - inst_t *inst = score_fetch_inst (gdbarch, cur_pc, NULL); - - if (inst->v == 0x23) - return 1; /* mv! r0, r2 */ - else if (G_FLD (inst->v, 14, 12) == 0x2 - && G_FLD (inst->v, 3, 0) == 0xa) - return 1; /* pop! */ - else if (G_FLD (inst->v, 14, 12) == 0x0 - && G_FLD (inst->v, 7, 0) == 0x34) - return 1; /* br! r3 */ - else if (G_FLD (inst->v, 29, 15) == 0x2 - && G_FLD (inst->v, 6, 1) == 0x2b) + CORE_ADDR cpc = pc; + int iscan = 32, stack_sub = 0; + while (iscan-- > 0) + { + inst_t *inst = score3_adjust_pc_and_fetch_inst (&cpc, NULL); + if (!inst) + break; + if (inst->len == 4 && !stack_sub + && (G_FLD (inst->v, 29, 25) == 0x1) + && (G_FLD (inst->v, 19, 17) == 0x0) + && (G_FLD (inst->v, 24, 20) == 0x0)) + { + /* addi r0, offset */ + stack_sub = cpc + inst->len; + pc = cpc + inst->len; + } + else if (inst->len == 4 + && (G_FLD (inst->v, 29, 25) == 0x0) + && (G_FLD (inst->v, 24, 20) == 0x2) + && (G_FLD (inst->v, 19, 15) == 0x0) + && (G_FLD (inst->v, 14, 10) == 0xF) + && (G_FLD (inst->v, 9, 0) == 0x56)) + { + /* mv r2, r0 */ + pc = cpc + inst->len; + break; + } + else if ((inst->len == 2) + && (G_FLD (inst->v, 14, 10) == 0x10) + && (G_FLD (inst->v, 9, 5) == 0x2) + && (G_FLD (inst->v, 4, 0) == 0x0)) + { + /* mv! r2, r0 */ + pc = cpc + inst->len; + break; + } + else if (inst->len == 2 + && ((G_FLD (inst->v, 14, 12) == 3) /* b15 form */ + || (G_FLD (inst->v, 14, 12) == 0x0 + && G_FLD (inst->v, 11, 5) == 0x4))) /* br! */ + break; + else if (inst->len == 4 + && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */ + || (G_FLD (inst->v, 29, 25) == 4))) /* b32 form */ + break; + + cpc += inst->len; + } + return pc; +} + +static int +score7_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc) +{ + inst_t *inst = score7_fetch_inst (gdbarch, cur_pc, NULL); + + if (inst->v == 0x23) + return 1; /* mv! r0, r2 */ + else if (G_FLD (inst->v, 14, 12) == 0x2 + && G_FLD (inst->v, 3, 0) == 0xa) + return 1; /* pop! */ + else if (G_FLD (inst->v, 14, 12) == 0x0 + && G_FLD (inst->v, 7, 0) == 0x34) + return 1; /* br! r3 */ + else if (G_FLD (inst->v, 29, 15) == 0x2 + && G_FLD (inst->v, 6, 1) == 0x2b) return 1; /* mv r0, r2 */ else if (G_FLD (inst->v, 29, 25) == 0x0 && G_FLD (inst->v, 6, 1) == 0x4 @@ -751,8 +794,104 @@ return 0; } +static int +score3_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc) +{ + CORE_ADDR pc = cur_pc; + inst_t *inst = score3_adjust_pc_and_fetch_inst (&pc, NULL); + + if (inst->len == 2 + && (G_FLD (inst->v, 14, 10) == 0x10) + && (G_FLD (inst->v, 9, 5) == 0x0) + && (G_FLD (inst->v, 4, 0) == 0x2)) + return 1; /* mv! r0, r2 */ + else if (inst->len == 4 + && (G_FLD (inst->v, 29, 25) == 0x0) + && (G_FLD (inst->v, 24, 20) == 0x2) + && (G_FLD (inst->v, 19, 15) == 0x0) + && (G_FLD (inst->v, 14, 10) == 0xF) + && (G_FLD (inst->v, 9, 0) == 0x56)) + return 1; /* mv r0, r2 */ + else if (inst->len == 2 + && (G_FLD (inst->v, 14, 12) == 0x0) + && (G_FLD (inst->v, 11, 5) == 0x2)) + return 1; /* pop! */ + else if (inst->len == 2 + && (G_FLD (inst->v, 14, 12) == 0x0) + && (G_FLD (inst->v, 11, 7) == 0x0) + && (G_FLD (inst->v, 6, 5) == 0x2)) + return 1; /* rpop! */ + else if (inst->len == 2 + && (G_FLD (inst->v, 14, 12) == 0x0) + && (G_FLD (inst->v, 11, 5) == 0x4) + && (G_FLD (inst->v, 4, 0) == 0x3)) + return 1; /* br! r3 */ + else if (inst->len == 4 + && (G_FLD (inst->v, 29, 25) == 0x0) + && (G_FLD (inst->v, 24, 20) == 0x0) + && (G_FLD (inst->v, 19, 15) == 0x3) + && (G_FLD (inst->v, 14, 10) == 0xF) + && (G_FLD (inst->v, 9, 0) == 0x8)) + return 1; /* br r3 */ + else + return 0; +} + +static char * +score7_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size) +{ + int ret; + char *memblock = NULL; + + if (size < 0) + { + error ("Error: malloc size < 0 in file:%s, line:%d!", + __FILE__, __LINE__); + return NULL; + } + else if (size == 0) + return NULL; + + memblock = (char *) xmalloc (size); + memset (memblock, 0, size); + ret = target_read_memory (addr & ~0x3, memblock, size); + if (ret) + { + error ("Error: target_read_memory in file:%s, line:%d!", + __FILE__, __LINE__); + return NULL; + } + return memblock; +} + +static void +score7_free_memblock (char *memblock) +{ + xfree (memblock); +} + +static void +score7_adjust_memblock_ptr (char **memblock, CORE_ADDR prev_pc, + CORE_ADDR cur_pc) +{ + if (prev_pc == -1) + { + /* First time call this function, do nothing. */ + } + else if (cur_pc - prev_pc == 2 && (cur_pc & 0x3) == 0) + { + /* First 16-bit instruction, then 32-bit instruction. */ + *memblock += SCORE_INSTLEN; + } + else if (cur_pc - prev_pc == 4) + { + /* Is 32-bit instruction, increase MEMBLOCK by 4. */ + *memblock += SCORE_INSTLEN; + } +} + static void -score_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc, +score7_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc, struct frame_info *this_frame, struct score_frame_cache *this_cache) { @@ -774,7 +913,7 @@ /* Allocate MEMBLOCK if PC - STARTADDR > 0. */ memblock_ptr = memblock = - score_malloc_and_get_memblock (startaddr, pc - startaddr); + score7_malloc_and_get_memblock (startaddr, pc - startaddr); sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM); fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM); @@ -786,17 +925,18 @@ { /* Reading memory block from target succefully and got all the instructions(from STARTADDR to PC) needed. */ - score_adjust_memblock_ptr (&memblock, prev_pc, cur_pc); - inst = score_fetch_inst (gdbarch, cur_pc, memblock); + score7_adjust_memblock_ptr (&memblock, prev_pc, cur_pc); + inst = score7_fetch_inst (gdbarch, cur_pc, memblock); } else { /* Otherwise, we fetch 4 bytes from target, and GDB also work correctly. */ - inst = score_fetch_inst (gdbarch, cur_pc, NULL); + inst = score7_fetch_inst (gdbarch, cur_pc, NULL); } - if (inst->is15 == 1) + /* FIXME: make a full-power prologue analyzer */ + if (inst->len == 2) { inst_len = SCORE16_INSTLEN; @@ -844,27 +984,48 @@ { inst_len = SCORE_INSTLEN; - if (G_FLD (inst->v, 29, 15) == 0xc60 - && G_FLD (inst->v, 2, 0) == 0x4) + if (G_FLD(inst->v, 29, 25) == 0x3 + && G_FLD(inst->v, 2, 0) == 0x4 + && G_FLD(inst->v, 19, 15) == 0) { - /* sw r3, [r0, offset]+ */ - sp_offset += SCORE_INSTLEN; - if (ra_offset_p == 0) - { - ra_offset = sp_offset; - ra_offset_p = 1; - } + /* sw rD, [r0, offset]+ */ + sp_offset += SCORE_INSTLEN; + + if (G_FLD(inst->v, 24, 20) == 0x3) + { + /* rD = r3 */ + if (ra_offset_p == 0) + { + ra_offset = sp_offset; + ra_offset_p = 1; + } + } + else if (G_FLD(inst->v, 24, 20) == 0x2) + { + /* rD = r2 */ + if (fp_offset_p == 0) + { + fp_offset = sp_offset; + fp_offset_p = 1; + } + } } - if (G_FLD (inst->v, 29, 15) == 0xc40 - && G_FLD (inst->v, 2, 0) == 0x4) + else if (G_FLD(inst->v, 29, 25) == 0x14 + && G_FLD(inst->v, 19,15) == 0) { - /* sw r2, [r0, offset]+ */ - sp_offset += SCORE_INSTLEN; - if (fp_offset_p == 0) - { - fp_offset = sp_offset; - fp_offset_p = 1; - } + /* sw rD, [r0, offset] */ + if (G_FLD(inst->v, 24, 20) == 0x3) + { + /* rD = r3 */ + ra_offset = sp_offset - G_FLD(inst->v, 14, 0); + ra_offset_p = 1; + } + else if (G_FLD(inst->v, 24, 20) == 0x2) + { + /* rD = r2 */ + fp_offset = sp_offset - G_FLD(inst->v, 14, 0); + fp_offset_p = 1; + } } else if (G_FLD (inst->v, 29, 15) == 0x1c60 && G_FLD (inst->v, 2, 0) == 0x0) @@ -895,7 +1056,7 @@ { unsigned int save_v = inst->v; inst_t *inst2 = - score_fetch_inst (gdbarch, cur_pc + SCORE_INSTLEN, NULL); + score7_fetch_inst (gdbarch, cur_pc + SCORE_INSTLEN, NULL); if (inst2->v == 0x23) { /* mv! r0, r2 */ @@ -933,7 +1094,249 @@ /* Don't forget to free MEMBLOCK if we allocated it. */ if (memblock_ptr != NULL) - score_free_memblock (memblock_ptr); + score7_free_memblock (memblock_ptr); +} + +static void +score3_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc, + struct frame_info *this_frame, + struct score_frame_cache *this_cache) +{ + CORE_ADDR sp; + CORE_ADDR fp; + CORE_ADDR cur_pc = startaddr; + + int sp_offset = 0; + int ra_offset = 0; + int fp_offset = 0; + int ra_offset_p = 0; + int fp_offset_p = 0; + int inst_len = 0; + + CORE_ADDR prev_pc = -1; + + sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM); + fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM); + + for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len) + { + inst_t *inst = NULL; + + inst = score3_adjust_pc_and_fetch_inst (&cur_pc, &inst_len); + + /* FIXME: make a full-power prologue analyzer */ + if (inst->len == 2) + { + if (G_FLD (inst->v, 14, 12) == 0x0 + && G_FLD (inst->v, 11, 7) == 0x0 + && G_FLD (inst->v, 6, 5) == 0x3) + { + /* push! */ + sp_offset += 4; + + if (G_FLD (inst->v, 4, 0) == 0x3 + && ra_offset_p == 0) + { + /* push! r3, [r0] */ + ra_offset = sp_offset; + ra_offset_p = 1; + } + else if (G_FLD (inst->v, 4, 0) == 0x2 + && fp_offset_p == 0) + { + /* push! r2, [r0] */ + fp_offset = sp_offset; + fp_offset_p = 1; + } + } + else if (G_FLD (inst->v, 14, 12) == 0x6 + && G_FLD (inst->v, 11, 10) == 0x3) + { + /* rpush! */ + int start_r = G_FLD (inst->v, 9, 5); + int cnt = G_FLD (inst->v, 4, 0); + + if ((ra_offset_p == 0) + && (start_r <= SCORE_RA_REGNUM) + && (SCORE_RA_REGNUM < start_r + cnt)) + { + /* rpush! contains r3 */ + ra_offset_p = 1; + ra_offset = sp_offset + 4 * (SCORE_RA_REGNUM - start_r) + 4; + } + + if ((fp_offset_p == 0) + && (start_r <= SCORE_FP_REGNUM) + && (SCORE_FP_REGNUM < start_r + cnt)) + { + /* rpush! contains r2 */ + fp_offset_p = 1; + fp_offset = sp_offset + 4 * (SCORE_FP_REGNUM - start_r) + 4; + } + + sp_offset += 4 * cnt; + } + else if (G_FLD (inst->v, 14, 12) == 0x0 + && G_FLD (inst->v, 11, 7) == 0x0 + && G_FLD (inst->v, 6, 5) == 0x2) + { + /* pop! */ + sp_offset -= 4; + } + else if (G_FLD (inst->v, 14, 12) == 0x6 + && G_FLD (inst->v, 11, 10) == 0x2) + { + /* rpop! */ + sp_offset -= 4 * G_FLD (inst->v, 4, 0); + } + else if (G_FLD (inst->v, 14, 12) == 0x5 + && G_FLD (inst->v, 11, 10) == 0x3 + && G_FLD (inst->v, 9, 6) == 0x0) + { + /* addi! r0, -offset */ + int imm = G_FLD (inst->v, 5, 0); + if (imm >> 5) + imm = -(0x3F - imm + 1); + sp_offset -= imm; + } + else if (G_FLD (inst->v, 14, 12) == 0x5 + && G_FLD (inst->v, 11, 10) == 0x3 + && G_FLD (inst->v, 9, 6) == 0x2) + { + /* addi! r2, offset */ + if (pc - cur_pc >= 2) + { + unsigned int save_v = inst->v; + inst_t *inst2; + + cur_pc += inst->len; + inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL); + + if (inst2->len == 2 + && G_FLD (inst2->v, 14, 10) == 0x10 + && G_FLD (inst2->v, 9, 5) == 0x0 + && G_FLD (inst2->v, 4, 0) == 0x2) + { + /* mv! r0, r2 */ + int imm = G_FLD (inst->v, 5, 0); + if (imm >> 5) + imm = -(0x3F - imm + 1); + sp_offset -= imm; + } + } + } + } + else if (inst->len == 4) + { + if (G_FLD (inst->v, 29, 25) == 0x3 + && G_FLD (inst->v, 2, 0) == 0x4 + && G_FLD (inst->v, 24, 20) == 0x3 + && G_FLD (inst->v, 19, 15) == 0x0) + { + /* sw r3, [r0, offset]+ */ + sp_offset += inst->len; + if (ra_offset_p == 0) + { + ra_offset = sp_offset; + ra_offset_p = 1; + } + } + else if (G_FLD (inst->v, 29, 25) == 0x3 + && G_FLD (inst->v, 2, 0) == 0x4 + && G_FLD (inst->v, 24, 20) == 0x2 + && G_FLD (inst->v, 19, 15) == 0x0) + { + /* sw r2, [r0, offset]+ */ + sp_offset += inst->len; + if (fp_offset_p == 0) + { + fp_offset = sp_offset; + fp_offset_p = 1; + } + } + else if (G_FLD (inst->v, 29, 25) == 0x7 + && G_FLD (inst->v, 2, 0) == 0x0 + && G_FLD (inst->v, 24, 20) == 0x3 + && G_FLD (inst->v, 19, 15) == 0x0) + { + /* lw r3, [r0]+, 4 */ + sp_offset -= inst->len; + ra_offset_p = 1; + } + else if (G_FLD (inst->v, 29, 25) == 0x7 + && G_FLD (inst->v, 2, 0) == 0x0 + && G_FLD (inst->v, 24, 20) == 0x2 + && G_FLD (inst->v, 19, 15) == 0x0) + { + /* lw r2, [r0]+, 4 */ + sp_offset -= inst->len; + fp_offset_p = 1; + } + else if (G_FLD (inst->v, 29, 25) == 0x1 + && G_FLD (inst->v, 19, 17) == 0x0 + && G_FLD (inst->v, 24, 20) == 0x0 + && G_FLD (inst->v, 0, 0) == 0x0) + { + /* addi r0, -offset */ + int imm = G_FLD (inst->v, 16, 1); + if (imm >> 15) + imm = -(0xFFFF - imm + 1); + sp_offset -= imm; + } + else if (G_FLD (inst->v, 29, 25) == 0x1 + && G_FLD (inst->v, 19, 17) == 0x0 + && G_FLD (inst->v, 24, 20) == 0x2 + && G_FLD (inst->v, 0, 0) == 0x0) + { + /* addi r2, offset */ + if (pc - cur_pc >= 2) + { + unsigned int save_v = inst->v; + inst_t *inst2; + + cur_pc += inst->len; + inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL); + + if (inst2->len == 2 + && G_FLD (inst2->v, 14, 10) == 0x10 + && G_FLD (inst2->v, 9, 5) == 0x0 + && G_FLD (inst2->v, 4, 0) == 0x2) + { + /* mv! r0, r2 */ + int imm = G_FLD (inst->v, 16, 1); + if (imm >> 15) + imm = -(0xFFFF - imm + 1); + sp_offset -= imm; + } + } + } + } + } + + /* Save RA. */ + if (ra_offset_p == 1) + { + if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1) + this_cache->saved_regs[SCORE_PC_REGNUM].addr = + sp + sp_offset - ra_offset; + } + else + { + this_cache->saved_regs[SCORE_PC_REGNUM] = + this_cache->saved_regs[SCORE_RA_REGNUM]; + } + + /* Save FP. */ + if (fp_offset_p == 1) + { + if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1) + this_cache->saved_regs[SCORE_FP_REGNUM].addr = + sp + sp_offset - fp_offset; + } + + /* Save SP and FP. */ + this_cache->base = sp + sp_offset; + this_cache->fp = fp; } static struct score_frame_cache * @@ -956,7 +1359,11 @@ find_pc_partial_function (pc, NULL, &start_addr, NULL); if (start_addr == 0) return cache; - score_analyze_prologue (start_addr, pc, this_frame, *this_cache); + + if (target_mach == bfd_mach_score3) + score3_analyze_prologue (start_addr, pc, this_frame, *this_cache); + else + score7_analyze_prologue (start_addr, pc, this_frame, *this_cache); } /* Save SP. */ @@ -989,7 +1396,8 @@ score_prologue_this_id, score_prologue_prev_register, NULL, - default_frame_sniffer + default_frame_sniffer, + NULL }; static CORE_ADDR @@ -1015,37 +1423,131 @@ return &score_prologue_frame_base; } +/* Core file support (dirty hack) + + The core file MUST be generated by GNU/Linux on S+core */ + +static void +score7_linux_supply_gregset(const struct regset *regset, + struct regcache *regcache, + int regnum, const void *gregs_buf, size_t len) +{ + int regno; + elf_gregset_t *gregs; + + gdb_assert (regset != NULL); + gdb_assert ((regcache != NULL) && (gregs_buf != NULL)); + + gregs = (elf_gregset_t *) gregs_buf; + + for (regno = 0; regno < 32; regno++) + if (regnum == -1 || regnum == regno) + regcache_raw_supply (regcache, regno, gregs->regs + regno); + + { + struct sreg { + int regnum; + void *buf; + } sregs [] = { + { 55, &(gregs->cel) }, /* CEL */ + { 54, &(gregs->ceh) }, /* CEH */ + { 53, &(gregs->sr0) }, /* sr0, i.e. cnt or COUNTER */ + { 52, &(gregs->sr1) }, /* sr1, i.e. lcr or LDCR */ + { 51, &(gregs->sr1) }, /* sr2, i.e. scr or STCR */ + + /* Exception occured at this address, exactly the PC we want */ + { 49, &(gregs->cp0_epc) }, /* PC */ + + { 38, &(gregs->cp0_ema) }, /* EMA */ + { 37, &(gregs->cp0_epc) }, /* EPC */ + { 34, &(gregs->cp0_ecr) }, /* ECR */ + { 33, &(gregs->cp0_condition) }, /* COND */ + { 32, &(gregs->cp0_psr) }, /* PSR */ + }; + + for (regno = 0; regno < sizeof(sregs)/sizeof(sregs[0]); regno++) + if (regnum == -1 || regnum == sregs[regno].regnum) + regcache_raw_supply (regcache, sregs[regno].regnum, sregs[regno].buf); + } +} + +/* Return the appropriate register set from the core section identified + by SECT_NAME and SECT_SIZE. */ + +static const struct regset * +score7_linux_regset_from_core_section(struct gdbarch *gdbarch, + const char *sect_name, size_t sect_size) +{ + struct gdbarch_tdep *tdep; + + gdb_assert (gdbarch != NULL); + gdb_assert (sect_name != NULL); + + tdep = gdbarch_tdep (gdbarch); + + if (strcmp(sect_name, ".reg") == 0 && sect_size == sizeof(elf_gregset_t)) + { + if (tdep->gregset == NULL) + tdep->gregset = regset_alloc (gdbarch, score7_linux_supply_gregset, NULL); + return tdep->gregset; + } + + return NULL; +} + static struct gdbarch * score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { struct gdbarch *gdbarch; + struct gdbarch_tdep *tdep; + target_mach = info.bfd_arch_info->mach; arches = gdbarch_list_lookup_by_info (arches, &info); if (arches != NULL) { return (arches->gdbarch); } - gdbarch = gdbarch_alloc (&info, 0); + tdep = xcalloc(1, sizeof(struct gdbarch_tdep)); + gdbarch = gdbarch_alloc (&info, tdep); set_gdbarch_short_bit (gdbarch, 16); set_gdbarch_int_bit (gdbarch, 32); set_gdbarch_float_bit (gdbarch, 32); set_gdbarch_double_bit (gdbarch, 64); set_gdbarch_long_double_bit (gdbarch, 64); +#if WITH_SIM set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno); +#endif set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM); set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM); - set_gdbarch_num_regs (gdbarch, SCORE_NUM_REGS); - set_gdbarch_register_name (gdbarch, score_register_name); - set_gdbarch_breakpoint_from_pc (gdbarch, score_breakpoint_from_pc); + set_gdbarch_adjust_breakpoint_address (gdbarch, score_adjust_breakpoint_address); set_gdbarch_register_type (gdbarch, score_register_type); set_gdbarch_frame_align (gdbarch, score_frame_align); set_gdbarch_inner_than (gdbarch, core_addr_lessthan); - set_gdbarch_unwind_pc (gdbarch, score_unwind_pc); set_gdbarch_unwind_sp (gdbarch, score_unwind_sp); + set_gdbarch_unwind_pc (gdbarch, score_unwind_pc); set_gdbarch_print_insn (gdbarch, score_print_insn); - set_gdbarch_skip_prologue (gdbarch, score_skip_prologue); - set_gdbarch_in_function_epilogue_p (gdbarch, score_in_function_epilogue_p); + + switch (target_mach) + { + case bfd_mach_score7: + set_gdbarch_breakpoint_from_pc (gdbarch, score7_breakpoint_from_pc); + set_gdbarch_skip_prologue (gdbarch, score7_skip_prologue); + set_gdbarch_in_function_epilogue_p (gdbarch, score7_in_function_epilogue_p); + set_gdbarch_register_name (gdbarch, score7_register_name); + set_gdbarch_num_regs (gdbarch, SCORE7_NUM_REGS); + /* Core file support. */ + set_gdbarch_regset_from_core_section (gdbarch, score7_linux_regset_from_core_section); + break; + + case bfd_mach_score3: + set_gdbarch_breakpoint_from_pc (gdbarch, score3_breakpoint_from_pc); + set_gdbarch_skip_prologue (gdbarch, score3_skip_prologue); + set_gdbarch_in_function_epilogue_p (gdbarch, score3_in_function_epilogue_p); + set_gdbarch_register_name (gdbarch, score3_register_name); + set_gdbarch_num_regs (gdbarch, SCORE3_NUM_REGS); + break; + } /* Watchpoint hooks. */ set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1); ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] Support new target S+core 3, a variant of S+core 2009-03-19 7:36 ` don.lee @ 2009-03-19 13:59 ` Joel Brobecker 2009-03-20 2:37 ` Eli Zaretskii 1 sibling, 0 replies; 10+ messages in thread From: Joel Brobecker @ 2009-03-19 13:59 UTC (permalink / raw) To: don.lee; +Cc: gdb-patches Just for the record: I just sent Don a private message asking if Qinwei could approve the S+core part or not. So I will not address this part. > --- src/gdb/configure.tgt 2009-03-16 23:04:14.000000000 +0800 > +++ src.mod/gdb/configure.tgt 2009-03-17 09:26:44.000000000 +0800 > @@ -375,7 +375,11 @@ > > score-*-*) > # Target: S+core embedded system > - gdb_target_obs="score-tdep.o" > + gdb_target_obs="score-tdep.o corelow.o" > + if test -f ../sim/score/Makefile; then > + gdb_sim=../sim/score/libsim.a > + fi > + build_gdbserver=yes > ;; > > sh*-*-linux*) Regarding this change, I am 50-50, leaning towards accepting it. Cons: There is no score simulator and you are not planning on contributing it. So, it is a useless change as far as the FSF is concerned. As such, I don't see why we should accept it. Maintaining small local changes in your own tree is very easy. Pros: I can't see any. That being said, the reason why I'm split on this is that it wouldn't cost us much to accept the change. I don't see how it could cause any trouble. GDB Global Maintainers: Do we have a policy on this sort of change? -- Joel ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] Support new target S+core 3, a variant of S+core 2009-03-19 7:36 ` don.lee 2009-03-19 13:59 ` Joel Brobecker @ 2009-03-20 2:37 ` Eli Zaretskii 2009-03-20 10:59 ` don.lee [not found] ` <OF51713D49.22E58C13-ON4825757F.00065D83-4825757F.000703CE@sunplusct.com> 1 sibling, 2 replies; 10+ messages in thread From: Eli Zaretskii @ 2009-03-20 2:37 UTC (permalink / raw) To: don.lee; +Cc: brobecker, gdb-patches > Cc: gdb-patches@sourceware.org > From: don.lee@sunplusct.com > Date: Thu, 19 Mar 2009 15:14:48 +0800 > > Attachments are my new patches, with context information. Thanks. If this is accepted, we will need an entry for NEWS about this new target. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] Support new target S+core 3, a variant of S+core 2009-03-20 2:37 ` Eli Zaretskii @ 2009-03-20 10:59 ` don.lee 2009-03-20 15:02 ` Eli Zaretskii [not found] ` <OF51713D49.22E58C13-ON4825757F.00065D83-4825757F.000703CE@sunplusct.com> 1 sibling, 1 reply; 10+ messages in thread From: don.lee @ 2009-03-20 10:59 UTC (permalink / raw) To: Eli Zaretskii; +Cc: brobecker, gdb-patches [-- Attachment #1: Type: text/plain, Size: 606 bytes --] gdb-patches-owner@sourceware.org 写于 2009-03-20 03:21:54: > > Cc: gdb-patches@sourceware.org > > From: don.lee@sunplusct.com > > Date: Thu, 19 Mar 2009 15:14:48 +0800 > > > > Attachments are my new patches, with context information. > > Thanks. > > If this is accepted, we will need an entry for NEWS about this new > target. Attachment is the patch for gdb/NEWS, says we add a new target, S+core 3, a variant of S+core. Thank you for your time, Don ChangLog entry: 2009-03-20 Don Lee <don.lee@sunplusct.com>: * gdb/NEWS: support new target, S+core 3 [-- Attachment #2: news.patch --] [-- Type: application/octet-stream, Size: 259 bytes --] --- src/gdb/NEWS 2009-02-18 01:56:50.000000000 +0800 +++ src.mod/gdb/NEWS 2009-03-20 10:15:53.000000000 +0800 @@ -209,6 +209,7 @@ x86 DICOS i[34567]86-*-dicos* x86_64 DICOS x86_64-*-dicos* +S+core 3 score-elf * Removed commands ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] Support new target S+core 3, a variant of S+core 2009-03-20 10:59 ` don.lee @ 2009-03-20 15:02 ` Eli Zaretskii 0 siblings, 0 replies; 10+ messages in thread From: Eli Zaretskii @ 2009-03-20 15:02 UTC (permalink / raw) To: don.lee; +Cc: brobecker, gdb-patches > Cc: brobecker@adacore.com, gdb-patches@sourceware.org > From: don.lee@sunplusct.com > Date: Fri, 20 Mar 2009 10:20:36 +0800 > > Attachment is the patch for gdb/NEWS, says we add a new target, S+core 3, > a variant of S+core. > > Thank you for your time, > Don > > ChangLog entry: > 2009-03-20 Don Lee <don.lee@sunplusct.com>: > > * gdb/NEWS: support new target, S+core 3 Thanks. > --- src/gdb/NEWS 2009-02-18 01:56:50.000000000 +0800 > +++ src.mod/gdb/NEWS 2009-03-20 10:15:53.000000000 +0800 > @@ -209,6 +209,7 @@ > > x86 DICOS i[34567]86-*-dicos* > x86_64 DICOS x86_64-*-dicos* > +S+core 3 score-elf Please align the "score-elf" part with the preceding lines. (I'm guessing that you are using an editor that displays a TAB as 4-column wide whitespace.) Also, I wonder if it would make sense to include with the NEWS entry a URL for where one could find a description of platforms that are not widely know/used. (DICOS could use such a URL as well, but at least I was able to find its description in a matter of seconds by googling for ``DICOS operating system''; no such luck for ``S+core 3'', whatever that is.) I realize that we have never asked for this in previous NEWS entries, but looking now at past entries, I see that they are all either sufficiently known or their names are spelled out in sufficient detail that googling for them yields instantaneous hits. ^ permalink raw reply [flat|nested] 10+ messages in thread
[parent not found: <OF51713D49.22E58C13-ON4825757F.00065D83-4825757F.000703CE@sunplusct.com>]
* Re: [PATCH] Support new target S+core 3, a variant of S+core [not found] ` <OF51713D49.22E58C13-ON4825757F.00065D83-4825757F.000703CE@sunplusct.com> @ 2009-03-24 20:33 ` Joel Brobecker [not found] ` <OF8D1ED069.1AB0D24B-ON48257586.0008306A-48257586.000B6BC2@sunplusct.com> 0 siblings, 1 reply; 10+ messages in thread From: Joel Brobecker @ 2009-03-24 20:33 UTC (permalink / raw) To: don.lee; +Cc: gdb-patches Don, > 2009-03-20 Don Lee <don.lee@sunplusct.com>: > > Support new target S+core 3, which is a variant of S+core > > * gdb/score-tdep.c: support new target S+core 3 > * gdb/score-tdep.c: Ditto. These changes were privately approved by Qinwei, so they can be checked in. Before you do so, I have a few comments, mostly procedural, so they should not require too much work. You will need to have write access priviledges to GDB. If you don't have these priviledges, can you please visit this web page? http://www.sourceware.org/cgi-bin/pdw/ps_form.cgi Once you write access have been granted, please add yourself to the WRITE AFTER APPROVAL section in the gdb/MAINTAINERS file. Please make sure to send the associated patch and ChangeLog entry to gdb-patches, so we can all know that the change was made. About the score changes, the ChangeLog entry for your changes to GDB are meant to be added at the start of the gdb/ChangeLog file - filenames in your entry should be relative to the ChangeLog file, so omit the "gdb/" in the filenames above. Also, there is a typo above, as you mentioned the same filename twice. And finally, you should be using sentences, which mean starting with a capital letter, and ending with a period. Here is an example of an acceptable entry: * score-tdep.h, score-tdep.c: Add support for S+core 3. The change in gdb/configure.ac is also approved, but please repost the patch with the associated ChangeLog entry as well. And finally, it would be great if you could post your patches with a different encoding than "applica/octet-stream", as this makes it harder to quote the contents of your patches when replying to your emails. Fixing this might be as simple as using score.diff as opposed to score.patch (but I see that you use Lotus Notes, so perhaps not as easy). -- Joel ^ permalink raw reply [flat|nested] 10+ messages in thread
[parent not found: <OF8D1ED069.1AB0D24B-ON48257586.0008306A-48257586.000B6BC2@sunplusct.com>]
* Re: [PATCH] Support new target S+core 3, a variant of S+core [not found] ` <OF8D1ED069.1AB0D24B-ON48257586.0008306A-48257586.000B6BC2@sunplusct.com> @ 2009-03-30 15:17 ` Joel Brobecker 0 siblings, 0 replies; 10+ messages in thread From: Joel Brobecker @ 2009-03-30 15:17 UTC (permalink / raw) To: don.lee; +Cc: gdb-patches > > The change in gdb/configure.ac is also approved, but please repost > > the patch with the associated ChangeLog entry as well. > > Do you mean gdb/configure.tgt? Because I didn't change gdb/configure.ac, > the file which I changed is gdb/configure.tgt. Anyway, I'll repost this > change with the associated ChangeLog entry. Yes - sorry. Small typo. > Do I need commit them separately? One commit in for score-tdep.[ch]? One > commit in for configure.tgt? Yes, please :). -- Joel ^ permalink raw reply [flat|nested] 10+ messages in thread
[parent not found: <OFDAF6A5BC.66B4412D-ON48257582.00087E06-48257582.00096DDA@sunplusct.com>]
* Re: [PATCH] Support new target S+core 3, a variant of S+core [not found] <OFDAF6A5BC.66B4412D-ON48257582.00087E06-48257582.00096DDA@sunplusct.com> @ 2009-03-23 4:28 ` Eli Zaretskii 0 siblings, 0 replies; 10+ messages in thread From: Eli Zaretskii @ 2009-03-23 4:28 UTC (permalink / raw) To: don.lee; +Cc: brobecker, gdb-patches > Cc: brobecker@adacore.com, gdb-patches@sourceware.org > From: don.lee@sunplusct.com > Date: Mon, 23 Mar 2009 09:41:23 +0800 > > I have added some more information in the NEWS entry, now you can google > with 'sunplus s+core' as keywords, and you'll got some detail information > (I got some, by the way). Thank you, this is good enough. ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2009-03-30 14:59 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-17 2:17 [PATCH] Support new target S+core 3, a variant of S+core don.lee
2009-03-17 16:12 ` Joel Brobecker
2009-03-19 7:36 ` don.lee
2009-03-19 13:59 ` Joel Brobecker
2009-03-20 2:37 ` Eli Zaretskii
2009-03-20 10:59 ` don.lee
2009-03-20 15:02 ` Eli Zaretskii
[not found] ` <OF51713D49.22E58C13-ON4825757F.00065D83-4825757F.000703CE@sunplusct.com>
2009-03-24 20:33 ` Joel Brobecker
[not found] ` <OF8D1ED069.1AB0D24B-ON48257586.0008306A-48257586.000B6BC2@sunplusct.com>
2009-03-30 15:17 ` Joel Brobecker
[not found] <OFDAF6A5BC.66B4412D-ON48257582.00087E06-48257582.00096DDA@sunplusct.com>
2009-03-23 4:28 ` Eli Zaretskii
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox