1b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma/* libunwind - a platform-independent unwind library
221ad2c19ea575b4485121e9f824609fe6e4f3be9Tommi Rantala   Copyright (C) 2012 Tommi Rantala <tt.rantala@gmail.com>
3b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
4b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaThis file is part of libunwind.
5b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
6b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaPermission is hereby granted, free of charge, to any person obtaining
7b08ae72d6c041c2c9d72d049f815d001032169caArun Sharmaa copy of this software and associated documentation files (the
8b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma"Software"), to deal in the Software without restriction, including
9b08ae72d6c041c2c9d72d049f815d001032169caArun Sharmawithout limitation the rights to use, copy, modify, merge, publish,
10b08ae72d6c041c2c9d72d049f815d001032169caArun Sharmadistribute, sublicense, and/or sell copies of the Software, and to
11b08ae72d6c041c2c9d72d049f815d001032169caArun Sharmapermit persons to whom the Software is furnished to do so, subject to
12b08ae72d6c041c2c9d72d049f815d001032169caArun Sharmathe following conditions:
13b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
14b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaThe above copyright notice and this permission notice shall be
15b08ae72d6c041c2c9d72d049f815d001032169caArun Sharmaincluded in all copies or substantial portions of the Software.
16b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
17b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23b08ae72d6c041c2c9d72d049f815d001032169caArun SharmaWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
24b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
25b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma#include "_UCD_lib.h"
26b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
27b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma#include "_UCD_internal.h"
28b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
29b08ae72d6c041c2c9d72d049f815d001032169caArun Sharmaint
30b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma_UCD_access_reg (unw_addr_space_t as,
31b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma                                unw_regnum_t regnum, unw_word_t *valp,
32b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma                                int write, void *arg)
33b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma{
3421ad2c19ea575b4485121e9f824609fe6e4f3be9Tommi Rantala  struct UCD_info *ui = arg;
3521ad2c19ea575b4485121e9f824609fe6e4f3be9Tommi Rantala
36b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  if (write)
37b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma    {
38e61c6f69c30d85584ece5250b8b82b03898384f5Tommi Rantala      Debug(0, "write is not supported\n");
39b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      return -UNW_EINVAL;
40b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma    }
41b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
42ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux#if defined(UNW_TARGET_AARCH64)
43ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux  if (regnum < 0 || regnum >= UNW_AARCH64_FPCR)
44ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux    goto badreg;
45ac6c0a6535975f1dc2da6e4e2766614baac2a14aYvan Roux#elif defined(UNW_TARGET_ARM)
4621ad2c19ea575b4485121e9f824609fe6e4f3be9Tommi Rantala  if (regnum < 0 || regnum >= 16)
4721ad2c19ea575b4485121e9f824609fe6e4f3be9Tommi Rantala    goto badreg;
488d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala#elif defined(UNW_TARGET_SH)
498d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala  if (regnum < 0 || regnum > UNW_SH_PR)
508d5b1aeeffb80515197fd7aeee0b3fbfac904ecdTommi Rantala    goto badreg;
5121ad2c19ea575b4485121e9f824609fe6e4f3be9Tommi Rantala#else
5279c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala#if defined(UNW_TARGET_MIPS)
5379c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala  static const uint8_t remap_regs[] =
5479c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala    {
5579c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R0]  = EF_REG0,
5679c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R1]  = EF_REG1,
5779c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R2]  = EF_REG2,
5879c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R3]  = EF_REG3,
5979c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R4]  = EF_REG4,
6079c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R5]  = EF_REG5,
6179c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R6]  = EF_REG6,
6279c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R7]  = EF_REG7,
6379c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R8]  = EF_REG8,
6479c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R9]  = EF_REG9,
6579c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R10] = EF_REG10,
6679c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R11] = EF_REG11,
6779c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R12] = EF_REG12,
6879c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R13] = EF_REG13,
6979c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R14] = EF_REG14,
7079c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R15] = EF_REG15,
7179c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R16] = EF_REG16,
7279c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R17] = EF_REG17,
7379c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R18] = EF_REG18,
7479c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R19] = EF_REG19,
7579c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R20] = EF_REG20,
7679c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R21] = EF_REG21,
7779c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R22] = EF_REG22,
7879c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R23] = EF_REG23,
7979c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R24] = EF_REG24,
8079c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R25] = EF_REG25,
8179c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R28] = EF_REG28,
8279c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R29] = EF_REG29,
8379c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R30] = EF_REG30,
8479c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_R31] = EF_REG31,
8579c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala      [UNW_MIPS_PC]  = EF_CP0_EPC,
8679c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala    };
8779c2c254a74ca850aefe2c49b973dea1fa2934c2Tommi Rantala#elif defined(UNW_TARGET_X86)
88b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  static const uint8_t remap_regs[] =
89b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma    {
90b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      /* names from libunwind-x86.h */
91b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      [UNW_X86_EAX]    = offsetof(struct user_regs_struct, eax) / sizeof(long),
92b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      [UNW_X86_EDX]    = offsetof(struct user_regs_struct, edx) / sizeof(long),
93b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      [UNW_X86_ECX]    = offsetof(struct user_regs_struct, ecx) / sizeof(long),
94b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      [UNW_X86_EBX]    = offsetof(struct user_regs_struct, ebx) / sizeof(long),
95b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      [UNW_X86_ESI]    = offsetof(struct user_regs_struct, esi) / sizeof(long),
96b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      [UNW_X86_EDI]    = offsetof(struct user_regs_struct, edi) / sizeof(long),
97b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      [UNW_X86_EBP]    = offsetof(struct user_regs_struct, ebp) / sizeof(long),
98b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      [UNW_X86_ESP]    = offsetof(struct user_regs_struct, esp) / sizeof(long),
99b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      [UNW_X86_EIP]    = offsetof(struct user_regs_struct, eip) / sizeof(long),
100b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      [UNW_X86_EFLAGS] = offsetof(struct user_regs_struct, eflags) / sizeof(long),
101b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma      [UNW_X86_TRAPNO] = offsetof(struct user_regs_struct, orig_eax) / sizeof(long),
102b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma    };
103b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma#elif defined(UNW_TARGET_X86_64)
104b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  static const int8_t remap_regs[] =
105b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma    {
1060f17b521716c8492f08f8671fd847fd3c26f8175Arun Sharma      [UNW_X86_64_RAX]    = offsetof(struct user_regs_struct, rax) / sizeof(long),
1070f17b521716c8492f08f8671fd847fd3c26f8175Arun Sharma      [UNW_X86_64_RDX]    = offsetof(struct user_regs_struct, rdx) / sizeof(long),
1080f17b521716c8492f08f8671fd847fd3c26f8175Arun Sharma      [UNW_X86_64_RCX]    = offsetof(struct user_regs_struct, rcx) / sizeof(long),
1090f17b521716c8492f08f8671fd847fd3c26f8175Arun Sharma      [UNW_X86_64_RBX]    = offsetof(struct user_regs_struct, rbx) / sizeof(long),
1100f17b521716c8492f08f8671fd847fd3c26f8175Arun Sharma      [UNW_X86_64_RSI]    = offsetof(struct user_regs_struct, rsi) / sizeof(long),
1110f17b521716c8492f08f8671fd847fd3c26f8175Arun Sharma      [UNW_X86_64_RDI]    = offsetof(struct user_regs_struct, rdi) / sizeof(long),
1120f17b521716c8492f08f8671fd847fd3c26f8175Arun Sharma      [UNW_X86_64_RBP]    = offsetof(struct user_regs_struct, rbp) / sizeof(long),
1130f17b521716c8492f08f8671fd847fd3c26f8175Arun Sharma      [UNW_X86_64_RSP]    = offsetof(struct user_regs_struct, rsp) / sizeof(long),
1140f17b521716c8492f08f8671fd847fd3c26f8175Arun Sharma      [UNW_X86_64_RIP]    = offsetof(struct user_regs_struct, rip) / sizeof(long),
115b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma    };
116b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma#else
117b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma#error Port me
118b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma#endif
119b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
120b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  if (regnum < 0 || regnum >= (unw_regnum_t)ARRAY_SIZE(remap_regs))
12121ad2c19ea575b4485121e9f824609fe6e4f3be9Tommi Rantala    goto badreg;
12221ad2c19ea575b4485121e9f824609fe6e4f3be9Tommi Rantala
123b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  regnum = remap_regs[regnum];
12421ad2c19ea575b4485121e9f824609fe6e4f3be9Tommi Rantala#endif
125b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
126b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  /* pr_reg is a long[] array, but it contains struct user_regs_struct's
127b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma   * image.
128b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma   */
1297e5cab6dacfaead42c483ba9cb2dc202bde703b5Tommi Rantala  Debug(1, "pr_reg[%d]:%ld (0x%lx)\n", regnum,
130b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma		(long)ui->prstatus->pr_reg[regnum],
131b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma		(long)ui->prstatus->pr_reg[regnum]
132b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  );
133b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  *valp = ui->prstatus->pr_reg[regnum];
134b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma
135b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma  return 0;
13621ad2c19ea575b4485121e9f824609fe6e4f3be9Tommi Rantala
13721ad2c19ea575b4485121e9f824609fe6e4f3be9Tommi Rantalabadreg:
13821ad2c19ea575b4485121e9f824609fe6e4f3be9Tommi Rantala  Debug(0, "bad regnum:%d\n", regnum);
13921ad2c19ea575b4485121e9f824609fe6e4f3be9Tommi Rantala  return -UNW_EINVAL;
140b08ae72d6c041c2c9d72d049f815d001032169caArun Sharma}
141