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 routine for .dynamic tag entries. 30 */ 31 #include <stdio.h> 32 #include <string.h> 33 #include <sys/elf_SPARC.h> 34 #include "rtld.h" 35 #include "_conv.h" 36 #include "dynamic_msg.h" 37 38 #define POSSZ MSG_GBL_OSQBRKT_SIZE + \ 39 MSG_DFP_LAZYLOAD_SIZE + \ 40 MSG_DFP_GROUPPERM_SIZE + \ 41 CONV_INV_STRSIZE + MSG_GBL_CSQBRKT_SIZE 42 43 const char * 44 conv_dyn_posflag1(Xword flags) 45 { 46 static char string[POSSZ]; 47 static Val_desc vda[] = { 48 { DF_P1_LAZYLOAD, MSG_ORIG(MSG_DFP_LAZYLOAD) }, 49 { DF_P1_GROUPPERM, MSG_ORIG(MSG_DFP_GROUPPERM) }, 50 { 0, 0 } 51 }; 52 53 if (flags == 0) 54 return (MSG_ORIG(MSG_GBL_ZERO)); 55 56 (void) strlcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT), POSSZ); 57 if (conv_expn_field(string, POSSZ, vda, flags, flags, 0, 0)) 58 (void) strlcat(string, MSG_ORIG(MSG_GBL_CSQBRKT), POSSZ); 59 60 return ((const char *)string); 61 } 62 63 #define FLAGSZ MSG_GBL_OSQBRKT_SIZE + \ 64 MSG_DF_ORIGIN_SIZE + \ 65 MSG_DF_SYMBOLIC_SIZE + \ 66 MSG_DF_TEXTREL_SIZE + \ 67 MSG_DF_BIND_NOW_SIZE + \ 68 MSG_DF_STATIC_TLS_SIZE + \ 69 CONV_INV_STRSIZE + MSG_GBL_CSQBRKT_SIZE 70 71 const char * 72 conv_dyn_flag(Xword flags) 73 { 74 static char string[FLAGSZ]; 75 static Val_desc vda[] = { 76 { DF_ORIGIN, MSG_ORIG(MSG_DF_ORIGIN) }, 77 { DF_SYMBOLIC, MSG_ORIG(MSG_DF_SYMBOLIC) }, 78 { DF_TEXTREL, MSG_ORIG(MSG_DF_TEXTREL) }, 79 { DF_BIND_NOW, MSG_ORIG(MSG_DF_BIND_NOW) }, 80 { DF_STATIC_TLS, MSG_ORIG(MSG_DF_STATIC_TLS) }, 81 { 0, 0 } 82 }; 83 84 if (flags == 0) 85 return (MSG_ORIG(MSG_GBL_ZERO)); 86 87 (void) strlcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT), FLAGSZ); 88 if (conv_expn_field(string, FLAGSZ, vda, flags, flags, 0, 0)) 89 (void) strlcat(string, MSG_ORIG(MSG_GBL_CSQBRKT), FLAGSZ); 90 91 return ((const char *)string); 92 } 93 94 #define FLAG1SZ MSG_GBL_OSQBRKT_SIZE + \ 95 MSG_DF1_NOW_SIZE + \ 96 MSG_DF1_GLOBAL_SIZE + \ 97 MSG_DF1_GROUP_SIZE + \ 98 MSG_DF1_NODELETE_SIZE + \ 99 MSG_DF1_LOADFLTR_SIZE + \ 100 MSG_DF1_INITFIRST_SIZE + \ 101 MSG_DF1_NOOPEN_SIZE + \ 102 MSG_DF1_ORIGIN_SIZE + \ 103 MSG_DF1_DIRECT_SIZE + \ 104 MSG_DF1_TRANS_SIZE + \ 105 MSG_DF1_INTERPOSE_SIZE + \ 106 MSG_DF1_NODEFLIB_SIZE + \ 107 MSG_DF1_NODUMP_SIZE + \ 108 MSG_DF1_CONFALT_SIZE + \ 109 MSG_DF1_ENDFILTEE_SIZE + \ 110 MSG_DF1_DISPRELPND_SIZE + \ 111 MSG_DF1_DISPRELDNE_SIZE + \ 112 MSG_DF1_NODIRECT_SIZE + \ 113 MSG_DF1_IGNMULDEF_SIZE + \ 114 MSG_DF1_NOKSYMS_SIZE + \ 115 MSG_DF1_NORELOC_SIZE + \ 116 MSG_DF1_NOHDR_SIZE + \ 117 CONV_INV_STRSIZE + MSG_GBL_CSQBRKT_SIZE 118 119 const char * 120 conv_dyn_flag1(Xword flags) 121 { 122 static char string[FLAG1SZ]; 123 static Val_desc vda[] = { 124 { DF_1_NOW, MSG_ORIG(MSG_DF_ORIGIN) }, 125 { DF_1_GLOBAL, MSG_ORIG(MSG_DF1_GLOBAL) }, 126 { DF_1_GROUP, MSG_ORIG(MSG_DF1_GROUP) }, 127 { DF_1_NODELETE, MSG_ORIG(MSG_DF1_NODELETE) }, 128 { DF_1_LOADFLTR, MSG_ORIG(MSG_DF1_LOADFLTR) }, 129 { DF_1_INITFIRST, MSG_ORIG(MSG_DF1_INITFIRST) }, 130 { DF_1_NOOPEN, MSG_ORIG(MSG_DF1_NOOPEN) }, 131 { DF_1_ORIGIN, MSG_ORIG(MSG_DF1_ORIGIN) }, 132 { DF_1_DIRECT, MSG_ORIG(MSG_DF1_DIRECT) }, 133 { DF_1_TRANS, MSG_ORIG(MSG_DF1_TRANS) }, 134 { DF_1_INTERPOSE, MSG_ORIG(MSG_DF1_INTERPOSE) }, 135 { DF_1_NODEFLIB, MSG_ORIG(MSG_DF1_NODEFLIB) }, 136 { DF_1_NODUMP, MSG_ORIG(MSG_DF1_NODUMP) }, 137 { DF_1_CONFALT, MSG_ORIG(MSG_DF1_CONFALT) }, 138 { DF_1_ENDFILTEE, MSG_ORIG(MSG_DF1_ENDFILTEE) }, 139 { DF_1_DISPRELPND, MSG_ORIG(MSG_DF1_DISPRELPND) }, 140 { DF_1_DISPRELDNE, MSG_ORIG(MSG_DF1_DISPRELDNE) }, 141 { DF_1_NODIRECT, MSG_ORIG(MSG_DF1_NODIRECT) }, 142 { DF_1_IGNMULDEF, MSG_ORIG(MSG_DF1_IGNMULDEF) }, 143 { DF_1_NOKSYMS, MSG_ORIG(MSG_DF1_NOKSYMS) }, 144 { DF_1_NORELOC, MSG_ORIG(MSG_DF1_NORELOC) }, 145 { DF_1_NOHDR, MSG_ORIG(MSG_DF1_NOHDR) }, 146 { 0, 0 } 147 }; 148 149 if (flags == 0) 150 return (MSG_ORIG(MSG_GBL_ZERO)); 151 152 (void) strlcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT), FLAG1SZ); 153 if (conv_expn_field(string, FLAG1SZ, vda, flags, flags, 0, 0)) 154 (void) strlcat(string, MSG_ORIG(MSG_GBL_CSQBRKT), FLAG1SZ); 155 156 return ((const char *)string); 157 } 158 159 #define FEATSZ MSG_GBL_OSQBRKT_SIZE + \ 160 MSG_DTF_PARINIT_SIZE + \ 161 MSG_DTF_CONFEXP_SIZE + \ 162 CONV_INV_STRSIZE + MSG_GBL_CSQBRKT_SIZE 163 164 const char * 165 conv_dyn_feature1(Xword flags) 166 { 167 static char string[FEATSZ]; 168 static Val_desc vda[] = { 169 { DTF_1_PARINIT, MSG_ORIG(MSG_DTF_PARINIT) }, 170 { DTF_1_CONFEXP, MSG_ORIG(MSG_DTF_CONFEXP) }, 171 { 0, 0 } 172 }; 173 174 if (flags == 0) 175 return (MSG_ORIG(MSG_GBL_ZERO)); 176 177 (void) strlcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT), FEATSZ); 178 if (conv_expn_field(string, FEATSZ, vda, flags, flags, 0, 0)) 179 (void) strlcat(string, MSG_ORIG(MSG_GBL_CSQBRKT), FEATSZ); 180 181 return ((const char *)string); 182 } 183 184 const char * 185 conv_dyn_tag(Xword tag, Half mach) 186 { 187 static char string[CONV_INV_STRSIZE]; 188 static const Msg tags[DT_MAXPOSTAGS] = { 189 MSG_DYN_NULL, MSG_DYN_NEEDED, 190 MSG_DYN_PLTRELSZ, MSG_DYN_PLTGOT, 191 MSG_DYN_HASH, MSG_DYN_STRTAB, 192 MSG_DYN_SYMTAB, MSG_DYN_RELA, 193 MSG_DYN_RELASZ, MSG_DYN_RELAENT, 194 MSG_DYN_STRSZ, MSG_DYN_SYMENT, 195 MSG_DYN_INIT, MSG_DYN_FINI, 196 MSG_DYN_SONAME, MSG_DYN_RPATH, 197 MSG_DYN_SYMBOLIC, MSG_DYN_REL, 198 MSG_DYN_RELSZ, MSG_DYN_RELENT, 199 MSG_DYN_PLTREL, MSG_DYN_DEBUG, 200 MSG_DYN_TEXTREL, MSG_DYN_JMPREL, 201 MSG_DYN_BIND_NOW, MSG_DYN_INIT_ARRAY, 202 MSG_DYN_FINI_ARRAY, MSG_DYN_INIT_ARRAYSZ, 203 MSG_DYN_FINI_ARRAYSZ, MSG_DYN_RUNPATH, 204 MSG_DYN_FLAGS, MSG_DYN_NULL, 205 MSG_DYN_PREINIT_ARRAY, MSG_DYN_PREINIT_ARRAYSZ 206 }; 207 208 if (tag < DT_MAXPOSTAGS) { 209 /* 210 * Generic dynamic tags. 211 */ 212 return (MSG_ORIG(tags[tag])); 213 } else { 214 /* 215 * SUNW: DT_LOOS -> DT_HIOS range. 216 */ 217 if (tag == DT_SUNW_AUXILIARY) 218 return (MSG_ORIG(MSG_DYN_SUNW_AUXILIARY)); 219 else if (tag == DT_SUNW_RTLDINF) 220 return (MSG_ORIG(MSG_DYN_SUNW_RTLDINF)); 221 else if (tag == DT_SUNW_FILTER) 222 return (MSG_ORIG(MSG_DYN_SUNW_FILTER)); 223 else if (tag == DT_SUNW_CAP) 224 return (MSG_ORIG(MSG_DYN_SUNW_CAP)); 225 226 /* 227 * SUNW: DT_VALRNGLO - DT_VALRNGHI range. 228 */ 229 else if (tag == DT_CHECKSUM) 230 return (MSG_ORIG(MSG_DYN_CHECKSUM)); 231 else if (tag == DT_PLTPADSZ) 232 return (MSG_ORIG(MSG_DYN_PLTPADSZ)); 233 else if (tag == DT_MOVEENT) 234 return (MSG_ORIG(MSG_DYN_MOVEENT)); 235 else if (tag == DT_MOVESZ) 236 return (MSG_ORIG(MSG_DYN_MOVESZ)); 237 else if (tag == DT_FEATURE_1) 238 return (MSG_ORIG(MSG_DYN_FEATURE_1)); 239 else if (tag == DT_POSFLAG_1) 240 return (MSG_ORIG(MSG_DYN_POSFLAG_1)); 241 else if (tag == DT_SYMINSZ) 242 return (MSG_ORIG(MSG_DYN_SYMINSZ)); 243 else if (tag == DT_SYMINENT) 244 return (MSG_ORIG(MSG_DYN_SYMINENT)); 245 246 /* 247 * SUNW: DT_ADDRRNGLO - DT_ADDRRNGHI range. 248 */ 249 else if (tag == DT_CONFIG) 250 return (MSG_ORIG(MSG_DYN_CONFIG)); 251 else if (tag == DT_DEPAUDIT) 252 return (MSG_ORIG(MSG_DYN_DEPAUDIT)); 253 else if (tag == DT_AUDIT) 254 return (MSG_ORIG(MSG_DYN_AUDIT)); 255 else if (tag == DT_PLTPAD) 256 return (MSG_ORIG(MSG_DYN_PLTPAD)); 257 else if (tag == DT_MOVETAB) 258 return (MSG_ORIG(MSG_DYN_MOVETAB)); 259 else if (tag == DT_SYMINFO) 260 return (MSG_ORIG(MSG_DYN_SYMINFO)); 261 262 /* 263 * SUNW: generic range. 264 */ 265 else if (tag == DT_VERSYM) 266 return (MSG_ORIG(MSG_DYN_VERSYM)); 267 else if (tag == DT_RELACOUNT) 268 return (MSG_ORIG(MSG_DYN_RELACOUNT)); 269 else if (tag == DT_RELCOUNT) 270 return (MSG_ORIG(MSG_DYN_RELCOUNT)); 271 else if (tag == DT_FLAGS_1) 272 return (MSG_ORIG(MSG_DYN_FLAGS_1)); 273 else if (tag == DT_VERDEF) 274 return (MSG_ORIG(MSG_DYN_VERDEF)); 275 else if (tag == DT_VERDEFNUM) 276 return (MSG_ORIG(MSG_DYN_VERDEFNUM)); 277 else if (tag == DT_VERNEED) 278 return (MSG_ORIG(MSG_DYN_VERNEED)); 279 else if (tag == DT_VERNEEDNUM) 280 return (MSG_ORIG(MSG_DYN_VERNEEDNUM)); 281 else if (tag == DT_AUXILIARY) 282 return (MSG_ORIG(MSG_DYN_AUXILIARY)); 283 else if (tag == DT_USED) 284 return (MSG_ORIG(MSG_DYN_USED)); 285 else if (tag == DT_FILTER) 286 return (MSG_ORIG(MSG_DYN_FILTER)); 287 288 /* 289 * SUNW: machine specific range. 290 */ 291 else if (((mach == EM_SPARC) || (mach == EM_SPARCV9) || 292 (mach == EM_SPARC32PLUS)) && (tag == DT_SPARC_REGISTER)) 293 /* this is so x86 can display a sparc binary */ 294 return (MSG_ORIG(MSG_DYN_REGISTER)); 295 else if (tag == DT_DEPRECATED_SPARC_REGISTER) 296 return (MSG_ORIG(MSG_DYN_REGISTER)); 297 else 298 return (conv_invalid_val(string, CONV_INV_STRSIZE, 299 tag, 0)); 300 } 301 } 302 303 #define BINDTSZ MSG_GBL_OSQBRKT_SIZE + \ 304 MSG_BND_NEEDED_SIZE + \ 305 MSG_BND_REFER_SIZE + \ 306 MSG_BND_FILTER_SIZE + \ 307 CONV_INV_STRSIZE + MSG_GBL_CSQBRKT_SIZE 308 309 const char * 310 conv_bnd_type(uint_t flags) 311 { 312 static char string[BINDTSZ]; 313 static Val_desc vda[] = { 314 { BND_NEEDED, MSG_ORIG(MSG_BND_NEEDED) }, 315 { BND_REFER, MSG_ORIG(MSG_BND_REFER) }, 316 { BND_FILTER, MSG_ORIG(MSG_BND_FILTER) }, 317 { 0, 0 } 318 }; 319 320 if (flags == 0) 321 return (MSG_ORIG(MSG_STR_EMPTY)); 322 323 (void) strlcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT), BINDTSZ); 324 if (conv_expn_field(string, BINDTSZ, vda, flags, flags, 0, 0)) 325 (void) strlcat(string, MSG_ORIG(MSG_GBL_CSQBRKT), BINDTSZ); 326 327 return ((const char *)string); 328 } 329 330 /* 331 * Note, conv_bnd_obj() is called with either: 332 * LML_FLG_OBJADDED (possibly with LML_FLG_OBJREEVAL added), or 333 * LML_FLG_OBJDELETED, or 334 * LML_FLG_ATEXIT. 335 */ 336 #define BINDOSZ MSG_GBL_OSQBRKT_SIZE + \ 337 MSG_BND_ADDED_SIZE + \ 338 MSG_BND_REEVAL_SIZE + \ 339 MSG_GBL_CSQBRKT_SIZE 340 341 const char * 342 conv_bnd_obj(uint_t flags) 343 { 344 static char string[BINDOSZ]; 345 static Val_desc vda[] = { 346 { LML_FLG_OBJADDED, MSG_ORIG(MSG_BND_ADDED) }, 347 { LML_FLG_OBJREEVAL, MSG_ORIG(MSG_BND_REEVAL) }, 348 { LML_FLG_OBJDELETED, MSG_ORIG(MSG_BND_DELETED) }, 349 { LML_FLG_ATEXIT, MSG_ORIG(MSG_BND_ATEXIT) }, 350 { 0, 0 } 351 }; 352 353 if ((flags & (LML_FLG_OBJADDED | LML_FLG_OBJREEVAL | 354 LML_FLG_OBJDELETED | LML_FLG_ATEXIT)) == 0) 355 return (MSG_ORIG(MSG_BND_REVISIT)); 356 357 /* 358 * Note, we're not worried about unknown flags for this family, only 359 * the selected flags are of interest. 360 */ 361 (void) strlcpy(string, MSG_ORIG(MSG_GBL_OSQBRKT), BINDOSZ); 362 if (conv_expn_field(string, BINDOSZ, vda, flags, 0, 0, 0)) 363 (void) strlcat(string, MSG_ORIG(MSG_GBL_CSQBRKT), BINDOSZ); 364 365 return ((const char *)string); 366 } 367