10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 51618Srie * Common Development and Distribution License (the "License"). 61618Srie * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 211618Srie 220Sstevel@tonic-gate /* 234031Srie * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 280Sstevel@tonic-gate 290Sstevel@tonic-gate /* 300Sstevel@tonic-gate * String conversion routines for program header attributes. 310Sstevel@tonic-gate */ 320Sstevel@tonic-gate #include <string.h> 330Sstevel@tonic-gate #include <_conv.h> 340Sstevel@tonic-gate #include <phdr_msg.h> 350Sstevel@tonic-gate 364031Srie /* Instantiate a local copy of conv_map2str() from _conv.h */ 374031Srie DEFINE_conv_map2str 380Sstevel@tonic-gate 390Sstevel@tonic-gate const char * 40*4734Sab196087 conv_phdr_type(Half mach, Word type, int fmt_flags, Conv_inv_buf_t *inv_buf) 410Sstevel@tonic-gate { 421618Srie static const Msg phdrs[] = { 434031Srie MSG_PT_NULL, MSG_PT_LOAD, 444031Srie MSG_PT_DYNAMIC, MSG_PT_INTERP, 454031Srie MSG_PT_NOTE, MSG_PT_SHLIB, 461618Srie MSG_PT_PHDR, MSG_PT_TLS 471618Srie }; 484031Srie static const Msg phdrs_alt[] = { 494031Srie MSG_PT_NULL_ALT, MSG_PT_LOAD_ALT, 504031Srie MSG_PT_DYNAMIC_ALT, MSG_PT_INTERP_ALT, 514031Srie MSG_PT_NOTE_ALT, MSG_PT_SHLIB_ALT, 524031Srie MSG_PT_PHDR_ALT, MSG_PT_TLS_ALT 534031Srie }; 544031Srie #if PT_NUM != (PT_TLS + 1) 554031Srie error "PT_NUM has grown. Update phdrs[]" 564031Srie #endif 574031Srie static const Msg uphdrs[] = { 584031Srie MSG_PT_SUNWBSS, MSG_PT_SUNWSTACK, 594031Srie MSG_PT_SUNWDTRACE, MSG_PT_SUNWCAP 604031Srie }; 614031Srie static const Msg uphdrs_alt[] = { 624031Srie MSG_PT_SUNWBSS_ALT, MSG_PT_SUNWSTACK_ALT, 634031Srie MSG_PT_SUNWDTRACE_ALT, MSG_PT_SUNWCAP_ALT 644031Srie }; 654031Srie #if PT_LOSUNW != PT_SUNWBSS 664031Srie #error "PT_LOSUNW has grown. Update uphdrs[]" 674031Srie #endif 680Sstevel@tonic-gate 694031Srie if (type < PT_NUM) { 70*4734Sab196087 return (conv_map2str(inv_buf, type, fmt_flags, 71*4734Sab196087 ARRAY_NELTS(phdrs), phdrs, phdrs_alt, phdrs_alt)); 724031Srie } else if ((type >= PT_SUNWBSS) && (type <= PT_HISUNW)) { 73*4734Sab196087 return (conv_map2str(inv_buf, (type - PT_SUNWBSS), fmt_flags, 74*4734Sab196087 ARRAY_NELTS(uphdrs), uphdrs, uphdrs_alt, uphdrs_alt)); 754031Srie } else if ((type == PT_SUNW_UNWIND) && (mach == EM_AMD64)) { 764031Srie return ((fmt_flags & CONV_FMTALTMASK) ? 774031Srie MSG_ORIG(MSG_PT_SUNW_UNWIND_ALT) : 784031Srie MSG_ORIG(MSG_PT_SUNW_UNWIND)); 794031Srie } else 80*4734Sab196087 return (conv_invalid_val(inv_buf, type, 0)); 810Sstevel@tonic-gate } 820Sstevel@tonic-gate 832352Sab196087 #define PHDRSZ CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \ 842352Sab196087 MSG_PF_X_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 852352Sab196087 MSG_PF_W_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 862352Sab196087 MSG_PF_R_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 872352Sab196087 MSG_PF_SUNW_FAILURE_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 88*4734Sab196087 CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE 89*4734Sab196087 90*4734Sab196087 /* 91*4734Sab196087 * Ensure that Conv_phdr_flags_buf_t is large enough: 92*4734Sab196087 * 93*4734Sab196087 * PHDRSZ is the real minimum size of the buffer required by conv_phdr_flags(). 94*4734Sab196087 * However, Conv_phdr_flags_buf_t uses CONV_PHDR_FLAGS_BUFSIZE to set the 95*4734Sab196087 * buffer size. We do things this way because the definition of PHDRSZ uses 96*4734Sab196087 * information that is not available in the environment of other programs 97*4734Sab196087 * that include the conv.h header file. 98*4734Sab196087 */ 99*4734Sab196087 #if CONV_PHDR_FLAGS_BUFSIZE < PHDRSZ 100*4734Sab196087 #error "CONV_PHDR_FLAGS_BUFSIZE is not large enough" 101*4734Sab196087 #endif 1020Sstevel@tonic-gate 1030Sstevel@tonic-gate const char * 104*4734Sab196087 conv_phdr_flags(Word flags, Conv_phdr_flags_buf_t *phdr_flags_buf) 1050Sstevel@tonic-gate { 1061618Srie static Val_desc vda[] = { 1071618Srie { PF_X, MSG_ORIG(MSG_PF_X) }, 1081618Srie { PF_W, MSG_ORIG(MSG_PF_W) }, 1091618Srie { PF_R, MSG_ORIG(MSG_PF_R) }, 1101618Srie { PF_SUNW_FAILURE, MSG_ORIG(MSG_PF_SUNW_FAILURE) }, 1111618Srie { 0, 0 } 1121618Srie }; 113*4734Sab196087 static CONV_EXPN_FIELD_ARG conv_arg = { 114*4734Sab196087 NULL, sizeof (phdr_flags_buf->buf), vda }; 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate if (flags == 0) 1170Sstevel@tonic-gate return (MSG_ORIG(MSG_GBL_ZERO)); 1180Sstevel@tonic-gate 119*4734Sab196087 conv_arg.buf = phdr_flags_buf->buf; 1202352Sab196087 conv_arg.oflags = conv_arg.rflags = flags; 1212352Sab196087 (void) conv_expn_field(&conv_arg); 1221618Srie 123*4734Sab196087 return ((const char *)phdr_flags_buf->buf); 1240Sstevel@tonic-gate } 125