17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 55aefb655Srie * Common Development and Distribution License (the "License"). 65aefb655Srie * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 215aefb655Srie 227c478bd9Sstevel@tonic-gate /* 23*f441771bSRod Evans * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include <string.h> 277c478bd9Sstevel@tonic-gate #include "_conv.h" 287c478bd9Sstevel@tonic-gate #include "dl_msg.h" 297c478bd9Sstevel@tonic-gate 30ba4e3c84Sab196087 #define MODESZ CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \ 31ba4e3c84Sab196087 MSG_RTLD_LAZY_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 32ba4e3c84Sab196087 MSG_RTLD_GLOBAL_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 33ba4e3c84Sab196087 MSG_RTLD_NOLOAD_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 34ba4e3c84Sab196087 MSG_RTLD_PARENT_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 35ba4e3c84Sab196087 MSG_RTLD_GROUP_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 36ba4e3c84Sab196087 MSG_RTLD_WORLD_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 37ba4e3c84Sab196087 MSG_RTLD_NODELETE_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 38ba4e3c84Sab196087 MSG_RTLD_FIRST_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 39ba4e3c84Sab196087 MSG_RTLD_CONFGEN_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 40de777a60Sab196087 CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE 415aefb655Srie 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate /* 44de777a60Sab196087 * Ensure that Conv_dl_mode_buf_t is large enough: 45de777a60Sab196087 * 46de777a60Sab196087 * MODESZ is the real minimum size of the buffer required by conv_dl_mode(). 47de777a60Sab196087 * However, Conv_dl_mode_buf_t uses CONV_DL_MODE_BUFSIZE to set the 48de777a60Sab196087 * buffer size. We do things this way because the definition of MODESZ uses 49de777a60Sab196087 * information that is not available in the environment of other programs 50de777a60Sab196087 * that include the conv.h header file. 51de777a60Sab196087 */ 526a074c93Sab196087 #if (CONV_DL_MODE_BUFSIZE != MODESZ) && !defined(__lint) 536a074c93Sab196087 #define REPORT_BUFSIZE MODESZ 546a074c93Sab196087 #include "report_bufsize.h" 556a074c93Sab196087 #error "CONV_DL_MODE_BUFSIZE does not match MODESZ" 56de777a60Sab196087 #endif 57de777a60Sab196087 58de777a60Sab196087 /* 597c478bd9Sstevel@tonic-gate * String conversion routine for dlopen() attributes. 607c478bd9Sstevel@tonic-gate */ 617c478bd9Sstevel@tonic-gate const char * 62de777a60Sab196087 conv_dl_mode(int mode, int fabricate, Conv_dl_mode_buf_t *dl_mode_buf) 637c478bd9Sstevel@tonic-gate { 644f680cc6SAli Bahrami static const Val_desc vda[] = { 654f680cc6SAli Bahrami { RTLD_NOLOAD, MSG_RTLD_NOLOAD }, 664f680cc6SAli Bahrami { RTLD_PARENT, MSG_RTLD_PARENT }, 674f680cc6SAli Bahrami { RTLD_GROUP, MSG_RTLD_GROUP }, 684f680cc6SAli Bahrami { RTLD_WORLD, MSG_RTLD_WORLD }, 694f680cc6SAli Bahrami { RTLD_NODELETE, MSG_RTLD_NODELETE }, 704f680cc6SAli Bahrami { RTLD_FIRST, MSG_RTLD_FIRST }, 714f680cc6SAli Bahrami { RTLD_CONFGEN, MSG_RTLD_CONFGEN }, 725aefb655Srie { 0, 0 } 735aefb655Srie }; 74ba4e3c84Sab196087 static const char *leading_str_arr[3]; 75de777a60Sab196087 static CONV_EXPN_FIELD_ARG conv_arg = { 764f680cc6SAli Bahrami NULL, sizeof (dl_mode_buf->buf), leading_str_arr }; 777c478bd9Sstevel@tonic-gate 78ba4e3c84Sab196087 const char **lstr = leading_str_arr; 79ba4e3c84Sab196087 80de777a60Sab196087 conv_arg.buf = dl_mode_buf->buf; 81ba4e3c84Sab196087 conv_arg.oflags = conv_arg.rflags = mode; 82ba4e3c84Sab196087 837c478bd9Sstevel@tonic-gate 845aefb655Srie if (mode & RTLD_NOW) { 85ba4e3c84Sab196087 *lstr++ = MSG_ORIG(MSG_RTLD_NOW); 86ca4eed8bSAli Bahrami } else if ((mode & RTLD_LAZY) || fabricate) { 87ba4e3c84Sab196087 *lstr++ = MSG_ORIG(MSG_RTLD_LAZY); 885aefb655Srie } 895aefb655Srie if (mode & RTLD_GLOBAL) { 90ba4e3c84Sab196087 *lstr++ = MSG_ORIG(MSG_RTLD_GLOBAL); 915aefb655Srie } else if (fabricate) { 92ba4e3c84Sab196087 *lstr++ = MSG_ORIG(MSG_RTLD_LOCAL); 935aefb655Srie } 94ba4e3c84Sab196087 *lstr = NULL; 95ba4e3c84Sab196087 conv_arg.oflags = mode; 96ba4e3c84Sab196087 conv_arg.rflags = mode & ~(RTLD_LAZY | RTLD_NOW | RTLD_GLOBAL); 977c478bd9Sstevel@tonic-gate 984f680cc6SAli Bahrami (void) conv_expn_field(&conv_arg, vda, 0); 997c478bd9Sstevel@tonic-gate 100de777a60Sab196087 return ((const char *)dl_mode_buf->buf); 1017c478bd9Sstevel@tonic-gate } 1027c478bd9Sstevel@tonic-gate 103ba4e3c84Sab196087 /* 104ba4e3c84Sab196087 * Note: We can use two different sets of prefix/separator/suffix 105ba4e3c84Sab196087 * strings in conv_dl_flag(), depending on the value of the separator 106ba4e3c84Sab196087 * argument. To size the buffer, I use the default prefix and suffix 107ba4e3c84Sab196087 * sizes, and the alternate separator size, because they are larger. 108ba4e3c84Sab196087 */ 109ba4e3c84Sab196087 110ba4e3c84Sab196087 #define FLAGSZ CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \ 1115aefb655Srie MSG_RTLD_REL_RELATIVE_SIZE + MSG_GBL_SEP_SIZE + \ 1125aefb655Srie MSG_RTLD_REL_EXEC_SIZE + MSG_GBL_SEP_SIZE + \ 1135aefb655Srie MSG_RTLD_REL_DEPENDS_SIZE + MSG_GBL_SEP_SIZE + \ 1145aefb655Srie MSG_RTLD_REL_PRELOAD_SIZE + MSG_GBL_SEP_SIZE + \ 1155aefb655Srie MSG_RTLD_REL_SELF_SIZE + MSG_GBL_SEP_SIZE + \ 1165aefb655Srie MSG_RTLD_REL_WEAK_SIZE + MSG_GBL_SEP_SIZE + \ 1175aefb655Srie MSG_RTLD_MEMORY_SIZE + MSG_GBL_SEP_SIZE + \ 1185aefb655Srie MSG_RTLD_STRIP_SIZE + MSG_GBL_SEP_SIZE + \ 1195aefb655Srie MSG_RTLD_NOHEAP_SIZE + MSG_GBL_SEP_SIZE + \ 1207c478bd9Sstevel@tonic-gate MSG_RTLD_CONFSET_SIZE + \ 121de777a60Sab196087 CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE 122de777a60Sab196087 123de777a60Sab196087 /* 124de777a60Sab196087 * Ensure that Conv_dl_flag_buf_t is large enough: 125de777a60Sab196087 * 126de777a60Sab196087 * FLAGSZ is the real minimum size of the buffer required by conv_dl_flag(). 127de777a60Sab196087 * However, Conv_dl_flag_buf_t uses CONV_DL_FLAG_BUFSIZE to set the 128de777a60Sab196087 * buffer size. We do things this way because the definition of FLAGSZ uses 129de777a60Sab196087 * information that is not available in the environment of other programs 130de777a60Sab196087 * that include the conv.h header file. 131de777a60Sab196087 */ 1326a074c93Sab196087 #if (CONV_DL_FLAG_BUFSIZE != FLAGSZ) && !defined(__lint) 1336a074c93Sab196087 #define REPORT_BUFSIZE FLAGSZ 1346a074c93Sab196087 #include "report_bufsize.h" 1356a074c93Sab196087 #error "CONV_DL_FLAG_BUFSIZE does not match FLAGSZ" 136de777a60Sab196087 #endif 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate /* 1397c478bd9Sstevel@tonic-gate * String conversion routine for dldump() flags. 1407c478bd9Sstevel@tonic-gate * crle(1) uses this routine to generate update information, and in this case 1417c478bd9Sstevel@tonic-gate * we build a "|" separated string. 1427c478bd9Sstevel@tonic-gate */ 1437c478bd9Sstevel@tonic-gate const char * 144d29b2c44Sab196087 conv_dl_flag(int flags, Conv_fmt_flags_t fmt_flags, 145d29b2c44Sab196087 Conv_dl_flag_buf_t *dl_flag_buf) 1467c478bd9Sstevel@tonic-gate { 1474f680cc6SAli Bahrami static const Val_desc vda[] = { 1484f680cc6SAli Bahrami { RTLD_REL_RELATIVE, MSG_RTLD_REL_RELATIVE }, 1494f680cc6SAli Bahrami { RTLD_REL_EXEC, MSG_RTLD_REL_EXEC }, 1504f680cc6SAli Bahrami { RTLD_REL_DEPENDS, MSG_RTLD_REL_DEPENDS }, 1514f680cc6SAli Bahrami { RTLD_REL_PRELOAD, MSG_RTLD_REL_PRELOAD }, 1524f680cc6SAli Bahrami { RTLD_REL_SELF, MSG_RTLD_REL_SELF }, 1534f680cc6SAli Bahrami { RTLD_REL_WEAK, MSG_RTLD_REL_WEAK }, 1544f680cc6SAli Bahrami { RTLD_MEMORY, MSG_RTLD_MEMORY }, 1554f680cc6SAli Bahrami { RTLD_STRIP, MSG_RTLD_STRIP }, 1564f680cc6SAli Bahrami { RTLD_NOHEAP, MSG_RTLD_NOHEAP }, 1574f680cc6SAli Bahrami { RTLD_CONFSET, MSG_RTLD_CONFSET }, 1585aefb655Srie { 0, 0 } 1595aefb655Srie }; 160ba4e3c84Sab196087 static const char *leading_str_arr[2]; 161de777a60Sab196087 static CONV_EXPN_FIELD_ARG conv_arg = { 1624f680cc6SAli Bahrami NULL, sizeof (dl_flag_buf->buf), leading_str_arr }; 163ba4e3c84Sab196087 164ba4e3c84Sab196087 const char **lstr = leading_str_arr; 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate if (flags == 0) 1677c478bd9Sstevel@tonic-gate return (MSG_ORIG(MSG_GBL_ZERO)); 1687c478bd9Sstevel@tonic-gate 169de777a60Sab196087 conv_arg.buf = dl_flag_buf->buf; 170d29b2c44Sab196087 if (CONV_TYPE_FMT_ALT(fmt_flags) == CONV_FMT_ALT_CRLE) { 171ba4e3c84Sab196087 conv_arg.prefix = conv_arg.suffix = MSG_ORIG(MSG_GBL_QUOTE); 172ba4e3c84Sab196087 conv_arg.sep = MSG_ORIG(MSG_GBL_SEP); 173ba4e3c84Sab196087 } else { /* Use default delimiters */ 174de777a60Sab196087 conv_arg.prefix = conv_arg.suffix = conv_arg.sep = NULL; 175ba4e3c84Sab196087 } 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate if ((flags & RTLD_REL_ALL) == RTLD_REL_ALL) { 178ba4e3c84Sab196087 *lstr++ = MSG_ORIG(MSG_RTLD_REL_ALL); 179ba4e3c84Sab196087 flags &= ~RTLD_REL_ALL; 1807c478bd9Sstevel@tonic-gate } 181ba4e3c84Sab196087 *lstr = NULL; 182ba4e3c84Sab196087 conv_arg.oflags = conv_arg.rflags = flags; 1837c478bd9Sstevel@tonic-gate 1844f680cc6SAli Bahrami (void) conv_expn_field(&conv_arg, vda, fmt_flags); 1857c478bd9Sstevel@tonic-gate 186de777a60Sab196087 return ((const char *)dl_flag_buf->buf); 1877c478bd9Sstevel@tonic-gate } 18898c080d5SRod Evans 18998c080d5SRod Evans const char * 19098c080d5SRod Evans conv_dl_info(int request) 19198c080d5SRod Evans { 19298c080d5SRod Evans static const Msg requests[RTLD_DI_MAX] = { 19398c080d5SRod Evans MSG_RTLD_DI_LMID, /* MSG_ORIG(MSG_RTLD_DI_LMID) */ 19498c080d5SRod Evans MSG_RTLD_DI_LINKMAP, /* MSG_ORIG(MSG_RTLD_DI_LINKMAP) */ 19598c080d5SRod Evans MSG_RTLD_DI_CONFIGADDR, /* MSG_ORIG(MSG_RTLD_DI_CONFIGADDR) */ 19698c080d5SRod Evans MSG_RTLD_DI_SERINFO, /* MSG_ORIG(MSG_RTLD_DI_SERINFO) */ 19798c080d5SRod Evans MSG_RTLD_DI_SERINFOSIZE, /* MSG_ORIG(MSG_RTLD_DI_SERINFOSIZE) */ 19898c080d5SRod Evans MSG_RTLD_DI_ORIGIN, /* MSG_ORIG(MSG_RTLD_DI_ORIGIN) */ 19998c080d5SRod Evans MSG_RTLD_DI_PROFILENAME, /* MSG_ORIG(MSG_RTLD_DI_PROFILENAME) */ 20098c080d5SRod Evans MSG_RTLD_DI_PROFILEOUT, /* MSG_ORIG(MSG_RTLD_DI_PROFILEOUT) */ 20198c080d5SRod Evans MSG_RTLD_DI_GETSIGNAL, /* MSG_ORIG(MSG_RTLD_DI_GETSIGNAL) */ 20298c080d5SRod Evans MSG_RTLD_DI_SETSIGNAL, /* MSG_ORIG(MSG_RTLD_DI_SETSIGNAL) */ 20398c080d5SRod Evans MSG_RTLD_DI_ARGSINFO, /* MSG_ORIG(MSG_RTLD_DI_ARGSINFO) */ 20498c080d5SRod Evans MSG_RTLD_DI_MMAPS, /* MSG_ORIG(MSG_RTLD_DI_MMAPS) */ 205*f441771bSRod Evans MSG_RTLD_DI_MMAPCNT, /* MSG_ORIG(MSG_RTLD_DI_MMAPCNT) */ 206*f441771bSRod Evans MSG_RTLD_DI_DEFERRED, /* MSG_ORIG(MSG_RTLD_DI_DEFERRED) */ 207*f441771bSRod Evans MSG_RTLD_DI_DEFERRED_SYM 208*f441771bSRod Evans /* MSG_ORIG(MSG_RTLD_DI_DEFERRED_SYM) */ 20998c080d5SRod Evans }; 21098c080d5SRod Evans static Conv_inv_buf_t inv_buf; 21198c080d5SRod Evans 212*f441771bSRod Evans #if (RTLD_DI_MAX != RTLD_DI_DEFERRED_SYM) 21398c080d5SRod Evans #error "RTLD_DI_MAX has grown" 21498c080d5SRod Evans #endif 21598c080d5SRod Evans if (request && (request <= RTLD_DI_MAX)) 21698c080d5SRod Evans return (MSG_ORIG(requests[request - 1])); 21798c080d5SRod Evans 21898c080d5SRod Evans (void) conv_invalid_val(&inv_buf, EC_NATPTR(request), 0); 21998c080d5SRod Evans return (inv_buf.buf); 22098c080d5SRod Evans } 221