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.
28 * String conversion routines for symbol attributes.
31 #include <sys/elf_SPARC.h>
32 #include <sys/elf_amd64.h>
34 #include "symbols_msg.h"
37 conv_sym_other(uchar_t other
, Conv_inv_buf_t
*inv_buf
)
39 static const char visibility
[7] = {
40 'D', /* STV_DEFAULT */
41 'I', /* STV_INTERNAL */
43 'P', /* STV_PROTECTED */
44 'X', /* STV_EXPORTED */
45 'S', /* STV_SINGLETON */
46 'E' /* STV_ELIMINATE */
48 uchar_t vis
= ELF_ST_VISIBILITY(other
);
51 inv_buf
->buf
[ndx
++] = visibility
[vis
];
54 * If unknown bits are present in st_other - throw out a '?'
56 if (other
& ~MSK_SYM_VISIBILITY
)
57 inv_buf
->buf
[ndx
++] = '?';
58 inv_buf
->buf
[ndx
++] = '\0';
60 return (inv_buf
->buf
);
63 static const conv_ds_t
**
64 conv_sym_other_vis_strings(Conv_fmt_flags_t fmt_flags
)
66 static const Msg vis_def
[] = {
67 MSG_STV_DEFAULT_DEF
, MSG_STV_INTERNAL_DEF
,
68 MSG_STV_HIDDEN_DEF
, MSG_STV_PROTECTED_DEF
,
69 MSG_STV_EXPORTED_DEF
, MSG_STV_SINGLETON_DEF
,
72 static const Msg vis_cf
[] = {
73 MSG_STV_DEFAULT_CF
, MSG_STV_INTERNAL_CF
,
74 MSG_STV_HIDDEN_CF
, MSG_STV_PROTECTED_CF
,
75 MSG_STV_EXPORTED_CF
, MSG_STV_SINGLETON_CF
,
78 static const Msg vis_nf
[] = {
79 MSG_STV_DEFAULT_NF
, MSG_STV_INTERNAL_NF
,
80 MSG_STV_HIDDEN_NF
, MSG_STV_PROTECTED_NF
,
81 MSG_STV_EXPORTED_NF
, MSG_STV_SINGLETON_NF
,
84 static const conv_ds_msg_t ds_vis_def
= {
85 CONV_DS_MSG_INIT(STV_DEFAULT
, vis_def
) };
86 static const conv_ds_msg_t ds_vis_cf
= {
87 CONV_DS_MSG_INIT(STV_DEFAULT
, vis_cf
) };
88 static const conv_ds_msg_t ds_vis_nf
= {
89 CONV_DS_MSG_INIT(STV_DEFAULT
, vis_nf
) };
91 /* Build NULL terminated return arrays for each string style */
92 static const const conv_ds_t
*ds_def
[] = {
93 CONV_DS_ADDR(ds_vis_def
), NULL
};
94 static const const conv_ds_t
*ds_cf
[] = {
95 CONV_DS_ADDR(ds_vis_cf
), NULL
};
96 static const const conv_ds_t
*ds_nf
[] = {
97 CONV_DS_ADDR(ds_vis_nf
), NULL
};
99 /* Select the strings to use */
100 switch (CONV_TYPE_FMT_ALT(fmt_flags
)) {
101 case CONV_FMT_ALT_CF
:
103 case CONV_FMT_ALT_NF
:
111 conv_sym_other_vis(uchar_t value
, Conv_fmt_flags_t fmt_flags
,
112 Conv_inv_buf_t
*inv_buf
)
114 return (conv_map_ds(ELFOSABI_NONE
, EM_NONE
, value
,
115 conv_sym_other_vis_strings(fmt_flags
), fmt_flags
, inv_buf
));
119 conv_iter_sym_other_vis(Conv_fmt_flags_t fmt_flags
, conv_iter_cb_t func
,
122 return (conv_iter_ds(ELFOSABI_NONE
, EM_NONE
,
123 conv_sym_other_vis_strings(fmt_flags
), func
, uvalue
));
126 static const conv_ds_t
**
127 conv_sym_info_type_strings(Half mach
, Conv_fmt_flags_t fmt_flags
)
130 * This routine can return an array with 1 generic array, and
131 * a machine array, plus the NULL termination.
135 static const Msg types_def
[] = {
136 MSG_STT_NOTYPE_DEF
, MSG_STT_OBJECT_DEF
,
137 MSG_STT_FUNC_DEF
, MSG_STT_SECTION_DEF
,
138 MSG_STT_FILE_DEF
, MSG_STT_COMMON_DEF
,
139 MSG_STT_TLS_DEF
, MSG_STT_IFUNC_DEF
141 static const Msg types_cf
[] = {
142 MSG_STT_NOTYPE_CF
, MSG_STT_OBJECT_CF
,
143 MSG_STT_FUNC_CF
, MSG_STT_SECTION_CF
,
144 MSG_STT_FILE_CF
, MSG_STT_COMMON_CF
,
145 MSG_STT_TLS_CF
, MSG_STT_IFUNC_CF
147 static const Msg types_nf
[] = {
148 MSG_STT_NOTYPE_NF
, MSG_STT_OBJECT_NF
,
149 MSG_STT_FUNC_NF
, MSG_STT_SECTION_NF
,
150 MSG_STT_FILE_NF
, MSG_STT_COMMON_NF
,
151 MSG_STT_TLS_NF
, MSG_STT_IFUNC_NF
153 static const conv_ds_msg_t ds_types_def
= {
154 CONV_DS_MSG_INIT(STT_NOTYPE
, types_def
) };
155 static const conv_ds_msg_t ds_types_cf
= {
156 CONV_DS_MSG_INIT(STT_NOTYPE
, types_cf
) };
157 static const conv_ds_msg_t ds_types_nf
= {
158 CONV_DS_MSG_INIT(STT_NOTYPE
, types_nf
) };
161 static const Msg sparc_def
[] = { MSG_STT_SPARC_REGISTER_DEF
};
162 static const Msg sparc_cf
[] = { MSG_STT_SPARC_REGISTER_CF
};
163 static const Msg sparc_nf
[] = { MSG_STT_SPARC_REGISTER_NF
};
164 static const conv_ds_msg_t ds_sparc_def
= {
165 CONV_DS_MSG_INIT(STT_SPARC_REGISTER
, sparc_def
) };
166 static const conv_ds_msg_t ds_sparc_cf
= {
167 CONV_DS_MSG_INIT(STT_SPARC_REGISTER
, sparc_cf
) };
168 static const conv_ds_msg_t ds_sparc_nf
= {
169 CONV_DS_MSG_INIT(STT_SPARC_REGISTER
, sparc_nf
) };
172 static const conv_ds_t
*retarr
[MAX_RET
];
177 is_sparc
= (mach
== EM_SPARC
) || (mach
== EM_SPARCV9
) ||
178 (mach
== EM_SPARC32PLUS
) || (mach
== CONV_MACH_ALL
);
180 switch (CONV_TYPE_FMT_ALT(fmt_flags
)) {
181 case CONV_FMT_ALT_CF
:
182 retarr
[retndx
++] = CONV_DS_ADDR(ds_types_cf
);
184 retarr
[retndx
++] = CONV_DS_ADDR(ds_sparc_cf
);
186 case CONV_FMT_ALT_NF
:
187 retarr
[retndx
++] = CONV_DS_ADDR(ds_types_nf
);
189 retarr
[retndx
++] = CONV_DS_ADDR(ds_sparc_nf
);
192 retarr
[retndx
++] = CONV_DS_ADDR(ds_types_def
);
194 retarr
[retndx
++] = CONV_DS_ADDR(ds_sparc_def
);
198 retarr
[retndx
++] = NULL
;
199 assert(retndx
<= MAX_RET
);
204 conv_sym_info_type(Half mach
, uchar_t type
, Conv_fmt_flags_t fmt_flags
,
205 Conv_inv_buf_t
*inv_buf
)
207 return (conv_map_ds(ELFOSABI_NONE
, mach
, type
,
208 conv_sym_info_type_strings(mach
, fmt_flags
), fmt_flags
, inv_buf
));
212 conv_iter_sym_info_type(Half mach
, Conv_fmt_flags_t fmt_flags
,
213 conv_iter_cb_t func
, void *uvalue
)
215 return (conv_iter_ds(ELFOSABI_NONE
, mach
,
216 conv_sym_info_type_strings(mach
, fmt_flags
), func
, uvalue
));
219 static const conv_ds_t
**
220 conv_sym_info_bind_strings(Conv_fmt_flags_t fmt_flags
)
222 static const Msg binds_def
[] = {
223 MSG_STB_LOCAL_DEF
, MSG_STB_GLOBAL_DEF
,
226 static const Msg binds_cf
[] = {
227 MSG_STB_LOCAL_CF
, MSG_STB_GLOBAL_CF
,
230 static const Msg binds_nf
[] = {
231 MSG_STB_LOCAL_NF
, MSG_STB_GLOBAL_NF
,
234 static const conv_ds_msg_t ds_binds_def
= {
235 CONV_DS_MSG_INIT(STB_LOCAL
, binds_def
) };
236 static const conv_ds_msg_t ds_binds_cf
= {
237 CONV_DS_MSG_INIT(STB_LOCAL
, binds_cf
) };
238 static const conv_ds_msg_t ds_binds_nf
= {
239 CONV_DS_MSG_INIT(STB_LOCAL
, binds_nf
) };
242 /* Build NULL terminated return arrays for each string style */
243 static const const conv_ds_t
*ds_def
[] = {
244 CONV_DS_ADDR(ds_binds_def
), NULL
};
245 static const const conv_ds_t
*ds_cf
[] = {
246 CONV_DS_ADDR(ds_binds_cf
), NULL
};
247 static const const conv_ds_t
*ds_nf
[] = {
248 CONV_DS_ADDR(ds_binds_nf
), NULL
};
251 /* Select the strings to use */
252 switch (CONV_TYPE_FMT_ALT(fmt_flags
)) {
253 case CONV_FMT_ALT_CF
:
255 case CONV_FMT_ALT_NF
:
263 conv_sym_info_bind(uchar_t bind
, Conv_fmt_flags_t fmt_flags
,
264 Conv_inv_buf_t
*inv_buf
)
266 return (conv_map_ds(ELFOSABI_NONE
, EM_NONE
, bind
,
267 conv_sym_info_bind_strings(fmt_flags
), fmt_flags
, inv_buf
));
271 conv_iter_sym_info_bind(Conv_fmt_flags_t fmt_flags
, conv_iter_cb_t func
,
274 return (conv_iter_ds(ELFOSABI_NONE
, EM_NONE
,
275 conv_sym_info_bind_strings(fmt_flags
), func
, uvalue
));
278 static const conv_ds_t
**
279 conv_sym_shndx_strings(Conv_fmt_flags_t fmt_flags
)
281 #define ALL ELFOSABI_NONE, EM_NONE
282 #define SOL ELFOSABI_SOLARIS, EM_NONE
283 #define AMD ELFOSABI_NONE, EM_AMD64
286 * There aren't many of these values, and they are sparse,
287 * so rather than separate them into different ranges, I use
288 * a single Val_desc2 array for all of them.
290 static const Val_desc2 shn_def
[] = {
291 { SHN_UNDEF
, ALL
, MSG_SHN_UNDEF_CFNP
},
292 { SHN_BEFORE
, ALL
, MSG_SHN_BEFORE_CFNP
},
293 { SHN_AFTER
, ALL
, MSG_SHN_AFTER_CFNP
},
294 { SHN_AMD64_LCOMMON
, AMD
, MSG_SHN_AMD64_LCOMMON_DEF
},
295 { SHN_SUNW_IGNORE
, SOL
, MSG_SHN_SUNW_IGNORE_DEF
},
296 { SHN_ABS
, ALL
, MSG_SHN_ABS_CFNP
},
297 { SHN_COMMON
, ALL
, MSG_SHN_COMMON_CFNP
},
298 { SHN_XINDEX
, ALL
, MSG_SHN_XINDEX_CFNP
},
301 static const Val_desc2 shn_cf
[] = {
302 { SHN_UNDEF
, ALL
, MSG_SHN_UNDEF_CF
},
303 { SHN_BEFORE
, ALL
, MSG_SHN_BEFORE_CF
},
304 { SHN_AFTER
, ALL
, MSG_SHN_AFTER_CF
},
305 { SHN_AMD64_LCOMMON
, AMD
, MSG_SHN_AMD64_LCOMMON_CF
},
306 { SHN_SUNW_IGNORE
, SOL
, MSG_SHN_SUNW_IGNORE_CF
},
307 { SHN_ABS
, ALL
, MSG_SHN_ABS_CF
},
308 { SHN_COMMON
, ALL
, MSG_SHN_COMMON_CF
},
309 { SHN_XINDEX
, ALL
, MSG_SHN_XINDEX_CF
},
312 static const Val_desc2 shn_cfnp
[] = {
313 { SHN_UNDEF
, ALL
, MSG_SHN_UNDEF_CFNP
},
314 { SHN_BEFORE
, ALL
, MSG_SHN_BEFORE_CFNP
},
315 { SHN_AFTER
, ALL
, MSG_SHN_AFTER_CFNP
},
316 { SHN_AMD64_LCOMMON
, AMD
, MSG_SHN_AMD64_LCOMMON_CFNP
},
317 { SHN_SUNW_IGNORE
, SOL
, MSG_SHN_SUNW_IGNORE_CFNP
},
318 { SHN_ABS
, ALL
, MSG_SHN_ABS_CFNP
},
319 { SHN_COMMON
, ALL
, MSG_SHN_COMMON_CFNP
},
320 { SHN_XINDEX
, ALL
, MSG_SHN_XINDEX_CFNP
},
323 static const Val_desc2 shn_nf
[] = {
324 { SHN_UNDEF
, ALL
, MSG_SHN_UNDEF_NF
},
325 { SHN_BEFORE
, ALL
, MSG_SHN_BEFORE_NF
},
326 { SHN_AFTER
, ALL
, MSG_SHN_AFTER_NF
},
327 { SHN_AMD64_LCOMMON
, AMD
, MSG_SHN_AMD64_LCOMMON_NF
},
328 { SHN_SUNW_IGNORE
, SOL
, MSG_SHN_SUNW_IGNORE_NF
},
329 { SHN_ABS
, ALL
, MSG_SHN_ABS_NF
},
330 { SHN_COMMON
, ALL
, MSG_SHN_COMMON_NF
},
331 { SHN_XINDEX
, ALL
, MSG_SHN_XINDEX_NF
},
334 static const conv_ds_vd2_t ds_shn_def
= {
335 CONV_DS_VD2
, SHN_UNDEF
, SHN_XINDEX
, shn_def
};
336 static const conv_ds_vd2_t ds_shn_cf
= {
337 CONV_DS_VD2
, SHN_UNDEF
, SHN_XINDEX
, shn_cf
};
338 static const conv_ds_vd2_t ds_shn_cfnp
= {
339 CONV_DS_VD2
, SHN_UNDEF
, SHN_XINDEX
, shn_cfnp
};
340 static const conv_ds_vd2_t ds_shn_nf
= {
341 CONV_DS_VD2
, SHN_UNDEF
, SHN_XINDEX
, shn_nf
};
343 /* Build NULL terminated return arrays for each string style */
344 static const const conv_ds_t
*ds_def
[] = {
345 CONV_DS_ADDR(ds_shn_def
), NULL
};
346 static const const conv_ds_t
*ds_cf
[] = {
347 CONV_DS_ADDR(ds_shn_cf
), NULL
};
348 static const const conv_ds_t
*ds_cfnp
[] = {
349 CONV_DS_ADDR(ds_shn_cfnp
), NULL
};
350 static const const conv_ds_t
*ds_nf
[] = {
351 CONV_DS_ADDR(ds_shn_nf
), NULL
};
353 /* Select the strings to use */
354 switch (CONV_TYPE_FMT_ALT(fmt_flags
)) {
355 case CONV_FMT_ALT_CF
:
357 case CONV_FMT_ALT_CFNP
:
359 case CONV_FMT_ALT_NF
:
371 conv_sym_shndx(uchar_t osabi
, Half mach
, Half shndx
, Conv_fmt_flags_t fmt_flags
,
372 Conv_inv_buf_t
*inv_buf
)
374 return (conv_map_ds(osabi
, mach
, shndx
,
375 conv_sym_shndx_strings(fmt_flags
), fmt_flags
, inv_buf
));
379 conv_iter_sym_shndx(conv_iter_osabi_t osabi
, Half mach
,
380 Conv_fmt_flags_t fmt_flags
, conv_iter_cb_t func
, void *uvalue
)
382 static const Msg amd64_alias_cf
[] = { MSG_SHN_X86_64_LCOMMON_CF
};
383 static const conv_ds_msg_t ds_msg_amd64_alias_cf
= {
384 CONV_DS_MSG_INIT(SHN_X86_64_LCOMMON
, amd64_alias_cf
) };
385 static const conv_ds_t
*ds_amd64_alias_cf
[] = {
386 CONV_DS_ADDR(ds_msg_amd64_alias_cf
), NULL
};
388 static const Msg amd64_alias_cfnp
[] = { MSG_SHN_X86_64_LCOMMON_CFNP
};
389 static const conv_ds_msg_t ds_msg_amd64_alias_cfnp
= {
390 CONV_DS_MSG_INIT(SHN_X86_64_LCOMMON
, amd64_alias_cfnp
) };
391 static const conv_ds_t
*ds_amd64_alias_cfnp
[] = {
392 CONV_DS_ADDR(ds_msg_amd64_alias_cfnp
), NULL
};
394 static const Msg amd64_alias_nf
[] = { MSG_SHN_X86_64_LCOMMON_NF
};
395 static const conv_ds_msg_t ds_msg_amd64_alias_nf
= {
396 CONV_DS_MSG_INIT(SHN_X86_64_LCOMMON
, amd64_alias_nf
) };
397 static const conv_ds_t
*ds_amd64_alias_nf
[] = {
398 CONV_DS_ADDR(ds_msg_amd64_alias_nf
), NULL
};
401 if (conv_iter_ds(osabi
, mach
, conv_sym_shndx_strings(fmt_flags
),
402 func
, uvalue
) == CONV_ITER_DONE
)
403 return (CONV_ITER_DONE
);
406 * SHN_AMD64_LCOMMON is also known as SHN_X86_64_LCOMMON
408 if (mach
== EM_AMD64
) {
409 const conv_ds_t
**ds
;
411 switch (CONV_TYPE_FMT_ALT(fmt_flags
)) {
412 case CONV_FMT_ALT_CF
:
413 ds
= ds_amd64_alias_cf
;
415 case CONV_FMT_ALT_NF
:
416 ds
= ds_amd64_alias_nf
;
419 ds
= ds_amd64_alias_cfnp
;
422 return (conv_iter_ds(ELFOSABI_NONE
, mach
, ds
, func
, uvalue
));
425 return (CONV_ITER_CONT
);