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 27 #include <strings.h> 28 #include <dwarf.h> 29 #include "_conv.h" 30 #include <dwarf_ehe_msg.h> 31 32 #define FLAGSZ MSG_GBL_OSQBRKT_SIZE + \ 33 MSG_DWEHE_SLEB128_SIZE + \ 34 MSG_DWEHE_INDIRECT_SIZE + \ 35 CONV_INV_BUFSIZE + MSG_GBL_CSQBRKT_SIZE 36 37 /* 38 * Ensure that Conv_dwarf_ehe_buf_t is large enough: 39 * 40 * FLAGSZ is the real minimum size of the buffer required by conv_dwarf_ehe(). 41 * However, Conv_dwarf_ehe_buf_t uses CONV_EHDR_FLAG_BUFSIZE to set the 42 * buffer size. We do things this way because the definition of FLAGSZ uses 43 * information that is not available in the environment of other programs 44 * that include the conv.h header file. 45 */ 46 #if (CONV_DWARF_EHE_BUFSIZE != FLAGSZ) && !defined(__lint) 47 #define REPORT_BUFSIZE FLAGSZ 48 #include "report_bufsize.h" 49 #error "CONV_DWARF_EHE_BUFSIZE does not match FLAGSZ" 50 #endif 51 52 const char * 53 conv_dwarf_ehe(uint_t flags, Conv_dwarf_ehe_buf_t *dwarf_ehe_buf) 54 { 55 char *buf = dwarf_ehe_buf->buf; 56 size_t ret = 0; 57 58 (void) strncpy(buf, MSG_ORIG(MSG_GBL_OSQBRKT), FLAGSZ); 59 60 if (flags == DW_EH_PE_omit) 61 ret = strlcat(buf, MSG_ORIG(MSG_DWEHE_OMIT), FLAGSZ); 62 else if (flags == DW_EH_PE_absptr) 63 ret = strlcat(buf, MSG_ORIG(MSG_DWEHE_ABSPTR), FLAGSZ); 64 65 if (ret >= FLAGSZ) 66 return (conv_invalid_val(&dwarf_ehe_buf->inv_buf, flags, 0)); 67 68 if ((flags == DW_EH_PE_omit) || (flags == DW_EH_PE_absptr)) { 69 (void) strlcat(buf, MSG_ORIG(MSG_GBL_CSQBRKT), FLAGSZ); 70 return (buf); 71 } 72 73 switch (flags & 0x0f) { 74 case DW_EH_PE_uleb128: 75 ret = strlcat(buf, MSG_ORIG(MSG_DWEHE_ULEB128), FLAGSZ); 76 break; 77 case DW_EH_PE_udata2: 78 ret = strlcat(buf, MSG_ORIG(MSG_DWEHE_UDATA2), FLAGSZ); 79 break; 80 case DW_EH_PE_udata4: 81 ret = strlcat(buf, MSG_ORIG(MSG_DWEHE_UDATA4), FLAGSZ); 82 break; 83 case DW_EH_PE_udata8: 84 ret = strlcat(buf, MSG_ORIG(MSG_DWEHE_UDATA8), FLAGSZ); 85 break; 86 case DW_EH_PE_sleb128: 87 ret = strlcat(buf, MSG_ORIG(MSG_DWEHE_SLEB128), FLAGSZ); 88 break; 89 case DW_EH_PE_sdata2: 90 ret = strlcat(buf, MSG_ORIG(MSG_DWEHE_SDATA2), FLAGSZ); 91 break; 92 case DW_EH_PE_sdata4: 93 ret = strlcat(buf, MSG_ORIG(MSG_DWEHE_SDATA4), FLAGSZ); 94 break; 95 case DW_EH_PE_sdata8: 96 ret = strlcat(buf, MSG_ORIG(MSG_DWEHE_SDATA8), FLAGSZ); 97 break; 98 } 99 if (ret >= FLAGSZ) 100 return (conv_invalid_val(&dwarf_ehe_buf->inv_buf, flags, 0)); 101 102 switch (flags & 0xf0) { 103 case DW_EH_PE_pcrel: 104 ret = strlcat(buf, MSG_ORIG(MSG_DWEHE_PCREL), FLAGSZ); 105 break; 106 case DW_EH_PE_textrel: 107 ret = strlcat(buf, MSG_ORIG(MSG_DWEHE_TEXTREL), FLAGSZ); 108 break; 109 case DW_EH_PE_datarel: 110 ret = strlcat(buf, MSG_ORIG(MSG_DWEHE_DATAREL), FLAGSZ); 111 break; 112 case DW_EH_PE_funcrel: 113 ret = strlcat(buf, MSG_ORIG(MSG_DWEHE_FUNCREL), FLAGSZ); 114 break; 115 case DW_EH_PE_aligned: 116 ret = strlcat(buf, MSG_ORIG(MSG_DWEHE_ALIGNED), FLAGSZ); 117 break; 118 case DW_EH_PE_indirect: 119 ret = strlcat(buf, MSG_ORIG(MSG_DWEHE_INDIRECT), FLAGSZ); 120 break; 121 } 122 if (ret >= FLAGSZ) 123 return (conv_invalid_val(&dwarf_ehe_buf->inv_buf, flags, 0)); 124 125 (void) strlcat(buf, MSG_ORIG(MSG_GBL_CSQBRKT), FLAGSZ); 126 return (buf); 127 } 128