4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
30 #include <dwarf_msg.h>
33 * This code is primarily of interest to elfdump. Separating it from dwarf_ehe
34 * allows other tools to use dwarf_ehe without also pulling this in.
38 * Translate DW_CFA_ codes, used to identify Call Frame Instructions.
41 conv_dwarf_cfa(uchar_t op
, Conv_fmt_flags_t fmt_flags
, Conv_inv_buf_t
*inv_buf
)
43 static const Msg cfa
[] = {
44 MSG_DW_CFA_NOP
, MSG_DW_CFA_SET_LOC
,
45 MSG_DW_CFA_ADVANCE_LOC_1
, MSG_DW_CFA_ADVANCE_LOC_2
,
46 MSG_DW_CFA_ADVANCE_LOC_4
, MSG_DW_CFA_OFFSET_EXTENDED
,
47 MSG_DW_CFA_RESTORE_EXTENDED
, MSG_DW_CFA_UNDEFINED
,
48 MSG_DW_CFA_SAME_VALUE
, MSG_DW_CFA_REGISTER
,
49 MSG_DW_CFA_REMEMBER_STATE
, MSG_DW_CFA_RESTORE_STATE
,
50 MSG_DW_CFA_DEF_CFA
, MSG_DW_CFA_DEF_CFA_REGISTER
,
51 MSG_DW_CFA_DEF_CFA_OFFSET
, MSG_DW_CFA_DEF_CFA_EXPRESSION
,
52 MSG_DW_CFA_EXPRESSION
, MSG_DW_CFA_OFFSET_EXTENDED_SF
,
53 MSG_DW_CFA_DEF_CFA_SF
, MSG_DW_CFA_DEF_CFA_OFFSET_SF
,
54 MSG_DW_CFA_VAL_OFFSET
, MSG_DW_CFA_VAL_OFFSET_SF
,
55 MSG_DW_CFA_VAL_EXPRESSION
57 static const Msg cfa_mips
[] = { MSG_DW_CFA_MIPS_ADV_LOC8
};
58 static const Msg cfa_gnu
[] = {
59 MSG_DW_CFA_GNU_WINDOW_SAVE
, MSG_DW_CFA_GNU_ARGS_SIZE
,
60 MSG_DW_CFA_GNU_NEGATIVE_OFF_X
62 static const conv_ds_msg_t ds_msg_cfa
= {
63 CONV_DS_MSG_INIT(0, cfa
) };
64 static const conv_ds_msg_t ds_msg_cfa_mips
= {
65 CONV_DS_MSG_INIT(0x1d, cfa_mips
) };
66 static const conv_ds_msg_t ds_msg_cfa_gnu
= {
67 CONV_DS_MSG_INIT(0x2d, cfa_gnu
) };
68 static const conv_ds_t
*ds_cfa
[] = { CONV_DS_ADDR(ds_msg_cfa
),
69 CONV_DS_ADDR(ds_msg_cfa_mips
), CONV_DS_ADDR(ds_msg_cfa_gnu
), NULL
};
73 * DWARF CFA opcodes are bytes. The top 2 bits are a primary
74 * opcode, and if zero, the lower 6 bits specify a sub-opcode
78 return (MSG_ORIG(MSG_DW_CFA_ADVANCE_LOC
));
80 return (MSG_ORIG(MSG_DW_CFA_OFFSET
));
82 return (MSG_ORIG(MSG_DW_CFA_RESTORE
));
85 return (conv_map_ds(ELFOSABI_NONE
, EM_NONE
, op
, ds_cfa
,
90 * Translate DWARF register numbers to hardware specific names
92 * If good_name is non-NULL, conv_dwarf_regname() will set the variable to
93 * True(1) if the returned string is considered to be a good name to
94 * display, and False(0) otherwise. To be considered "good":
96 * - The name must be a well known mnemonic for a register
97 * from the machine type in question.
99 * - The name must be different than the DWARF name for
102 * The returned string is usable, regardless of the value returned in
106 conv_dwarf_regname(Half mach
, Word regno
, Conv_fmt_flags_t fmt_flags
,
107 int *good_name
, Conv_inv_buf_t
*inv_buf
)
109 static const Msg reg_amd64
[67] = {
110 MSG_REG_RAX
, MSG_REG_RDX
,
111 MSG_REG_RCX
, MSG_REG_RBX
,
112 MSG_REG_RSI
, MSG_REG_RDI
,
113 MSG_REG_RBP
, MSG_REG_RSP
,
114 MSG_REG_R8
, MSG_REG_R9
,
115 MSG_REG_R10
, MSG_REG_R11
,
116 MSG_REG_R12
, MSG_REG_R13
,
117 MSG_REG_R14
, MSG_REG_R15
,
118 MSG_REG_RA
, MSG_REG_PERXMM0
,
119 MSG_REG_PERXMM1
, MSG_REG_PERXMM2
,
120 MSG_REG_PERXMM3
, MSG_REG_PERXMM4
,
121 MSG_REG_PERXMM5
, MSG_REG_PERXMM6
,
122 MSG_REG_PERXMM7
, MSG_REG_PERXMM8
,
123 MSG_REG_PERXMM9
, MSG_REG_PERXMM10
,
124 MSG_REG_PERXMM11
, MSG_REG_PERXMM12
,
125 MSG_REG_PERXMM13
, MSG_REG_PERXMM14
,
126 MSG_REG_PERXMM15
, MSG_REG_PERST0
,
127 MSG_REG_PERST1
, MSG_REG_PERST2
,
128 MSG_REG_PERST3
, MSG_REG_PERST4
,
129 MSG_REG_PERST5
, MSG_REG_PERST6
,
130 MSG_REG_PERST7
, MSG_REG_PERMM0
,
131 MSG_REG_PERMM1
, MSG_REG_PERMM2
,
132 MSG_REG_PERMM3
, MSG_REG_PERMM4
,
133 MSG_REG_PERMM5
, MSG_REG_PERMM6
,
134 MSG_REG_PERMM7
, MSG_REG_PERRFLAGS
,
135 MSG_REG_PERES
, MSG_REG_PERCS
,
136 MSG_REG_PERSS
, MSG_REG_PERDS
,
137 MSG_REG_PERFS
, MSG_REG_PERGS
,
138 MSG_REG_RESERVED
, MSG_REG_RESERVED
,
139 MSG_REG_PERFSDOTBASE
, MSG_REG_PERGSDOTBASE
,
140 MSG_REG_RESERVED
, MSG_REG_RESERVED
,
141 MSG_REG_PERTR
, MSG_REG_PERLDTR
,
142 MSG_REG_PERMXCSR
, MSG_REG_PERFCW
,
145 static const conv_ds_msg_t ds_msg_reg_amd64
= {
146 CONV_DS_MSG_INIT(0, reg_amd64
) };
147 static const conv_ds_t
*ds_reg_amd64
[] = {
148 CONV_DS_ADDR(ds_msg_reg_amd64
), NULL
};
150 static const Msg reg_i386
[8] = {
151 MSG_REG_EAX
, MSG_REG_ECX
,
152 MSG_REG_EDX
, MSG_REG_EBX
,
153 MSG_REG_UESP
, MSG_REG_EBP
,
154 MSG_REG_ESI
, MSG_REG_EDI
156 static const conv_ds_msg_t ds_msg_reg_i386
= {
157 CONV_DS_MSG_INIT(0, reg_i386
) };
158 static const conv_ds_t
*ds_reg_i386
[] = {
159 CONV_DS_ADDR(ds_msg_reg_i386
), NULL
};
161 static const Msg reg_sparc
[64] = {
162 MSG_REG_G0
, MSG_REG_G1
,
163 MSG_REG_G2
, MSG_REG_G3
,
164 MSG_REG_G4
, MSG_REG_G5
,
165 MSG_REG_G6
, MSG_REG_G7
,
166 MSG_REG_O0
, MSG_REG_O1
,
167 MSG_REG_O2
, MSG_REG_O3
,
168 MSG_REG_O4
, MSG_REG_O5
,
169 MSG_REG_O6
, MSG_REG_O7
,
170 MSG_REG_L0
, MSG_REG_L1
,
171 MSG_REG_L2
, MSG_REG_L3
,
172 MSG_REG_L4
, MSG_REG_L5
,
173 MSG_REG_L6
, MSG_REG_L7
,
174 MSG_REG_I0
, MSG_REG_I1
,
175 MSG_REG_I2
, MSG_REG_I3
,
176 MSG_REG_I4
, MSG_REG_I5
,
177 MSG_REG_I6
, MSG_REG_I7
,
178 MSG_REG_F0
, MSG_REG_F1
,
179 MSG_REG_F2
, MSG_REG_F3
,
180 MSG_REG_F4
, MSG_REG_F5
,
181 MSG_REG_F6
, MSG_REG_F7
,
182 MSG_REG_F8
, MSG_REG_F9
,
183 MSG_REG_F10
, MSG_REG_F11
,
184 MSG_REG_F12
, MSG_REG_F13
,
185 MSG_REG_F14
, MSG_REG_F15
,
186 MSG_REG_F16
, MSG_REG_F17
,
187 MSG_REG_F18
, MSG_REG_F19
,
188 MSG_REG_F20
, MSG_REG_F21
,
189 MSG_REG_F22
, MSG_REG_F23
,
190 MSG_REG_F24
, MSG_REG_F25
,
191 MSG_REG_F26
, MSG_REG_F27
,
192 MSG_REG_F28
, MSG_REG_F29
,
193 MSG_REG_F30
, MSG_REG_F31
195 static const conv_ds_msg_t ds_msg_reg_sparc
= {
196 CONV_DS_MSG_INIT(0, reg_sparc
) };
197 static const conv_ds_t
*ds_reg_sparc
[] = {
198 CONV_DS_ADDR(ds_msg_reg_sparc
), NULL
};
203 * amd64 has several in-bounds names we'd rather not
204 * use. R8-R15 have the same name as their DWARF counterparts.
205 * 56-57, and 60-61 are reserved, and don't have a good name.
208 *good_name
= ((regno
< 8) || (regno
> 15)) &&
209 (regno
!= 56) && (regno
!= 57) &&
210 (regno
!= 60) && (regno
!= 61) &&
211 (regno
< ARRAY_NELTS(reg_amd64
));
212 return (conv_map_ds(ELFOSABI_NONE
, EM_NONE
, regno
,
213 ds_reg_amd64
, fmt_flags
, inv_buf
));
218 *good_name
= (regno
< ARRAY_NELTS(reg_i386
));
219 return (conv_map_ds(ELFOSABI_NONE
, EM_NONE
, regno
,
220 ds_reg_i386
, fmt_flags
, inv_buf
));
226 *good_name
= (regno
< ARRAY_NELTS(reg_sparc
));
227 return (conv_map_ds(ELFOSABI_NONE
, EM_NONE
, regno
,
228 ds_reg_sparc
, fmt_flags
, inv_buf
));
233 return (conv_invalid_val(inv_buf
, regno
, 0));