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