1 /* Target-dependent code for the Matsushita MN10300 for GDB, the GNU debugger. 2 3 Copyright (C) 2003-2024 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #include "gdbcore.h" 21 #include "regcache.h" 22 #include "mn10300-tdep.h" 23 #include "bfd.h" 24 #include "elf-bfd.h" 25 #include "osabi.h" 26 #include "regset.h" 27 #include "solib-svr4.h" 28 #include "frame.h" 29 #include "trad-frame.h" 30 #include "tramp-frame.h" 31 #include "linux-tdep.h" 32 #include "gdbarch.h" 33 34 /* Transliterated from <asm-mn10300/elf.h>... */ 35 #define MN10300_ELF_NGREG 28 36 #define MN10300_ELF_NFPREG 32 37 38 typedef gdb_byte mn10300_elf_greg_t[4]; 39 typedef mn10300_elf_greg_t mn10300_elf_gregset_t[MN10300_ELF_NGREG]; 40 41 typedef gdb_byte mn10300_elf_fpreg_t[4]; 42 typedef struct 43 { 44 mn10300_elf_fpreg_t fpregs[MN10300_ELF_NFPREG]; 45 gdb_byte fpcr[4]; 46 } mn10300_elf_fpregset_t; 47 48 /* elf_gregset_t register indices stolen from include/asm-mn10300/ptrace.h. */ 49 #define MN10300_ELF_GREGSET_T_REG_INDEX_A3 0 50 #define MN10300_ELF_GREGSET_T_REG_INDEX_A2 1 51 #define MN10300_ELF_GREGSET_T_REG_INDEX_D3 2 52 #define MN10300_ELF_GREGSET_T_REG_INDEX_D2 3 53 #define MN10300_ELF_GREGSET_T_REG_INDEX_MCVF 4 54 #define MN10300_ELF_GREGSET_T_REG_INDEX_MCRL 5 55 #define MN10300_ELF_GREGSET_T_REG_INDEX_MCRH 6 56 #define MN10300_ELF_GREGSET_T_REG_INDEX_MDRQ 7 57 #define MN10300_ELF_GREGSET_T_REG_INDEX_E1 8 58 #define MN10300_ELF_GREGSET_T_REG_INDEX_E0 9 59 #define MN10300_ELF_GREGSET_T_REG_INDEX_E7 10 60 #define MN10300_ELF_GREGSET_T_REG_INDEX_E6 11 61 #define MN10300_ELF_GREGSET_T_REG_INDEX_E5 12 62 #define MN10300_ELF_GREGSET_T_REG_INDEX_E4 13 63 #define MN10300_ELF_GREGSET_T_REG_INDEX_E3 14 64 #define MN10300_ELF_GREGSET_T_REG_INDEX_E2 15 65 #define MN10300_ELF_GREGSET_T_REG_INDEX_SP 16 66 #define MN10300_ELF_GREGSET_T_REG_INDEX_LAR 17 67 #define MN10300_ELF_GREGSET_T_REG_INDEX_LIR 18 68 #define MN10300_ELF_GREGSET_T_REG_INDEX_MDR 19 69 #define MN10300_ELF_GREGSET_T_REG_INDEX_A1 20 70 #define MN10300_ELF_GREGSET_T_REG_INDEX_A0 21 71 #define MN10300_ELF_GREGSET_T_REG_INDEX_D1 22 72 #define MN10300_ELF_GREGSET_T_REG_INDEX_D0 23 73 #define MN10300_ELF_GREGSET_T_REG_INDEX_ORIG_D0 24 74 #define MN10300_ELF_GREGSET_T_REG_INDEX_EPSW 25 75 #define MN10300_ELF_GREGSET_T_REG_INDEX_PC 26 76 77 /* New gdbarch API for corefile registers. 78 Given a section name and size, create a struct reg object 79 with a supply_register and a collect_register method. */ 80 81 /* Copy register value of REGNUM from regset to regcache. 82 If REGNUM is -1, do this for all gp registers in regset. */ 83 84 static void 85 am33_supply_gregset_method (const struct regset *regset, 86 struct regcache *regcache, 87 int regnum, const void *gregs, size_t len) 88 { 89 const mn10300_elf_greg_t *regp = (const mn10300_elf_greg_t *) gregs; 90 int i; 91 92 gdb_assert (len >= sizeof (mn10300_elf_gregset_t)); 93 94 switch (regnum) { 95 case E_D0_REGNUM: 96 regcache->raw_supply (E_D0_REGNUM, 97 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D0)); 98 break; 99 case E_D1_REGNUM: 100 regcache->raw_supply (E_D1_REGNUM, 101 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D1)); 102 break; 103 case E_D2_REGNUM: 104 regcache->raw_supply (E_D2_REGNUM, 105 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D2)); 106 break; 107 case E_D3_REGNUM: 108 regcache->raw_supply (E_D3_REGNUM, 109 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D3)); 110 break; 111 case E_A0_REGNUM: 112 regcache->raw_supply (E_A0_REGNUM, 113 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A0)); 114 break; 115 case E_A1_REGNUM: 116 regcache->raw_supply (E_A1_REGNUM, 117 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A1)); 118 break; 119 case E_A2_REGNUM: 120 regcache->raw_supply (E_A2_REGNUM, 121 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A2)); 122 break; 123 case E_A3_REGNUM: 124 regcache->raw_supply (E_A3_REGNUM, 125 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A3)); 126 break; 127 case E_SP_REGNUM: 128 regcache->raw_supply (E_SP_REGNUM, 129 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_SP)); 130 break; 131 case E_PC_REGNUM: 132 regcache->raw_supply (E_PC_REGNUM, 133 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_PC)); 134 break; 135 case E_MDR_REGNUM: 136 regcache->raw_supply (E_MDR_REGNUM, 137 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDR)); 138 break; 139 case E_PSW_REGNUM: 140 regcache->raw_supply (E_PSW_REGNUM, 141 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_EPSW)); 142 break; 143 case E_LIR_REGNUM: 144 regcache->raw_supply (E_LIR_REGNUM, 145 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LIR)); 146 break; 147 case E_LAR_REGNUM: 148 regcache->raw_supply (E_LAR_REGNUM, 149 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LAR)); 150 break; 151 case E_MDRQ_REGNUM: 152 regcache->raw_supply (E_MDRQ_REGNUM, 153 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDRQ)); 154 break; 155 case E_E0_REGNUM: 156 regcache->raw_supply (E_E0_REGNUM, 157 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E0)); 158 break; 159 case E_E1_REGNUM: 160 regcache->raw_supply (E_E1_REGNUM, 161 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E1)); 162 break; 163 case E_E2_REGNUM: 164 regcache->raw_supply (E_E2_REGNUM, 165 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E2)); 166 break; 167 case E_E3_REGNUM: 168 regcache->raw_supply (E_E3_REGNUM, 169 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E3)); 170 break; 171 case E_E4_REGNUM: 172 regcache->raw_supply (E_E4_REGNUM, 173 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E4)); 174 break; 175 case E_E5_REGNUM: 176 regcache->raw_supply (E_E5_REGNUM, 177 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E5)); 178 break; 179 case E_E6_REGNUM: 180 regcache->raw_supply (E_E6_REGNUM, 181 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E6)); 182 break; 183 case E_E7_REGNUM: 184 regcache->raw_supply (E_E7_REGNUM, 185 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E7)); 186 break; 187 188 /* ssp, msp, and usp are inaccessible. */ 189 case E_E8_REGNUM: 190 regcache->raw_supply_zeroed (E_E8_REGNUM); 191 break; 192 case E_E9_REGNUM: 193 regcache->raw_supply_zeroed (E_E9_REGNUM); 194 break; 195 case E_E10_REGNUM: 196 regcache->raw_supply_zeroed (E_E10_REGNUM); 197 break; 198 case E_MCRH_REGNUM: 199 regcache->raw_supply (E_MCRH_REGNUM, 200 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRH)); 201 break; 202 case E_MCRL_REGNUM: 203 regcache->raw_supply (E_MCRL_REGNUM, 204 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRL)); 205 break; 206 case E_MCVF_REGNUM: 207 regcache->raw_supply (E_MCVF_REGNUM, 208 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCVF)); 209 break; 210 case E_FPCR_REGNUM: 211 /* FPCR is numbered among the GP regs, but handled as an FP reg. 212 Do nothing. */ 213 break; 214 case E_FPCR_REGNUM + 1: 215 /* The two unused registers beyond fpcr are inaccessible. */ 216 regcache->raw_supply_zeroed (E_FPCR_REGNUM + 1); 217 break; 218 case E_FPCR_REGNUM + 2: 219 regcache->raw_supply_zeroed (E_FPCR_REGNUM + 2); 220 break; 221 default: /* An error, obviously, but should we error out? */ 222 break; 223 case -1: 224 for (i = 0; i < MN10300_ELF_NGREG; i++) 225 am33_supply_gregset_method (regset, regcache, i, gregs, len); 226 break; 227 } 228 return; 229 } 230 231 /* Copy fp register value of REGNUM from regset to regcache. 232 If REGNUM is -1, do this for all fp registers in regset. */ 233 234 static void 235 am33_supply_fpregset_method (const struct regset *regset, 236 struct regcache *regcache, 237 int regnum, const void *fpregs, size_t len) 238 { 239 const mn10300_elf_fpregset_t *fpregset 240 = (const mn10300_elf_fpregset_t *) fpregs; 241 242 gdb_assert (len >= sizeof (mn10300_elf_fpregset_t)); 243 244 if (regnum == -1) 245 { 246 int i; 247 248 for (i = 0; i < MN10300_ELF_NFPREG; i++) 249 am33_supply_fpregset_method (regset, regcache, 250 E_FS0_REGNUM + i, fpregs, len); 251 am33_supply_fpregset_method (regset, regcache, 252 E_FPCR_REGNUM, fpregs, len); 253 } 254 else if (regnum == E_FPCR_REGNUM) 255 regcache->raw_supply (E_FPCR_REGNUM, &fpregset->fpcr); 256 else if (E_FS0_REGNUM <= regnum 257 && regnum < E_FS0_REGNUM + MN10300_ELF_NFPREG) 258 regcache->raw_supply (regnum, &fpregset->fpregs[regnum - E_FS0_REGNUM]); 259 260 return; 261 } 262 263 /* Copy register values from regcache to regset. */ 264 265 static void 266 am33_collect_gregset_method (const struct regset *regset, 267 const struct regcache *regcache, 268 int regnum, void *gregs, size_t len) 269 { 270 mn10300_elf_gregset_t *regp = (gdb_byte (*)[28][4]) gregs; 271 int i; 272 273 gdb_assert (len >= sizeof (mn10300_elf_gregset_t)); 274 275 switch (regnum) { 276 case E_D0_REGNUM: 277 regcache->raw_collect (E_D0_REGNUM, 278 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D0)); 279 break; 280 case E_D1_REGNUM: 281 regcache->raw_collect (E_D1_REGNUM, 282 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D1)); 283 break; 284 case E_D2_REGNUM: 285 regcache->raw_collect (E_D2_REGNUM, 286 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D2)); 287 break; 288 case E_D3_REGNUM: 289 regcache->raw_collect (E_D3_REGNUM, 290 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_D3)); 291 break; 292 case E_A0_REGNUM: 293 regcache->raw_collect (E_A0_REGNUM, 294 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A0)); 295 break; 296 case E_A1_REGNUM: 297 regcache->raw_collect (E_A1_REGNUM, 298 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A1)); 299 break; 300 case E_A2_REGNUM: 301 regcache->raw_collect (E_A2_REGNUM, 302 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A2)); 303 break; 304 case E_A3_REGNUM: 305 regcache->raw_collect (E_A3_REGNUM, 306 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_A3)); 307 break; 308 case E_SP_REGNUM: 309 regcache->raw_collect (E_SP_REGNUM, 310 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_SP)); 311 break; 312 case E_PC_REGNUM: 313 regcache->raw_collect (E_PC_REGNUM, 314 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_PC)); 315 break; 316 case E_MDR_REGNUM: 317 regcache->raw_collect (E_MDR_REGNUM, 318 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDR)); 319 break; 320 case E_PSW_REGNUM: 321 regcache->raw_collect (E_PSW_REGNUM, 322 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_EPSW)); 323 break; 324 case E_LIR_REGNUM: 325 regcache->raw_collect (E_LIR_REGNUM, 326 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LIR)); 327 break; 328 case E_LAR_REGNUM: 329 regcache->raw_collect (E_LAR_REGNUM, 330 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_LAR)); 331 break; 332 case E_MDRQ_REGNUM: 333 regcache->raw_collect (E_MDRQ_REGNUM, 334 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MDRQ)); 335 break; 336 case E_E0_REGNUM: 337 regcache->raw_collect (E_E0_REGNUM, 338 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E0)); 339 break; 340 case E_E1_REGNUM: 341 regcache->raw_collect (E_E1_REGNUM, 342 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E1)); 343 break; 344 case E_E2_REGNUM: 345 regcache->raw_collect (E_E2_REGNUM, 346 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E2)); 347 break; 348 case E_E3_REGNUM: 349 regcache->raw_collect (E_E3_REGNUM, 350 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E3)); 351 break; 352 case E_E4_REGNUM: 353 regcache->raw_collect (E_E4_REGNUM, 354 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E4)); 355 break; 356 case E_E5_REGNUM: 357 regcache->raw_collect (E_E5_REGNUM, 358 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E5)); 359 break; 360 case E_E6_REGNUM: 361 regcache->raw_collect (E_E6_REGNUM, 362 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E6)); 363 break; 364 case E_E7_REGNUM: 365 regcache->raw_collect (E_E7_REGNUM, 366 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_E7)); 367 break; 368 369 /* ssp, msp, and usp are inaccessible. */ 370 case E_E8_REGNUM: 371 /* The gregset struct has noplace to put this: do nothing. */ 372 break; 373 case E_E9_REGNUM: 374 /* The gregset struct has noplace to put this: do nothing. */ 375 break; 376 case E_E10_REGNUM: 377 /* The gregset struct has noplace to put this: do nothing. */ 378 break; 379 case E_MCRH_REGNUM: 380 regcache->raw_collect (E_MCRH_REGNUM, 381 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRH)); 382 break; 383 case E_MCRL_REGNUM: 384 regcache->raw_collect (E_MCRL_REGNUM, 385 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCRL)); 386 break; 387 case E_MCVF_REGNUM: 388 regcache->raw_collect (E_MCVF_REGNUM, 389 (regp + MN10300_ELF_GREGSET_T_REG_INDEX_MCVF)); 390 break; 391 case E_FPCR_REGNUM: 392 /* FPCR is numbered among the GP regs, but handled as an FP reg. 393 Do nothing. */ 394 break; 395 case E_FPCR_REGNUM + 1: 396 /* The gregset struct has noplace to put this: do nothing. */ 397 break; 398 case E_FPCR_REGNUM + 2: 399 /* The gregset struct has noplace to put this: do nothing. */ 400 break; 401 default: /* An error, obviously, but should we error out? */ 402 break; 403 case -1: 404 for (i = 0; i < MN10300_ELF_NGREG; i++) 405 am33_collect_gregset_method (regset, regcache, i, gregs, len); 406 break; 407 } 408 return; 409 } 410 411 /* Copy fp register values from regcache to regset. */ 412 413 static void 414 am33_collect_fpregset_method (const struct regset *regset, 415 const struct regcache *regcache, 416 int regnum, void *fpregs, size_t len) 417 { 418 mn10300_elf_fpregset_t *fpregset = (mn10300_elf_fpregset_t *) fpregs; 419 420 gdb_assert (len >= sizeof (mn10300_elf_fpregset_t)); 421 422 if (regnum == -1) 423 { 424 int i; 425 for (i = 0; i < MN10300_ELF_NFPREG; i++) 426 am33_collect_fpregset_method (regset, regcache, E_FS0_REGNUM + i, 427 fpregs, len); 428 am33_collect_fpregset_method (regset, regcache, 429 E_FPCR_REGNUM, fpregs, len); 430 } 431 else if (regnum == E_FPCR_REGNUM) 432 regcache->raw_collect (E_FPCR_REGNUM, &fpregset->fpcr); 433 else if (E_FS0_REGNUM <= regnum 434 && regnum < E_FS0_REGNUM + MN10300_ELF_NFPREG) 435 regcache->raw_collect (regnum, &fpregset->fpregs[regnum - E_FS0_REGNUM]); 436 437 return; 438 } 439 440 static const struct regset am33_gregset = 441 { 442 NULL, am33_supply_gregset_method, am33_collect_gregset_method 443 }; 444 445 static const struct regset am33_fpregset = 446 { 447 NULL, am33_supply_fpregset_method, am33_collect_fpregset_method 448 }; 449 450 /* Iterate over core file register note sections. */ 451 452 static void 453 am33_iterate_over_regset_sections (struct gdbarch *gdbarch, 454 iterate_over_regset_sections_cb *cb, 455 void *cb_data, 456 const struct regcache *regcache) 457 { 458 cb (".reg", sizeof (mn10300_elf_gregset_t), sizeof (mn10300_elf_gregset_t), 459 &am33_gregset, NULL, cb_data); 460 cb (".reg2", sizeof (mn10300_elf_fpregset_t), sizeof (mn10300_elf_fpregset_t), 461 &am33_fpregset, NULL, cb_data); 462 } 463 464 static void 465 am33_linux_sigframe_cache_init (const struct tramp_frame *self, 466 const frame_info_ptr &this_frame, 467 struct trad_frame_cache *this_cache, 468 CORE_ADDR func); 469 470 static const struct tramp_frame am33_linux_sigframe = { 471 SIGTRAMP_FRAME, 472 1, 473 { 474 /* mov 119,d0 */ 475 { 0x2c, ULONGEST_MAX }, 476 { 0x77, ULONGEST_MAX }, 477 { 0x00, ULONGEST_MAX }, 478 /* syscall 0 */ 479 { 0xf0, ULONGEST_MAX }, 480 { 0xe0, ULONGEST_MAX }, 481 { TRAMP_SENTINEL_INSN, ULONGEST_MAX } 482 }, 483 am33_linux_sigframe_cache_init 484 }; 485 486 static const struct tramp_frame am33_linux_rt_sigframe = { 487 SIGTRAMP_FRAME, 488 1, 489 { 490 /* mov 173,d0 */ 491 { 0x2c, ULONGEST_MAX }, 492 { 0xad, ULONGEST_MAX }, 493 { 0x00, ULONGEST_MAX }, 494 /* syscall 0 */ 495 { 0xf0, ULONGEST_MAX }, 496 { 0xe0, ULONGEST_MAX }, 497 { TRAMP_SENTINEL_INSN, ULONGEST_MAX } 498 }, 499 am33_linux_sigframe_cache_init 500 }; 501 502 /* Relevant struct definitions for signal handling... 503 504 From arch/mn10300/kernel/sigframe.h: 505 506 struct sigframe 507 { 508 void (*pretcode)(void); 509 int sig; 510 struct sigcontext *psc; 511 struct sigcontext sc; 512 struct fpucontext fpuctx; 513 unsigned long extramask[_NSIG_WORDS-1]; 514 char retcode[8]; 515 }; 516 517 struct rt_sigframe 518 { 519 void (*pretcode)(void); 520 int sig; 521 struct siginfo *pinfo; 522 void *puc; 523 struct siginfo info; 524 struct ucontext uc; 525 struct fpucontext fpuctx; 526 char retcode[8]; 527 }; 528 529 From include/asm-mn10300/ucontext.h: 530 531 struct ucontext { 532 unsigned long uc_flags; 533 struct ucontext *uc_link; 534 stack_t uc_stack; 535 struct sigcontext uc_mcontext; 536 sigset_t uc_sigmask; 537 }; 538 539 From include/asm-mn10300/sigcontext.h: 540 541 struct fpucontext { 542 unsigned long fs[32]; 543 unsigned long fpcr; 544 }; 545 546 struct sigcontext { 547 unsigned long d0; 548 unsigned long d1; 549 unsigned long d2; 550 unsigned long d3; 551 unsigned long a0; 552 unsigned long a1; 553 unsigned long a2; 554 unsigned long a3; 555 unsigned long e0; 556 unsigned long e1; 557 unsigned long e2; 558 unsigned long e3; 559 unsigned long e4; 560 unsigned long e5; 561 unsigned long e6; 562 unsigned long e7; 563 unsigned long lar; 564 unsigned long lir; 565 unsigned long mdr; 566 unsigned long mcvf; 567 unsigned long mcrl; 568 unsigned long mcrh; 569 unsigned long mdrq; 570 unsigned long sp; 571 unsigned long epsw; 572 unsigned long pc; 573 struct fpucontext *fpucontext; 574 unsigned long oldmask; 575 }; */ 576 577 578 #define AM33_SIGCONTEXT_D0 0 579 #define AM33_SIGCONTEXT_D1 4 580 #define AM33_SIGCONTEXT_D2 8 581 #define AM33_SIGCONTEXT_D3 12 582 #define AM33_SIGCONTEXT_A0 16 583 #define AM33_SIGCONTEXT_A1 20 584 #define AM33_SIGCONTEXT_A2 24 585 #define AM33_SIGCONTEXT_A3 28 586 #define AM33_SIGCONTEXT_E0 32 587 #define AM33_SIGCONTEXT_E1 36 588 #define AM33_SIGCONTEXT_E2 40 589 #define AM33_SIGCONTEXT_E3 44 590 #define AM33_SIGCONTEXT_E4 48 591 #define AM33_SIGCONTEXT_E5 52 592 #define AM33_SIGCONTEXT_E6 56 593 #define AM33_SIGCONTEXT_E7 60 594 #define AM33_SIGCONTEXT_LAR 64 595 #define AM33_SIGCONTEXT_LIR 68 596 #define AM33_SIGCONTEXT_MDR 72 597 #define AM33_SIGCONTEXT_MCVF 76 598 #define AM33_SIGCONTEXT_MCRL 80 599 #define AM33_SIGCONTEXT_MCRH 84 600 #define AM33_SIGCONTEXT_MDRQ 88 601 #define AM33_SIGCONTEXT_SP 92 602 #define AM33_SIGCONTEXT_EPSW 96 603 #define AM33_SIGCONTEXT_PC 100 604 #define AM33_SIGCONTEXT_FPUCONTEXT 104 605 606 607 static void 608 am33_linux_sigframe_cache_init (const struct tramp_frame *self, 609 const frame_info_ptr &this_frame, 610 struct trad_frame_cache *this_cache, 611 CORE_ADDR func) 612 { 613 CORE_ADDR sc_base, fpubase; 614 int i; 615 616 sc_base = get_frame_register_unsigned (this_frame, E_SP_REGNUM); 617 if (self == &am33_linux_sigframe) 618 { 619 sc_base += 8; 620 sc_base = get_frame_memory_unsigned (this_frame, sc_base, 4); 621 } 622 else 623 { 624 sc_base += 12; 625 sc_base = get_frame_memory_unsigned (this_frame, sc_base, 4); 626 sc_base += 20; 627 } 628 629 trad_frame_set_reg_addr (this_cache, E_D0_REGNUM, 630 sc_base + AM33_SIGCONTEXT_D0); 631 trad_frame_set_reg_addr (this_cache, E_D1_REGNUM, 632 sc_base + AM33_SIGCONTEXT_D1); 633 trad_frame_set_reg_addr (this_cache, E_D2_REGNUM, 634 sc_base + AM33_SIGCONTEXT_D2); 635 trad_frame_set_reg_addr (this_cache, E_D3_REGNUM, 636 sc_base + AM33_SIGCONTEXT_D3); 637 638 trad_frame_set_reg_addr (this_cache, E_A0_REGNUM, 639 sc_base + AM33_SIGCONTEXT_A0); 640 trad_frame_set_reg_addr (this_cache, E_A1_REGNUM, 641 sc_base + AM33_SIGCONTEXT_A1); 642 trad_frame_set_reg_addr (this_cache, E_A2_REGNUM, 643 sc_base + AM33_SIGCONTEXT_A2); 644 trad_frame_set_reg_addr (this_cache, E_A3_REGNUM, 645 sc_base + AM33_SIGCONTEXT_A3); 646 647 trad_frame_set_reg_addr (this_cache, E_E0_REGNUM, 648 sc_base + AM33_SIGCONTEXT_E0); 649 trad_frame_set_reg_addr (this_cache, E_E1_REGNUM, 650 sc_base + AM33_SIGCONTEXT_E1); 651 trad_frame_set_reg_addr (this_cache, E_E2_REGNUM, 652 sc_base + AM33_SIGCONTEXT_E2); 653 trad_frame_set_reg_addr (this_cache, E_E3_REGNUM, 654 sc_base + AM33_SIGCONTEXT_E3); 655 trad_frame_set_reg_addr (this_cache, E_E4_REGNUM, 656 sc_base + AM33_SIGCONTEXT_E4); 657 trad_frame_set_reg_addr (this_cache, E_E5_REGNUM, 658 sc_base + AM33_SIGCONTEXT_E5); 659 trad_frame_set_reg_addr (this_cache, E_E6_REGNUM, 660 sc_base + AM33_SIGCONTEXT_E6); 661 trad_frame_set_reg_addr (this_cache, E_E7_REGNUM, 662 sc_base + AM33_SIGCONTEXT_E7); 663 664 trad_frame_set_reg_addr (this_cache, E_LAR_REGNUM, 665 sc_base + AM33_SIGCONTEXT_LAR); 666 trad_frame_set_reg_addr (this_cache, E_LIR_REGNUM, 667 sc_base + AM33_SIGCONTEXT_LIR); 668 trad_frame_set_reg_addr (this_cache, E_MDR_REGNUM, 669 sc_base + AM33_SIGCONTEXT_MDR); 670 trad_frame_set_reg_addr (this_cache, E_MCVF_REGNUM, 671 sc_base + AM33_SIGCONTEXT_MCVF); 672 trad_frame_set_reg_addr (this_cache, E_MCRL_REGNUM, 673 sc_base + AM33_SIGCONTEXT_MCRL); 674 trad_frame_set_reg_addr (this_cache, E_MDRQ_REGNUM, 675 sc_base + AM33_SIGCONTEXT_MDRQ); 676 677 trad_frame_set_reg_addr (this_cache, E_SP_REGNUM, 678 sc_base + AM33_SIGCONTEXT_SP); 679 trad_frame_set_reg_addr (this_cache, E_PSW_REGNUM, 680 sc_base + AM33_SIGCONTEXT_EPSW); 681 trad_frame_set_reg_addr (this_cache, E_PC_REGNUM, 682 sc_base + AM33_SIGCONTEXT_PC); 683 684 fpubase = get_frame_memory_unsigned (this_frame, 685 sc_base + AM33_SIGCONTEXT_FPUCONTEXT, 686 4); 687 if (fpubase) 688 { 689 for (i = 0; i < 32; i++) 690 { 691 trad_frame_set_reg_addr (this_cache, E_FS0_REGNUM + i, 692 fpubase + 4 * i); 693 } 694 trad_frame_set_reg_addr (this_cache, E_FPCR_REGNUM, fpubase + 4 * 32); 695 } 696 697 trad_frame_set_id (this_cache, frame_id_build (sc_base, func)); 698 } 699 700 /* AM33 GNU/Linux osabi has been recognized. 701 Now's our chance to register our corefile handling. */ 702 703 static void 704 am33_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch) 705 { 706 linux_init_abi (info, gdbarch, 0); 707 708 set_gdbarch_iterate_over_regset_sections 709 (gdbarch, am33_iterate_over_regset_sections); 710 set_solib_svr4_fetch_link_map_offsets 711 (gdbarch, linux_ilp32_fetch_link_map_offsets); 712 713 tramp_frame_prepend_unwinder (gdbarch, &am33_linux_sigframe); 714 tramp_frame_prepend_unwinder (gdbarch, &am33_linux_rt_sigframe); 715 } 716 717 void _initialize_mn10300_linux_tdep (); 718 void 719 _initialize_mn10300_linux_tdep () 720 { 721 gdbarch_register_osabi (bfd_arch_mn10300, 0, 722 GDB_OSABI_LINUX, am33_linux_init_osabi); 723 } 724 725