GDB (API)
|
00001 /* Target-dependent code for Moxie. 00002 00003 Copyright (C) 2009-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "defs.h" 00021 #include "frame.h" 00022 #include "frame-unwind.h" 00023 #include "frame-base.h" 00024 #include "symtab.h" 00025 #include "gdbtypes.h" 00026 #include "gdbcmd.h" 00027 #include "gdbcore.h" 00028 #include "gdb_string.h" 00029 #include "value.h" 00030 #include "inferior.h" 00031 #include "symfile.h" 00032 #include "objfiles.h" 00033 #include "osabi.h" 00034 #include "language.h" 00035 #include "arch-utils.h" 00036 #include "regcache.h" 00037 #include "trad-frame.h" 00038 #include "dis-asm.h" 00039 #include "record.h" 00040 #include "record-full.h" 00041 00042 #include "gdb_assert.h" 00043 00044 #include "moxie-tdep.h" 00045 00046 /* Local functions. */ 00047 00048 extern void _initialize_moxie_tdep (void); 00049 00050 /* Use an invalid address value as 'not available' marker. */ 00051 enum { REG_UNAVAIL = (CORE_ADDR) -1 }; 00052 00053 struct moxie_frame_cache 00054 { 00055 /* Base address. */ 00056 CORE_ADDR base; 00057 CORE_ADDR pc; 00058 LONGEST framesize; 00059 CORE_ADDR saved_regs[MOXIE_NUM_REGS]; 00060 CORE_ADDR saved_sp; 00061 }; 00062 00063 /* Implement the "frame_align" gdbarch method. */ 00064 00065 static CORE_ADDR 00066 moxie_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp) 00067 { 00068 /* Align to the size of an instruction (so that they can safely be 00069 pushed onto the stack. */ 00070 return sp & ~1; 00071 } 00072 00073 /* Implement the "breakpoint_from_pc" gdbarch method. */ 00074 00075 static const unsigned char * 00076 moxie_breakpoint_from_pc (struct gdbarch *gdbarch, 00077 CORE_ADDR *pcptr, int *lenptr) 00078 { 00079 static unsigned char breakpoint[] = { 0x35, 0x00 }; 00080 00081 *lenptr = sizeof (breakpoint); 00082 return breakpoint; 00083 } 00084 00085 /* Moxie register names. */ 00086 00087 char *moxie_register_names[] = { 00088 "$fp", "$sp", "$r0", "$r1", "$r2", 00089 "$r3", "$r4", "$r5", "$r6", "$r7", 00090 "$r8", "$r9", "$r10", "$r11", "$r12", 00091 "$r13", "$pc", "$cc" }; 00092 00093 /* Implement the "register_name" gdbarch method. */ 00094 00095 static const char * 00096 moxie_register_name (struct gdbarch *gdbarch, int reg_nr) 00097 { 00098 if (reg_nr < 0) 00099 return NULL; 00100 if (reg_nr >= MOXIE_NUM_REGS) 00101 return NULL; 00102 return moxie_register_names[reg_nr]; 00103 } 00104 00105 /* Implement the "register_type" gdbarch method. */ 00106 00107 static struct type * 00108 moxie_register_type (struct gdbarch *gdbarch, int reg_nr) 00109 { 00110 if (reg_nr == MOXIE_PC_REGNUM) 00111 return builtin_type (gdbarch)->builtin_func_ptr; 00112 else if (reg_nr == MOXIE_SP_REGNUM || reg_nr == MOXIE_FP_REGNUM) 00113 return builtin_type (gdbarch)->builtin_data_ptr; 00114 else 00115 return builtin_type (gdbarch)->builtin_int32; 00116 } 00117 00118 /* Write into appropriate registers a function return value 00119 of type TYPE, given in virtual format. */ 00120 00121 static void 00122 moxie_store_return_value (struct type *type, struct regcache *regcache, 00123 const void *valbuf) 00124 { 00125 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00126 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 00127 CORE_ADDR regval; 00128 int len = TYPE_LENGTH (type); 00129 00130 /* Things always get returned in RET1_REGNUM, RET2_REGNUM. */ 00131 regval = extract_unsigned_integer (valbuf, len > 4 ? 4 : len, byte_order); 00132 regcache_cooked_write_unsigned (regcache, RET1_REGNUM, regval); 00133 if (len > 4) 00134 { 00135 regval = extract_unsigned_integer ((gdb_byte *) valbuf + 4, 00136 len - 4, byte_order); 00137 regcache_cooked_write_unsigned (regcache, RET1_REGNUM + 1, regval); 00138 } 00139 } 00140 00141 /* Decode the instructions within the given address range. Decide 00142 when we must have reached the end of the function prologue. If a 00143 frame_info pointer is provided, fill in its saved_regs etc. 00144 00145 Returns the address of the first instruction after the prologue. */ 00146 00147 static CORE_ADDR 00148 moxie_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr, 00149 struct moxie_frame_cache *cache, 00150 struct gdbarch *gdbarch) 00151 { 00152 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 00153 CORE_ADDR next_addr; 00154 ULONGEST inst, inst2; 00155 LONGEST offset; 00156 int regnum; 00157 00158 /* Record where the jsra instruction saves the PC and FP. */ 00159 cache->saved_regs[MOXIE_PC_REGNUM] = -4; 00160 cache->saved_regs[MOXIE_FP_REGNUM] = 0; 00161 cache->framesize = 0; 00162 00163 if (start_addr >= end_addr) 00164 return end_addr; 00165 00166 for (next_addr = start_addr; next_addr < end_addr; ) 00167 { 00168 inst = read_memory_unsigned_integer (next_addr, 2, byte_order); 00169 00170 /* Match "push $sp $rN" where N is between 0 and 13 inclusive. */ 00171 if (inst >= 0x0612 && inst <= 0x061f) 00172 { 00173 regnum = inst & 0x000f; 00174 cache->framesize += 4; 00175 cache->saved_regs[regnum] = cache->framesize; 00176 next_addr += 2; 00177 } 00178 else 00179 break; 00180 } 00181 00182 inst = read_memory_unsigned_integer (next_addr, 2, byte_order); 00183 00184 /* Optional stack allocation for args and local vars <= 4 00185 byte. */ 00186 if (inst == 0x01e0) /* ldi.l $r12, X */ 00187 { 00188 offset = read_memory_integer (next_addr + 2, 4, byte_order); 00189 inst2 = read_memory_unsigned_integer (next_addr + 6, 2, byte_order); 00190 00191 if (inst2 == 0x291e) /* sub.l $sp, $r12 */ 00192 { 00193 cache->framesize += offset; 00194 } 00195 00196 return (next_addr + 8); 00197 } 00198 else if ((inst & 0xff00) == 0x9100) /* dec $sp, X */ 00199 { 00200 cache->framesize += (inst & 0x00ff); 00201 next_addr += 2; 00202 00203 while (next_addr < end_addr) 00204 { 00205 inst = read_memory_unsigned_integer (next_addr, 2, byte_order); 00206 if ((inst & 0xff00) != 0x9100) /* no more dec $sp, X */ 00207 break; 00208 cache->framesize += (inst & 0x00ff); 00209 next_addr += 2; 00210 } 00211 } 00212 00213 return next_addr; 00214 } 00215 00216 /* Find the end of function prologue. */ 00217 00218 static CORE_ADDR 00219 moxie_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) 00220 { 00221 CORE_ADDR func_addr = 0, func_end = 0; 00222 const char *func_name; 00223 00224 /* See if we can determine the end of the prologue via the symbol table. 00225 If so, then return either PC, or the PC after the prologue, whichever 00226 is greater. */ 00227 if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end)) 00228 { 00229 CORE_ADDR post_prologue_pc 00230 = skip_prologue_using_sal (gdbarch, func_addr); 00231 if (post_prologue_pc != 0) 00232 return max (pc, post_prologue_pc); 00233 else 00234 { 00235 /* Can't determine prologue from the symbol table, need to examine 00236 instructions. */ 00237 struct symtab_and_line sal; 00238 struct symbol *sym; 00239 struct moxie_frame_cache cache; 00240 CORE_ADDR plg_end; 00241 00242 memset (&cache, 0, sizeof cache); 00243 00244 plg_end = moxie_analyze_prologue (func_addr, 00245 func_end, &cache, gdbarch); 00246 /* Found a function. */ 00247 sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL); 00248 /* Don't use line number debug info for assembly source 00249 files. */ 00250 if (sym && SYMBOL_LANGUAGE (sym) != language_asm) 00251 { 00252 sal = find_pc_line (func_addr, 0); 00253 if (sal.end && sal.end < func_end) 00254 { 00255 /* Found a line number, use it as end of 00256 prologue. */ 00257 return sal.end; 00258 } 00259 } 00260 /* No useable line symbol. Use result of prologue parsing 00261 method. */ 00262 return plg_end; 00263 } 00264 } 00265 00266 /* No function symbol -- just return the PC. */ 00267 return (CORE_ADDR) pc; 00268 } 00269 00270 struct moxie_unwind_cache 00271 { 00272 /* The previous frame's inner most stack address. Used as this 00273 frame ID's stack_addr. */ 00274 CORE_ADDR prev_sp; 00275 /* The frame's base, optionally used by the high-level debug info. */ 00276 CORE_ADDR base; 00277 int size; 00278 /* How far the SP and r13 (FP) have been offset from the start of 00279 the stack frame (as defined by the previous frame's stack 00280 pointer). */ 00281 LONGEST sp_offset; 00282 LONGEST r13_offset; 00283 int uses_frame; 00284 /* Table indicating the location of each and every register. */ 00285 struct trad_frame_saved_reg *saved_regs; 00286 }; 00287 00288 /* Implement the "read_pc" gdbarch method. */ 00289 00290 static CORE_ADDR 00291 moxie_read_pc (struct regcache *regcache) 00292 { 00293 ULONGEST pc; 00294 00295 regcache_cooked_read_unsigned (regcache, MOXIE_PC_REGNUM, &pc); 00296 return pc; 00297 } 00298 00299 /* Implement the "write_pc" gdbarch method. */ 00300 00301 static void 00302 moxie_write_pc (struct regcache *regcache, CORE_ADDR val) 00303 { 00304 regcache_cooked_write_unsigned (regcache, MOXIE_PC_REGNUM, val); 00305 } 00306 00307 /* Implement the "unwind_sp" gdbarch method. */ 00308 00309 static CORE_ADDR 00310 moxie_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame) 00311 { 00312 return frame_unwind_register_unsigned (next_frame, MOXIE_SP_REGNUM); 00313 } 00314 00315 /* Given a return value in `regbuf' with a type `valtype', 00316 extract and copy its value into `valbuf'. */ 00317 00318 static void 00319 moxie_extract_return_value (struct type *type, struct regcache *regcache, 00320 void *dst) 00321 { 00322 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00323 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 00324 bfd_byte *valbuf = dst; 00325 int len = TYPE_LENGTH (type); 00326 ULONGEST tmp; 00327 00328 /* By using store_unsigned_integer we avoid having to do 00329 anything special for small big-endian values. */ 00330 regcache_cooked_read_unsigned (regcache, RET1_REGNUM, &tmp); 00331 store_unsigned_integer (valbuf, (len > 4 ? len - 4 : len), byte_order, tmp); 00332 00333 /* Ignore return values more than 8 bytes in size because the moxie 00334 returns anything more than 8 bytes in the stack. */ 00335 if (len > 4) 00336 { 00337 regcache_cooked_read_unsigned (regcache, RET1_REGNUM + 1, &tmp); 00338 store_unsigned_integer (valbuf + len - 4, 4, byte_order, tmp); 00339 } 00340 } 00341 00342 /* Implement the "return_value" gdbarch method. */ 00343 00344 static enum return_value_convention 00345 moxie_return_value (struct gdbarch *gdbarch, struct value *function, 00346 struct type *valtype, struct regcache *regcache, 00347 gdb_byte *readbuf, const gdb_byte *writebuf) 00348 { 00349 if (TYPE_LENGTH (valtype) > 8) 00350 return RETURN_VALUE_STRUCT_CONVENTION; 00351 else 00352 { 00353 if (readbuf != NULL) 00354 moxie_extract_return_value (valtype, regcache, readbuf); 00355 if (writebuf != NULL) 00356 moxie_store_return_value (valtype, regcache, writebuf); 00357 return RETURN_VALUE_REGISTER_CONVENTION; 00358 } 00359 } 00360 00361 /* Allocate and initialize a moxie_frame_cache object. */ 00362 00363 static struct moxie_frame_cache * 00364 moxie_alloc_frame_cache (void) 00365 { 00366 struct moxie_frame_cache *cache; 00367 int i; 00368 00369 cache = FRAME_OBSTACK_ZALLOC (struct moxie_frame_cache); 00370 00371 cache->base = 0; 00372 cache->saved_sp = 0; 00373 cache->pc = 0; 00374 cache->framesize = 0; 00375 for (i = 0; i < MOXIE_NUM_REGS; ++i) 00376 cache->saved_regs[i] = REG_UNAVAIL; 00377 00378 return cache; 00379 } 00380 00381 /* Populate a moxie_frame_cache object for this_frame. */ 00382 00383 static struct moxie_frame_cache * 00384 moxie_frame_cache (struct frame_info *this_frame, void **this_cache) 00385 { 00386 struct moxie_frame_cache *cache; 00387 CORE_ADDR current_pc; 00388 int i; 00389 00390 if (*this_cache) 00391 return *this_cache; 00392 00393 cache = moxie_alloc_frame_cache (); 00394 *this_cache = cache; 00395 00396 cache->base = get_frame_register_unsigned (this_frame, MOXIE_FP_REGNUM); 00397 if (cache->base == 0) 00398 return cache; 00399 00400 cache->pc = get_frame_func (this_frame); 00401 current_pc = get_frame_pc (this_frame); 00402 if (cache->pc) 00403 { 00404 struct gdbarch *gdbarch = get_frame_arch (this_frame); 00405 moxie_analyze_prologue (cache->pc, current_pc, cache, gdbarch); 00406 } 00407 00408 cache->saved_sp = cache->base - cache->framesize; 00409 00410 for (i = 0; i < MOXIE_NUM_REGS; ++i) 00411 if (cache->saved_regs[i] != REG_UNAVAIL) 00412 cache->saved_regs[i] = cache->base - cache->saved_regs[i]; 00413 00414 return cache; 00415 } 00416 00417 /* Implement the "unwind_pc" gdbarch method. */ 00418 00419 static CORE_ADDR 00420 moxie_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) 00421 { 00422 return frame_unwind_register_unsigned (next_frame, MOXIE_PC_REGNUM); 00423 } 00424 00425 /* Given a GDB frame, determine the address of the calling function's 00426 frame. This will be used to create a new GDB frame struct. */ 00427 00428 static void 00429 moxie_frame_this_id (struct frame_info *this_frame, 00430 void **this_prologue_cache, struct frame_id *this_id) 00431 { 00432 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame, 00433 this_prologue_cache); 00434 00435 /* This marks the outermost frame. */ 00436 if (cache->base == 0) 00437 return; 00438 00439 *this_id = frame_id_build (cache->saved_sp, cache->pc); 00440 } 00441 00442 /* Get the value of register regnum in the previous stack frame. */ 00443 00444 static struct value * 00445 moxie_frame_prev_register (struct frame_info *this_frame, 00446 void **this_prologue_cache, int regnum) 00447 { 00448 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame, 00449 this_prologue_cache); 00450 00451 gdb_assert (regnum >= 0); 00452 00453 if (regnum == MOXIE_SP_REGNUM && cache->saved_sp) 00454 return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp); 00455 00456 if (regnum < MOXIE_NUM_REGS && cache->saved_regs[regnum] != REG_UNAVAIL) 00457 return frame_unwind_got_memory (this_frame, regnum, 00458 cache->saved_regs[regnum]); 00459 00460 return frame_unwind_got_register (this_frame, regnum, regnum); 00461 } 00462 00463 static const struct frame_unwind moxie_frame_unwind = { 00464 NORMAL_FRAME, 00465 default_frame_unwind_stop_reason, 00466 moxie_frame_this_id, 00467 moxie_frame_prev_register, 00468 NULL, 00469 default_frame_sniffer 00470 }; 00471 00472 /* Return the base address of this_frame. */ 00473 00474 static CORE_ADDR 00475 moxie_frame_base_address (struct frame_info *this_frame, void **this_cache) 00476 { 00477 struct moxie_frame_cache *cache = moxie_frame_cache (this_frame, 00478 this_cache); 00479 00480 return cache->base; 00481 } 00482 00483 static const struct frame_base moxie_frame_base = { 00484 &moxie_frame_unwind, 00485 moxie_frame_base_address, 00486 moxie_frame_base_address, 00487 moxie_frame_base_address 00488 }; 00489 00490 static struct frame_id 00491 moxie_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame) 00492 { 00493 CORE_ADDR sp = get_frame_register_unsigned (this_frame, MOXIE_SP_REGNUM); 00494 00495 return frame_id_build (sp, get_frame_pc (this_frame)); 00496 } 00497 00498 /* Read an unsigned integer from the inferior, and adjust 00499 endianess. */ 00500 static ULONGEST 00501 moxie_process_readu (CORE_ADDR addr, gdb_byte *buf, 00502 int length, enum bfd_endian byte_order) 00503 { 00504 if (target_read_memory (addr, buf, length)) 00505 { 00506 if (record_debug) 00507 printf_unfiltered (_("Process record: error reading memory at " 00508 "addr 0x%s len = %d.\n"), 00509 paddress (target_gdbarch (), addr), length); 00510 return -1; 00511 } 00512 00513 return extract_unsigned_integer (buf, length, byte_order); 00514 } 00515 00516 /* Parse the current instruction and record the values of the registers and 00517 memory that will be changed in current instruction to "record_arch_list". 00518 Return -1 if something wrong. */ 00519 00520 static int 00521 moxie_process_record (struct gdbarch *gdbarch, struct regcache *regcache, 00522 CORE_ADDR addr) 00523 { 00524 gdb_byte buf[4]; 00525 uint16_t inst; 00526 uint32_t tmpu32; 00527 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 00528 00529 if (record_debug > 1) 00530 fprintf_unfiltered (gdb_stdlog, "Process record: moxie_process_record " 00531 "addr = 0x%s\n", 00532 paddress (target_gdbarch (), addr)); 00533 00534 inst = (uint16_t) moxie_process_readu (addr, buf, 2, byte_order); 00535 00536 /* Decode instruction. */ 00537 if (inst & (1 << 15)) 00538 { 00539 if (inst & (1 << 14)) 00540 { 00541 /* This is a Form 3 instruction. */ 00542 int opcode = (inst >> 10 & 0xf); 00543 00544 switch (opcode) 00545 { 00546 case 0x00: /* beq */ 00547 case 0x01: /* bne */ 00548 case 0x02: /* blt */ 00549 case 0x03: /* bgt */ 00550 case 0x04: /* bltu */ 00551 case 0x05: /* bgtu */ 00552 case 0x06: /* bge */ 00553 case 0x07: /* ble */ 00554 case 0x08: /* bgeu */ 00555 case 0x09: /* bleu */ 00556 /* Do nothing. */ 00557 break; 00558 default: 00559 { 00560 /* Do nothing. */ 00561 break; 00562 } 00563 } 00564 } 00565 else 00566 { 00567 /* This is a Form 2 instruction. */ 00568 int opcode = (inst >> 12 & 0x3); 00569 switch (opcode) 00570 { 00571 case 0x00: /* inc */ 00572 case 0x01: /* dec */ 00573 case 0x02: /* gsr */ 00574 { 00575 int reg = (inst >> 8) & 0xf; 00576 if (record_full_arch_list_add_reg (regcache, reg)) 00577 return -1; 00578 } 00579 break; 00580 case 0x03: /* ssr */ 00581 { 00582 /* Do nothing until GDB learns about moxie's special 00583 registers. */ 00584 } 00585 break; 00586 default: 00587 /* Do nothing. */ 00588 break; 00589 } 00590 } 00591 } 00592 else 00593 { 00594 /* This is a Form 1 instruction. */ 00595 int opcode = inst >> 8; 00596 00597 switch (opcode) 00598 { 00599 case 0x00: /* nop */ 00600 /* Do nothing. */ 00601 break; 00602 case 0x01: /* ldi.l (immediate) */ 00603 case 0x02: /* mov (register-to-register) */ 00604 { 00605 int reg = (inst >> 4) & 0xf; 00606 if (record_full_arch_list_add_reg (regcache, reg)) 00607 return -1; 00608 } 00609 break; 00610 case 0x03: /* jsra */ 00611 { 00612 regcache_raw_read (regcache, 00613 MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32); 00614 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 00615 4, byte_order); 00616 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM) 00617 || (record_full_arch_list_add_reg (regcache, 00618 MOXIE_SP_REGNUM)) 00619 || record_full_arch_list_add_mem (tmpu32 - 12, 12)) 00620 return -1; 00621 } 00622 break; 00623 case 0x04: /* ret */ 00624 { 00625 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM) 00626 || (record_full_arch_list_add_reg (regcache, 00627 MOXIE_SP_REGNUM))) 00628 return -1; 00629 } 00630 break; 00631 case 0x05: /* add.l */ 00632 { 00633 int reg = (inst >> 4) & 0xf; 00634 if (record_full_arch_list_add_reg (regcache, reg)) 00635 return -1; 00636 } 00637 break; 00638 case 0x06: /* push */ 00639 { 00640 int reg = (inst >> 4) & 0xf; 00641 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32); 00642 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 00643 4, byte_order); 00644 if (record_full_arch_list_add_reg (regcache, reg) 00645 || record_full_arch_list_add_mem (tmpu32 - 4, 4)) 00646 return -1; 00647 } 00648 break; 00649 case 0x07: /* pop */ 00650 { 00651 int a = (inst >> 4) & 0xf; 00652 int b = inst & 0xf; 00653 if (record_full_arch_list_add_reg (regcache, a) 00654 || record_full_arch_list_add_reg (regcache, b)) 00655 return -1; 00656 } 00657 break; 00658 case 0x08: /* lda.l */ 00659 { 00660 int reg = (inst >> 4) & 0xf; 00661 if (record_full_arch_list_add_reg (regcache, reg)) 00662 return -1; 00663 } 00664 break; 00665 case 0x09: /* sta.l */ 00666 { 00667 tmpu32 = (uint32_t) moxie_process_readu (addr+2, buf, 00668 4, byte_order); 00669 if (record_full_arch_list_add_mem (tmpu32, 4)) 00670 return -1; 00671 } 00672 break; 00673 case 0x0a: /* ld.l (register indirect) */ 00674 { 00675 int reg = (inst >> 4) & 0xf; 00676 if (record_full_arch_list_add_reg (regcache, reg)) 00677 return -1; 00678 } 00679 break; 00680 case 0x0b: /* st.l */ 00681 { 00682 int reg = (inst >> 4) & 0xf; 00683 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32); 00684 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 00685 4, byte_order); 00686 if (record_full_arch_list_add_mem (tmpu32, 4)) 00687 return -1; 00688 } 00689 break; 00690 case 0x0c: /* ldo.l */ 00691 { 00692 int reg = (inst >> 4) & 0xf; 00693 if (record_full_arch_list_add_reg (regcache, reg)) 00694 return -1; 00695 } 00696 break; 00697 case 0x0d: /* sto.l */ 00698 { 00699 int reg = (inst >> 4) & 0xf; 00700 uint32_t offset = (uint32_t) moxie_process_readu (addr+2, buf, 4, 00701 byte_order); 00702 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32); 00703 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 00704 4, byte_order); 00705 tmpu32 += offset; 00706 if (record_full_arch_list_add_mem (tmpu32, 4)) 00707 return -1; 00708 } 00709 break; 00710 case 0x0e: /* cmp */ 00711 { 00712 if (record_full_arch_list_add_reg (regcache, MOXIE_CC_REGNUM)) 00713 return -1; 00714 } 00715 break; 00716 case 0x0f: 00717 case 0x10: 00718 case 0x11: 00719 case 0x12: 00720 case 0x13: 00721 case 0x14: 00722 case 0x15: 00723 case 0x16: 00724 case 0x17: 00725 case 0x18: 00726 { 00727 /* Do nothing. */ 00728 break; 00729 } 00730 case 0x19: /* jsr */ 00731 { 00732 regcache_raw_read (regcache, 00733 MOXIE_SP_REGNUM, (gdb_byte *) & tmpu32); 00734 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 00735 4, byte_order); 00736 if (record_full_arch_list_add_reg (regcache, MOXIE_FP_REGNUM) 00737 || (record_full_arch_list_add_reg (regcache, 00738 MOXIE_SP_REGNUM)) 00739 || record_full_arch_list_add_mem (tmpu32 - 12, 12)) 00740 return -1; 00741 } 00742 break; 00743 case 0x1a: /* jmpa */ 00744 { 00745 /* Do nothing. */ 00746 } 00747 break; 00748 case 0x1b: /* ldi.b (immediate) */ 00749 case 0x1c: /* ld.b (register indirect) */ 00750 case 0x1d: /* lda.b */ 00751 { 00752 int reg = (inst >> 4) & 0xf; 00753 if (record_full_arch_list_add_reg (regcache, reg)) 00754 return -1; 00755 } 00756 break; 00757 case 0x1e: /* st.b */ 00758 { 00759 int reg = (inst >> 4) & 0xf; 00760 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32); 00761 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 00762 4, byte_order); 00763 if (record_full_arch_list_add_mem (tmpu32, 1)) 00764 return -1; 00765 } 00766 break; 00767 case 0x1f: /* sta.b */ 00768 { 00769 tmpu32 = moxie_process_readu (addr+2, buf, 4, byte_order); 00770 if (record_full_arch_list_add_mem (tmpu32, 1)) 00771 return -1; 00772 } 00773 break; 00774 case 0x20: /* ldi.s (immediate) */ 00775 case 0x21: /* ld.s (register indirect) */ 00776 case 0x22: /* lda.s */ 00777 { 00778 int reg = (inst >> 4) & 0xf; 00779 if (record_full_arch_list_add_reg (regcache, reg)) 00780 return -1; 00781 } 00782 break; 00783 case 0x23: /* st.s */ 00784 { 00785 int reg = (inst >> 4) & 0xf; 00786 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32); 00787 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 00788 4, byte_order); 00789 if (record_full_arch_list_add_mem (tmpu32, 2)) 00790 return -1; 00791 } 00792 break; 00793 case 0x24: /* sta.s */ 00794 { 00795 tmpu32 = moxie_process_readu (addr+2, buf, 4, byte_order); 00796 if (record_full_arch_list_add_mem (tmpu32, 2)) 00797 return -1; 00798 } 00799 break; 00800 case 0x25: /* jmp */ 00801 { 00802 /* Do nothing. */ 00803 } 00804 break; 00805 case 0x26: /* and */ 00806 case 0x27: /* lshr */ 00807 case 0x28: /* ashl */ 00808 case 0x29: /* sub.l */ 00809 case 0x2a: /* neg */ 00810 case 0x2b: /* or */ 00811 case 0x2c: /* not */ 00812 case 0x2d: /* ashr */ 00813 case 0x2e: /* xor */ 00814 case 0x2f: /* mul.l */ 00815 { 00816 int reg = (inst >> 4) & 0xf; 00817 if (record_full_arch_list_add_reg (regcache, reg)) 00818 return -1; 00819 } 00820 break; 00821 case 0x30: /* swi */ 00822 { 00823 /* We currently implement support for libgloss' 00824 system calls. */ 00825 00826 int inum = moxie_process_readu (addr+2, buf, 4, byte_order); 00827 00828 switch (inum) 00829 { 00830 case 0x1: /* SYS_exit */ 00831 { 00832 /* Do nothing. */ 00833 } 00834 break; 00835 case 0x2: /* SYS_open */ 00836 { 00837 if (record_full_arch_list_add_reg (regcache, RET1_REGNUM)) 00838 return -1; 00839 } 00840 break; 00841 case 0x4: /* SYS_read */ 00842 { 00843 uint32_t length, ptr; 00844 00845 /* Read buffer pointer is in $r1. */ 00846 regcache_raw_read (regcache, 3, (gdb_byte *) & ptr); 00847 ptr = extract_unsigned_integer ((gdb_byte *) & ptr, 00848 4, byte_order); 00849 00850 /* String length is at 0x12($fp). */ 00851 regcache_raw_read (regcache, 00852 MOXIE_FP_REGNUM, (gdb_byte *) & tmpu32); 00853 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 00854 4, byte_order); 00855 length = moxie_process_readu (tmpu32+20, buf, 4, byte_order); 00856 00857 if (record_full_arch_list_add_mem (ptr, length)) 00858 return -1; 00859 } 00860 break; 00861 case 0x5: /* SYS_write */ 00862 { 00863 if (record_full_arch_list_add_reg (regcache, RET1_REGNUM)) 00864 return -1; 00865 } 00866 break; 00867 default: 00868 break; 00869 } 00870 } 00871 break; 00872 case 0x31: /* div.l */ 00873 case 0x32: /* udiv.l */ 00874 case 0x33: /* mod.l */ 00875 case 0x34: /* umod.l */ 00876 { 00877 int reg = (inst >> 4) & 0xf; 00878 if (record_full_arch_list_add_reg (regcache, reg)) 00879 return -1; 00880 } 00881 break; 00882 case 0x35: /* brk */ 00883 /* Do nothing. */ 00884 break; 00885 case 0x36: /* ldo.b */ 00886 { 00887 int reg = (inst >> 4) & 0xf; 00888 if (record_full_arch_list_add_reg (regcache, reg)) 00889 return -1; 00890 } 00891 break; 00892 case 0x37: /* sto.b */ 00893 { 00894 int reg = (inst >> 4) & 0xf; 00895 uint32_t offset = (uint32_t) moxie_process_readu (addr+2, buf, 4, 00896 byte_order); 00897 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32); 00898 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 00899 4, byte_order); 00900 tmpu32 += offset; 00901 if (record_full_arch_list_add_mem (tmpu32, 1)) 00902 return -1; 00903 } 00904 break; 00905 case 0x38: /* ldo.s */ 00906 { 00907 int reg = (inst >> 4) & 0xf; 00908 if (record_full_arch_list_add_reg (regcache, reg)) 00909 return -1; 00910 } 00911 break; 00912 case 0x39: /* sto.s */ 00913 { 00914 int reg = (inst >> 4) & 0xf; 00915 uint32_t offset = (uint32_t) moxie_process_readu (addr+2, buf, 4, 00916 byte_order); 00917 regcache_raw_read (regcache, reg, (gdb_byte *) & tmpu32); 00918 tmpu32 = extract_unsigned_integer ((gdb_byte *) & tmpu32, 00919 4, byte_order); 00920 tmpu32 += offset; 00921 if (record_full_arch_list_add_mem (tmpu32, 2)) 00922 return -1; 00923 } 00924 break; 00925 default: 00926 /* Do nothing. */ 00927 break; 00928 } 00929 } 00930 00931 if (record_full_arch_list_add_reg (regcache, MOXIE_PC_REGNUM)) 00932 return -1; 00933 if (record_full_arch_list_add_end ()) 00934 return -1; 00935 return 0; 00936 } 00937 00938 /* Allocate and initialize the moxie gdbarch object. */ 00939 00940 static struct gdbarch * 00941 moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 00942 { 00943 struct gdbarch *gdbarch; 00944 struct gdbarch_tdep *tdep; 00945 00946 /* If there is already a candidate, use it. */ 00947 arches = gdbarch_list_lookup_by_info (arches, &info); 00948 if (arches != NULL) 00949 return arches->gdbarch; 00950 00951 /* Allocate space for the new architecture. */ 00952 tdep = XMALLOC (struct gdbarch_tdep); 00953 gdbarch = gdbarch_alloc (&info, tdep); 00954 00955 set_gdbarch_read_pc (gdbarch, moxie_read_pc); 00956 set_gdbarch_write_pc (gdbarch, moxie_write_pc); 00957 set_gdbarch_unwind_sp (gdbarch, moxie_unwind_sp); 00958 00959 set_gdbarch_num_regs (gdbarch, MOXIE_NUM_REGS); 00960 set_gdbarch_sp_regnum (gdbarch, MOXIE_SP_REGNUM); 00961 set_gdbarch_pc_regnum (gdbarch, MOXIE_PC_REGNUM); 00962 set_gdbarch_register_name (gdbarch, moxie_register_name); 00963 set_gdbarch_register_type (gdbarch, moxie_register_type); 00964 00965 set_gdbarch_return_value (gdbarch, moxie_return_value); 00966 00967 set_gdbarch_skip_prologue (gdbarch, moxie_skip_prologue); 00968 set_gdbarch_inner_than (gdbarch, core_addr_lessthan); 00969 set_gdbarch_breakpoint_from_pc (gdbarch, moxie_breakpoint_from_pc); 00970 set_gdbarch_frame_align (gdbarch, moxie_frame_align); 00971 00972 frame_base_set_default (gdbarch, &moxie_frame_base); 00973 00974 /* Methods for saving / extracting a dummy frame's ID. The ID's 00975 stack address must match the SP value returned by 00976 PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos. */ 00977 set_gdbarch_dummy_id (gdbarch, moxie_dummy_id); 00978 00979 set_gdbarch_unwind_pc (gdbarch, moxie_unwind_pc); 00980 00981 set_gdbarch_print_insn (gdbarch, print_insn_moxie); 00982 00983 /* Hook in ABI-specific overrides, if they have been registered. */ 00984 gdbarch_init_osabi (info, gdbarch); 00985 00986 /* Hook in the default unwinders. */ 00987 frame_unwind_append_unwinder (gdbarch, &moxie_frame_unwind); 00988 00989 /* Support simple overlay manager. */ 00990 set_gdbarch_overlay_update (gdbarch, simple_overlay_update); 00991 00992 /* Support reverse debugging. */ 00993 set_gdbarch_process_record (gdbarch, moxie_process_record); 00994 00995 return gdbarch; 00996 } 00997 00998 /* Register this machine's init routine. */ 00999 01000 void 01001 _initialize_moxie_tdep (void) 01002 { 01003 register_gdbarch_init (bfd_arch_moxie, moxie_gdbarch_init); 01004 }