1fead7960SIan Munsie /* 2fead7960SIan Munsie * Mapping of DWARF debug register numbers into register names. 3fead7960SIan Munsie * 4fead7960SIan Munsie * Copyright (C) 2010 Ian Munsie, IBM Corporation. 5fead7960SIan Munsie * 6fead7960SIan Munsie * This program is free software; you can redistribute it and/or 7fead7960SIan Munsie * modify it under the terms of the GNU General Public License 8fead7960SIan Munsie * as published by the Free Software Foundation; either version 9fead7960SIan Munsie * 2 of the License, or (at your option) any later version. 10fead7960SIan Munsie */ 11fead7960SIan Munsie 12861e10beSCody P Schafer #include <stddef.h> 13*4679bccaSNaveen N. Rao #include <errno.h> 14*4679bccaSNaveen N. Rao #include <string.h> 15fead7960SIan Munsie #include <dwarf-regs.h> 16*4679bccaSNaveen N. Rao #include <linux/ptrace.h> 17*4679bccaSNaveen N. Rao #include <linux/kernel.h> 18*4679bccaSNaveen N. Rao #include "util.h" 19fead7960SIan Munsie 20fead7960SIan Munsie struct pt_regs_dwarfnum { 21fead7960SIan Munsie const char *name; 22fead7960SIan Munsie unsigned int dwarfnum; 23*4679bccaSNaveen N. Rao unsigned int ptregs_offset; 24fead7960SIan Munsie }; 25fead7960SIan Munsie 26*4679bccaSNaveen N. Rao #define REG_DWARFNUM_NAME(r, num) \ 27*4679bccaSNaveen N. Rao {.name = STR(%)STR(r), .dwarfnum = num, \ 28*4679bccaSNaveen N. Rao .ptregs_offset = offsetof(struct pt_regs, r)} 29fead7960SIan Munsie #define GPR_DWARFNUM_NAME(num) \ 30*4679bccaSNaveen N. Rao {.name = STR(%gpr##num), .dwarfnum = num, \ 31*4679bccaSNaveen N. Rao .ptregs_offset = offsetof(struct pt_regs, gpr[num])} 32*4679bccaSNaveen N. Rao #define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0, .ptregs_offset = 0} 33fead7960SIan Munsie 34fead7960SIan Munsie /* 35fead7960SIan Munsie * Reference: 36fead7960SIan Munsie * http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html 37fead7960SIan Munsie */ 38fead7960SIan Munsie static const struct pt_regs_dwarfnum regdwarfnum_table[] = { 39fead7960SIan Munsie GPR_DWARFNUM_NAME(0), 40fead7960SIan Munsie GPR_DWARFNUM_NAME(1), 41fead7960SIan Munsie GPR_DWARFNUM_NAME(2), 42fead7960SIan Munsie GPR_DWARFNUM_NAME(3), 43fead7960SIan Munsie GPR_DWARFNUM_NAME(4), 44fead7960SIan Munsie GPR_DWARFNUM_NAME(5), 45fead7960SIan Munsie GPR_DWARFNUM_NAME(6), 46fead7960SIan Munsie GPR_DWARFNUM_NAME(7), 47fead7960SIan Munsie GPR_DWARFNUM_NAME(8), 48fead7960SIan Munsie GPR_DWARFNUM_NAME(9), 49fead7960SIan Munsie GPR_DWARFNUM_NAME(10), 50fead7960SIan Munsie GPR_DWARFNUM_NAME(11), 51fead7960SIan Munsie GPR_DWARFNUM_NAME(12), 52fead7960SIan Munsie GPR_DWARFNUM_NAME(13), 53fead7960SIan Munsie GPR_DWARFNUM_NAME(14), 54fead7960SIan Munsie GPR_DWARFNUM_NAME(15), 55fead7960SIan Munsie GPR_DWARFNUM_NAME(16), 56fead7960SIan Munsie GPR_DWARFNUM_NAME(17), 57fead7960SIan Munsie GPR_DWARFNUM_NAME(18), 58fead7960SIan Munsie GPR_DWARFNUM_NAME(19), 59fead7960SIan Munsie GPR_DWARFNUM_NAME(20), 60fead7960SIan Munsie GPR_DWARFNUM_NAME(21), 61fead7960SIan Munsie GPR_DWARFNUM_NAME(22), 62fead7960SIan Munsie GPR_DWARFNUM_NAME(23), 63fead7960SIan Munsie GPR_DWARFNUM_NAME(24), 64fead7960SIan Munsie GPR_DWARFNUM_NAME(25), 65fead7960SIan Munsie GPR_DWARFNUM_NAME(26), 66fead7960SIan Munsie GPR_DWARFNUM_NAME(27), 67fead7960SIan Munsie GPR_DWARFNUM_NAME(28), 68fead7960SIan Munsie GPR_DWARFNUM_NAME(29), 69fead7960SIan Munsie GPR_DWARFNUM_NAME(30), 70fead7960SIan Munsie GPR_DWARFNUM_NAME(31), 71*4679bccaSNaveen N. Rao REG_DWARFNUM_NAME(msr, 66), 72*4679bccaSNaveen N. Rao REG_DWARFNUM_NAME(ctr, 109), 73*4679bccaSNaveen N. Rao REG_DWARFNUM_NAME(link, 108), 74*4679bccaSNaveen N. Rao REG_DWARFNUM_NAME(xer, 101), 75*4679bccaSNaveen N. Rao REG_DWARFNUM_NAME(dar, 119), 76*4679bccaSNaveen N. Rao REG_DWARFNUM_NAME(dsisr, 118), 77fead7960SIan Munsie REG_DWARFNUM_END, 78fead7960SIan Munsie }; 79fead7960SIan Munsie 80fead7960SIan Munsie /** 81fead7960SIan Munsie * get_arch_regstr() - lookup register name from it's DWARF register number 82fead7960SIan Munsie * @n: the DWARF register number 83fead7960SIan Munsie * 84fead7960SIan Munsie * get_arch_regstr() returns the name of the register in struct 85fead7960SIan Munsie * regdwarfnum_table from it's DWARF register number. If the register is not 86fead7960SIan Munsie * found in the table, this returns NULL; 87fead7960SIan Munsie */ 88fead7960SIan Munsie const char *get_arch_regstr(unsigned int n) 89fead7960SIan Munsie { 90fead7960SIan Munsie const struct pt_regs_dwarfnum *roff; 91fead7960SIan Munsie for (roff = regdwarfnum_table; roff->name != NULL; roff++) 92fead7960SIan Munsie if (roff->dwarfnum == n) 93fead7960SIan Munsie return roff->name; 94fead7960SIan Munsie return NULL; 95fead7960SIan Munsie } 96*4679bccaSNaveen N. Rao 97*4679bccaSNaveen N. Rao int regs_query_register_offset(const char *name) 98*4679bccaSNaveen N. Rao { 99*4679bccaSNaveen N. Rao const struct pt_regs_dwarfnum *roff; 100*4679bccaSNaveen N. Rao for (roff = regdwarfnum_table; roff->name != NULL; roff++) 101*4679bccaSNaveen N. Rao if (!strcmp(roff->name, name)) 102*4679bccaSNaveen N. Rao return roff->ptregs_offset; 103*4679bccaSNaveen N. Rao return -EINVAL; 104*4679bccaSNaveen N. Rao } 105