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_LDYNSYM, MSG_SHT_SUNW_dof, 69 MSG_SHT_SUNW_cap, MSG_SHT_SUNW_SIGNATURE, 70 MSG_SHT_SUNW_ANNOTATE, MSG_SHT_SUNW_DEBUGSTR, 71 MSG_SHT_SUNW_DEBUG, MSG_SHT_SUNW_move, 72 MSG_SHT_SUNW_COMDAT, MSG_SHT_SUNW_syminfo, 73 MSG_SHT_SUNW_verdef, MSG_SHT_SUNW_verneed, 74 MSG_SHT_SUNW_versym 75 }; 76 static const Msg usecs_alt[SHT_HISUNW - SHT_LOSUNW + 1] = { 77 MSG_SHT_SUNW_LDYNSYM_ALT, MSG_SHT_SUNW_dof_ALT, 78 MSG_SHT_SUNW_cap_ALT, MSG_SHT_SUNW_SIGNATURE_ALT, 79 MSG_SHT_SUNW_ANNOTATE_ALT, MSG_SHT_SUNW_DEBUGSTR_ALT, 80 MSG_SHT_SUNW_DEBUG_ALT, MSG_SHT_SUNW_move_ALT, 81 MSG_SHT_SUNW_COMDAT_ALT, MSG_SHT_SUNW_syminfo_ALT, 82 MSG_SHT_SUNW_verdef_ALT, MSG_SHT_SUNW_verneed_ALT, 83 MSG_SHT_SUNW_versym_ALT 84 }; 85 #if (SHT_LOSUNW != SHT_SUNW_LDYNSYM) 86 #error "SHT_LOSUNW has moved" 87 #endif 88 89 90 const char * 91 conv_sec_type(Half mach, Word sec, int fmt_flags) 92 { 93 static char string[CONV_INV_STRSIZE]; 94 95 if (sec < SHT_NUM) { 96 return (conv_map2str(string, sizeof (string), sec, fmt_flags, 97 ARRAY_NELTS(secs), secs, secs_alt, NULL)); 98 } else if ((sec >= SHT_LOSUNW) && (sec <= SHT_HISUNW)) { 99 return (conv_map2str(string, sizeof (string), sec - SHT_LOSUNW, 100 fmt_flags, ARRAY_NELTS(usecs), usecs, usecs_alt, NULL)); 101 } else if ((sec >= SHT_LOPROC) && (sec <= SHT_HIPROC)) { 102 switch (mach) { 103 case EM_SPARC: 104 case EM_SPARC32PLUS: 105 case EM_SPARCV9: 106 if (sec == SHT_SPARC_GOTDATA) { 107 return (fmt_flags & CONV_FMT_ALTDUMP) 108 ? MSG_ORIG(MSG_SHT_SPARC_GOTDATA_ALT) 109 : MSG_ORIG(MSG_SHT_SPARC_GOTDATA); 110 } 111 break; 112 case EM_AMD64: 113 if (sec == SHT_AMD64_UNWIND) { 114 return (fmt_flags & CONV_FMT_ALTDUMP) 115 ? MSG_ORIG(MSG_SHT_AMD64_UNWIND_ALT) 116 : MSG_ORIG(MSG_SHT_AMD64_UNWIND); 117 } 118 } 119 } 120 121 /* If we get here, it's an unknown type */ 122 return (conv_invalid_val(string, CONV_INV_STRSIZE, sec, fmt_flags)); 123 } 124 125 #define FLAGSZ CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \ 126 MSG_SHF_WRITE_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 127 MSG_SHF_ALLOC_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 128 MSG_SHF_EXECINSTR_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 129 MSG_SHF_MERGE_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 130 MSG_SHF_STRINGS_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 131 MSG_SHF_INFO_LINK_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 132 MSG_SHF_LINK_ORDER_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 133 MSG_SHF_OS_NONCONFORMING_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 134 MSG_SHF_GROUP_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 135 MSG_SHF_TLS_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 136 MSG_SHF_EXCLUDE_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 137 MSG_SHF_ORDERED_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 138 MSG_SHF_AMD64_LARGE_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 139 CONV_INV_STRSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE 140 141 const char * 142 conv_sec_flags(Xword flags) 143 { 144 static char string[FLAGSZ]; 145 static Val_desc vda[] = { 146 { SHF_WRITE, MSG_ORIG(MSG_SHF_WRITE) }, 147 { SHF_ALLOC, MSG_ORIG(MSG_SHF_ALLOC) }, 148 { SHF_EXECINSTR, MSG_ORIG(MSG_SHF_EXECINSTR) }, 149 { SHF_MERGE, MSG_ORIG(MSG_SHF_MERGE) }, 150 { SHF_STRINGS, MSG_ORIG(MSG_SHF_STRINGS) }, 151 { SHF_INFO_LINK, MSG_ORIG(MSG_SHF_INFO_LINK) }, 152 { SHF_LINK_ORDER, MSG_ORIG(MSG_SHF_LINK_ORDER) }, 153 { SHF_OS_NONCONFORMING, MSG_ORIG(MSG_SHF_OS_NONCONFORMING) }, 154 { SHF_GROUP, MSG_ORIG(MSG_SHF_GROUP) }, 155 { SHF_TLS, MSG_ORIG(MSG_SHF_TLS) }, 156 { SHF_EXCLUDE, MSG_ORIG(MSG_SHF_EXCLUDE) }, 157 { SHF_ORDERED, MSG_ORIG(MSG_SHF_ORDERED) }, 158 { SHF_AMD64_LARGE, MSG_ORIG(MSG_SHF_AMD64_LARGE) }, 159 { 0, 0 } 160 }; 161 static CONV_EXPN_FIELD_ARG conv_arg = { string, sizeof (string), vda }; 162 163 if (flags == 0) 164 return (MSG_ORIG(MSG_GBL_ZERO)); 165 166 conv_arg.oflags = conv_arg.rflags = flags; 167 (void) conv_expn_field(&conv_arg); 168 169 return ((const char *)string); 170 } 171 172 const char * 173 conv_sec_linkinfo(Word info, Xword flags) 174 { 175 static char string[CONV_INV_STRSIZE]; 176 177 if (flags & ALL_SHF_ORDER) { 178 if (info == SHN_BEFORE) 179 return (MSG_ORIG(MSG_SHN_BEFORE)); 180 else if (info == SHN_AFTER) 181 return (MSG_ORIG(MSG_SHN_AFTER)); 182 } 183 (void) conv_invalid_val(string, CONV_INV_STRSIZE, info, 1); 184 return ((const char *)string); 185 } 186