GDB (API)
|
00001 /* Target-dependent code for the S+core architecture, for GDB, 00002 the GNU Debugger. 00003 00004 Copyright (C) 2006-2013 Free Software Foundation, Inc. 00005 00006 Contributed by Qinwei (qinwei@sunnorth.com.cn) 00007 Contributed by Ching-Peng Lin (cplin@sunplus.com) 00008 00009 This file is part of GDB. 00010 00011 This program is free software; you can redistribute it and/or modify 00012 it under the terms of the GNU General Public License as published by 00013 the Free Software Foundation; either version 3 of the License, or 00014 (at your option) any later version. 00015 00016 This program is distributed in the hope that it will be useful, 00017 but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 GNU General Public License for more details. 00020 00021 You should have received a copy of the GNU General Public License 00022 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00023 00024 #include "defs.h" 00025 #include "gdb_assert.h" 00026 #include "inferior.h" 00027 #include "symtab.h" 00028 #include "objfiles.h" 00029 #include "gdbcore.h" 00030 #include "target.h" 00031 #include "arch-utils.h" 00032 #include "regcache.h" 00033 #include "regset.h" 00034 #include "dis-asm.h" 00035 #include "frame-unwind.h" 00036 #include "frame-base.h" 00037 #include "trad-frame.h" 00038 #include "dwarf2-frame.h" 00039 #include "score-tdep.h" 00040 00041 #define G_FLD(_i,_ms,_ls) \ 00042 ((unsigned)((_i) << (31 - (_ms))) >> (31 - (_ms) + (_ls))) 00043 00044 typedef struct{ 00045 unsigned long long v; 00046 unsigned long long raw; 00047 unsigned int len; 00048 }inst_t; 00049 00050 struct score_frame_cache 00051 { 00052 CORE_ADDR base; 00053 CORE_ADDR fp; 00054 struct trad_frame_saved_reg *saved_regs; 00055 }; 00056 00057 static int target_mach = bfd_mach_score7; 00058 00059 static struct type * 00060 score_register_type (struct gdbarch *gdbarch, int regnum) 00061 { 00062 gdb_assert (regnum >= 0 00063 && regnum < ((target_mach == bfd_mach_score7) 00064 ? SCORE7_NUM_REGS : SCORE3_NUM_REGS)); 00065 return builtin_type (gdbarch)->builtin_uint32; 00066 } 00067 00068 static CORE_ADDR 00069 score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame) 00070 { 00071 return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM); 00072 } 00073 00074 static CORE_ADDR 00075 score_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) 00076 { 00077 return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM); 00078 } 00079 00080 static const char * 00081 score7_register_name (struct gdbarch *gdbarch, int regnum) 00082 { 00083 const char *score_register_names[] = { 00084 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 00085 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 00086 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 00087 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 00088 00089 "PSR", "COND", "ECR", "EXCPVEC", "CCR", 00090 "EPC", "EMA", "TLBLOCK", "TLBPT", "PEADDR", 00091 "TLBRPT", "PEVN", "PECTX", "LIMPFN", "LDMPFN", 00092 "PREV", "DREG", "PC", "DSAVE", "COUNTER", 00093 "LDCR", "STCR", "CEH", "CEL", 00094 }; 00095 00096 gdb_assert (regnum >= 0 && regnum < SCORE7_NUM_REGS); 00097 return score_register_names[regnum]; 00098 } 00099 00100 static const char * 00101 score3_register_name (struct gdbarch *gdbarch, int regnum) 00102 { 00103 const char *score_register_names[] = { 00104 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 00105 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 00106 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 00107 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 00108 00109 "PSR", "COND", "ECR", "EXCPVEC", "CCR", 00110 "EPC", "EMA", "PREV", "DREG", "DSAVE", 00111 "COUNTER", "LDCR", "STCR", "CEH", "CEL", 00112 "", "", "PC", 00113 }; 00114 00115 gdb_assert (regnum >= 0 && regnum < SCORE3_NUM_REGS); 00116 return score_register_names[regnum]; 00117 } 00118 00119 #if WITH_SIM 00120 static int 00121 score_register_sim_regno (struct gdbarch *gdbarch, int regnum) 00122 { 00123 gdb_assert (regnum >= 0 00124 && regnum < ((target_mach == bfd_mach_score7) 00125 ? SCORE7_NUM_REGS : SCORE3_NUM_REGS)); 00126 return regnum; 00127 } 00128 #endif 00129 00130 static int 00131 score_print_insn (bfd_vma memaddr, struct disassemble_info *info) 00132 { 00133 if (info->endian == BFD_ENDIAN_BIG) 00134 return print_insn_big_score (memaddr, info); 00135 else 00136 return print_insn_little_score (memaddr, info); 00137 } 00138 00139 static inst_t * 00140 score7_fetch_inst (struct gdbarch *gdbarch, CORE_ADDR addr, gdb_byte *memblock) 00141 { 00142 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 00143 static inst_t inst = { 0, 0, 0 }; 00144 gdb_byte buf[SCORE_INSTLEN] = { 0 }; 00145 int big; 00146 int ret; 00147 00148 if (target_has_execution && memblock != NULL) 00149 { 00150 /* Fetch instruction from local MEMBLOCK. */ 00151 memcpy (buf, memblock, SCORE_INSTLEN); 00152 } 00153 else 00154 { 00155 /* Fetch instruction from target. */ 00156 ret = target_read_memory (addr & ~0x3, buf, SCORE_INSTLEN); 00157 if (ret) 00158 { 00159 error (_("Error: target_read_memory in file:%s, line:%d!"), 00160 __FILE__, __LINE__); 00161 return 0; 00162 } 00163 } 00164 00165 inst.raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order); 00166 inst.len = (inst.raw & 0x80008000) ? 4 : 2; 00167 inst.v = ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF); 00168 big = (byte_order == BFD_ENDIAN_BIG); 00169 if (inst.len == 2) 00170 { 00171 if (big ^ ((addr & 0x2) == 2)) 00172 inst.v = G_FLD (inst.v, 29, 15); 00173 else 00174 inst.v = G_FLD (inst.v, 14, 0); 00175 } 00176 return &inst; 00177 } 00178 00179 static inst_t * 00180 score3_adjust_pc_and_fetch_inst (CORE_ADDR *pcptr, int *lenptr, 00181 enum bfd_endian byte_order) 00182 { 00183 static inst_t inst = { 0, 0, 0 }; 00184 00185 struct breakplace 00186 { 00187 int break_offset; 00188 int inst_len; 00189 }; 00190 /* raw table 1 (column 2, 3, 4) 00191 * 0 1 0 * # 2 00192 * 0 1 1 0 # 3 00193 0 1 1 0 * # 6 00194 table 2 (column 1, 2, 3) 00195 * 0 0 * * # 0, 4 00196 0 1 0 * * # 2 00197 1 1 0 * * # 6 00198 */ 00199 00200 static const struct breakplace bk_table[16] = 00201 { 00202 /* table 1 */ 00203 {0, 0}, 00204 {0, 0}, 00205 {0, 4}, 00206 {0, 6}, 00207 {0, 0}, 00208 {0, 0}, 00209 {-2, 6}, 00210 {0, 0}, 00211 /* table 2 */ 00212 {0, 2}, 00213 {0, 0}, 00214 {-2, 4}, 00215 {0, 0}, 00216 {0, 2}, 00217 {0, 0}, 00218 {-4, 6}, 00219 {0, 0} 00220 }; 00221 00222 #define EXTRACT_LEN 2 00223 CORE_ADDR adjust_pc = *pcptr & ~0x1; 00224 gdb_byte buf[5][EXTRACT_LEN] = 00225 { 00226 {'\0', '\0'}, 00227 {'\0', '\0'}, 00228 {'\0', '\0'}, 00229 {'\0', '\0'}, 00230 {'\0', '\0'} 00231 }; 00232 int ret; 00233 unsigned int raw; 00234 unsigned int cbits = 0; 00235 int bk_index; 00236 int i, count; 00237 00238 inst.v = 0; 00239 inst.raw = 0; 00240 inst.len = 0; 00241 00242 adjust_pc -= 4; 00243 for (i = 0; i < 5; i++) 00244 { 00245 ret = target_read_memory (adjust_pc + 2 * i, buf[i], EXTRACT_LEN); 00246 if (ret != 0) 00247 { 00248 buf[i][0] = '\0'; 00249 buf[i][1] = '\0'; 00250 if (i == 2) 00251 error (_("Error: target_read_memory in file:%s, line:%d!"), 00252 __FILE__, __LINE__); 00253 } 00254 00255 raw = extract_unsigned_integer (buf[i], EXTRACT_LEN, byte_order); 00256 cbits = (cbits << 1) | (raw >> 15); 00257 } 00258 adjust_pc += 4; 00259 00260 if (cbits & 0x4) 00261 { 00262 /* table 1 */ 00263 cbits = (cbits >> 1) & 0x7; 00264 bk_index = cbits; 00265 } 00266 else 00267 { 00268 /* table 2 */ 00269 cbits = (cbits >> 2) & 0x7; 00270 bk_index = cbits + 8; 00271 } 00272 00273 gdb_assert (!((bk_table[bk_index].break_offset == 0) 00274 && (bk_table[bk_index].inst_len == 0))); 00275 00276 inst.len = bk_table[bk_index].inst_len; 00277 00278 i = (bk_table[bk_index].break_offset + 4) / 2; 00279 count = inst.len / 2; 00280 for (; count > 0; i++, count--) 00281 { 00282 inst.raw = (inst.raw << 16) 00283 | extract_unsigned_integer (buf[i], EXTRACT_LEN, byte_order); 00284 } 00285 00286 switch (inst.len) 00287 { 00288 case 2: 00289 inst.v = inst.raw & 0x7FFF; 00290 break; 00291 case 4: 00292 inst.v = ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF); 00293 break; 00294 case 6: 00295 inst.v = ((inst.raw >> 32 & 0x7FFF) << 30) 00296 | ((inst.raw >> 16 & 0x7FFF) << 15) | (inst.raw & 0x7FFF); 00297 break; 00298 } 00299 00300 if (pcptr) 00301 *pcptr = adjust_pc + bk_table[bk_index].break_offset; 00302 if (lenptr) 00303 *lenptr = bk_table[bk_index].inst_len; 00304 00305 #undef EXTRACT_LEN 00306 00307 return &inst; 00308 } 00309 00310 static const gdb_byte * 00311 score7_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, 00312 int *lenptr) 00313 { 00314 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 00315 gdb_byte buf[SCORE_INSTLEN] = { 0 }; 00316 int ret; 00317 unsigned int raw; 00318 00319 if ((ret = target_read_memory (*pcptr & ~0x3, buf, SCORE_INSTLEN)) != 0) 00320 { 00321 error (_("Error: target_read_memory in file:%s, line:%d!"), 00322 __FILE__, __LINE__); 00323 } 00324 raw = extract_unsigned_integer (buf, SCORE_INSTLEN, byte_order); 00325 00326 if (byte_order == BFD_ENDIAN_BIG) 00327 { 00328 if (!(raw & 0x80008000)) 00329 { 00330 /* 16bits instruction. */ 00331 static gdb_byte big_breakpoint16[] = { 0x60, 0x02 }; 00332 *pcptr &= ~0x1; 00333 *lenptr = sizeof (big_breakpoint16); 00334 return big_breakpoint16; 00335 } 00336 else 00337 { 00338 /* 32bits instruction. */ 00339 static gdb_byte big_breakpoint32[] = { 0x80, 0x00, 0x80, 0x06 }; 00340 *pcptr &= ~0x3; 00341 *lenptr = sizeof (big_breakpoint32); 00342 return big_breakpoint32; 00343 } 00344 } 00345 else 00346 { 00347 if (!(raw & 0x80008000)) 00348 { 00349 /* 16bits instruction. */ 00350 static gdb_byte little_breakpoint16[] = { 0x02, 0x60 }; 00351 *pcptr &= ~0x1; 00352 *lenptr = sizeof (little_breakpoint16); 00353 return little_breakpoint16; 00354 } 00355 else 00356 { 00357 /* 32bits instruction. */ 00358 static gdb_byte little_breakpoint32[] = { 0x06, 0x80, 0x00, 0x80 }; 00359 *pcptr &= ~0x3; 00360 *lenptr = sizeof (little_breakpoint32); 00361 return little_breakpoint32; 00362 } 00363 } 00364 } 00365 00366 static const gdb_byte * 00367 score3_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, 00368 int *lenptr) 00369 { 00370 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 00371 CORE_ADDR adjust_pc = *pcptr; 00372 int len; 00373 static gdb_byte score_break_insns[6][6] = { 00374 /* The following three instructions are big endian. */ 00375 { 0x00, 0x20 }, 00376 { 0x80, 0x00, 0x00, 0x06 }, 00377 { 0x80, 0x00, 0x80, 0x00, 0x00, 0x00 }, 00378 /* The following three instructions are little endian. */ 00379 { 0x20, 0x00 }, 00380 { 0x00, 0x80, 0x06, 0x00 }, 00381 { 0x00, 0x80, 0x00, 0x80, 0x00, 0x00 }}; 00382 00383 gdb_byte *p = NULL; 00384 int index = 0; 00385 00386 score3_adjust_pc_and_fetch_inst (&adjust_pc, &len, byte_order); 00387 00388 index = ((byte_order == BFD_ENDIAN_BIG) ? 0 : 3) + (len / 2 - 1); 00389 p = score_break_insns[index]; 00390 00391 *pcptr = adjust_pc; 00392 *lenptr = len; 00393 00394 return p; 00395 } 00396 00397 static CORE_ADDR 00398 score_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr) 00399 { 00400 CORE_ADDR adjust_pc = bpaddr; 00401 00402 if (target_mach == bfd_mach_score3) 00403 score3_adjust_pc_and_fetch_inst (&adjust_pc, NULL, 00404 gdbarch_byte_order (gdbarch)); 00405 else 00406 adjust_pc = align_down (adjust_pc, 2); 00407 00408 return adjust_pc; 00409 } 00410 00411 static CORE_ADDR 00412 score_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr) 00413 { 00414 return align_down (addr, 16); 00415 } 00416 00417 static void 00418 score_xfer_register (struct regcache *regcache, int regnum, int length, 00419 enum bfd_endian endian, gdb_byte *readbuf, 00420 const gdb_byte *writebuf, int buf_offset) 00421 { 00422 int reg_offset = 0; 00423 gdb_assert (regnum >= 0 00424 && regnum < ((target_mach == bfd_mach_score7) 00425 ? SCORE7_NUM_REGS : SCORE3_NUM_REGS)); 00426 00427 switch (endian) 00428 { 00429 case BFD_ENDIAN_BIG: 00430 reg_offset = SCORE_REGSIZE - length; 00431 break; 00432 case BFD_ENDIAN_LITTLE: 00433 reg_offset = 0; 00434 break; 00435 case BFD_ENDIAN_UNKNOWN: 00436 reg_offset = 0; 00437 break; 00438 default: 00439 error (_("Error: score_xfer_register in file:%s, line:%d!"), 00440 __FILE__, __LINE__); 00441 } 00442 00443 if (readbuf != NULL) 00444 regcache_cooked_read_part (regcache, regnum, reg_offset, length, 00445 readbuf + buf_offset); 00446 if (writebuf != NULL) 00447 regcache_cooked_write_part (regcache, regnum, reg_offset, length, 00448 writebuf + buf_offset); 00449 } 00450 00451 static enum return_value_convention 00452 score_return_value (struct gdbarch *gdbarch, struct value *function, 00453 struct type *type, struct regcache *regcache, 00454 gdb_byte * readbuf, const gdb_byte * writebuf) 00455 { 00456 if (TYPE_CODE (type) == TYPE_CODE_STRUCT 00457 || TYPE_CODE (type) == TYPE_CODE_UNION 00458 || TYPE_CODE (type) == TYPE_CODE_ARRAY) 00459 return RETURN_VALUE_STRUCT_CONVENTION; 00460 else 00461 { 00462 int offset; 00463 int regnum; 00464 for (offset = 0, regnum = SCORE_A0_REGNUM; 00465 offset < TYPE_LENGTH (type); 00466 offset += SCORE_REGSIZE, regnum++) 00467 { 00468 int xfer = SCORE_REGSIZE; 00469 00470 if (offset + xfer > TYPE_LENGTH (type)) 00471 xfer = TYPE_LENGTH (type) - offset; 00472 score_xfer_register (regcache, regnum, xfer, 00473 gdbarch_byte_order(gdbarch), 00474 readbuf, writebuf, offset); 00475 } 00476 return RETURN_VALUE_REGISTER_CONVENTION; 00477 } 00478 } 00479 00480 static struct frame_id 00481 score_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame) 00482 { 00483 return frame_id_build (get_frame_register_unsigned (this_frame, 00484 SCORE_SP_REGNUM), 00485 get_frame_pc (this_frame)); 00486 } 00487 00488 static int 00489 score_type_needs_double_align (struct type *type) 00490 { 00491 enum type_code typecode = TYPE_CODE (type); 00492 00493 if ((typecode == TYPE_CODE_INT && TYPE_LENGTH (type) == 8) 00494 || (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8)) 00495 return 1; 00496 else if (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION) 00497 { 00498 int i, n; 00499 00500 n = TYPE_NFIELDS (type); 00501 for (i = 0; i < n; i++) 00502 if (score_type_needs_double_align (TYPE_FIELD_TYPE (type, i))) 00503 return 1; 00504 return 0; 00505 } 00506 return 0; 00507 } 00508 00509 static CORE_ADDR 00510 score_push_dummy_call (struct gdbarch *gdbarch, struct value *function, 00511 struct regcache *regcache, CORE_ADDR bp_addr, 00512 int nargs, struct value **args, CORE_ADDR sp, 00513 int struct_return, CORE_ADDR struct_addr) 00514 { 00515 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 00516 int argnum; 00517 int argreg; 00518 int arglen = 0; 00519 CORE_ADDR stack_offset = 0; 00520 CORE_ADDR addr = 0; 00521 00522 /* Step 1, Save RA. */ 00523 regcache_cooked_write_unsigned (regcache, SCORE_RA_REGNUM, bp_addr); 00524 00525 /* Step 2, Make space on the stack for the args. */ 00526 struct_addr = align_down (struct_addr, 16); 00527 sp = align_down (sp, 16); 00528 for (argnum = 0; argnum < nargs; argnum++) 00529 arglen += align_up (TYPE_LENGTH (value_type (args[argnum])), 00530 SCORE_REGSIZE); 00531 sp -= align_up (arglen, 16); 00532 00533 argreg = SCORE_BEGIN_ARG_REGNUM; 00534 00535 /* Step 3, Check if struct return then save the struct address to 00536 r4 and increase the stack_offset by 4. */ 00537 if (struct_return) 00538 { 00539 regcache_cooked_write_unsigned (regcache, argreg++, struct_addr); 00540 stack_offset += SCORE_REGSIZE; 00541 } 00542 00543 /* Step 4, Load arguments: 00544 If arg length is too long (> 4 bytes), then split the arg and 00545 save every parts. */ 00546 for (argnum = 0; argnum < nargs; argnum++) 00547 { 00548 struct value *arg = args[argnum]; 00549 struct type *arg_type = check_typedef (value_type (arg)); 00550 enum type_code typecode = TYPE_CODE (arg_type); 00551 const gdb_byte *val = value_contents (arg); 00552 int downward_offset = 0; 00553 int odd_sized_struct_p; 00554 int arg_last_part_p = 0; 00555 00556 arglen = TYPE_LENGTH (arg_type); 00557 odd_sized_struct_p = (arglen > SCORE_REGSIZE 00558 && arglen % SCORE_REGSIZE != 0); 00559 00560 /* If a arg should be aligned to 8 bytes (long long or double), 00561 the value should be put to even register numbers. */ 00562 if (score_type_needs_double_align (arg_type)) 00563 { 00564 if (argreg & 1) 00565 argreg++; 00566 } 00567 00568 /* If sizeof a block < SCORE_REGSIZE, then Score GCC will chose 00569 the default "downward"/"upward" method: 00570 00571 Example: 00572 00573 struct struc 00574 { 00575 char a; char b; char c; 00576 } s = {'a', 'b', 'c'}; 00577 00578 Big endian: s = {X, 'a', 'b', 'c'} 00579 Little endian: s = {'a', 'b', 'c', X} 00580 00581 Where X is a hole. */ 00582 00583 if (gdbarch_byte_order(gdbarch) == BFD_ENDIAN_BIG 00584 && (typecode == TYPE_CODE_STRUCT 00585 || typecode == TYPE_CODE_UNION) 00586 && argreg > SCORE_LAST_ARG_REGNUM 00587 && arglen < SCORE_REGSIZE) 00588 downward_offset += (SCORE_REGSIZE - arglen); 00589 00590 while (arglen > 0) 00591 { 00592 int partial_len = arglen < SCORE_REGSIZE ? arglen : SCORE_REGSIZE; 00593 ULONGEST regval = extract_unsigned_integer (val, partial_len, 00594 byte_order); 00595 00596 /* The last part of a arg should shift left when 00597 gdbarch_byte_order is BFD_ENDIAN_BIG. */ 00598 if (byte_order == BFD_ENDIAN_BIG 00599 && arg_last_part_p == 1 00600 && (typecode == TYPE_CODE_STRUCT 00601 || typecode == TYPE_CODE_UNION)) 00602 regval <<= ((SCORE_REGSIZE - partial_len) * TARGET_CHAR_BIT); 00603 00604 /* Always increase the stack_offset and save args to stack. */ 00605 addr = sp + stack_offset + downward_offset; 00606 write_memory (addr, val, partial_len); 00607 00608 if (argreg <= SCORE_LAST_ARG_REGNUM) 00609 { 00610 regcache_cooked_write_unsigned (regcache, argreg++, regval); 00611 if (arglen > SCORE_REGSIZE && arglen < SCORE_REGSIZE * 2) 00612 arg_last_part_p = 1; 00613 } 00614 00615 val += partial_len; 00616 arglen -= partial_len; 00617 stack_offset += align_up (partial_len, SCORE_REGSIZE); 00618 } 00619 } 00620 00621 /* Step 5, Save SP. */ 00622 regcache_cooked_write_unsigned (regcache, SCORE_SP_REGNUM, sp); 00623 00624 return sp; 00625 } 00626 00627 static CORE_ADDR 00628 score7_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) 00629 { 00630 CORE_ADDR cpc = pc; 00631 int iscan = 32, stack_sub = 0; 00632 while (iscan-- > 0) 00633 { 00634 inst_t *inst = score7_fetch_inst (gdbarch, cpc, NULL); 00635 if (!inst) 00636 break; 00637 if ((inst->len == 4) && !stack_sub 00638 && (G_FLD (inst->v, 29, 25) == 0x1 00639 && G_FLD (inst->v, 24, 20) == 0x0)) 00640 { 00641 /* addi r0, offset */ 00642 stack_sub = cpc + SCORE_INSTLEN; 00643 pc = cpc + SCORE_INSTLEN; 00644 } 00645 else if ((inst->len == 4) 00646 && (G_FLD (inst->v, 29, 25) == 0x0) 00647 && (G_FLD (inst->v, 24, 20) == 0x2) 00648 && (G_FLD (inst->v, 19, 15) == 0x0) 00649 && (G_FLD (inst->v, 14, 10) == 0xF) 00650 && (G_FLD (inst->v, 9, 0) == 0x56)) 00651 { 00652 /* mv r2, r0 */ 00653 pc = cpc + SCORE_INSTLEN; 00654 break; 00655 } 00656 else if ((inst->len == 2) 00657 && (G_FLD (inst->v, 14, 12) == 0x0) 00658 && (G_FLD (inst->v, 11, 8) == 0x2) 00659 && (G_FLD (inst->v, 7, 4) == 0x0) 00660 && (G_FLD (inst->v, 3, 0) == 0x3)) 00661 { 00662 /* mv! r2, r0 */ 00663 pc = cpc + SCORE16_INSTLEN; 00664 break; 00665 } 00666 else if ((inst->len == 2) 00667 && ((G_FLD (inst->v, 14, 12) == 3) /* j15 form */ 00668 || (G_FLD (inst->v, 14, 12) == 4) /* b15 form */ 00669 || (G_FLD (inst->v, 14, 12) == 0x0 00670 && G_FLD (inst->v, 3, 0) == 0x4))) /* br! */ 00671 break; 00672 else if ((inst->len == 4) 00673 && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */ 00674 || (G_FLD (inst->v, 29, 25) == 4) /* b32 form */ 00675 || (G_FLD (inst->v, 29, 25) == 0x0 00676 && G_FLD (inst->v, 6, 1) == 0x4))) /* br */ 00677 break; 00678 00679 cpc += (inst->len == 2) ? SCORE16_INSTLEN : SCORE_INSTLEN; 00680 } 00681 return pc; 00682 } 00683 00684 static CORE_ADDR 00685 score3_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) 00686 { 00687 CORE_ADDR cpc = pc; 00688 int iscan = 32, stack_sub = 0; 00689 while (iscan-- > 0) 00690 { 00691 inst_t *inst 00692 = score3_adjust_pc_and_fetch_inst (&cpc, NULL, 00693 gdbarch_byte_order (gdbarch)); 00694 00695 if (!inst) 00696 break; 00697 if (inst->len == 4 && !stack_sub 00698 && (G_FLD (inst->v, 29, 25) == 0x1) 00699 && (G_FLD (inst->v, 19, 17) == 0x0) 00700 && (G_FLD (inst->v, 24, 20) == 0x0)) 00701 { 00702 /* addi r0, offset */ 00703 stack_sub = cpc + inst->len; 00704 pc = cpc + inst->len; 00705 } 00706 else if (inst->len == 4 00707 && (G_FLD (inst->v, 29, 25) == 0x0) 00708 && (G_FLD (inst->v, 24, 20) == 0x2) 00709 && (G_FLD (inst->v, 19, 15) == 0x0) 00710 && (G_FLD (inst->v, 14, 10) == 0xF) 00711 && (G_FLD (inst->v, 9, 0) == 0x56)) 00712 { 00713 /* mv r2, r0 */ 00714 pc = cpc + inst->len; 00715 break; 00716 } 00717 else if ((inst->len == 2) 00718 && (G_FLD (inst->v, 14, 10) == 0x10) 00719 && (G_FLD (inst->v, 9, 5) == 0x2) 00720 && (G_FLD (inst->v, 4, 0) == 0x0)) 00721 { 00722 /* mv! r2, r0 */ 00723 pc = cpc + inst->len; 00724 break; 00725 } 00726 else if (inst->len == 2 00727 && ((G_FLD (inst->v, 14, 12) == 3) /* b15 form */ 00728 || (G_FLD (inst->v, 14, 12) == 0x0 00729 && G_FLD (inst->v, 11, 5) == 0x4))) /* br! */ 00730 break; 00731 else if (inst->len == 4 00732 && ((G_FLD (inst->v, 29, 25) == 2) /* j32 form */ 00733 || (G_FLD (inst->v, 29, 25) == 4))) /* b32 form */ 00734 break; 00735 00736 cpc += inst->len; 00737 } 00738 return pc; 00739 } 00740 00741 static int 00742 score7_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc) 00743 { 00744 inst_t *inst = score7_fetch_inst (gdbarch, cur_pc, NULL); 00745 00746 if (inst->v == 0x23) 00747 return 1; /* mv! r0, r2 */ 00748 else if (G_FLD (inst->v, 14, 12) == 0x2 00749 && G_FLD (inst->v, 3, 0) == 0xa) 00750 return 1; /* pop! */ 00751 else if (G_FLD (inst->v, 14, 12) == 0x0 00752 && G_FLD (inst->v, 7, 0) == 0x34) 00753 return 1; /* br! r3 */ 00754 else if (G_FLD (inst->v, 29, 15) == 0x2 00755 && G_FLD (inst->v, 6, 1) == 0x2b) 00756 return 1; /* mv r0, r2 */ 00757 else if (G_FLD (inst->v, 29, 25) == 0x0 00758 && G_FLD (inst->v, 6, 1) == 0x4 00759 && G_FLD (inst->v, 19, 15) == 0x3) 00760 return 1; /* br r3 */ 00761 else 00762 return 0; 00763 } 00764 00765 static int 00766 score3_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR cur_pc) 00767 { 00768 CORE_ADDR pc = cur_pc; 00769 inst_t *inst 00770 = score3_adjust_pc_and_fetch_inst (&pc, NULL, 00771 gdbarch_byte_order (gdbarch)); 00772 00773 if (inst->len == 2 00774 && (G_FLD (inst->v, 14, 10) == 0x10) 00775 && (G_FLD (inst->v, 9, 5) == 0x0) 00776 && (G_FLD (inst->v, 4, 0) == 0x2)) 00777 return 1; /* mv! r0, r2 */ 00778 else if (inst->len == 4 00779 && (G_FLD (inst->v, 29, 25) == 0x0) 00780 && (G_FLD (inst->v, 24, 20) == 0x2) 00781 && (G_FLD (inst->v, 19, 15) == 0x0) 00782 && (G_FLD (inst->v, 14, 10) == 0xF) 00783 && (G_FLD (inst->v, 9, 0) == 0x56)) 00784 return 1; /* mv r0, r2 */ 00785 else if (inst->len == 2 00786 && (G_FLD (inst->v, 14, 12) == 0x0) 00787 && (G_FLD (inst->v, 11, 5) == 0x2)) 00788 return 1; /* pop! */ 00789 else if (inst->len == 2 00790 && (G_FLD (inst->v, 14, 12) == 0x0) 00791 && (G_FLD (inst->v, 11, 7) == 0x0) 00792 && (G_FLD (inst->v, 6, 5) == 0x2)) 00793 return 1; /* rpop! */ 00794 else if (inst->len == 2 00795 && (G_FLD (inst->v, 14, 12) == 0x0) 00796 && (G_FLD (inst->v, 11, 5) == 0x4) 00797 && (G_FLD (inst->v, 4, 0) == 0x3)) 00798 return 1; /* br! r3 */ 00799 else if (inst->len == 4 00800 && (G_FLD (inst->v, 29, 25) == 0x0) 00801 && (G_FLD (inst->v, 24, 20) == 0x0) 00802 && (G_FLD (inst->v, 19, 15) == 0x3) 00803 && (G_FLD (inst->v, 14, 10) == 0xF) 00804 && (G_FLD (inst->v, 9, 0) == 0x8)) 00805 return 1; /* br r3 */ 00806 else 00807 return 0; 00808 } 00809 00810 static gdb_byte * 00811 score7_malloc_and_get_memblock (CORE_ADDR addr, CORE_ADDR size) 00812 { 00813 int ret; 00814 gdb_byte *memblock = NULL; 00815 00816 if (size < 0) 00817 { 00818 error (_("Error: malloc size < 0 in file:%s, line:%d!"), 00819 __FILE__, __LINE__); 00820 return NULL; 00821 } 00822 else if (size == 0) 00823 return NULL; 00824 00825 memblock = xmalloc (size); 00826 memset (memblock, 0, size); 00827 ret = target_read_memory (addr & ~0x3, memblock, size); 00828 if (ret) 00829 { 00830 error (_("Error: target_read_memory in file:%s, line:%d!"), 00831 __FILE__, __LINE__); 00832 return NULL; 00833 } 00834 return memblock; 00835 } 00836 00837 static void 00838 score7_free_memblock (gdb_byte *memblock) 00839 { 00840 xfree (memblock); 00841 } 00842 00843 static void 00844 score7_adjust_memblock_ptr (gdb_byte **memblock, CORE_ADDR prev_pc, 00845 CORE_ADDR cur_pc) 00846 { 00847 if (prev_pc == -1) 00848 { 00849 /* First time call this function, do nothing. */ 00850 } 00851 else if (cur_pc - prev_pc == 2 && (cur_pc & 0x3) == 0) 00852 { 00853 /* First 16-bit instruction, then 32-bit instruction. */ 00854 *memblock += SCORE_INSTLEN; 00855 } 00856 else if (cur_pc - prev_pc == 4) 00857 { 00858 /* Is 32-bit instruction, increase MEMBLOCK by 4. */ 00859 *memblock += SCORE_INSTLEN; 00860 } 00861 } 00862 00863 static void 00864 score7_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc, 00865 struct frame_info *this_frame, 00866 struct score_frame_cache *this_cache) 00867 { 00868 struct gdbarch *gdbarch = get_frame_arch (this_frame); 00869 CORE_ADDR sp; 00870 CORE_ADDR fp; 00871 CORE_ADDR cur_pc = startaddr; 00872 00873 int sp_offset = 0; 00874 int ra_offset = 0; 00875 int fp_offset = 0; 00876 int ra_offset_p = 0; 00877 int fp_offset_p = 0; 00878 int inst_len = 0; 00879 00880 gdb_byte *memblock = NULL; 00881 gdb_byte *memblock_ptr = NULL; 00882 CORE_ADDR prev_pc = -1; 00883 00884 /* Allocate MEMBLOCK if PC - STARTADDR > 0. */ 00885 memblock_ptr = memblock = 00886 score7_malloc_and_get_memblock (startaddr, pc - startaddr); 00887 00888 sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM); 00889 fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM); 00890 00891 for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len) 00892 { 00893 inst_t *inst = NULL; 00894 if (memblock != NULL) 00895 { 00896 /* Reading memory block from target succefully and got all 00897 the instructions(from STARTADDR to PC) needed. */ 00898 score7_adjust_memblock_ptr (&memblock, prev_pc, cur_pc); 00899 inst = score7_fetch_inst (gdbarch, cur_pc, memblock); 00900 } 00901 else 00902 { 00903 /* Otherwise, we fetch 4 bytes from target, and GDB also 00904 work correctly. */ 00905 inst = score7_fetch_inst (gdbarch, cur_pc, NULL); 00906 } 00907 00908 /* FIXME: make a full-power prologue analyzer. */ 00909 if (inst->len == 2) 00910 { 00911 inst_len = SCORE16_INSTLEN; 00912 00913 if (G_FLD (inst->v, 14, 12) == 0x2 00914 && G_FLD (inst->v, 3, 0) == 0xe) 00915 { 00916 /* push! */ 00917 sp_offset += 4; 00918 00919 if (G_FLD (inst->v, 11, 7) == 0x6 00920 && ra_offset_p == 0) 00921 { 00922 /* push! r3, [r0] */ 00923 ra_offset = sp_offset; 00924 ra_offset_p = 1; 00925 } 00926 else if (G_FLD (inst->v, 11, 7) == 0x4 00927 && fp_offset_p == 0) 00928 { 00929 /* push! r2, [r0] */ 00930 fp_offset = sp_offset; 00931 fp_offset_p = 1; 00932 } 00933 } 00934 else if (G_FLD (inst->v, 14, 12) == 0x2 00935 && G_FLD (inst->v, 3, 0) == 0xa) 00936 { 00937 /* pop! */ 00938 sp_offset -= 4; 00939 } 00940 else if (G_FLD (inst->v, 14, 7) == 0xc1 00941 && G_FLD (inst->v, 2, 0) == 0x0) 00942 { 00943 /* subei! r0, n */ 00944 sp_offset += (int) pow (2, G_FLD (inst->v, 6, 3)); 00945 } 00946 else if (G_FLD (inst->v, 14, 7) == 0xc0 00947 && G_FLD (inst->v, 2, 0) == 0x0) 00948 { 00949 /* addei! r0, n */ 00950 sp_offset -= (int) pow (2, G_FLD (inst->v, 6, 3)); 00951 } 00952 } 00953 else 00954 { 00955 inst_len = SCORE_INSTLEN; 00956 00957 if (G_FLD(inst->v, 29, 25) == 0x3 00958 && G_FLD(inst->v, 2, 0) == 0x4 00959 && G_FLD(inst->v, 19, 15) == 0) 00960 { 00961 /* sw rD, [r0, offset]+ */ 00962 sp_offset += SCORE_INSTLEN; 00963 00964 if (G_FLD(inst->v, 24, 20) == 0x3) 00965 { 00966 /* rD = r3 */ 00967 if (ra_offset_p == 0) 00968 { 00969 ra_offset = sp_offset; 00970 ra_offset_p = 1; 00971 } 00972 } 00973 else if (G_FLD(inst->v, 24, 20) == 0x2) 00974 { 00975 /* rD = r2 */ 00976 if (fp_offset_p == 0) 00977 { 00978 fp_offset = sp_offset; 00979 fp_offset_p = 1; 00980 } 00981 } 00982 } 00983 else if (G_FLD(inst->v, 29, 25) == 0x14 00984 && G_FLD(inst->v, 19,15) == 0) 00985 { 00986 /* sw rD, [r0, offset] */ 00987 if (G_FLD(inst->v, 24, 20) == 0x3) 00988 { 00989 /* rD = r3 */ 00990 ra_offset = sp_offset - G_FLD(inst->v, 14, 0); 00991 ra_offset_p = 1; 00992 } 00993 else if (G_FLD(inst->v, 24, 20) == 0x2) 00994 { 00995 /* rD = r2 */ 00996 fp_offset = sp_offset - G_FLD(inst->v, 14, 0); 00997 fp_offset_p = 1; 00998 } 00999 } 01000 else if (G_FLD (inst->v, 29, 15) == 0x1c60 01001 && G_FLD (inst->v, 2, 0) == 0x0) 01002 { 01003 /* lw r3, [r0]+, 4 */ 01004 sp_offset -= SCORE_INSTLEN; 01005 ra_offset_p = 1; 01006 } 01007 else if (G_FLD (inst->v, 29, 15) == 0x1c40 01008 && G_FLD (inst->v, 2, 0) == 0x0) 01009 { 01010 /* lw r2, [r0]+, 4 */ 01011 sp_offset -= SCORE_INSTLEN; 01012 fp_offset_p = 1; 01013 } 01014 01015 else if (G_FLD (inst->v, 29, 17) == 0x100 01016 && G_FLD (inst->v, 0, 0) == 0x0) 01017 { 01018 /* addi r0, -offset */ 01019 sp_offset += 65536 - G_FLD (inst->v, 16, 1); 01020 } 01021 else if (G_FLD (inst->v, 29, 17) == 0x110 01022 && G_FLD (inst->v, 0, 0) == 0x0) 01023 { 01024 /* addi r2, offset */ 01025 if (pc - cur_pc > 4) 01026 { 01027 unsigned int save_v = inst->v; 01028 inst_t *inst2 = 01029 score7_fetch_inst (gdbarch, cur_pc + SCORE_INSTLEN, NULL); 01030 if (inst2->v == 0x23) 01031 { 01032 /* mv! r0, r2 */ 01033 sp_offset -= G_FLD (save_v, 16, 1); 01034 } 01035 } 01036 } 01037 } 01038 } 01039 01040 /* Save RA. */ 01041 if (ra_offset_p == 1) 01042 { 01043 if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1) 01044 this_cache->saved_regs[SCORE_PC_REGNUM].addr = 01045 sp + sp_offset - ra_offset; 01046 } 01047 else 01048 { 01049 this_cache->saved_regs[SCORE_PC_REGNUM] = 01050 this_cache->saved_regs[SCORE_RA_REGNUM]; 01051 } 01052 01053 /* Save FP. */ 01054 if (fp_offset_p == 1) 01055 { 01056 if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1) 01057 this_cache->saved_regs[SCORE_FP_REGNUM].addr = 01058 sp + sp_offset - fp_offset; 01059 } 01060 01061 /* Save SP and FP. */ 01062 this_cache->base = sp + sp_offset; 01063 this_cache->fp = fp; 01064 01065 /* Don't forget to free MEMBLOCK if we allocated it. */ 01066 if (memblock_ptr != NULL) 01067 score7_free_memblock (memblock_ptr); 01068 } 01069 01070 static void 01071 score3_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc, 01072 struct frame_info *this_frame, 01073 struct score_frame_cache *this_cache) 01074 { 01075 CORE_ADDR sp; 01076 CORE_ADDR fp; 01077 CORE_ADDR cur_pc = startaddr; 01078 enum bfd_endian byte_order 01079 = gdbarch_byte_order (get_frame_arch (this_frame)); 01080 01081 int sp_offset = 0; 01082 int ra_offset = 0; 01083 int fp_offset = 0; 01084 int ra_offset_p = 0; 01085 int fp_offset_p = 0; 01086 int inst_len = 0; 01087 01088 CORE_ADDR prev_pc = -1; 01089 01090 sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM); 01091 fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM); 01092 01093 for (; cur_pc < pc; prev_pc = cur_pc, cur_pc += inst_len) 01094 { 01095 inst_t *inst = NULL; 01096 01097 inst = score3_adjust_pc_and_fetch_inst (&cur_pc, &inst_len, byte_order); 01098 01099 /* FIXME: make a full-power prologue analyzer. */ 01100 if (inst->len == 2) 01101 { 01102 if (G_FLD (inst->v, 14, 12) == 0x0 01103 && G_FLD (inst->v, 11, 7) == 0x0 01104 && G_FLD (inst->v, 6, 5) == 0x3) 01105 { 01106 /* push! */ 01107 sp_offset += 4; 01108 01109 if (G_FLD (inst->v, 4, 0) == 0x3 01110 && ra_offset_p == 0) 01111 { 01112 /* push! r3, [r0] */ 01113 ra_offset = sp_offset; 01114 ra_offset_p = 1; 01115 } 01116 else if (G_FLD (inst->v, 4, 0) == 0x2 01117 && fp_offset_p == 0) 01118 { 01119 /* push! r2, [r0] */ 01120 fp_offset = sp_offset; 01121 fp_offset_p = 1; 01122 } 01123 } 01124 else if (G_FLD (inst->v, 14, 12) == 0x6 01125 && G_FLD (inst->v, 11, 10) == 0x3) 01126 { 01127 /* rpush! */ 01128 int start_r = G_FLD (inst->v, 9, 5); 01129 int cnt = G_FLD (inst->v, 4, 0); 01130 01131 if ((ra_offset_p == 0) 01132 && (start_r <= SCORE_RA_REGNUM) 01133 && (SCORE_RA_REGNUM < start_r + cnt)) 01134 { 01135 /* rpush! contains r3 */ 01136 ra_offset_p = 1; 01137 ra_offset = sp_offset + 4 * (SCORE_RA_REGNUM - start_r) + 4; 01138 } 01139 01140 if ((fp_offset_p == 0) 01141 && (start_r <= SCORE_FP_REGNUM) 01142 && (SCORE_FP_REGNUM < start_r + cnt)) 01143 { 01144 /* rpush! contains r2 */ 01145 fp_offset_p = 1; 01146 fp_offset = sp_offset + 4 * (SCORE_FP_REGNUM - start_r) + 4; 01147 } 01148 01149 sp_offset += 4 * cnt; 01150 } 01151 else if (G_FLD (inst->v, 14, 12) == 0x0 01152 && G_FLD (inst->v, 11, 7) == 0x0 01153 && G_FLD (inst->v, 6, 5) == 0x2) 01154 { 01155 /* pop! */ 01156 sp_offset -= 4; 01157 } 01158 else if (G_FLD (inst->v, 14, 12) == 0x6 01159 && G_FLD (inst->v, 11, 10) == 0x2) 01160 { 01161 /* rpop! */ 01162 sp_offset -= 4 * G_FLD (inst->v, 4, 0); 01163 } 01164 else if (G_FLD (inst->v, 14, 12) == 0x5 01165 && G_FLD (inst->v, 11, 10) == 0x3 01166 && G_FLD (inst->v, 9, 6) == 0x0) 01167 { 01168 /* addi! r0, -offset */ 01169 int imm = G_FLD (inst->v, 5, 0); 01170 if (imm >> 5) 01171 imm = -(0x3F - imm + 1); 01172 sp_offset -= imm; 01173 } 01174 else if (G_FLD (inst->v, 14, 12) == 0x5 01175 && G_FLD (inst->v, 11, 10) == 0x3 01176 && G_FLD (inst->v, 9, 6) == 0x2) 01177 { 01178 /* addi! r2, offset */ 01179 if (pc - cur_pc >= 2) 01180 { 01181 unsigned int save_v = inst->v; 01182 inst_t *inst2; 01183 01184 cur_pc += inst->len; 01185 inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL, 01186 byte_order); 01187 01188 if (inst2->len == 2 01189 && G_FLD (inst2->v, 14, 10) == 0x10 01190 && G_FLD (inst2->v, 9, 5) == 0x0 01191 && G_FLD (inst2->v, 4, 0) == 0x2) 01192 { 01193 /* mv! r0, r2 */ 01194 int imm = G_FLD (inst->v, 5, 0); 01195 if (imm >> 5) 01196 imm = -(0x3F - imm + 1); 01197 sp_offset -= imm; 01198 } 01199 } 01200 } 01201 } 01202 else if (inst->len == 4) 01203 { 01204 if (G_FLD (inst->v, 29, 25) == 0x3 01205 && G_FLD (inst->v, 2, 0) == 0x4 01206 && G_FLD (inst->v, 24, 20) == 0x3 01207 && G_FLD (inst->v, 19, 15) == 0x0) 01208 { 01209 /* sw r3, [r0, offset]+ */ 01210 sp_offset += inst->len; 01211 if (ra_offset_p == 0) 01212 { 01213 ra_offset = sp_offset; 01214 ra_offset_p = 1; 01215 } 01216 } 01217 else if (G_FLD (inst->v, 29, 25) == 0x3 01218 && G_FLD (inst->v, 2, 0) == 0x4 01219 && G_FLD (inst->v, 24, 20) == 0x2 01220 && G_FLD (inst->v, 19, 15) == 0x0) 01221 { 01222 /* sw r2, [r0, offset]+ */ 01223 sp_offset += inst->len; 01224 if (fp_offset_p == 0) 01225 { 01226 fp_offset = sp_offset; 01227 fp_offset_p = 1; 01228 } 01229 } 01230 else if (G_FLD (inst->v, 29, 25) == 0x7 01231 && G_FLD (inst->v, 2, 0) == 0x0 01232 && G_FLD (inst->v, 24, 20) == 0x3 01233 && G_FLD (inst->v, 19, 15) == 0x0) 01234 { 01235 /* lw r3, [r0]+, 4 */ 01236 sp_offset -= inst->len; 01237 ra_offset_p = 1; 01238 } 01239 else if (G_FLD (inst->v, 29, 25) == 0x7 01240 && G_FLD (inst->v, 2, 0) == 0x0 01241 && G_FLD (inst->v, 24, 20) == 0x2 01242 && G_FLD (inst->v, 19, 15) == 0x0) 01243 { 01244 /* lw r2, [r0]+, 4 */ 01245 sp_offset -= inst->len; 01246 fp_offset_p = 1; 01247 } 01248 else if (G_FLD (inst->v, 29, 25) == 0x1 01249 && G_FLD (inst->v, 19, 17) == 0x0 01250 && G_FLD (inst->v, 24, 20) == 0x0 01251 && G_FLD (inst->v, 0, 0) == 0x0) 01252 { 01253 /* addi r0, -offset */ 01254 int imm = G_FLD (inst->v, 16, 1); 01255 if (imm >> 15) 01256 imm = -(0xFFFF - imm + 1); 01257 sp_offset -= imm; 01258 } 01259 else if (G_FLD (inst->v, 29, 25) == 0x1 01260 && G_FLD (inst->v, 19, 17) == 0x0 01261 && G_FLD (inst->v, 24, 20) == 0x2 01262 && G_FLD (inst->v, 0, 0) == 0x0) 01263 { 01264 /* addi r2, offset */ 01265 if (pc - cur_pc >= 2) 01266 { 01267 unsigned int save_v = inst->v; 01268 inst_t *inst2; 01269 01270 cur_pc += inst->len; 01271 inst2 = score3_adjust_pc_and_fetch_inst (&cur_pc, NULL, 01272 byte_order); 01273 01274 if (inst2->len == 2 01275 && G_FLD (inst2->v, 14, 10) == 0x10 01276 && G_FLD (inst2->v, 9, 5) == 0x0 01277 && G_FLD (inst2->v, 4, 0) == 0x2) 01278 { 01279 /* mv! r0, r2 */ 01280 int imm = G_FLD (inst->v, 16, 1); 01281 if (imm >> 15) 01282 imm = -(0xFFFF - imm + 1); 01283 sp_offset -= imm; 01284 } 01285 } 01286 } 01287 } 01288 } 01289 01290 /* Save RA. */ 01291 if (ra_offset_p == 1) 01292 { 01293 if (this_cache->saved_regs[SCORE_PC_REGNUM].addr == -1) 01294 this_cache->saved_regs[SCORE_PC_REGNUM].addr = 01295 sp + sp_offset - ra_offset; 01296 } 01297 else 01298 { 01299 this_cache->saved_regs[SCORE_PC_REGNUM] = 01300 this_cache->saved_regs[SCORE_RA_REGNUM]; 01301 } 01302 01303 /* Save FP. */ 01304 if (fp_offset_p == 1) 01305 { 01306 if (this_cache->saved_regs[SCORE_FP_REGNUM].addr == -1) 01307 this_cache->saved_regs[SCORE_FP_REGNUM].addr = 01308 sp + sp_offset - fp_offset; 01309 } 01310 01311 /* Save SP and FP. */ 01312 this_cache->base = sp + sp_offset; 01313 this_cache->fp = fp; 01314 } 01315 01316 static struct score_frame_cache * 01317 score_make_prologue_cache (struct frame_info *this_frame, void **this_cache) 01318 { 01319 struct score_frame_cache *cache; 01320 01321 if ((*this_cache) != NULL) 01322 return (*this_cache); 01323 01324 cache = FRAME_OBSTACK_ZALLOC (struct score_frame_cache); 01325 (*this_cache) = cache; 01326 cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); 01327 01328 /* Analyze the prologue. */ 01329 { 01330 const CORE_ADDR pc = get_frame_pc (this_frame); 01331 CORE_ADDR start_addr; 01332 01333 find_pc_partial_function (pc, NULL, &start_addr, NULL); 01334 if (start_addr == 0) 01335 return cache; 01336 01337 if (target_mach == bfd_mach_score3) 01338 score3_analyze_prologue (start_addr, pc, this_frame, *this_cache); 01339 else 01340 score7_analyze_prologue (start_addr, pc, this_frame, *this_cache); 01341 } 01342 01343 /* Save SP. */ 01344 trad_frame_set_value (cache->saved_regs, SCORE_SP_REGNUM, cache->base); 01345 01346 return (*this_cache); 01347 } 01348 01349 static void 01350 score_prologue_this_id (struct frame_info *this_frame, void **this_cache, 01351 struct frame_id *this_id) 01352 { 01353 struct score_frame_cache *info = score_make_prologue_cache (this_frame, 01354 this_cache); 01355 (*this_id) = frame_id_build (info->base, get_frame_func (this_frame)); 01356 } 01357 01358 static struct value * 01359 score_prologue_prev_register (struct frame_info *this_frame, 01360 void **this_cache, int regnum) 01361 { 01362 struct score_frame_cache *info = score_make_prologue_cache (this_frame, 01363 this_cache); 01364 return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum); 01365 } 01366 01367 static const struct frame_unwind score_prologue_unwind = 01368 { 01369 NORMAL_FRAME, 01370 default_frame_unwind_stop_reason, 01371 score_prologue_this_id, 01372 score_prologue_prev_register, 01373 NULL, 01374 default_frame_sniffer, 01375 NULL 01376 }; 01377 01378 static CORE_ADDR 01379 score_prologue_frame_base_address (struct frame_info *this_frame, 01380 void **this_cache) 01381 { 01382 struct score_frame_cache *info = 01383 score_make_prologue_cache (this_frame, this_cache); 01384 return info->fp; 01385 } 01386 01387 static const struct frame_base score_prologue_frame_base = 01388 { 01389 &score_prologue_unwind, 01390 score_prologue_frame_base_address, 01391 score_prologue_frame_base_address, 01392 score_prologue_frame_base_address, 01393 }; 01394 01395 static const struct frame_base * 01396 score_prologue_frame_base_sniffer (struct frame_info *this_frame) 01397 { 01398 return &score_prologue_frame_base; 01399 } 01400 01401 /* Core file support (dirty hack) 01402 01403 The core file MUST be generated by GNU/Linux on S+core. */ 01404 01405 static void 01406 score7_linux_supply_gregset(const struct regset *regset, 01407 struct regcache *regcache, 01408 int regnum, const void *gregs_buf, size_t len) 01409 { 01410 int regno; 01411 elf_gregset_t *gregs; 01412 01413 gdb_assert (regset != NULL); 01414 gdb_assert ((regcache != NULL) && (gregs_buf != NULL)); 01415 01416 gregs = (elf_gregset_t *) gregs_buf; 01417 01418 for (regno = 0; regno < 32; regno++) 01419 if (regnum == -1 || regnum == regno) 01420 regcache_raw_supply (regcache, regno, gregs->regs + regno); 01421 01422 { 01423 struct sreg { 01424 int regnum; 01425 void *buf; 01426 } sregs [] = { 01427 { 55, &(gregs->cel) }, /* CEL */ 01428 { 54, &(gregs->ceh) }, /* CEH */ 01429 { 53, &(gregs->sr0) }, /* sr0, i.e. cnt or COUNTER */ 01430 { 52, &(gregs->sr1) }, /* sr1, i.e. lcr or LDCR */ 01431 { 51, &(gregs->sr1) }, /* sr2, i.e. scr or STCR */ 01432 01433 /* Exception occured at this address, exactly the PC we want */ 01434 { 49, &(gregs->cp0_epc) }, /* PC */ 01435 01436 { 38, &(gregs->cp0_ema) }, /* EMA */ 01437 { 37, &(gregs->cp0_epc) }, /* EPC */ 01438 { 34, &(gregs->cp0_ecr) }, /* ECR */ 01439 { 33, &(gregs->cp0_condition) }, /* COND */ 01440 { 32, &(gregs->cp0_psr) }, /* PSR */ 01441 }; 01442 01443 for (regno = 0; regno < sizeof(sregs)/sizeof(sregs[0]); regno++) 01444 if (regnum == -1 || regnum == sregs[regno].regnum) 01445 regcache_raw_supply (regcache, 01446 sregs[regno].regnum, sregs[regno].buf); 01447 } 01448 } 01449 01450 /* Return the appropriate register set from the core section identified 01451 by SECT_NAME and SECT_SIZE. */ 01452 01453 static const struct regset * 01454 score7_linux_regset_from_core_section(struct gdbarch *gdbarch, 01455 const char *sect_name, size_t sect_size) 01456 { 01457 struct gdbarch_tdep *tdep; 01458 01459 gdb_assert (gdbarch != NULL); 01460 gdb_assert (sect_name != NULL); 01461 01462 tdep = gdbarch_tdep (gdbarch); 01463 01464 if (strcmp(sect_name, ".reg") == 0 && sect_size == sizeof(elf_gregset_t)) 01465 { 01466 if (tdep->gregset == NULL) 01467 tdep->gregset = regset_alloc (gdbarch, 01468 score7_linux_supply_gregset, NULL); 01469 return tdep->gregset; 01470 } 01471 01472 return NULL; 01473 } 01474 01475 static struct gdbarch * 01476 score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 01477 { 01478 struct gdbarch *gdbarch; 01479 struct gdbarch_tdep *tdep; 01480 target_mach = info.bfd_arch_info->mach; 01481 01482 arches = gdbarch_list_lookup_by_info (arches, &info); 01483 if (arches != NULL) 01484 { 01485 return (arches->gdbarch); 01486 } 01487 tdep = xcalloc(1, sizeof(struct gdbarch_tdep)); 01488 gdbarch = gdbarch_alloc (&info, tdep); 01489 01490 set_gdbarch_short_bit (gdbarch, 16); 01491 set_gdbarch_int_bit (gdbarch, 32); 01492 set_gdbarch_float_bit (gdbarch, 32); 01493 set_gdbarch_double_bit (gdbarch, 64); 01494 set_gdbarch_long_double_bit (gdbarch, 64); 01495 #if WITH_SIM 01496 set_gdbarch_register_sim_regno (gdbarch, score_register_sim_regno); 01497 #endif 01498 set_gdbarch_pc_regnum (gdbarch, SCORE_PC_REGNUM); 01499 set_gdbarch_sp_regnum (gdbarch, SCORE_SP_REGNUM); 01500 set_gdbarch_adjust_breakpoint_address (gdbarch, 01501 score_adjust_breakpoint_address); 01502 set_gdbarch_register_type (gdbarch, score_register_type); 01503 set_gdbarch_frame_align (gdbarch, score_frame_align); 01504 set_gdbarch_inner_than (gdbarch, core_addr_lessthan); 01505 set_gdbarch_unwind_sp (gdbarch, score_unwind_sp); 01506 set_gdbarch_unwind_pc (gdbarch, score_unwind_pc); 01507 set_gdbarch_print_insn (gdbarch, score_print_insn); 01508 01509 switch (target_mach) 01510 { 01511 case bfd_mach_score7: 01512 set_gdbarch_breakpoint_from_pc (gdbarch, score7_breakpoint_from_pc); 01513 set_gdbarch_skip_prologue (gdbarch, score7_skip_prologue); 01514 set_gdbarch_in_function_epilogue_p (gdbarch, 01515 score7_in_function_epilogue_p); 01516 set_gdbarch_register_name (gdbarch, score7_register_name); 01517 set_gdbarch_num_regs (gdbarch, SCORE7_NUM_REGS); 01518 /* Core file support. */ 01519 set_gdbarch_regset_from_core_section (gdbarch, 01520 score7_linux_regset_from_core_section); 01521 break; 01522 01523 case bfd_mach_score3: 01524 set_gdbarch_breakpoint_from_pc (gdbarch, score3_breakpoint_from_pc); 01525 set_gdbarch_skip_prologue (gdbarch, score3_skip_prologue); 01526 set_gdbarch_in_function_epilogue_p (gdbarch, 01527 score3_in_function_epilogue_p); 01528 set_gdbarch_register_name (gdbarch, score3_register_name); 01529 set_gdbarch_num_regs (gdbarch, SCORE3_NUM_REGS); 01530 break; 01531 } 01532 01533 /* Watchpoint hooks. */ 01534 set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1); 01535 01536 /* Dummy frame hooks. */ 01537 set_gdbarch_return_value (gdbarch, score_return_value); 01538 set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT); 01539 set_gdbarch_dummy_id (gdbarch, score_dummy_id); 01540 set_gdbarch_push_dummy_call (gdbarch, score_push_dummy_call); 01541 01542 /* Normal frame hooks. */ 01543 dwarf2_append_unwinders (gdbarch); 01544 frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer); 01545 frame_unwind_append_unwinder (gdbarch, &score_prologue_unwind); 01546 frame_base_append_sniffer (gdbarch, score_prologue_frame_base_sniffer); 01547 01548 return gdbarch; 01549 } 01550 01551 extern initialize_file_ftype _initialize_score_tdep; 01552 01553 void 01554 _initialize_score_tdep (void) 01555 { 01556 gdbarch_register (bfd_arch_score, score_gdbarch_init, NULL); 01557 }