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 #include <string.h> 29 #include "_conv.h" 30 #include "dl_msg.h" 31 32 #define MODESZ CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \ 33 MSG_RTLD_LAZY_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 34 MSG_RTLD_GLOBAL_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 35 MSG_RTLD_NOLOAD_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 36 MSG_RTLD_PARENT_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 37 MSG_RTLD_GROUP_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 38 MSG_RTLD_WORLD_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 39 MSG_RTLD_NODELETE_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 40 MSG_RTLD_FIRST_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 41 MSG_RTLD_CONFGEN_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 42 CONV_INV_STRSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE 43 44 45 /* 46 * String conversion routine for dlopen() attributes. 47 */ 48 const char * 49 conv_dl_mode(int mode, int fabricate) 50 { 51 static char string[MODESZ]; 52 static Val_desc vda[] = { 53 { RTLD_NOLOAD, MSG_ORIG(MSG_RTLD_NOLOAD) }, 54 { RTLD_PARENT, MSG_ORIG(MSG_RTLD_PARENT) }, 55 { RTLD_GROUP, MSG_ORIG(MSG_RTLD_GROUP) }, 56 { RTLD_WORLD, MSG_ORIG(MSG_RTLD_WORLD) }, 57 { RTLD_NODELETE, MSG_ORIG(MSG_RTLD_NODELETE) }, 58 { RTLD_FIRST, MSG_ORIG(MSG_RTLD_FIRST) }, 59 { RTLD_CONFGEN, MSG_ORIG(MSG_RTLD_CONFGEN) }, 60 { 0, 0 } 61 }; 62 static const char *leading_str_arr[3]; 63 static CONV_EXPN_FIELD_ARG conv_arg = { string, sizeof (string), vda, 64 leading_str_arr }; 65 66 const char **lstr = leading_str_arr; 67 68 conv_arg.oflags = conv_arg.rflags = mode; 69 70 71 if (mode & RTLD_NOW) { 72 *lstr++ = MSG_ORIG(MSG_RTLD_NOW); 73 } else if (fabricate) { 74 *lstr++ = MSG_ORIG(MSG_RTLD_LAZY); 75 } 76 if (mode & RTLD_GLOBAL) { 77 *lstr++ = MSG_ORIG(MSG_RTLD_GLOBAL); 78 } else if (fabricate) { 79 *lstr++ = MSG_ORIG(MSG_RTLD_LOCAL); 80 } 81 *lstr = NULL; 82 conv_arg.oflags = mode; 83 conv_arg.rflags = mode & ~(RTLD_LAZY | RTLD_NOW | RTLD_GLOBAL); 84 85 (void) conv_expn_field(&conv_arg); 86 87 return ((const char *)string); 88 } 89 90 /* 91 * Note: We can use two different sets of prefix/separator/suffix 92 * strings in conv_dl_flag(), depending on the value of the separator 93 * argument. To size the buffer, I use the default prefix and suffix 94 * sizes, and the alternate separator size, because they are larger. 95 */ 96 97 #define FLAGSZ CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \ 98 MSG_RTLD_REL_RELATIVE_SIZE + MSG_GBL_SEP_SIZE + \ 99 MSG_RTLD_REL_EXEC_SIZE + MSG_GBL_SEP_SIZE + \ 100 MSG_RTLD_REL_DEPENDS_SIZE + MSG_GBL_SEP_SIZE + \ 101 MSG_RTLD_REL_PRELOAD_SIZE + MSG_GBL_SEP_SIZE + \ 102 MSG_RTLD_REL_SELF_SIZE + MSG_GBL_SEP_SIZE + \ 103 MSG_RTLD_REL_WEAK_SIZE + MSG_GBL_SEP_SIZE + \ 104 MSG_RTLD_MEMORY_SIZE + MSG_GBL_SEP_SIZE + \ 105 MSG_RTLD_STRIP_SIZE + MSG_GBL_SEP_SIZE + \ 106 MSG_RTLD_NOHEAP_SIZE + MSG_GBL_SEP_SIZE + \ 107 MSG_RTLD_CONFSET_SIZE + \ 108 CONV_INV_STRSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE 109 110 /* 111 * String conversion routine for dldump() flags. 112 * crle(1) uses this routine to generate update information, and in this case 113 * we build a "|" separated string. 114 */ 115 const char * 116 conv_dl_flag(int flags, int fmt_flags) 117 { 118 static char string[FLAGSZ]; 119 static Val_desc vda[] = { 120 { RTLD_REL_RELATIVE, MSG_ORIG(MSG_RTLD_REL_RELATIVE) }, 121 { RTLD_REL_EXEC, MSG_ORIG(MSG_RTLD_REL_EXEC) }, 122 { RTLD_REL_DEPENDS, MSG_ORIG(MSG_RTLD_REL_DEPENDS) }, 123 { RTLD_REL_PRELOAD, MSG_ORIG(MSG_RTLD_REL_PRELOAD) }, 124 { RTLD_REL_SELF, MSG_ORIG(MSG_RTLD_REL_SELF) }, 125 { RTLD_REL_WEAK, MSG_ORIG(MSG_RTLD_REL_WEAK) }, 126 { RTLD_MEMORY, MSG_ORIG(MSG_RTLD_MEMORY) }, 127 { RTLD_STRIP, MSG_ORIG(MSG_RTLD_STRIP) }, 128 { RTLD_NOHEAP, MSG_ORIG(MSG_RTLD_NOHEAP) }, 129 { RTLD_CONFSET, MSG_ORIG(MSG_RTLD_CONFSET) }, 130 { 0, 0 } 131 }; 132 static const char *leading_str_arr[2]; 133 static CONV_EXPN_FIELD_ARG conv_arg = { string, sizeof (string), vda, 134 leading_str_arr }; 135 136 const char **lstr = leading_str_arr; 137 138 if (flags == 0) 139 return (MSG_ORIG(MSG_GBL_ZERO)); 140 141 142 if (fmt_flags & CONV_FMT_ALTCRLE) { 143 conv_arg.prefix = conv_arg.suffix = MSG_ORIG(MSG_GBL_QUOTE); 144 conv_arg.sep = MSG_ORIG(MSG_GBL_SEP); 145 } else { /* Use default delimiters */ 146 conv_arg.prefix = conv_arg.suffix = 147 conv_arg.sep = NULL; 148 } 149 150 if ((flags & RTLD_REL_ALL) == RTLD_REL_ALL) { 151 *lstr++ = MSG_ORIG(MSG_RTLD_REL_ALL); 152 flags &= ~RTLD_REL_ALL; 153 } 154 *lstr = NULL; 155 conv_arg.oflags = conv_arg.rflags = flags; 156 157 (void) conv_expn_field(&conv_arg); 158 159 return ((const char *)string); 160 } 161