19085SAli.Bahrami@Sun.COM /*
29085SAli.Bahrami@Sun.COM * CDDL HEADER START
39085SAli.Bahrami@Sun.COM *
49085SAli.Bahrami@Sun.COM * The contents of this file are subject to the terms of the
59085SAli.Bahrami@Sun.COM * Common Development and Distribution License (the "License").
69085SAli.Bahrami@Sun.COM * You may not use this file except in compliance with the License.
79085SAli.Bahrami@Sun.COM *
89085SAli.Bahrami@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99085SAli.Bahrami@Sun.COM * or http://www.opensolaris.org/os/licensing.
109085SAli.Bahrami@Sun.COM * See the License for the specific language governing permissions
119085SAli.Bahrami@Sun.COM * and limitations under the License.
129085SAli.Bahrami@Sun.COM *
139085SAli.Bahrami@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
149085SAli.Bahrami@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159085SAli.Bahrami@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
169085SAli.Bahrami@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
179085SAli.Bahrami@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
189085SAli.Bahrami@Sun.COM *
199085SAli.Bahrami@Sun.COM * CDDL HEADER END
209085SAli.Bahrami@Sun.COM */
219085SAli.Bahrami@Sun.COM
229085SAli.Bahrami@Sun.COM /*
239085SAli.Bahrami@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
249085SAli.Bahrami@Sun.COM * Use is subject to license terms.
259085SAli.Bahrami@Sun.COM */
269085SAli.Bahrami@Sun.COM
279085SAli.Bahrami@Sun.COM #include <strings.h>
289085SAli.Bahrami@Sun.COM #include <dwarf.h>
299085SAli.Bahrami@Sun.COM #include "_conv.h"
309085SAli.Bahrami@Sun.COM #include <dwarf_msg.h>
319085SAli.Bahrami@Sun.COM
329085SAli.Bahrami@Sun.COM /*
339085SAli.Bahrami@Sun.COM * This code is primarily of interest to elfdump. Separating it from dwarf_ehe
349085SAli.Bahrami@Sun.COM * allows other tools to use dwarf_ehe without also pulling this in.
359085SAli.Bahrami@Sun.COM */
369085SAli.Bahrami@Sun.COM
379085SAli.Bahrami@Sun.COM /*
389085SAli.Bahrami@Sun.COM * Translate DW_CFA_ codes, used to identify Call Frame Instructions.
399085SAli.Bahrami@Sun.COM */
409085SAli.Bahrami@Sun.COM const char *
conv_dwarf_cfa(uchar_t op,Conv_fmt_flags_t fmt_flags,Conv_inv_buf_t * inv_buf)419085SAli.Bahrami@Sun.COM conv_dwarf_cfa(uchar_t op, Conv_fmt_flags_t fmt_flags, Conv_inv_buf_t *inv_buf)
429085SAli.Bahrami@Sun.COM {
439085SAli.Bahrami@Sun.COM static const Msg cfa[] = {
449085SAli.Bahrami@Sun.COM MSG_DW_CFA_NOP, MSG_DW_CFA_SET_LOC,
459085SAli.Bahrami@Sun.COM MSG_DW_CFA_ADVANCE_LOC_1, MSG_DW_CFA_ADVANCE_LOC_2,
469085SAli.Bahrami@Sun.COM MSG_DW_CFA_ADVANCE_LOC_4, MSG_DW_CFA_OFFSET_EXTENDED,
479085SAli.Bahrami@Sun.COM MSG_DW_CFA_RESTORE_EXTENDED, MSG_DW_CFA_UNDEFINED,
489085SAli.Bahrami@Sun.COM MSG_DW_CFA_SAME_VALUE, MSG_DW_CFA_REGISTER,
499085SAli.Bahrami@Sun.COM MSG_DW_CFA_REMEMBER_STATE, MSG_DW_CFA_RESTORE_STATE,
509085SAli.Bahrami@Sun.COM MSG_DW_CFA_DEF_CFA, MSG_DW_CFA_DEF_CFA_REGISTER,
519085SAli.Bahrami@Sun.COM MSG_DW_CFA_DEF_CFA_OFFSET, MSG_DW_CFA_DEF_CFA_EXPRESSION,
529085SAli.Bahrami@Sun.COM MSG_DW_CFA_EXPRESSION, MSG_DW_CFA_OFFSET_EXTENDED_SF,
539085SAli.Bahrami@Sun.COM MSG_DW_CFA_DEF_CFA_SF, MSG_DW_CFA_DEF_CFA_OFFSET_SF,
549085SAli.Bahrami@Sun.COM MSG_DW_CFA_VAL_OFFSET, MSG_DW_CFA_VAL_OFFSET_SF,
559085SAli.Bahrami@Sun.COM MSG_DW_CFA_VAL_EXPRESSION
569085SAli.Bahrami@Sun.COM };
57*9273SAli.Bahrami@Sun.COM static const Msg cfa_mips[] = { MSG_DW_CFA_MIPS_ADV_LOC8 };
58*9273SAli.Bahrami@Sun.COM static const Msg cfa_gnu[] = {
599085SAli.Bahrami@Sun.COM MSG_DW_CFA_GNU_WINDOW_SAVE, MSG_DW_CFA_GNU_ARGS_SIZE,
609085SAli.Bahrami@Sun.COM MSG_DW_CFA_GNU_NEGATIVE_OFF_X
619085SAli.Bahrami@Sun.COM };
62*9273SAli.Bahrami@Sun.COM static const conv_ds_msg_t ds_msg_cfa = {
63*9273SAli.Bahrami@Sun.COM CONV_DS_MSG_INIT(0, cfa) };
64*9273SAli.Bahrami@Sun.COM static const conv_ds_msg_t ds_msg_cfa_mips = {
65*9273SAli.Bahrami@Sun.COM CONV_DS_MSG_INIT(0x1d, cfa_mips) };
66*9273SAli.Bahrami@Sun.COM static const conv_ds_msg_t ds_msg_cfa_gnu = {
67*9273SAli.Bahrami@Sun.COM CONV_DS_MSG_INIT(0x2d, cfa_gnu) };
68*9273SAli.Bahrami@Sun.COM static const conv_ds_t *ds_cfa[] = { CONV_DS_ADDR(ds_msg_cfa),
69*9273SAli.Bahrami@Sun.COM CONV_DS_ADDR(ds_msg_cfa_mips), CONV_DS_ADDR(ds_msg_cfa_gnu), NULL };
70*9273SAli.Bahrami@Sun.COM
719085SAli.Bahrami@Sun.COM
729085SAli.Bahrami@Sun.COM /*
739085SAli.Bahrami@Sun.COM * DWARF CFA opcodes are bytes. The top 2 bits are a primary
749085SAli.Bahrami@Sun.COM * opcode, and if zero, the lower 6 bits specify a sub-opcode
759085SAli.Bahrami@Sun.COM */
769085SAli.Bahrami@Sun.COM switch (op >> 6) {
779085SAli.Bahrami@Sun.COM case 0x1:
789085SAli.Bahrami@Sun.COM return (MSG_ORIG(MSG_DW_CFA_ADVANCE_LOC));
799085SAli.Bahrami@Sun.COM case 0x2:
809085SAli.Bahrami@Sun.COM return (MSG_ORIG(MSG_DW_CFA_OFFSET));
819085SAli.Bahrami@Sun.COM case 0x3:
829085SAli.Bahrami@Sun.COM return (MSG_ORIG(MSG_DW_CFA_RESTORE));
839085SAli.Bahrami@Sun.COM }
849085SAli.Bahrami@Sun.COM
85*9273SAli.Bahrami@Sun.COM return (conv_map_ds(ELFOSABI_NONE, EM_NONE, op, ds_cfa,
86*9273SAli.Bahrami@Sun.COM fmt_flags, inv_buf));
879085SAli.Bahrami@Sun.COM }
889085SAli.Bahrami@Sun.COM
899085SAli.Bahrami@Sun.COM /*
909085SAli.Bahrami@Sun.COM * Translate DWARF register numbers to hardware specific names
919085SAli.Bahrami@Sun.COM *
929085SAli.Bahrami@Sun.COM * If good_name is non-NULL, conv_dwarf_regname() will set the variable to
939085SAli.Bahrami@Sun.COM * True(1) if the returned string is considered to be a good name to
949085SAli.Bahrami@Sun.COM * display, and False(0) otherwise. To be considered "good":
959085SAli.Bahrami@Sun.COM *
969085SAli.Bahrami@Sun.COM * - The name must be a well known mnemonic for a register
979085SAli.Bahrami@Sun.COM * from the machine type in question.
989085SAli.Bahrami@Sun.COM *
999085SAli.Bahrami@Sun.COM * - The name must be different than the DWARF name for
1009085SAli.Bahrami@Sun.COM * the same register.
1019085SAli.Bahrami@Sun.COM *
1029085SAli.Bahrami@Sun.COM * The returned string is usable, regardless of the value returned in
1039085SAli.Bahrami@Sun.COM * *good_name.
1049085SAli.Bahrami@Sun.COM */
1059085SAli.Bahrami@Sun.COM const char *
conv_dwarf_regname(Half mach,Word regno,Conv_fmt_flags_t fmt_flags,int * good_name,Conv_inv_buf_t * inv_buf)1069085SAli.Bahrami@Sun.COM conv_dwarf_regname(Half mach, Word regno, Conv_fmt_flags_t fmt_flags,
1079085SAli.Bahrami@Sun.COM int *good_name, Conv_inv_buf_t *inv_buf)
1089085SAli.Bahrami@Sun.COM {
1099085SAli.Bahrami@Sun.COM static const Msg reg_amd64[67] = {
1109085SAli.Bahrami@Sun.COM MSG_REG_RAX, MSG_REG_RDX,
1119085SAli.Bahrami@Sun.COM MSG_REG_RCX, MSG_REG_RBX,
1129085SAli.Bahrami@Sun.COM MSG_REG_RSI, MSG_REG_RDI,
1139085SAli.Bahrami@Sun.COM MSG_REG_RBP, MSG_REG_RSP,
1149085SAli.Bahrami@Sun.COM MSG_REG_R8, MSG_REG_R9,
1159085SAli.Bahrami@Sun.COM MSG_REG_R10, MSG_REG_R11,
1169085SAli.Bahrami@Sun.COM MSG_REG_R12, MSG_REG_R13,
1179085SAli.Bahrami@Sun.COM MSG_REG_R14, MSG_REG_R15,
1189085SAli.Bahrami@Sun.COM MSG_REG_RA, MSG_REG_PERXMM0,
1199085SAli.Bahrami@Sun.COM MSG_REG_PERXMM1, MSG_REG_PERXMM2,
1209085SAli.Bahrami@Sun.COM MSG_REG_PERXMM3, MSG_REG_PERXMM4,
1219085SAli.Bahrami@Sun.COM MSG_REG_PERXMM5, MSG_REG_PERXMM6,
1229085SAli.Bahrami@Sun.COM MSG_REG_PERXMM7, MSG_REG_PERXMM8,
1239085SAli.Bahrami@Sun.COM MSG_REG_PERXMM9, MSG_REG_PERXMM10,
1249085SAli.Bahrami@Sun.COM MSG_REG_PERXMM11, MSG_REG_PERXMM12,
1259085SAli.Bahrami@Sun.COM MSG_REG_PERXMM13, MSG_REG_PERXMM14,
1269085SAli.Bahrami@Sun.COM MSG_REG_PERXMM15, MSG_REG_PERST0,
1279085SAli.Bahrami@Sun.COM MSG_REG_PERST1, MSG_REG_PERST2,
1289085SAli.Bahrami@Sun.COM MSG_REG_PERST3, MSG_REG_PERST4,
1299085SAli.Bahrami@Sun.COM MSG_REG_PERST5, MSG_REG_PERST6,
1309085SAli.Bahrami@Sun.COM MSG_REG_PERST7, MSG_REG_PERMM0,
1319085SAli.Bahrami@Sun.COM MSG_REG_PERMM1, MSG_REG_PERMM2,
1329085SAli.Bahrami@Sun.COM MSG_REG_PERMM3, MSG_REG_PERMM4,
1339085SAli.Bahrami@Sun.COM MSG_REG_PERMM5, MSG_REG_PERMM6,
1349085SAli.Bahrami@Sun.COM MSG_REG_PERMM7, MSG_REG_PERRFLAGS,
1359085SAli.Bahrami@Sun.COM MSG_REG_PERES, MSG_REG_PERCS,
1369085SAli.Bahrami@Sun.COM MSG_REG_PERSS, MSG_REG_PERDS,
1379085SAli.Bahrami@Sun.COM MSG_REG_PERFS, MSG_REG_PERGS,
1389085SAli.Bahrami@Sun.COM MSG_REG_RESERVED, MSG_REG_RESERVED,
1399085SAli.Bahrami@Sun.COM MSG_REG_PERFSDOTBASE, MSG_REG_PERGSDOTBASE,
1409085SAli.Bahrami@Sun.COM MSG_REG_RESERVED, MSG_REG_RESERVED,
1419085SAli.Bahrami@Sun.COM MSG_REG_PERTR, MSG_REG_PERLDTR,
1429085SAli.Bahrami@Sun.COM MSG_REG_PERMXCSR, MSG_REG_PERFCW,
1439085SAli.Bahrami@Sun.COM MSG_REG_PERFSW
1449085SAli.Bahrami@Sun.COM };
145*9273SAli.Bahrami@Sun.COM static const conv_ds_msg_t ds_msg_reg_amd64 = {
146*9273SAli.Bahrami@Sun.COM CONV_DS_MSG_INIT(0, reg_amd64) };
147*9273SAli.Bahrami@Sun.COM static const conv_ds_t *ds_reg_amd64[] = {
148*9273SAli.Bahrami@Sun.COM CONV_DS_ADDR(ds_msg_reg_amd64), NULL };
1499085SAli.Bahrami@Sun.COM
1509085SAli.Bahrami@Sun.COM static const Msg reg_i386[8] = {
1519085SAli.Bahrami@Sun.COM MSG_REG_EAX, MSG_REG_ECX,
1529085SAli.Bahrami@Sun.COM MSG_REG_EDX, MSG_REG_EBX,
1539085SAli.Bahrami@Sun.COM MSG_REG_UESP, MSG_REG_EBP,
1549085SAli.Bahrami@Sun.COM MSG_REG_ESI, MSG_REG_EDI
1559085SAli.Bahrami@Sun.COM };
156*9273SAli.Bahrami@Sun.COM static const conv_ds_msg_t ds_msg_reg_i386 = {
157*9273SAli.Bahrami@Sun.COM CONV_DS_MSG_INIT(0, reg_i386) };
158*9273SAli.Bahrami@Sun.COM static const conv_ds_t *ds_reg_i386[] = {
159*9273SAli.Bahrami@Sun.COM CONV_DS_ADDR(ds_msg_reg_i386), NULL };
1609085SAli.Bahrami@Sun.COM
1619085SAli.Bahrami@Sun.COM static const Msg reg_sparc[64] = {
1629085SAli.Bahrami@Sun.COM MSG_REG_G0, MSG_REG_G1,
1639085SAli.Bahrami@Sun.COM MSG_REG_G2, MSG_REG_G3,
1649085SAli.Bahrami@Sun.COM MSG_REG_G4, MSG_REG_G5,
1659085SAli.Bahrami@Sun.COM MSG_REG_G6, MSG_REG_G7,
1669085SAli.Bahrami@Sun.COM MSG_REG_O0, MSG_REG_O1,
1679085SAli.Bahrami@Sun.COM MSG_REG_O2, MSG_REG_O3,
1689085SAli.Bahrami@Sun.COM MSG_REG_O4, MSG_REG_O5,
1699085SAli.Bahrami@Sun.COM MSG_REG_O6, MSG_REG_O7,
1709085SAli.Bahrami@Sun.COM MSG_REG_L0, MSG_REG_L1,
1719085SAli.Bahrami@Sun.COM MSG_REG_L2, MSG_REG_L3,
1729085SAli.Bahrami@Sun.COM MSG_REG_L4, MSG_REG_L5,
1739085SAli.Bahrami@Sun.COM MSG_REG_L6, MSG_REG_L7,
1749085SAli.Bahrami@Sun.COM MSG_REG_I0, MSG_REG_I1,
1759085SAli.Bahrami@Sun.COM MSG_REG_I2, MSG_REG_I3,
1769085SAli.Bahrami@Sun.COM MSG_REG_I4, MSG_REG_I5,
1779085SAli.Bahrami@Sun.COM MSG_REG_I6, MSG_REG_I7,
1789085SAli.Bahrami@Sun.COM MSG_REG_F0, MSG_REG_F1,
1799085SAli.Bahrami@Sun.COM MSG_REG_F2, MSG_REG_F3,
1809085SAli.Bahrami@Sun.COM MSG_REG_F4, MSG_REG_F5,
1819085SAli.Bahrami@Sun.COM MSG_REG_F6, MSG_REG_F7,
1829085SAli.Bahrami@Sun.COM MSG_REG_F8, MSG_REG_F9,
1839085SAli.Bahrami@Sun.COM MSG_REG_F10, MSG_REG_F11,
1849085SAli.Bahrami@Sun.COM MSG_REG_F12, MSG_REG_F13,
1859085SAli.Bahrami@Sun.COM MSG_REG_F14, MSG_REG_F15,
1869085SAli.Bahrami@Sun.COM MSG_REG_F16, MSG_REG_F17,
1879085SAli.Bahrami@Sun.COM MSG_REG_F18, MSG_REG_F19,
1889085SAli.Bahrami@Sun.COM MSG_REG_F20, MSG_REG_F21,
1899085SAli.Bahrami@Sun.COM MSG_REG_F22, MSG_REG_F23,
1909085SAli.Bahrami@Sun.COM MSG_REG_F24, MSG_REG_F25,
1919085SAli.Bahrami@Sun.COM MSG_REG_F26, MSG_REG_F27,
1929085SAli.Bahrami@Sun.COM MSG_REG_F28, MSG_REG_F29,
1939085SAli.Bahrami@Sun.COM MSG_REG_F30, MSG_REG_F31
1949085SAli.Bahrami@Sun.COM };
195*9273SAli.Bahrami@Sun.COM static const conv_ds_msg_t ds_msg_reg_sparc = {
196*9273SAli.Bahrami@Sun.COM CONV_DS_MSG_INIT(0, reg_sparc) };
197*9273SAli.Bahrami@Sun.COM static const conv_ds_t *ds_reg_sparc[] = {
198*9273SAli.Bahrami@Sun.COM CONV_DS_ADDR(ds_msg_reg_sparc), NULL };
1999085SAli.Bahrami@Sun.COM
2009085SAli.Bahrami@Sun.COM switch (mach) {
2019085SAli.Bahrami@Sun.COM case EM_AMD64:
2029085SAli.Bahrami@Sun.COM /*
2039085SAli.Bahrami@Sun.COM * amd64 has several in-bounds names we'd rather not
2049085SAli.Bahrami@Sun.COM * use. R8-R15 have the same name as their DWARF counterparts.
2059085SAli.Bahrami@Sun.COM * 56-57, and 60-61 are reserved, and don't have a good name.
2069085SAli.Bahrami@Sun.COM */
2079085SAli.Bahrami@Sun.COM if (good_name)
2089085SAli.Bahrami@Sun.COM *good_name = ((regno < 8) || (regno > 15)) &&
2099085SAli.Bahrami@Sun.COM (regno != 56) && (regno != 57) &&
2109085SAli.Bahrami@Sun.COM (regno != 60) && (regno != 61) &&
2119085SAli.Bahrami@Sun.COM (regno < ARRAY_NELTS(reg_amd64));
212*9273SAli.Bahrami@Sun.COM return (conv_map_ds(ELFOSABI_NONE, EM_NONE, regno,
213*9273SAli.Bahrami@Sun.COM ds_reg_amd64, fmt_flags, inv_buf));
2149085SAli.Bahrami@Sun.COM
2159085SAli.Bahrami@Sun.COM case EM_386:
2169085SAli.Bahrami@Sun.COM case EM_486:
2179085SAli.Bahrami@Sun.COM if (good_name)
2189085SAli.Bahrami@Sun.COM *good_name = (regno < ARRAY_NELTS(reg_i386));
219*9273SAli.Bahrami@Sun.COM return (conv_map_ds(ELFOSABI_NONE, EM_NONE, regno,
220*9273SAli.Bahrami@Sun.COM ds_reg_i386, fmt_flags, inv_buf));
2219085SAli.Bahrami@Sun.COM
2229085SAli.Bahrami@Sun.COM case EM_SPARC:
2239085SAli.Bahrami@Sun.COM case EM_SPARC32PLUS:
2249085SAli.Bahrami@Sun.COM case EM_SPARCV9:
2259085SAli.Bahrami@Sun.COM if (good_name)
2269085SAli.Bahrami@Sun.COM *good_name = (regno < ARRAY_NELTS(reg_sparc));
227*9273SAli.Bahrami@Sun.COM return (conv_map_ds(ELFOSABI_NONE, EM_NONE, regno,
228*9273SAli.Bahrami@Sun.COM ds_reg_sparc, fmt_flags, inv_buf));
2299085SAli.Bahrami@Sun.COM }
2309085SAli.Bahrami@Sun.COM
2319085SAli.Bahrami@Sun.COM if (good_name)
2329085SAli.Bahrami@Sun.COM *good_name = 0;
2339085SAli.Bahrami@Sun.COM return (conv_invalid_val(inv_buf, regno, 0));
2349085SAli.Bahrami@Sun.COM }
235