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 2008 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 "msg.h" 29 #include "_debug.h" 30 #include "libld.h" 31 #include "_string_table.h" 32 33 void 34 Dbg_sec_strtab(Lm_list *lml, Os_desc *osp, Str_tbl *stp) 35 { 36 uint_t cnt; 37 38 if (DBG_NOTCLASS(DBG_C_STRTAB)) 39 return; 40 41 if (!osp) 42 return; 43 44 Dbg_util_nl(lml, DBG_NL_STD); 45 if (stp->st_flags & FLG_STTAB_COMPRESS) 46 dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_COMP), osp->os_name, 47 EC_XWORD(stp->st_fullstrsize), EC_XWORD(stp->st_strsize)); 48 else 49 dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_STND), osp->os_name, 50 EC_XWORD(stp->st_fullstrsize)); 51 52 if ((DBG_NOTDETAIL()) || 53 ((stp->st_flags & FLG_STTAB_COMPRESS) == 0)) 54 return; 55 56 dbg_print(lml, MSG_ORIG(MSG_STR_EMPTY)); 57 dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_HD), osp->os_name, 58 stp->st_hbckcnt); 59 60 for (cnt = 0; cnt < stp->st_hbckcnt; cnt++) { 61 Str_hash *strhash = stp->st_hashbcks[cnt]; 62 63 if (strhash == 0) 64 continue; 65 66 dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_BCKT), cnt); 67 68 while (strhash) { 69 size_t stroff = strhash->hi_mstr->sm_strlen - 70 strhash->hi_strlen; 71 72 if (stroff == 0) { 73 dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_MSTR), 74 EC_XWORD(strhash->hi_refcnt), 75 strhash->hi_mstr->sm_str); 76 } else { 77 dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_SUFSTR), 78 EC_XWORD(strhash->hi_refcnt), 79 &strhash->hi_mstr->sm_str[stroff], 80 strhash->hi_mstr->sm_str); 81 } 82 83 strhash = strhash->hi_next; 84 } 85 } 86 } 87 88 void 89 Dbg_sec_genstr_compress(Lm_list *lml, const char *os_name, 90 Xword raw_size, Xword merge_size) 91 { 92 if (DBG_NOTCLASS(DBG_C_SECTIONS)) 93 return; 94 95 dbg_print(lml, MSG_INTL(MSG_SEC_GENSTR_COMP), os_name, 96 EC_XWORD(raw_size), EC_XWORD(merge_size)); 97 } 98 99 void 100 Dbg_sec_unsup_strmerge(Lm_list *lml, Is_desc *isp) 101 { 102 const char *str; 103 104 if (DBG_NOTCLASS(DBG_C_SECTIONS)) 105 return; 106 107 /* 108 * We can only merge string table sections with single byte 109 * (char) characters. For any other (wide) character types, 110 * issue a message so the user will understand why these 111 * sections are not being picked up. 112 */ 113 if ((isp->is_shdr->sh_entsize > 1) || 114 (isp->is_shdr->sh_addralign > 1)) { 115 str = (isp->is_file != NULL) ? isp->is_file->ifl_name : 116 MSG_INTL(MSG_STR_NULL); 117 dbg_print(lml, MSG_INTL(MSG_SEC_STRMERGE_UNSUP), 118 isp->is_basename, str, EC_XWORD(isp->is_shdr->sh_addralign), 119 EC_XWORD(isp->is_shdr->sh_entsize)); 120 } 121 } 122 123 void 124 Dbg_sec_in(Lm_list *lml, Is_desc *isp) 125 { 126 const char *str; 127 128 if (DBG_NOTCLASS(DBG_C_SECTIONS)) 129 return; 130 131 if (isp->is_flags & FLG_IS_GNSTRMRG) { 132 /* 133 * This section was generated because we have 1 or 134 * more SHF_MERGE|SHF_STRINGS input sections that we 135 * wish to merge. This new section will ultimately 136 * end up replacing those sections once it has been filled 137 * with their strings (merged and compressed) and relocations 138 * have been redirected. 139 */ 140 dbg_print(lml, MSG_INTL(MSG_SEC_INPUT_GENSTR), isp->is_name); 141 } else { 142 /* Standard input section */ 143 str = (isp->is_file != NULL) ? isp->is_file->ifl_name : 144 MSG_INTL(MSG_STR_NULL); 145 dbg_print(lml, MSG_INTL(MSG_SEC_INPUT), isp->is_name, str); 146 } 147 } 148 149 void 150 Dbg_sec_added(Lm_list *lml, Os_desc *osp, Sg_desc *sgp) 151 { 152 const char *str; 153 154 if (DBG_NOTCLASS(DBG_C_SECTIONS)) 155 return; 156 157 if (sgp->sg_name && *sgp->sg_name) 158 str = sgp->sg_name; 159 else 160 str = MSG_INTL(MSG_STR_NULL); 161 162 dbg_print(lml, MSG_INTL(MSG_SEC_ADDED), osp->os_name, str); 163 } 164 165 void 166 Dbg_sec_created(Lm_list *lml, Os_desc *osp, Sg_desc *sgp) 167 { 168 const char *str; 169 170 if (DBG_NOTCLASS(DBG_C_SECTIONS)) 171 return; 172 173 if (sgp->sg_name && *sgp->sg_name) 174 str = sgp->sg_name; 175 else 176 str = MSG_INTL(MSG_STR_NULL); 177 178 dbg_print(lml, MSG_INTL(MSG_SEC_CREATED), osp->os_name, str); 179 } 180 181 void 182 Dbg_sec_discarded(Lm_list *lml, Is_desc *isp, Is_desc *disp) 183 { 184 if (DBG_NOTCLASS(DBG_C_SECTIONS | DBG_C_UNUSED)) 185 return; 186 187 if ((isp->is_flags & FLG_IS_INSTRMRG) && 188 (disp->is_flags & FLG_IS_GNSTRMRG)) { 189 /* 190 * This SHF_MERGE|SHF_STRINGS input section is being 191 * discarded in favor of the generated merged string section. 192 */ 193 dbg_print(lml, MSG_INTL(MSG_SEC_STRMERGE_DISCARDED), 194 isp->is_basename, isp->is_file->ifl_name); 195 } else { 196 /* Generic section discard */ 197 dbg_print(lml, MSG_INTL(MSG_SEC_DISCARDED), isp->is_basename, 198 isp->is_file->ifl_name, disp->is_basename, 199 disp->is_file->ifl_name); 200 } 201 } 202 203 void 204 Dbg_sec_group(Lm_list *lml, Is_desc *isp, Group_desc *gdp) 205 { 206 const char *fmt; 207 208 if (DBG_NOTCLASS(DBG_C_SECTIONS)) 209 return; 210 211 if (gdp->gd_flags & GRP_FLG_DISCARD) 212 fmt = MSG_INTL(MSG_SEC_GRP_DISCARDED); 213 else 214 fmt = MSG_INTL(MSG_SEC_GRP_INPUT); 215 216 dbg_print(lml, fmt, isp->is_name, isp->is_file->ifl_name, 217 gdp->gd_gsectname, gdp->gd_symname); 218 } 219 220 void 221 Dbg_sec_order_list(Ofl_desc *ofl, int flag) 222 { 223 Os_desc *osp; 224 Is_desc *isp1; 225 Listnode *lnp1, *lnp2; 226 Lm_list *lml = ofl->ofl_lml; 227 const char *str; 228 229 if (DBG_NOTCLASS(DBG_C_SECTIONS)) 230 return; 231 if (DBG_NOTDETAIL()) 232 return; 233 234 Dbg_util_nl(lml, DBG_NL_STD); 235 236 /* 237 * If the flag == 0, then the routine is called before sorting. 238 */ 239 if (flag == 0) 240 str = MSG_INTL(MSG_ORD_SORT_BEFORE); 241 else 242 str = MSG_INTL(MSG_ORD_SORT_AFTER); 243 244 for (LIST_TRAVERSE(&ofl->ofl_ordered, lnp1, osp)) { 245 Sort_desc *sort = osp->os_sort; 246 247 dbg_print(lml, str, osp->os_name); 248 dbg_print(lml, MSG_INTL(MSG_ORD_HDR_1), 249 EC_WORD(sort->st_beforecnt), EC_WORD(sort->st_aftercnt), 250 EC_WORD(sort->st_ordercnt)); 251 252 for (LIST_TRAVERSE(&osp->os_isdescs, lnp2, isp1)) { 253 Word link; 254 Ifl_desc *ifl = isp1->is_file; 255 Is_desc *isp2; 256 const char *msg; 257 258 if ((isp1->is_flags & FLG_IS_ORDERED) == 0) { 259 dbg_print(lml, MSG_INTL(MSG_ORD_TITLE_0), 260 isp1->is_name, isp1->is_file->ifl_name); 261 continue; 262 } 263 264 if (isp1->is_shdr->sh_flags & SHF_ORDERED) { 265 link = isp1->is_shdr->sh_info; 266 msg = MSG_ORIG(MSG_SH_INFO); 267 } else { 268 /* SHF_LINK_ORDER */ 269 link = isp1->is_shdr->sh_link; 270 msg = MSG_ORIG(MSG_SH_LINK); 271 } 272 273 if (link == SHN_BEFORE) { 274 dbg_print(lml, MSG_INTL(MSG_ORD_TITLE_1), 275 isp1->is_name, isp1->is_file->ifl_name, 276 msg); 277 continue; 278 } 279 280 if (link == SHN_AFTER) { 281 dbg_print(lml, MSG_INTL(MSG_ORD_TITLE_2), 282 isp1->is_name, isp1->is_file->ifl_name, 283 msg); 284 continue; 285 } 286 287 isp2 = ifl->ifl_isdesc[link]; 288 dbg_print(lml, MSG_INTL(MSG_ORD_TITLE_3), 289 isp1->is_name, ifl->ifl_name, msg, isp2->is_name, 290 isp2->is_key); 291 } 292 } 293 Dbg_util_nl(lml, DBG_NL_STD); 294 } 295 296 /* 297 * Error message string table. 298 */ 299 static const Msg order_errors[] = { 300 MSG_ORD_ERR_INFORANGE, /* MSG_INTL(MSG_ORD_ERR_INFORANGE) */ 301 MSG_ORD_ERR_ORDER, /* MSG_INTL(MSG_ORD_ERR_ORDER) */ 302 MSG_ORD_ERR_LINKRANGE, /* MSG_INTL(MSG_ORD_ERR_LINKRANGE) */ 303 MSG_ORD_ERR_FLAGS, /* MSG_INTL(MSG_ORD_ERR_FLAGS) */ 304 MSG_ORD_ERR_CYCLIC, /* MSG_INTL(MSG_ORD_ERR_CYCLIC) */ 305 MSG_ORD_ERR_LINKINV /* MSG_INTL(MSG_ORD_ERR_LINKINV) */ 306 }; 307 308 void 309 Dbg_sec_order_error(Lm_list *lml, Ifl_desc *ifl, Word ndx, int error) 310 { 311 if (DBG_NOTCLASS(DBG_C_SECTIONS)) 312 return; 313 if (DBG_NOTDETAIL()) 314 return; 315 316 if (error == 0) 317 return; 318 319 dbg_print(lml, MSG_INTL(MSG_ORD_ERR_TITLE), 320 ifl->ifl_isdesc[ndx]->is_name, ifl->ifl_name); 321 322 if (error) 323 dbg_print(lml, MSG_INTL(order_errors[error - 1])); 324 } 325