0004-Add-support-for-Renesas-SH-sh4-architecture.patch 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913
  1. From 26e406962cf7298837b350b979afff0ac34ecb0b Mon Sep 17 00:00:00 2001
  2. From: Khem Raj <raj.khem@gmail.com>
  3. Date: Mon, 2 Mar 2015 02:31:12 +0000
  4. Subject: [PATCH 04/11] Add support for Renesas SH (sh4) architecture.
  5. gdb (7.4-1~cvs20111117.2) experimental; urgency=low
  6. .
  7. * Add Renesas SH (sh4) support (Closes: #576242)
  8. - Thanks Nobuhiro Iwamatsu, Takashi Yoshii.
  9. Author: Hector Oron <zumbi@debian.org>
  10. Bug-Debian: http://bugs.debian.org/576242
  11. Upstream-Status: Pending
  12. Signed-off-by: Khem Raj <raj.khem@gmail.com>
  13. ---
  14. gdb/Makefile.in | 2 +
  15. gdb/configure.host | 1 +
  16. gdb/sh-linux-tdep.c | 519 +++++++++++++++++++++++++++
  17. gdb/sh-tdep.c | 52 +--
  18. gdb/sh-tdep.h | 49 +++
  19. gdb/testsuite/gdb.asm/asm-source.exp | 5 +
  20. gdb/testsuite/gdb.asm/sh.inc | 3 +-
  21. gdb/testsuite/gdb.base/annota1.c | 3 +
  22. gdb/testsuite/gdb.base/annota3.c | 4 +
  23. gdb/testsuite/gdb.base/sigall.c | 3 +
  24. gdb/testsuite/gdb.base/signals.c | 4 +
  25. 11 files changed, 617 insertions(+), 28 deletions(-)
  26. diff --git a/gdb/Makefile.in b/gdb/Makefile.in
  27. index 4808357e651..a009004ab05 100644
  28. --- a/gdb/Makefile.in
  29. +++ b/gdb/Makefile.in
  30. @@ -2273,6 +2273,8 @@ ALLDEPFILES = \
  31. sh-nbsd-nat.c \
  32. sh-nbsd-tdep.c \
  33. sh-tdep.c \
  34. + sh-linux-tdep.c \
  35. + sh-linux-nat.c \
  36. sol2-tdep.c \
  37. solib-aix.c \
  38. solib-svr4.c \
  39. diff --git a/gdb/configure.host b/gdb/configure.host
  40. index ce528237291..5b5173a71aa 100644
  41. --- a/gdb/configure.host
  42. +++ b/gdb/configure.host
  43. @@ -148,6 +148,7 @@ riscv*-*-linux*) gdb_host=linux ;;
  44. s390*-*-linux*) gdb_host=linux ;;
  45. +sh*-*-linux*) gdb_host=linux ;;
  46. sh*-*-netbsdelf* | sh*-*-knetbsd*-gnu)
  47. gdb_host=nbsd ;;
  48. sh*-*-openbsd*) gdb_host=nbsd ;;
  49. diff --git a/gdb/sh-linux-tdep.c b/gdb/sh-linux-tdep.c
  50. index 5d2f38f5801..06a45b74827 100644
  51. --- a/gdb/sh-linux-tdep.c
  52. +++ b/gdb/sh-linux-tdep.c
  53. @@ -18,14 +18,37 @@
  54. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  55. #include "defs.h"
  56. +#include "gdbcore.h"
  57. +#include "frame.h"
  58. +#include "frame-base.h"
  59. +#include "frame-unwind.h"
  60. +#include "dwarf2-frame.h"
  61. +#include "value.h"
  62. +#include "regcache.h"
  63. +#include "inferior.h"
  64. #include "osabi.h"
  65. +#include "reggroups.h"
  66. +#include "arch-utils.h"
  67. +#include "floatformat.h"
  68. #include "solib-svr4.h"
  69. #include "symtab.h"
  70. +#include "gdb_string.h"
  71. +#include "command.h"
  72. +#include "gdb_assert.h"
  73. #include "trad-frame.h"
  74. #include "tramp-frame.h"
  75. +#include <sys/ptrace.h>
  76. +#include <sys/types.h>
  77. +#include <sys/param.h>
  78. +#include <sys/user.h>
  79. +#include <sys/syscall.h>
  80. +
  81. +#include <asm/ptrace.h>
  82. +
  83. +#include "regset.h"
  84. #include "glibc-tdep.h"
  85. #include "sh-tdep.h"
  86. #include "linux-tdep.h"
  87. @@ -181,9 +204,505 @@ static struct tramp_frame sh_linux_rt_sigreturn_tramp_frame = {
  88. sh_linux_rt_sigreturn_init
  89. };
  90. +/* Recognizing signal handler frames. */
  91. +
  92. +/* GNU/Linux has two flavors of signals. Normal signal handlers, and
  93. + "realtime" (RT) signals. The RT signals can provide additional
  94. + information to the signal handler if the SA_SIGINFO flag is set
  95. + when establishing a signal handler using `sigaction'. It is not
  96. + unlikely that future versions of GNU/Linux will support SA_SIGINFO
  97. + for normal signals too. */
  98. +
  99. +/* When the SH Linux kernel calls a signal handler and the
  100. + SA_RESTORER flag isn't set, the return address points to a bit of
  101. + code on the stack. This function returns whether the PC appears to
  102. + be within this bit of code.
  103. +
  104. + The instruction sequence for normal signals is
  105. + mov.w 1f,r3
  106. + trapa #16
  107. + or r0, r0
  108. + or r0, r0
  109. + or r0, r0
  110. + or r0, r0
  111. + or r0, r0
  112. + 1: .word __NR_sigreturn
  113. + or 0x9305 0xc310 0x200b 0x200b 0x200b 0x200b 0x200b 0x0077.
  114. +
  115. + Checking for the code sequence should be somewhat reliable, because
  116. + the effect is to call the system call sigreturn. This is unlikely
  117. + to occur anywhere other than a signal trampoline.
  118. +
  119. + It kind of sucks that we have to read memory from the process in
  120. + order to identify a signal trampoline, but there doesn't seem to be
  121. + any other way. The PC_IN_SIGTRAMP macro in tm-linux.h arranges to
  122. + only call us if no function name could be identified, which should
  123. + be the case since the code is on the stack.
  124. +
  125. + Detection of signal trampolines for handlers that set the
  126. + SA_RESTORER flag is in general not possible. Unfortunately this is
  127. + what the GNU C Library has been doing for quite some time now.
  128. + However, as of version 2.1.2, the GNU C Library uses signal
  129. + trampolines (named __restore and __restore_rt) that are identical
  130. + to the ones used by the kernel. Therefore, these trampolines are
  131. + supported too. */
  132. +
  133. +#define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */
  134. +#define TRAP16 0xc310 /* Syscall w/no args (NR in R3) */
  135. +#define OR_R0_R0 0x200b /* or r0,r0 (insert to avoid hardware bug) */
  136. +
  137. +#define LINUX_SIGTRAMP_INSN0 MOVW(7) /* Move mem word at PC+7 to R3 */
  138. +#define LINUX_SIGTRAMP_INSN1 TRAP16 /* Syscall w/no args (NR in R3) */
  139. +#define LINUX_SIGTRAMP_INSN2 OR_R0_R0 /* or r0,r0 (insert to avoid hardware bug) */
  140. +
  141. +static const unsigned short linux_sigtramp_code[] =
  142. +{
  143. + LINUX_SIGTRAMP_INSN0,
  144. + LINUX_SIGTRAMP_INSN1,
  145. + LINUX_SIGTRAMP_INSN2,
  146. + LINUX_SIGTRAMP_INSN2,
  147. + LINUX_SIGTRAMP_INSN2,
  148. + LINUX_SIGTRAMP_INSN2,
  149. + LINUX_SIGTRAMP_INSN2,
  150. + __NR_sigreturn
  151. +};
  152. +
  153. +#define LINUX_SIGTRAMP_LEN (sizeof linux_sigtramp_code)
  154. +
  155. +/* If PC is in a sigtramp routine, return the address of the start of
  156. + the routine. Otherwise, return 0. */
  157. +
  158. +static CORE_ADDR
  159. +sh_linux_sigtramp_start (struct frame_info *next_frame)
  160. +{
  161. + CORE_ADDR pc = get_frame_pc (next_frame);
  162. + gdb_byte buf[LINUX_SIGTRAMP_LEN];
  163. +
  164. + /* We only recognize a signal trampoline if PC is at the start of
  165. + one of the three instructions. We optimize for finding the PC at
  166. + the start, as will be the case when the trampoline is not the
  167. + first frame on the stack. We assume that in the case where the
  168. + PC is not at the start of the instruction sequence, there will be
  169. + a few trailing readable bytes on the stack. */
  170. +
  171. + if (!safe_frame_unwind_memory (next_frame, pc, buf, LINUX_SIGTRAMP_LEN))
  172. + return 0;
  173. +
  174. + if (buf[0] != LINUX_SIGTRAMP_INSN0)
  175. + {
  176. + if (buf[0] != LINUX_SIGTRAMP_INSN1)
  177. + return 0;
  178. +
  179. + pc -= 2;
  180. +
  181. + if (!safe_frame_unwind_memory (next_frame, pc, buf, LINUX_SIGTRAMP_LEN))
  182. + return 0;
  183. + }
  184. +
  185. + if (memcmp (buf, linux_sigtramp_code, LINUX_SIGTRAMP_LEN) != 0)
  186. + return 0;
  187. +
  188. + return pc;
  189. +}
  190. +
  191. +/* This function does the same for RT signals. Here the instruction
  192. + sequence is
  193. + mov.w 1f,r3
  194. + trapa #16
  195. + or r0, r0
  196. + or r0, r0
  197. + or r0, r0
  198. + or r0, r0
  199. + or r0, r0
  200. + 1: .word __NR_rt_sigreturn
  201. + or 0x9305 0xc310 0x200b 0x200b 0x200b 0x200b 0x200b 0x00ad.
  202. +
  203. + The effect is to call the system call rt_sigreturn. */
  204. +
  205. +#define LINUX_RT_SIGTRAMP_INSN0 MOVW(7) /* Move mem word at PC+7 to R3 */
  206. +#define LINUX_RT_SIGTRAMP_INSN1 TRAP16 /* Syscall w/no args (NR in R3) */
  207. +#define LINUX_RT_SIGTRAMP_INSN2 OR_R0_R0 /* or r0,r0 (insert to avoid hardware bug) */
  208. +
  209. +static const unsigned short linux_rt_sigtramp_code[] =
  210. +{
  211. + LINUX_RT_SIGTRAMP_INSN0,
  212. + LINUX_RT_SIGTRAMP_INSN1,
  213. + LINUX_RT_SIGTRAMP_INSN2,
  214. + LINUX_RT_SIGTRAMP_INSN2,
  215. + LINUX_RT_SIGTRAMP_INSN2,
  216. + LINUX_RT_SIGTRAMP_INSN2,
  217. + LINUX_RT_SIGTRAMP_INSN2,
  218. + __NR_rt_sigreturn
  219. +};
  220. +
  221. +#define LINUX_RT_SIGTRAMP_LEN (sizeof linux_rt_sigtramp_code)
  222. +
  223. +/* If PC is in a RT sigtramp routine, return the address of the start
  224. + of the routine. Otherwise, return 0. */
  225. +
  226. +static CORE_ADDR
  227. +sh_linux_rt_sigtramp_start (struct frame_info *next_frame)
  228. +{
  229. + CORE_ADDR pc = get_frame_pc (next_frame);
  230. + gdb_byte buf[LINUX_RT_SIGTRAMP_LEN];
  231. +
  232. + /* We only recognize a signal trampoline if PC is at the start of
  233. + one of the two instructions. We optimize for finding the PC at
  234. + the start, as will be the case when the trampoline is not the
  235. + first frame on the stack. We assume that in the case where the
  236. + PC is not at the start of the instruction sequence, there will be
  237. + a few trailing readable bytes on the stack. */
  238. +
  239. + if (!safe_frame_unwind_memory (next_frame, pc, buf, LINUX_RT_SIGTRAMP_LEN))
  240. + return 0;
  241. +
  242. + if (buf[0] != LINUX_RT_SIGTRAMP_INSN0)
  243. + {
  244. + if (buf[0] != LINUX_RT_SIGTRAMP_INSN1)
  245. + return 0;
  246. +
  247. + pc -= 2;
  248. +
  249. + if (!safe_frame_unwind_memory (next_frame, pc, buf,
  250. + LINUX_RT_SIGTRAMP_LEN))
  251. + return 0;
  252. + }
  253. +
  254. + if (memcmp (buf, linux_rt_sigtramp_code, LINUX_RT_SIGTRAMP_LEN) != 0)
  255. + return 0;
  256. +
  257. + return pc;
  258. +}
  259. +
  260. +/* Return whether PC is in a GNU/Linux sigtramp routine. */
  261. +
  262. +static int
  263. +sh_linux_sigtramp_p (struct frame_info *this_frame)
  264. +{
  265. + CORE_ADDR pc = get_frame_pc (this_frame);
  266. + char *name;
  267. +
  268. + find_pc_partial_function (pc, &name, NULL, NULL);
  269. +
  270. + /* If we have NAME, we can optimize the search. The trampolines are
  271. + named __restore and __restore_rt. However, they aren't dynamically
  272. + exported from the shared C library, so the trampoline may appear to
  273. + be part of the preceding function. This should always be sigaction,
  274. + __sigaction, or __libc_sigaction (all aliases to the same function). */
  275. + if (name == NULL || strstr (name, "sigaction") != NULL)
  276. + return (sh_linux_sigtramp_start (this_frame) != 0
  277. + || sh_linux_rt_sigtramp_start (this_frame) != 0);
  278. +
  279. + return (strcmp ("__restore", name) == 0
  280. + || strcmp ("__restore_rt", name) == 0);
  281. +}
  282. +
  283. +/* Offset to struct sigcontext in ucontext, from <asm/ucontext.h>. */
  284. +#define SH_LINUX_UCONTEXT_SIGCONTEXT_OFFSET 12
  285. +
  286. +
  287. +/* Assuming NEXT_FRAME is a frame following a GNU/Linux sigtramp
  288. + routine, return the address of the associated sigcontext structure. */
  289. +
  290. +static CORE_ADDR
  291. +sh_linux_sigcontext_addr (struct frame_info *this_frame)
  292. +{
  293. + CORE_ADDR pc;
  294. + CORE_ADDR sp;
  295. +
  296. + sp = get_frame_register_unsigned (this_frame, SP_REGNUM);
  297. +
  298. + pc = sh_linux_sigtramp_start (this_frame);
  299. + if (pc)
  300. + {
  301. + return sp;
  302. + }
  303. +
  304. + pc = sh_linux_rt_sigtramp_start (this_frame);
  305. + if (pc)
  306. + {
  307. + CORE_ADDR ucontext_addr;
  308. +
  309. + /* The sigcontext structure is part of the user context. A
  310. + pointer to the user context is passed as the third argument
  311. + to the signal handler. */
  312. + ucontext_addr = get_frame_register_unsigned (this_frame, ARG0_REGNUM+2);
  313. + return ucontext_addr + SH_LINUX_UCONTEXT_SIGCONTEXT_OFFSET;
  314. + }
  315. +
  316. + error ("Couldn't recognize signal trampoline.");
  317. + return 0;
  318. +}
  319. +
  320. +/* Signal trampolines. */
  321. +extern struct sh_frame_cache *sh_alloc_frame_cache (void);
  322. +
  323. +static struct sh_frame_cache *
  324. +sh_linux_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
  325. +{
  326. + struct sh_frame_cache *cache;
  327. + struct gdbarch_tdep *tdep = gdbarch_tdep (get_current_arch ());
  328. + CORE_ADDR sigcontext_addr;
  329. +
  330. + if (*this_cache)
  331. + return *this_cache;
  332. +
  333. + cache = sh_alloc_frame_cache ();
  334. +
  335. + cache->base = get_frame_register_unsigned (this_frame, SP_REGNUM);
  336. + sigcontext_addr = tdep->sigcontext_addr (this_frame);
  337. + if (tdep->sc_reg_offset)
  338. + {
  339. + int i;
  340. +
  341. + gdb_assert (tdep->sc_num_regs <= SH_NUM_REGS);
  342. +
  343. + for (i = 0; i < tdep->sc_num_regs; i++)
  344. + if (tdep->sc_reg_offset[i] != -1)
  345. + cache->saved_regs[i] = sigcontext_addr + tdep->sc_reg_offset[i];
  346. + }
  347. +
  348. + *this_cache = cache;
  349. + return cache;
  350. +}
  351. +
  352. +static void
  353. +sh_linux_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache,
  354. + struct frame_id *this_id)
  355. +{
  356. + struct sh_frame_cache *cache =
  357. + sh_linux_sigtramp_frame_cache (this_frame, this_cache);
  358. +
  359. + (*this_id) = frame_id_build (cache->base + 64, cache->pc);
  360. +}
  361. +
  362. +extern struct value * sh_frame_prev_register ();
  363. +static struct value *
  364. +sh_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
  365. + void **this_cache, int regnum)
  366. +{
  367. + sh_linux_sigtramp_frame_cache (this_frame, this_cache);
  368. +
  369. + return sh_frame_prev_register (this_frame, this_cache, regnum);
  370. +}
  371. +
  372. +static int
  373. +sh_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
  374. + struct frame_info *this_frame,
  375. + void **this_prologue_cache)
  376. +{
  377. + struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame));
  378. +
  379. + /* We shouldn't even bother if we don't have a sigcontext_addr
  380. + handler. */
  381. + if (tdep->sigcontext_addr == NULL)
  382. + return 0;
  383. +
  384. + if (tdep->sigtramp_p != NULL)
  385. + {
  386. + if (tdep->sigtramp_p (this_frame))
  387. + return 1;
  388. + }
  389. +
  390. + return 0;
  391. +}
  392. +
  393. +static const struct frame_unwind sh_linux_sigtramp_frame_unwind =
  394. +{
  395. + SIGTRAMP_FRAME,
  396. + sh_linux_sigtramp_frame_this_id,
  397. + sh_linux_sigtramp_frame_prev_register,
  398. + NULL,
  399. + sh_linux_sigtramp_frame_sniffer
  400. +};
  401. +
  402. +/* Supply register REGNUM from the buffer specified by GREGS and LEN
  403. + in the general-purpose register set REGSET to register cache
  404. + REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
  405. +
  406. +void
  407. +sh_supply_gregset (const struct regset *regset, struct regcache *regcache,
  408. + int regnum, const void *gregs, size_t len)
  409. +{
  410. + const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
  411. + const char *regs = gregs;
  412. + int i;
  413. +
  414. + gdb_assert (len == tdep->sizeof_gregset);
  415. +
  416. + for (i = 0; i < tdep->gregset_num_regs; i++)
  417. + {
  418. + if ((regnum == i || regnum == -1)
  419. + && tdep->gregset_reg_offset[i] != -1)
  420. + regcache_raw_supply (regcache, i, regs + tdep->gregset_reg_offset[i]);
  421. + }
  422. +}
  423. +
  424. +/* Collect register REGNUM from the register cache REGCACHE and store
  425. + it in the buffer specified by GREGS and LEN as described by the
  426. + general-purpose register set REGSET. If REGNUM is -1, do this for
  427. + all registers in REGSET. */
  428. +
  429. +void
  430. +sh_collect_gregset (const struct regset *regset,
  431. + const struct regcache *regcache,
  432. + int regnum, void *gregs, size_t len)
  433. +{
  434. + const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
  435. + char *regs = gregs;
  436. + int i;
  437. +
  438. + gdb_assert (len == tdep->sizeof_gregset);
  439. +
  440. + for (i = 0; i < tdep->gregset_num_regs; i++)
  441. + {
  442. + if ((regnum == i || regnum == -1)
  443. + && tdep->gregset_reg_offset[i] != -1)
  444. + regcache_raw_collect (regcache, i, regs + tdep->gregset_reg_offset[i]);
  445. + }
  446. +}
  447. +
  448. +/* Supply register REGNUM from the buffer specified by FPREGS and LEN
  449. + in the floating-point register set REGSET to register cache
  450. + REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
  451. +
  452. +static void
  453. +sh_supply_fpregset (const struct regset *regset, struct regcache *regcache,
  454. + int regnum, const void *fpregs, size_t len)
  455. +{
  456. + const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
  457. + const char *regs = fpregs;
  458. + int i;
  459. +
  460. + gdb_assert (len == tdep->sizeof_fpregset);
  461. + for (i = 0; i < 16; i++)
  462. + {
  463. + if (regnum == i+25 || regnum == -1)
  464. + regcache_raw_supply (regcache, i+25, regs + i*4);
  465. + }
  466. + if (regnum == FPSCR_REGNUM || regnum == -1)
  467. + regcache_raw_supply (regcache, FPSCR_REGNUM, regs + 32*4);
  468. + if (regnum == FPUL_REGNUM || regnum == -1)
  469. + regcache_raw_supply (regcache, FPUL_REGNUM, regs + 33*4);
  470. +}
  471. +
  472. +/* Collect register REGNUM from the register cache REGCACHE and store
  473. + it in the buffer specified by FPREGS and LEN as described by the
  474. + floating-point register set REGSET. If REGNUM is -1, do this for
  475. + all registers in REGSET. */
  476. +
  477. +static void
  478. +sh_collect_fpregset (const struct regset *regset,
  479. + const struct regcache *regcache,
  480. + int regnum, void *fpregs, size_t len)
  481. +{
  482. + const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
  483. + char *regs = fpregs;
  484. + int i;
  485. +
  486. + gdb_assert (len == tdep->sizeof_fpregset);
  487. + for (i = 0; i < 16; i++)
  488. + {
  489. + if (regnum == i+25 || regnum == -1)
  490. + regcache_raw_collect (regcache, i+25, regs + i*4);
  491. + }
  492. + if (regnum == FPSCR_REGNUM || regnum == -1)
  493. + regcache_raw_collect (regcache, FPSCR_REGNUM, regs + 32*4);
  494. + if (regnum == FPUL_REGNUM || regnum == -1)
  495. + regcache_raw_collect (regcache, FPUL_REGNUM, regs + 33*4);
  496. +}
  497. +
  498. +/* Return the appropriate register set for the core section identified
  499. + by SECT_NAME and SECT_SIZE. */
  500. +
  501. +const struct regset *
  502. +sh_linux_regset_from_core_section (struct gdbarch *gdbarch,
  503. + const char *sect_name, size_t sect_size)
  504. +{
  505. + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  506. +
  507. + if (strcmp (sect_name, ".reg") == 0 && sect_size == tdep->sizeof_gregset)
  508. + {
  509. + if (tdep->gregset == NULL)
  510. + tdep->gregset = regset_alloc (gdbarch, sh_supply_gregset,
  511. + sh_collect_gregset);
  512. + return tdep->gregset;
  513. + }
  514. +
  515. + if ((strcmp (sect_name, ".reg2") == 0 && sect_size == tdep->sizeof_fpregset))
  516. + {
  517. + if (tdep->fpregset == NULL)
  518. + tdep->fpregset = regset_alloc (gdbarch, sh_supply_fpregset,
  519. + sh_collect_fpregset);
  520. + return tdep->fpregset;
  521. + }
  522. +
  523. + return NULL;
  524. +}
  525. +
  526. +/* The register sets used in GNU/Linux ELF core-dumps are identical to
  527. + the register sets in `struct user' that are used for a.out
  528. + core-dumps. These are also used by ptrace(2). The corresponding
  529. + types are `elf_gregset_t' for the general-purpose registers (with
  530. + `elf_greg_t' the type of a single GP register) and `elf_fpregset_t'
  531. + for the floating-point registers.
  532. +
  533. + Those types used to be available under the names `gregset_t' and
  534. + `fpregset_t' too, and GDB used those names in the past. But those
  535. + names are now used for the register sets used in the `mcontext_t'
  536. + type, which have a different size and layout. */
  537. +
  538. +/* Mapping between the general-purpose registers in `struct user'
  539. + format and GDB's register cache layout. */
  540. +
  541. +/* From <sys/reg.h>. */
  542. +static int sh_linux_gregset_reg_offset[] =
  543. +{
  544. + 0, 4, 8, 12, 16, 20, 24, 28,
  545. + 32, 36, 40, 44, 48, 52, 56, 60,
  546. +
  547. + REG_PC*4, REG_PR*4, REG_GBR*4, -1,
  548. + REG_MACH*4, REG_MACL*4, REG_SR*4,
  549. +};
  550. +
  551. +/* Mapping between the general-purpose registers in `struct
  552. + sigcontext' format and GDB's register cache layout. */
  553. +
  554. +/* From <asm/sigcontext.h>. */
  555. +static int sh_linux_sc_reg_offset[] =
  556. +{
  557. + 4, 8, 12, 16, 20, 24, 28, 32,
  558. + 36, 40, 44, 48, 52, 56, 60, 64,
  559. + 68, 72, 80, -1,
  560. + 84, 88, 76
  561. +};
  562. +
  563. static void
  564. sh_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
  565. {
  566. + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  567. + bfd abfd;
  568. +
  569. + tdep->gregset_reg_offset = sh_linux_gregset_reg_offset;
  570. + tdep->gregset_num_regs = ARRAY_SIZE (sh_linux_gregset_reg_offset);
  571. + tdep->sizeof_gregset = 23 * 4;
  572. +
  573. + tdep->jb_pc_offset = 32; /* From <bits/setjmp.h>. */
  574. +
  575. + tdep->sigtramp_p = sh_linux_sigtramp_p;
  576. + tdep->sigcontext_addr = sh_linux_sigcontext_addr;
  577. + tdep->sc_reg_offset = sh_linux_sc_reg_offset;
  578. + tdep->sc_num_regs = ARRAY_SIZE (sh_linux_sc_reg_offset);
  579. +
  580. + frame_unwind_append_unwinder(gdbarch, &sh_linux_sigtramp_frame_unwind);
  581. +
  582. + /* If we have a register mapping, enable the generic core file
  583. + support, unless it has already been enabled. */
  584. + if (tdep->gregset_reg_offset
  585. + && !gdbarch_regset_from_core_section_p (gdbarch))
  586. + set_gdbarch_regset_from_core_section (gdbarch,
  587. + sh_linux_regset_from_core_section);
  588. +
  589. linux_init_abi (info, gdbarch);
  590. /* GNU/Linux uses SVR4-style shared libraries. */
  591. diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
  592. index 7aadf9165ca..e173e215a2d 100644
  593. --- a/gdb/sh-tdep.c
  594. +++ b/gdb/sh-tdep.c
  595. @@ -21,6 +21,9 @@
  596. sac@cygnus.com. */
  597. #include "defs.h"
  598. +#include "arch-utils.h"
  599. +#include "command.h"
  600. +#include "dummy-frame.h"
  601. #include "frame.h"
  602. #include "frame-base.h"
  603. #include "frame-unwind.h"
  604. @@ -66,23 +69,6 @@ static const char *const sh_cc_enum[] = {
  605. static const char *sh_active_calling_convention = sh_cc_gcc;
  606. -#define SH_NUM_REGS 67
  607. -
  608. -struct sh_frame_cache
  609. -{
  610. - /* Base address. */
  611. - CORE_ADDR base;
  612. - LONGEST sp_offset;
  613. - CORE_ADDR pc;
  614. -
  615. - /* Flag showing that a frame has been created in the prologue code. */
  616. - int uses_fp;
  617. -
  618. - /* Saved registers. */
  619. - CORE_ADDR saved_regs[SH_NUM_REGS];
  620. - CORE_ADDR saved_sp;
  621. -};
  622. -
  623. static int
  624. sh_is_renesas_calling_convention (struct type *func_type)
  625. {
  626. @@ -1050,6 +1036,7 @@ sh_treat_as_flt_p (struct type *type)
  627. return 0;
  628. /* Otherwise if the type of that member is float, the whole type is
  629. treated as float. */
  630. + type = check_typedef (type);
  631. if (type->field (0).type ()->code () == TYPE_CODE_FLT)
  632. return 1;
  633. /* Otherwise it's not treated as float. */
  634. @@ -1100,7 +1087,7 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
  635. in four registers available. Loop thru args from first to last. */
  636. for (argnum = 0; argnum < nargs; argnum++)
  637. {
  638. - type = value_type (args[argnum]);
  639. + type = check_typedef (value_type (args[argnum]));
  640. len = TYPE_LENGTH (type);
  641. val = sh_justify_value_in_reg (gdbarch, args[argnum], len);
  642. @@ -1835,7 +1822,7 @@ sh_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
  643. reg->how = DWARF2_FRAME_REG_UNDEFINED;
  644. }
  645. -static struct sh_frame_cache *
  646. +struct sh_frame_cache *
  647. sh_alloc_frame_cache (void)
  648. {
  649. struct sh_frame_cache *cache;
  650. @@ -1862,7 +1849,7 @@ sh_alloc_frame_cache (void)
  651. return cache;
  652. }
  653. -static struct sh_frame_cache *
  654. +struct sh_frame_cache *
  655. sh_frame_cache (struct frame_info *this_frame, void **this_cache)
  656. {
  657. struct gdbarch *gdbarch = get_frame_arch (this_frame);
  658. @@ -1929,9 +1916,9 @@ sh_frame_cache (struct frame_info *this_frame, void **this_cache)
  659. return cache;
  660. }
  661. -static struct value *
  662. -sh_frame_prev_register (struct frame_info *this_frame,
  663. - void **this_cache, int regnum)
  664. +struct value *
  665. +sh_frame_prev_register (struct frame_info *this_frame, void **this_cache,
  666. + int regnum)
  667. {
  668. struct gdbarch *gdbarch = get_frame_arch (this_frame);
  669. struct sh_frame_cache *cache = sh_frame_cache (this_frame, this_cache);
  670. @@ -1945,7 +1932,7 @@ sh_frame_prev_register (struct frame_info *this_frame,
  671. the current frame. Frob regnum so that we pull the value from
  672. the correct place. */
  673. if (regnum == gdbarch_pc_regnum (gdbarch))
  674. - regnum = PR_REGNUM;
  675. + regnum = PR_REGNUM; /* XXX: really? */
  676. if (regnum < SH_NUM_REGS && cache->saved_regs[regnum] != -1)
  677. return frame_unwind_got_memory (this_frame, regnum,
  678. @@ -2234,8 +2221,8 @@ sh_return_in_first_hidden_param_p (struct gdbarch *gdbarch,
  679. static struct gdbarch *
  680. sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
  681. {
  682. - struct gdbarch *gdbarch;
  683. struct gdbarch_tdep *tdep;
  684. + struct gdbarch *gdbarch;
  685. /* If there is already a candidate, use it. */
  686. arches = gdbarch_list_lookup_by_info (arches, &info);
  687. @@ -2247,6 +2234,18 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
  688. tdep = XCNEW (struct gdbarch_tdep);
  689. gdbarch = gdbarch_alloc (&info, tdep);
  690. + /* General-purpose registers. */
  691. + tdep->gregset = NULL;
  692. + tdep->gregset_reg_offset = NULL;
  693. + tdep->gregset_num_regs = 23;
  694. + tdep->sizeof_gregset = 0;
  695. +
  696. + /* Floating-point registers. */
  697. + tdep->fpregset = NULL;
  698. + tdep->sizeof_fpregset = 34*4;
  699. +
  700. + tdep->jb_pc_offset = -1;
  701. +
  702. set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
  703. set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
  704. set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
  705. @@ -2398,10 +2397,11 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
  706. break;
  707. }
  708. + dwarf2_append_unwinders (gdbarch);
  709. +
  710. /* Hook in ABI-specific overrides, if they have been registered. */
  711. gdbarch_init_osabi (info, gdbarch);
  712. - dwarf2_append_unwinders (gdbarch);
  713. frame_unwind_append_unwinder (gdbarch, &sh_stub_unwind);
  714. frame_unwind_append_unwinder (gdbarch, &sh_frame_unwind);
  715. diff --git a/gdb/sh-tdep.h b/gdb/sh-tdep.h
  716. index 76e2e76e39b..2710f63010c 100644
  717. --- a/gdb/sh-tdep.h
  718. +++ b/gdb/sh-tdep.h
  719. @@ -21,6 +21,12 @@
  720. /* Contributed by Steve Chamberlain sac@cygnus.com. */
  721. +struct frame_info;
  722. +struct gdbarch;
  723. +struct reggroup;
  724. +struct regset;
  725. +struct regcache;
  726. +
  727. /* Registers for all SH variants. Used also by sh3-rom.c. */
  728. enum
  729. {
  730. @@ -29,6 +35,7 @@ enum
  731. ARG0_REGNUM = 4,
  732. ARGLAST_REGNUM = 7,
  733. FP_REGNUM = 14,
  734. + SP_REGNUM = 15,
  735. PC_REGNUM = 16,
  736. PR_REGNUM = 17,
  737. GBR_REGNUM = 18,
  738. @@ -81,6 +88,24 @@ enum
  739. FV0_REGNUM = 76,
  740. FV_LAST_REGNUM = 79
  741. };
  742. +#define SH_NUM_REGS 67
  743. +
  744. +struct sh_frame_cache
  745. +{
  746. + /* Base address. */
  747. + CORE_ADDR base;
  748. + LONGEST sp_offset;
  749. + CORE_ADDR pc;
  750. +
  751. + /* Flag showing that a frame has been created in the prologue code. */
  752. + int uses_fp;
  753. +
  754. + /* Saved registers. */
  755. + CORE_ADDR saved_regs[SH_NUM_REGS];
  756. + CORE_ADDR saved_sp;
  757. +};
  758. +
  759. +extern struct sh_frame_cache *sh_frame_cache (struct frame_info *next_frame, void **this_cache);
  760. /* This structure describes a register in a core-file. */
  761. struct sh_corefile_regmap
  762. @@ -89,8 +114,32 @@ struct sh_corefile_regmap
  763. unsigned int offset;
  764. };
  765. +/* sh architecture specific information. */
  766. struct gdbarch_tdep
  767. {
  768. + /* General-purpose registers. */
  769. + struct regset *gregset;
  770. + int *gregset_reg_offset;
  771. + int gregset_num_regs;
  772. + size_t sizeof_gregset;
  773. +
  774. + /* Floating-point registers. */
  775. + struct regset *fpregset;
  776. + size_t sizeof_fpregset;
  777. +
  778. + /* Offset of saved PC in jmp_buf. */
  779. + int jb_pc_offset;
  780. +
  781. + /* Detect sigtramp. */
  782. + int (*sigtramp_p) (struct frame_info *);
  783. +
  784. + /* Get address of sigcontext for sigtramp. */
  785. + CORE_ADDR (*sigcontext_addr) (struct frame_info *);
  786. +
  787. + /* Offset of registers in `struct sigcontext'. */
  788. + int *sc_reg_offset;
  789. + int sc_num_regs;
  790. +
  791. /* Non-NULL when debugging from a core file. Provides the offset
  792. where each general-purpose register is stored inside the associated
  793. core file section. */
  794. diff --git a/gdb/testsuite/gdb.asm/asm-source.exp b/gdb/testsuite/gdb.asm/asm-source.exp
  795. index 4914498f98c..6e25cbed185 100644
  796. --- a/gdb/testsuite/gdb.asm/asm-source.exp
  797. +++ b/gdb/testsuite/gdb.asm/asm-source.exp
  798. @@ -116,6 +116,11 @@ switch -glob -- [istarget] {
  799. append link-flags " -m elf32ppc"
  800. }
  801. }
  802. + "sh*-linux*" {
  803. + set asm-arch sh-linux
  804. + set asm-flags "-I${srcdir}/${subdir} -I${objdir}/${subdir}"
  805. + set debug-flags "-gdwarf-2"
  806. + }
  807. "sh*-*-*" {
  808. set asm-arch sh
  809. set debug-flags "-gdwarf-2"
  810. diff --git a/gdb/testsuite/gdb.asm/sh.inc b/gdb/testsuite/gdb.asm/sh.inc
  811. index a4a5fc545e4..89efed7795c 100644
  812. --- a/gdb/testsuite/gdb.asm/sh.inc
  813. +++ b/gdb/testsuite/gdb.asm/sh.inc
  814. @@ -40,9 +40,8 @@
  815. mov.l .Lconst\@,r1
  816. bra .Lafterconst\@
  817. nop
  818. - nop
  819. -.Lconst\@:
  820. .align 2
  821. +.Lconst\@:
  822. .long \subr
  823. .align 1
  824. .Lafterconst\@:
  825. diff --git a/gdb/testsuite/gdb.base/annota1.c b/gdb/testsuite/gdb.base/annota1.c
  826. index 424e1b83278..0de2e7b633a 100644
  827. --- a/gdb/testsuite/gdb.base/annota1.c
  828. +++ b/gdb/testsuite/gdb.base/annota1.c
  829. @@ -1,6 +1,9 @@
  830. #include <stdio.h>
  831. #include <signal.h>
  832. +#ifdef __sh__
  833. +#define signal(a,b) /* Signals not supported on this target - make them go away */
  834. +#endif
  835. void
  836. handle_USR1 (int sig)
  837. diff --git a/gdb/testsuite/gdb.base/annota3.c b/gdb/testsuite/gdb.base/annota3.c
  838. index 424e1b83278..952aaf218ab 100644
  839. --- a/gdb/testsuite/gdb.base/annota3.c
  840. +++ b/gdb/testsuite/gdb.base/annota3.c
  841. @@ -1,6 +1,10 @@
  842. #include <stdio.h>
  843. #include <signal.h>
  844. +#ifdef __sh__
  845. +#define signal(a,b) /* Signals not supported on this target - make them go away */
  846. +#endif
  847. +
  848. void
  849. handle_USR1 (int sig)
  850. diff --git a/gdb/testsuite/gdb.base/sigall.c b/gdb/testsuite/gdb.base/sigall.c
  851. index 81f3b08d6bc..1574b2d6cb8 100644
  852. --- a/gdb/testsuite/gdb.base/sigall.c
  853. +++ b/gdb/testsuite/gdb.base/sigall.c
  854. @@ -1,6 +1,9 @@
  855. #include <signal.h>
  856. #include <unistd.h>
  857. +#ifdef __sh__
  858. +#define signal(a,b) /* Signals not supported on this target - make them go away */
  859. +#endif
  860. /* Signal handlers, we set breakpoints in them to make sure that the
  861. signals really get delivered. */
  862. diff --git a/gdb/testsuite/gdb.base/signals.c b/gdb/testsuite/gdb.base/signals.c
  863. index 756606880fa..1205a9bc9c5 100644
  864. --- a/gdb/testsuite/gdb.base/signals.c
  865. +++ b/gdb/testsuite/gdb.base/signals.c
  866. @@ -3,6 +3,10 @@
  867. #include <signal.h>
  868. #include <unistd.h>
  869. +#ifdef __sh__
  870. +#define signal(a,b) /* Signals not supported on this target - make them go away */
  871. +#define alarm(a) /* Ditto for alarm() */
  872. +#endif
  873. static int count = 0;
  874. --
  875. 2.29.2