17e16fca0SAli Bahrami /* 27e16fca0SAli Bahrami * CDDL HEADER START 37e16fca0SAli Bahrami * 47e16fca0SAli Bahrami * The contents of this file are subject to the terms of the 57e16fca0SAli Bahrami * Common Development and Distribution License (the "License"). 67e16fca0SAli Bahrami * You may not use this file except in compliance with the License. 77e16fca0SAli Bahrami * 87e16fca0SAli Bahrami * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97e16fca0SAli Bahrami * or http://www.opensolaris.org/os/licensing. 107e16fca0SAli Bahrami * See the License for the specific language governing permissions 117e16fca0SAli Bahrami * and limitations under the License. 127e16fca0SAli Bahrami * 137e16fca0SAli Bahrami * When distributing Covered Code, include this CDDL HEADER in each 147e16fca0SAli Bahrami * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157e16fca0SAli Bahrami * If applicable, add the following below this CDDL HEADER, with the 167e16fca0SAli Bahrami * fields enclosed by brackets "[]" replaced with your own identifying 177e16fca0SAli Bahrami * information: Portions Copyright [yyyy] [name of copyright owner] 187e16fca0SAli Bahrami * 197e16fca0SAli Bahrami * CDDL HEADER END 207e16fca0SAli Bahrami */ 217e16fca0SAli Bahrami 227e16fca0SAli Bahrami /* 237e16fca0SAli Bahrami * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 247e16fca0SAli Bahrami * Use is subject to license terms. 257e16fca0SAli Bahrami */ 267e16fca0SAli Bahrami 277e16fca0SAli Bahrami #include <strings.h> 287e16fca0SAli Bahrami #include <dwarf.h> 297e16fca0SAli Bahrami #include "_conv.h" 307e16fca0SAli Bahrami #include <dwarf_msg.h> 317e16fca0SAli Bahrami 327e16fca0SAli Bahrami /* 337e16fca0SAli Bahrami * This code is primarily of interest to elfdump. Separating it from dwarf_ehe 347e16fca0SAli Bahrami * allows other tools to use dwarf_ehe without also pulling this in. 357e16fca0SAli Bahrami */ 367e16fca0SAli Bahrami 377e16fca0SAli Bahrami /* 387e16fca0SAli Bahrami * Translate DW_CFA_ codes, used to identify Call Frame Instructions. 397e16fca0SAli Bahrami */ 407e16fca0SAli Bahrami const char * 417e16fca0SAli Bahrami conv_dwarf_cfa(uchar_t op, Conv_fmt_flags_t fmt_flags, Conv_inv_buf_t *inv_buf) 427e16fca0SAli Bahrami { 437e16fca0SAli Bahrami static const Msg cfa[] = { 447e16fca0SAli Bahrami MSG_DW_CFA_NOP, MSG_DW_CFA_SET_LOC, 457e16fca0SAli Bahrami MSG_DW_CFA_ADVANCE_LOC_1, MSG_DW_CFA_ADVANCE_LOC_2, 467e16fca0SAli Bahrami MSG_DW_CFA_ADVANCE_LOC_4, MSG_DW_CFA_OFFSET_EXTENDED, 477e16fca0SAli Bahrami MSG_DW_CFA_RESTORE_EXTENDED, MSG_DW_CFA_UNDEFINED, 487e16fca0SAli Bahrami MSG_DW_CFA_SAME_VALUE, MSG_DW_CFA_REGISTER, 497e16fca0SAli Bahrami MSG_DW_CFA_REMEMBER_STATE, MSG_DW_CFA_RESTORE_STATE, 507e16fca0SAli Bahrami MSG_DW_CFA_DEF_CFA, MSG_DW_CFA_DEF_CFA_REGISTER, 517e16fca0SAli Bahrami MSG_DW_CFA_DEF_CFA_OFFSET, MSG_DW_CFA_DEF_CFA_EXPRESSION, 527e16fca0SAli Bahrami MSG_DW_CFA_EXPRESSION, MSG_DW_CFA_OFFSET_EXTENDED_SF, 537e16fca0SAli Bahrami MSG_DW_CFA_DEF_CFA_SF, MSG_DW_CFA_DEF_CFA_OFFSET_SF, 547e16fca0SAli Bahrami MSG_DW_CFA_VAL_OFFSET, MSG_DW_CFA_VAL_OFFSET_SF, 557e16fca0SAli Bahrami MSG_DW_CFA_VAL_EXPRESSION 567e16fca0SAli Bahrami }; 57*4f680cc6SAli Bahrami static const Msg cfa_mips[] = { MSG_DW_CFA_MIPS_ADV_LOC8 }; 58*4f680cc6SAli Bahrami static const Msg cfa_gnu[] = { 597e16fca0SAli Bahrami MSG_DW_CFA_GNU_WINDOW_SAVE, MSG_DW_CFA_GNU_ARGS_SIZE, 607e16fca0SAli Bahrami MSG_DW_CFA_GNU_NEGATIVE_OFF_X 617e16fca0SAli Bahrami }; 62*4f680cc6SAli Bahrami static const conv_ds_msg_t ds_msg_cfa = { 63*4f680cc6SAli Bahrami CONV_DS_MSG_INIT(0, cfa) }; 64*4f680cc6SAli Bahrami static const conv_ds_msg_t ds_msg_cfa_mips = { 65*4f680cc6SAli Bahrami CONV_DS_MSG_INIT(0x1d, cfa_mips) }; 66*4f680cc6SAli Bahrami static const conv_ds_msg_t ds_msg_cfa_gnu = { 67*4f680cc6SAli Bahrami CONV_DS_MSG_INIT(0x2d, cfa_gnu) }; 68*4f680cc6SAli Bahrami static const conv_ds_t *ds_cfa[] = { CONV_DS_ADDR(ds_msg_cfa), 69*4f680cc6SAli Bahrami CONV_DS_ADDR(ds_msg_cfa_mips), CONV_DS_ADDR(ds_msg_cfa_gnu), NULL }; 70*4f680cc6SAli Bahrami 717e16fca0SAli Bahrami 727e16fca0SAli Bahrami /* 737e16fca0SAli Bahrami * DWARF CFA opcodes are bytes. The top 2 bits are a primary 747e16fca0SAli Bahrami * opcode, and if zero, the lower 6 bits specify a sub-opcode 757e16fca0SAli Bahrami */ 767e16fca0SAli Bahrami switch (op >> 6) { 777e16fca0SAli Bahrami case 0x1: 787e16fca0SAli Bahrami return (MSG_ORIG(MSG_DW_CFA_ADVANCE_LOC)); 797e16fca0SAli Bahrami case 0x2: 807e16fca0SAli Bahrami return (MSG_ORIG(MSG_DW_CFA_OFFSET)); 817e16fca0SAli Bahrami case 0x3: 827e16fca0SAli Bahrami return (MSG_ORIG(MSG_DW_CFA_RESTORE)); 837e16fca0SAli Bahrami } 847e16fca0SAli Bahrami 85*4f680cc6SAli Bahrami return (conv_map_ds(ELFOSABI_NONE, EM_NONE, op, ds_cfa, 86*4f680cc6SAli Bahrami fmt_flags, inv_buf)); 877e16fca0SAli Bahrami } 887e16fca0SAli Bahrami 897e16fca0SAli Bahrami /* 907e16fca0SAli Bahrami * Translate DWARF register numbers to hardware specific names 917e16fca0SAli Bahrami * 927e16fca0SAli Bahrami * If good_name is non-NULL, conv_dwarf_regname() will set the variable to 937e16fca0SAli Bahrami * True(1) if the returned string is considered to be a good name to 947e16fca0SAli Bahrami * display, and False(0) otherwise. To be considered "good": 957e16fca0SAli Bahrami * 967e16fca0SAli Bahrami * - The name must be a well known mnemonic for a register 977e16fca0SAli Bahrami * from the machine type in question. 987e16fca0SAli Bahrami * 997e16fca0SAli Bahrami * - The name must be different than the DWARF name for 1007e16fca0SAli Bahrami * the same register. 1017e16fca0SAli Bahrami * 1027e16fca0SAli Bahrami * The returned string is usable, regardless of the value returned in 1037e16fca0SAli Bahrami * *good_name. 1047e16fca0SAli Bahrami */ 1057e16fca0SAli Bahrami const char * 1067e16fca0SAli Bahrami conv_dwarf_regname(Half mach, Word regno, Conv_fmt_flags_t fmt_flags, 1077e16fca0SAli Bahrami int *good_name, Conv_inv_buf_t *inv_buf) 1087e16fca0SAli Bahrami { 1097e16fca0SAli Bahrami static const Msg reg_amd64[67] = { 1107e16fca0SAli Bahrami MSG_REG_RAX, MSG_REG_RDX, 1117e16fca0SAli Bahrami MSG_REG_RCX, MSG_REG_RBX, 1127e16fca0SAli Bahrami MSG_REG_RSI, MSG_REG_RDI, 1137e16fca0SAli Bahrami MSG_REG_RBP, MSG_REG_RSP, 1147e16fca0SAli Bahrami MSG_REG_R8, MSG_REG_R9, 1157e16fca0SAli Bahrami MSG_REG_R10, MSG_REG_R11, 1167e16fca0SAli Bahrami MSG_REG_R12, MSG_REG_R13, 1177e16fca0SAli Bahrami MSG_REG_R14, MSG_REG_R15, 1187e16fca0SAli Bahrami MSG_REG_RA, MSG_REG_PERXMM0, 1197e16fca0SAli Bahrami MSG_REG_PERXMM1, MSG_REG_PERXMM2, 1207e16fca0SAli Bahrami MSG_REG_PERXMM3, MSG_REG_PERXMM4, 1217e16fca0SAli Bahrami MSG_REG_PERXMM5, MSG_REG_PERXMM6, 1227e16fca0SAli Bahrami MSG_REG_PERXMM7, MSG_REG_PERXMM8, 1237e16fca0SAli Bahrami MSG_REG_PERXMM9, MSG_REG_PERXMM10, 1247e16fca0SAli Bahrami MSG_REG_PERXMM11, MSG_REG_PERXMM12, 1257e16fca0SAli Bahrami MSG_REG_PERXMM13, MSG_REG_PERXMM14, 1267e16fca0SAli Bahrami MSG_REG_PERXMM15, MSG_REG_PERST0, 1277e16fca0SAli Bahrami MSG_REG_PERST1, MSG_REG_PERST2, 1287e16fca0SAli Bahrami MSG_REG_PERST3, MSG_REG_PERST4, 1297e16fca0SAli Bahrami MSG_REG_PERST5, MSG_REG_PERST6, 1307e16fca0SAli Bahrami MSG_REG_PERST7, MSG_REG_PERMM0, 1317e16fca0SAli Bahrami MSG_REG_PERMM1, MSG_REG_PERMM2, 1327e16fca0SAli Bahrami MSG_REG_PERMM3, MSG_REG_PERMM4, 1337e16fca0SAli Bahrami MSG_REG_PERMM5, MSG_REG_PERMM6, 1347e16fca0SAli Bahrami MSG_REG_PERMM7, MSG_REG_PERRFLAGS, 1357e16fca0SAli Bahrami MSG_REG_PERES, MSG_REG_PERCS, 1367e16fca0SAli Bahrami MSG_REG_PERSS, MSG_REG_PERDS, 1377e16fca0SAli Bahrami MSG_REG_PERFS, MSG_REG_PERGS, 1387e16fca0SAli Bahrami MSG_REG_RESERVED, MSG_REG_RESERVED, 1397e16fca0SAli Bahrami MSG_REG_PERFSDOTBASE, MSG_REG_PERGSDOTBASE, 1407e16fca0SAli Bahrami MSG_REG_RESERVED, MSG_REG_RESERVED, 1417e16fca0SAli Bahrami MSG_REG_PERTR, MSG_REG_PERLDTR, 1427e16fca0SAli Bahrami MSG_REG_PERMXCSR, MSG_REG_PERFCW, 1437e16fca0SAli Bahrami MSG_REG_PERFSW 1447e16fca0SAli Bahrami }; 145*4f680cc6SAli Bahrami static const conv_ds_msg_t ds_msg_reg_amd64 = { 146*4f680cc6SAli Bahrami CONV_DS_MSG_INIT(0, reg_amd64) }; 147*4f680cc6SAli Bahrami static const conv_ds_t *ds_reg_amd64[] = { 148*4f680cc6SAli Bahrami CONV_DS_ADDR(ds_msg_reg_amd64), NULL }; 1497e16fca0SAli Bahrami 1507e16fca0SAli Bahrami static const Msg reg_i386[8] = { 1517e16fca0SAli Bahrami MSG_REG_EAX, MSG_REG_ECX, 1527e16fca0SAli Bahrami MSG_REG_EDX, MSG_REG_EBX, 1537e16fca0SAli Bahrami MSG_REG_UESP, MSG_REG_EBP, 1547e16fca0SAli Bahrami MSG_REG_ESI, MSG_REG_EDI 1557e16fca0SAli Bahrami }; 156*4f680cc6SAli Bahrami static const conv_ds_msg_t ds_msg_reg_i386 = { 157*4f680cc6SAli Bahrami CONV_DS_MSG_INIT(0, reg_i386) }; 158*4f680cc6SAli Bahrami static const conv_ds_t *ds_reg_i386[] = { 159*4f680cc6SAli Bahrami CONV_DS_ADDR(ds_msg_reg_i386), NULL }; 1607e16fca0SAli Bahrami 1617e16fca0SAli Bahrami static const Msg reg_sparc[64] = { 1627e16fca0SAli Bahrami MSG_REG_G0, MSG_REG_G1, 1637e16fca0SAli Bahrami MSG_REG_G2, MSG_REG_G3, 1647e16fca0SAli Bahrami MSG_REG_G4, MSG_REG_G5, 1657e16fca0SAli Bahrami MSG_REG_G6, MSG_REG_G7, 1667e16fca0SAli Bahrami MSG_REG_O0, MSG_REG_O1, 1677e16fca0SAli Bahrami MSG_REG_O2, MSG_REG_O3, 1687e16fca0SAli Bahrami MSG_REG_O4, MSG_REG_O5, 1697e16fca0SAli Bahrami MSG_REG_O6, MSG_REG_O7, 1707e16fca0SAli Bahrami MSG_REG_L0, MSG_REG_L1, 1717e16fca0SAli Bahrami MSG_REG_L2, MSG_REG_L3, 1727e16fca0SAli Bahrami MSG_REG_L4, MSG_REG_L5, 1737e16fca0SAli Bahrami MSG_REG_L6, MSG_REG_L7, 1747e16fca0SAli Bahrami MSG_REG_I0, MSG_REG_I1, 1757e16fca0SAli Bahrami MSG_REG_I2, MSG_REG_I3, 1767e16fca0SAli Bahrami MSG_REG_I4, MSG_REG_I5, 1777e16fca0SAli Bahrami MSG_REG_I6, MSG_REG_I7, 1787e16fca0SAli Bahrami MSG_REG_F0, MSG_REG_F1, 1797e16fca0SAli Bahrami MSG_REG_F2, MSG_REG_F3, 1807e16fca0SAli Bahrami MSG_REG_F4, MSG_REG_F5, 1817e16fca0SAli Bahrami MSG_REG_F6, MSG_REG_F7, 1827e16fca0SAli Bahrami MSG_REG_F8, MSG_REG_F9, 1837e16fca0SAli Bahrami MSG_REG_F10, MSG_REG_F11, 1847e16fca0SAli Bahrami MSG_REG_F12, MSG_REG_F13, 1857e16fca0SAli Bahrami MSG_REG_F14, MSG_REG_F15, 1867e16fca0SAli Bahrami MSG_REG_F16, MSG_REG_F17, 1877e16fca0SAli Bahrami MSG_REG_F18, MSG_REG_F19, 1887e16fca0SAli Bahrami MSG_REG_F20, MSG_REG_F21, 1897e16fca0SAli Bahrami MSG_REG_F22, MSG_REG_F23, 1907e16fca0SAli Bahrami MSG_REG_F24, MSG_REG_F25, 1917e16fca0SAli Bahrami MSG_REG_F26, MSG_REG_F27, 1927e16fca0SAli Bahrami MSG_REG_F28, MSG_REG_F29, 1937e16fca0SAli Bahrami MSG_REG_F30, MSG_REG_F31 1947e16fca0SAli Bahrami }; 195*4f680cc6SAli Bahrami static const conv_ds_msg_t ds_msg_reg_sparc = { 196*4f680cc6SAli Bahrami CONV_DS_MSG_INIT(0, reg_sparc) }; 197*4f680cc6SAli Bahrami static const conv_ds_t *ds_reg_sparc[] = { 198*4f680cc6SAli Bahrami CONV_DS_ADDR(ds_msg_reg_sparc), NULL }; 1997e16fca0SAli Bahrami 2007e16fca0SAli Bahrami switch (mach) { 2017e16fca0SAli Bahrami case EM_AMD64: 2027e16fca0SAli Bahrami /* 2037e16fca0SAli Bahrami * amd64 has several in-bounds names we'd rather not 2047e16fca0SAli Bahrami * use. R8-R15 have the same name as their DWARF counterparts. 2057e16fca0SAli Bahrami * 56-57, and 60-61 are reserved, and don't have a good name. 2067e16fca0SAli Bahrami */ 2077e16fca0SAli Bahrami if (good_name) 2087e16fca0SAli Bahrami *good_name = ((regno < 8) || (regno > 15)) && 2097e16fca0SAli Bahrami (regno != 56) && (regno != 57) && 2107e16fca0SAli Bahrami (regno != 60) && (regno != 61) && 2117e16fca0SAli Bahrami (regno < ARRAY_NELTS(reg_amd64)); 212*4f680cc6SAli Bahrami return (conv_map_ds(ELFOSABI_NONE, EM_NONE, regno, 213*4f680cc6SAli Bahrami ds_reg_amd64, fmt_flags, inv_buf)); 2147e16fca0SAli Bahrami 2157e16fca0SAli Bahrami case EM_386: 2167e16fca0SAli Bahrami case EM_486: 2177e16fca0SAli Bahrami if (good_name) 2187e16fca0SAli Bahrami *good_name = (regno < ARRAY_NELTS(reg_i386)); 219*4f680cc6SAli Bahrami return (conv_map_ds(ELFOSABI_NONE, EM_NONE, regno, 220*4f680cc6SAli Bahrami ds_reg_i386, fmt_flags, inv_buf)); 2217e16fca0SAli Bahrami 2227e16fca0SAli Bahrami case EM_SPARC: 2237e16fca0SAli Bahrami case EM_SPARC32PLUS: 2247e16fca0SAli Bahrami case EM_SPARCV9: 2257e16fca0SAli Bahrami if (good_name) 2267e16fca0SAli Bahrami *good_name = (regno < ARRAY_NELTS(reg_sparc)); 227*4f680cc6SAli Bahrami return (conv_map_ds(ELFOSABI_NONE, EM_NONE, regno, 228*4f680cc6SAli Bahrami ds_reg_sparc, fmt_flags, inv_buf)); 2297e16fca0SAli Bahrami } 2307e16fca0SAli Bahrami 2317e16fca0SAli Bahrami if (good_name) 2327e16fca0SAli Bahrami *good_name = 0; 2337e16fca0SAli Bahrami return (conv_invalid_val(inv_buf, regno, 0)); 2347e16fca0SAli Bahrami } 235