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> 134679bccaSNaveen N. Rao #include <errno.h> 144679bccaSNaveen N. Rao #include <string.h> 15fead7960SIan Munsie #include <dwarf-regs.h> 164679bccaSNaveen N. Rao #include <linux/ptrace.h> 174679bccaSNaveen N. Rao #include <linux/kernel.h> 18*aa8cc2f6SArnaldo Carvalho de Melo #include <linux/stringify.h> 194679bccaSNaveen N. Rao #include "util.h" 20fead7960SIan Munsie 21fead7960SIan Munsie struct pt_regs_dwarfnum { 22fead7960SIan Munsie const char *name; 23fead7960SIan Munsie unsigned int dwarfnum; 244679bccaSNaveen N. Rao unsigned int ptregs_offset; 25fead7960SIan Munsie }; 26fead7960SIan Munsie 274679bccaSNaveen N. Rao #define REG_DWARFNUM_NAME(r, num) \ 28*aa8cc2f6SArnaldo Carvalho de Melo {.name = __stringify(%)__stringify(r), .dwarfnum = num, \ 294679bccaSNaveen N. Rao .ptregs_offset = offsetof(struct pt_regs, r)} 30fead7960SIan Munsie #define GPR_DWARFNUM_NAME(num) \ 31*aa8cc2f6SArnaldo Carvalho de Melo {.name = __stringify(%gpr##num), .dwarfnum = num, \ 324679bccaSNaveen N. Rao .ptregs_offset = offsetof(struct pt_regs, gpr[num])} 334679bccaSNaveen N. Rao #define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0, .ptregs_offset = 0} 34fead7960SIan Munsie 35fead7960SIan Munsie /* 36fead7960SIan Munsie * Reference: 37fead7960SIan Munsie * http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html 38fead7960SIan Munsie */ 39fead7960SIan Munsie static const struct pt_regs_dwarfnum regdwarfnum_table[] = { 40fead7960SIan Munsie GPR_DWARFNUM_NAME(0), 41fead7960SIan Munsie GPR_DWARFNUM_NAME(1), 42fead7960SIan Munsie GPR_DWARFNUM_NAME(2), 43fead7960SIan Munsie GPR_DWARFNUM_NAME(3), 44fead7960SIan Munsie GPR_DWARFNUM_NAME(4), 45fead7960SIan Munsie GPR_DWARFNUM_NAME(5), 46fead7960SIan Munsie GPR_DWARFNUM_NAME(6), 47fead7960SIan Munsie GPR_DWARFNUM_NAME(7), 48fead7960SIan Munsie GPR_DWARFNUM_NAME(8), 49fead7960SIan Munsie GPR_DWARFNUM_NAME(9), 50fead7960SIan Munsie GPR_DWARFNUM_NAME(10), 51fead7960SIan Munsie GPR_DWARFNUM_NAME(11), 52fead7960SIan Munsie GPR_DWARFNUM_NAME(12), 53fead7960SIan Munsie GPR_DWARFNUM_NAME(13), 54fead7960SIan Munsie GPR_DWARFNUM_NAME(14), 55fead7960SIan Munsie GPR_DWARFNUM_NAME(15), 56fead7960SIan Munsie GPR_DWARFNUM_NAME(16), 57fead7960SIan Munsie GPR_DWARFNUM_NAME(17), 58fead7960SIan Munsie GPR_DWARFNUM_NAME(18), 59fead7960SIan Munsie GPR_DWARFNUM_NAME(19), 60fead7960SIan Munsie GPR_DWARFNUM_NAME(20), 61fead7960SIan Munsie GPR_DWARFNUM_NAME(21), 62fead7960SIan Munsie GPR_DWARFNUM_NAME(22), 63fead7960SIan Munsie GPR_DWARFNUM_NAME(23), 64fead7960SIan Munsie GPR_DWARFNUM_NAME(24), 65fead7960SIan Munsie GPR_DWARFNUM_NAME(25), 66fead7960SIan Munsie GPR_DWARFNUM_NAME(26), 67fead7960SIan Munsie GPR_DWARFNUM_NAME(27), 68fead7960SIan Munsie GPR_DWARFNUM_NAME(28), 69fead7960SIan Munsie GPR_DWARFNUM_NAME(29), 70fead7960SIan Munsie GPR_DWARFNUM_NAME(30), 71fead7960SIan Munsie GPR_DWARFNUM_NAME(31), 724679bccaSNaveen N. Rao REG_DWARFNUM_NAME(msr, 66), 734679bccaSNaveen N. Rao REG_DWARFNUM_NAME(ctr, 109), 744679bccaSNaveen N. Rao REG_DWARFNUM_NAME(link, 108), 754679bccaSNaveen N. Rao REG_DWARFNUM_NAME(xer, 101), 764679bccaSNaveen N. Rao REG_DWARFNUM_NAME(dar, 119), 774679bccaSNaveen N. Rao REG_DWARFNUM_NAME(dsisr, 118), 78fead7960SIan Munsie REG_DWARFNUM_END, 79fead7960SIan Munsie }; 80fead7960SIan Munsie 81fead7960SIan Munsie /** 82fead7960SIan Munsie * get_arch_regstr() - lookup register name from it's DWARF register number 83fead7960SIan Munsie * @n: the DWARF register number 84fead7960SIan Munsie * 85fead7960SIan Munsie * get_arch_regstr() returns the name of the register in struct 86fead7960SIan Munsie * regdwarfnum_table from it's DWARF register number. If the register is not 87fead7960SIan Munsie * found in the table, this returns NULL; 88fead7960SIan Munsie */ 89fead7960SIan Munsie const char *get_arch_regstr(unsigned int n) 90fead7960SIan Munsie { 91fead7960SIan Munsie const struct pt_regs_dwarfnum *roff; 92fead7960SIan Munsie for (roff = regdwarfnum_table; roff->name != NULL; roff++) 93fead7960SIan Munsie if (roff->dwarfnum == n) 94fead7960SIan Munsie return roff->name; 95fead7960SIan Munsie return NULL; 96fead7960SIan Munsie } 974679bccaSNaveen N. Rao 984679bccaSNaveen N. Rao int regs_query_register_offset(const char *name) 994679bccaSNaveen N. Rao { 1004679bccaSNaveen N. Rao const struct pt_regs_dwarfnum *roff; 1014679bccaSNaveen N. Rao for (roff = regdwarfnum_table; roff->name != NULL; roff++) 1024679bccaSNaveen N. Rao if (!strcmp(roff->name, name)) 1034679bccaSNaveen N. Rao return roff->ptregs_offset; 1044679bccaSNaveen N. Rao return -EINVAL; 1054679bccaSNaveen N. Rao } 106