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