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 * 405088Sab196087 conv_phdr_type(Half mach, Word type, Conv_fmt_flags_t fmt_flags, 415088Sab196087 Conv_inv_buf_t *inv_buf) 420Sstevel@tonic-gate { 431618Srie static const Msg phdrs[] = { 444031Srie MSG_PT_NULL, MSG_PT_LOAD, 454031Srie MSG_PT_DYNAMIC, MSG_PT_INTERP, 464031Srie MSG_PT_NOTE, MSG_PT_SHLIB, 471618Srie MSG_PT_PHDR, MSG_PT_TLS 481618Srie }; 494031Srie static const Msg phdrs_alt[] = { 504031Srie MSG_PT_NULL_ALT, MSG_PT_LOAD_ALT, 514031Srie MSG_PT_DYNAMIC_ALT, MSG_PT_INTERP_ALT, 524031Srie MSG_PT_NOTE_ALT, MSG_PT_SHLIB_ALT, 534031Srie MSG_PT_PHDR_ALT, MSG_PT_TLS_ALT 544031Srie }; 554031Srie #if PT_NUM != (PT_TLS + 1) 564031Srie error "PT_NUM has grown. Update phdrs[]" 574031Srie #endif 584031Srie static const Msg uphdrs[] = { 594031Srie MSG_PT_SUNWBSS, MSG_PT_SUNWSTACK, 604031Srie MSG_PT_SUNWDTRACE, MSG_PT_SUNWCAP 614031Srie }; 624031Srie static const Msg uphdrs_alt[] = { 634031Srie MSG_PT_SUNWBSS_ALT, MSG_PT_SUNWSTACK_ALT, 644031Srie MSG_PT_SUNWDTRACE_ALT, MSG_PT_SUNWCAP_ALT 654031Srie }; 664031Srie #if PT_LOSUNW != PT_SUNWBSS 674031Srie #error "PT_LOSUNW has grown. Update uphdrs[]" 684031Srie #endif 690Sstevel@tonic-gate 704031Srie if (type < PT_NUM) { 715088Sab196087 switch (CONV_TYPE_FMT_ALT(fmt_flags)) { 725088Sab196087 case CONV_FMT_ALT_DUMP: 735088Sab196087 case CONV_FMT_ALT_FILE: 745088Sab196087 return (conv_map2str(inv_buf, type, fmt_flags, 755088Sab196087 ARRAY_NELTS(phdrs_alt), phdrs_alt)); 765088Sab196087 default: 775088Sab196087 return (conv_map2str(inv_buf, type, fmt_flags, 785088Sab196087 ARRAY_NELTS(phdrs), phdrs)); 795088Sab196087 } 804031Srie } else if ((type >= PT_SUNWBSS) && (type <= PT_HISUNW)) { 815088Sab196087 switch (CONV_TYPE_FMT_ALT(fmt_flags)) { 825088Sab196087 case CONV_FMT_ALT_DUMP: 835088Sab196087 case CONV_FMT_ALT_FILE: 845088Sab196087 return (conv_map2str(inv_buf, (type - PT_SUNWBSS), 855088Sab196087 fmt_flags, ARRAY_NELTS(uphdrs_alt), uphdrs_alt)); 865088Sab196087 default: 875088Sab196087 return (conv_map2str(inv_buf, (type - PT_SUNWBSS), 885088Sab196087 fmt_flags, ARRAY_NELTS(uphdrs), uphdrs)); 895088Sab196087 } 904031Srie } else if ((type == PT_SUNW_UNWIND) && (mach == EM_AMD64)) { 915088Sab196087 switch (CONV_TYPE_FMT_ALT(fmt_flags)) { 925088Sab196087 case CONV_FMT_ALT_DUMP: 935088Sab196087 case CONV_FMT_ALT_FILE: 945088Sab196087 return (MSG_ORIG(MSG_PT_SUNW_UNWIND_ALT)); 955088Sab196087 default: 965088Sab196087 return (MSG_ORIG(MSG_PT_SUNW_UNWIND)); 975088Sab196087 } 984031Srie } else 994734Sab196087 return (conv_invalid_val(inv_buf, type, 0)); 1000Sstevel@tonic-gate } 1010Sstevel@tonic-gate 1022352Sab196087 #define PHDRSZ CONV_EXPN_FIELD_DEF_PREFIX_SIZE + \ 1032352Sab196087 MSG_PF_X_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 1042352Sab196087 MSG_PF_W_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 1052352Sab196087 MSG_PF_R_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 1062352Sab196087 MSG_PF_SUNW_FAILURE_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ 1074734Sab196087 CONV_INV_BUFSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE 1084734Sab196087 1094734Sab196087 /* 1104734Sab196087 * Ensure that Conv_phdr_flags_buf_t is large enough: 1114734Sab196087 * 1124734Sab196087 * PHDRSZ is the real minimum size of the buffer required by conv_phdr_flags(). 1134734Sab196087 * However, Conv_phdr_flags_buf_t uses CONV_PHDR_FLAGS_BUFSIZE to set the 1144734Sab196087 * buffer size. We do things this way because the definition of PHDRSZ uses 1154734Sab196087 * information that is not available in the environment of other programs 1164734Sab196087 * that include the conv.h header file. 1174734Sab196087 */ 118*5152Sab196087 #if (CONV_PHDR_FLAGS_BUFSIZE != PHDRSZ) && !defined(__lint) 119*5152Sab196087 #define REPORT_BUFSIZE PHDRSZ 120*5152Sab196087 #include "report_bufsize.h" 121*5152Sab196087 #error "CONV_PHDR_FLAGS_BUFSIZE does not match PHDRSZ" 1224734Sab196087 #endif 1230Sstevel@tonic-gate 1240Sstevel@tonic-gate const char * 1255088Sab196087 conv_phdr_flags(Word flags, Conv_fmt_flags_t fmt_flags, 1265088Sab196087 Conv_phdr_flags_buf_t *phdr_flags_buf) 1270Sstevel@tonic-gate { 1281618Srie static Val_desc vda[] = { 1291618Srie { PF_X, MSG_ORIG(MSG_PF_X) }, 1301618Srie { PF_W, MSG_ORIG(MSG_PF_W) }, 1311618Srie { PF_R, MSG_ORIG(MSG_PF_R) }, 1321618Srie { PF_SUNW_FAILURE, MSG_ORIG(MSG_PF_SUNW_FAILURE) }, 1331618Srie { 0, 0 } 1341618Srie }; 1354734Sab196087 static CONV_EXPN_FIELD_ARG conv_arg = { 1364734Sab196087 NULL, sizeof (phdr_flags_buf->buf), vda }; 1370Sstevel@tonic-gate 1380Sstevel@tonic-gate if (flags == 0) 1390Sstevel@tonic-gate return (MSG_ORIG(MSG_GBL_ZERO)); 1400Sstevel@tonic-gate 1414734Sab196087 conv_arg.buf = phdr_flags_buf->buf; 1422352Sab196087 conv_arg.oflags = conv_arg.rflags = flags; 1435088Sab196087 (void) conv_expn_field(&conv_arg, fmt_flags); 1441618Srie 1454734Sab196087 return ((const char *)phdr_flags_buf->buf); 1460Sstevel@tonic-gate } 147