1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * String conversion routines for section attributes. 30 */ 31 #include <string.h> 32 #include <sys/param.h> 33 #include <sys/elf_SPARC.h> 34 #include <sys/elf_amd64.h> 35 #include <_conv.h> 36 #include <sections_msg.h> 37 38 39 40 /* Instantiate a local copy of conv_map2str() from _conv.h */ 41 DEFINE_conv_map2str 42 43 44 45 static const Msg secs[SHT_NUM] = { 46 MSG_SHT_NULL, MSG_SHT_PROGBITS, MSG_SHT_SYMTAB, 47 MSG_SHT_STRTAB, MSG_SHT_RELA, MSG_SHT_HASH, 48 MSG_SHT_DYNAMIC, MSG_SHT_NOTE, MSG_SHT_NOBITS, 49 MSG_SHT_REL, MSG_SHT_SHLIB, MSG_SHT_DYNSYM, 50 MSG_SHT_UNKNOWN12, MSG_SHT_UNKNOWN13, MSG_SHT_INIT_ARRAY, 51 MSG_SHT_FINI_ARRAY, MSG_SHT_PREINIT_ARRAY, MSG_SHT_GROUP, 52 MSG_SHT_SYMTAB_SHNDX 53 }; 54 static const Msg secs_alt[SHT_NUM] = { 55 MSG_SHT_NULL_ALT, MSG_SHT_PROGBITS_ALT, MSG_SHT_SYMTAB_ALT, 56 MSG_SHT_STRTAB_ALT, MSG_SHT_RELA_ALT, MSG_SHT_HASH_ALT, 57 MSG_SHT_DYNAMIC_ALT, MSG_SHT_NOTE_ALT, MSG_SHT_NOBITS_ALT, 58 MSG_SHT_REL_ALT, MSG_SHT_SHLIB_ALT, MSG_SHT_DYNSYM_ALT, 59 MSG_SHT_UNKNOWN12, MSG_SHT_UNKNOWN13, MSG_SHT_INIT_ARRAY_ALT, 60 MSG_SHT_FINI_ARRAY_ALT, MSG_SHT_PREINIT_ARRAY_ALT, MSG_SHT_GROUP_ALT, 61 MSG_SHT_SYMTAB_SHNDX_ALT 62 }; 63 #if (SHT_NUM != (SHT_SYMTAB_SHNDX + 1)) 64 #error "SHT_NUM has grown" 65 #endif 66 67 static const Msg usecs[SHT_HISUNW - SHT_LOSUNW + 1] = { 68 MSG_SHT_SUNW_dof, MSG_SHT_SUNW_cap, 69 MSG_SHT_SUNW_SIGNATURE, MSG_SHT_SUNW_ANNOTATE, 70 MSG_SHT_SUNW_DEBUGSTR, MSG_SHT_SUNW_DEBUG, 71 MSG_SHT_SUNW_move, MSG_SHT_SUNW_COMDAT, 72 MSG_SHT_SUNW_syminfo, MSG_SHT_SUNW_verdef, 73 MSG_SHT_SUNW_verneed, MSG_SHT_SUNW_versym 74 }; 75 static const Msg usecs_alt[SHT_HISUNW - SHT_LOSUNW + 1] = { 76 MSG_SHT_SUNW_dof_ALT, MSG_SHT_SUNW_cap_ALT, 77 MSG_SHT_SUNW_SIGNATURE_ALT, MSG_SHT_SUNW_ANNOTATE_ALT, 78 MSG_SHT_SUNW_DEBUGSTR_ALT, MSG_SHT_SUNW_DEBUG_ALT, 79 MSG_SHT_SUNW_move_ALT, MSG_SHT_SUNW_COMDAT_ALT, 80 MSG_SHT_SUNW_syminfo_ALT, MSG_SHT_SUNW_verdef_ALT, 81 MSG_SHT_SUNW_verneed_ALT, MSG_SHT_SUNW_versym_ALT 82 }; 83 #if (SHT_LOSUNW != SHT_SUNW_dof) 84 #error "SHT_LOSUNW has moved" 85 #endif 86 87 88 const char * 89 conv_sec_type(Half mach, Word sec, int fmt_flags) 90 { 91 static char string[CONV_INV_STRSIZE]; 92 93 if (sec < SHT_NUM) { 94 return (conv_map2str(string, sizeof (string), sec, fmt_flags, 95 ARRAY_NELTS(secs), secs, secs_alt, NULL)); 96 } else if ((sec >= SHT_LOSUNW) && (sec <= SHT_HISUNW)) { 97 return (conv_map2str(string, sizeof (string), sec - SHT_LOSUNW, 98 fmt_flags, ARRAY_NELTS(usecs), usecs, usecs_alt, NULL)); 99 } else if ((sec >= SHT_LOPROC) && (sec <= SHT_HIPROC)) { 100 switch (mach) { 101 case EM_SPARC: 102 case EM_SPARC32PLUS: 103 case EM_SPARCV9: 104 if (sec == SHT_SPARC_GOTDATA) { 105 return (fmt_flags & CONV_FMT_ALTDUMP) 106 ? MSG_ORIG(MSG_SHT_SPARC_GOTDATA_ALT) 107 : MSG_ORIG(MSG_SHT_SPARC_GOTDATA); 108 } 109 break; 110 case EM_AMD64: 111 if (sec == SHT_AMD64_UNWIND) { 112 return (fmt_flags & CONV_FMT_ALTDUMP) 113 ? MSG_ORIG(MSG_SHT_AMD64_UNWIND_ALT) 114 : MSG_ORIG(MSG_SHT_AMD64_UNWIND); 115 } 116 } 117 } 118 119 /* If we get here, it's an unknown type */ 120 return (conv_invalid_val(string, CONV_INV_STRSIZE, sec, fmt_flags)); 121 } 122 123 #define FLAGSZ CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \ 124 MSG_SHF_WRITE_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 125 MSG_SHF_ALLOC_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 126 MSG_SHF_EXECINSTR_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 127 MSG_SHF_MERGE_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 128 MSG_SHF_STRINGS_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 129 MSG_SHF_INFO_LINK_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 130 MSG_SHF_LINK_ORDER_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 131 MSG_SHF_OS_NONCONFORMING_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 132 MSG_SHF_GROUP_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 133 MSG_SHF_TLS_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 134 MSG_SHF_EXCLUDE_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 135 MSG_SHF_ORDERED_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 136 MSG_SHF_AMD64_LARGE_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 137 CONV_INV_STRSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE 138 139 const char * 140 conv_sec_flags(Xword flags) 141 { 142 static char string[FLAGSZ]; 143 static Val_desc vda[] = { 144 { SHF_WRITE, MSG_ORIG(MSG_SHF_WRITE) }, 145 { SHF_ALLOC, MSG_ORIG(MSG_SHF_ALLOC) }, 146 { SHF_EXECINSTR, MSG_ORIG(MSG_SHF_EXECINSTR) }, 147 { SHF_MERGE, MSG_ORIG(MSG_SHF_MERGE) }, 148 { SHF_STRINGS, MSG_ORIG(MSG_SHF_STRINGS) }, 149 { SHF_INFO_LINK, MSG_ORIG(MSG_SHF_INFO_LINK) }, 150 { SHF_LINK_ORDER, MSG_ORIG(MSG_SHF_LINK_ORDER) }, 151 { SHF_OS_NONCONFORMING, MSG_ORIG(MSG_SHF_OS_NONCONFORMING) }, 152 { SHF_GROUP, MSG_ORIG(MSG_SHF_GROUP) }, 153 { SHF_TLS, MSG_ORIG(MSG_SHF_TLS) }, 154 { SHF_EXCLUDE, MSG_ORIG(MSG_SHF_EXCLUDE) }, 155 { SHF_ORDERED, MSG_ORIG(MSG_SHF_ORDERED) }, 156 { SHF_AMD64_LARGE, MSG_ORIG(MSG_SHF_AMD64_LARGE) }, 157 { 0, 0 } 158 }; 159 static CONV_EXPN_FIELD_ARG conv_arg = { string, sizeof (string), vda }; 160 161 if (flags == 0) 162 return (MSG_ORIG(MSG_GBL_ZERO)); 163 164 conv_arg.oflags = conv_arg.rflags = flags; 165 (void) conv_expn_field(&conv_arg); 166 167 return ((const char *)string); 168 } 169 170 const char * 171 conv_sec_info(Word info, Xword flags) 172 { 173 static char string[CONV_INV_STRSIZE]; 174 175 if (flags & SHF_ORDERED) { 176 if (info == SHN_BEFORE) 177 return (MSG_ORIG(MSG_SHN_BEFORE)); 178 else if (info == SHN_AFTER) 179 return (MSG_ORIG(MSG_SHN_AFTER)); 180 } 181 (void) conv_invalid_val(string, CONV_INV_STRSIZE, info, 1); 182 return ((const char *)string); 183 } 184