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.
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.
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]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
30 #include "_string_table.h"
33 * Format an input section descriptor name for output, in the format
35 * If possible, a user supplied fixed size buffer is used. Failing that,
36 * dynamic memory is allocated, which must be freed by the caller.
39 * [dbg_fmt_isec_name2]: name, scnndx - Name and section index
40 * [dbg_fmt_isec_name]: isp - Input section descriptor giving name
43 * buf - Caller supplied buffer
44 * alloc_mem - Address of pointer to be set to address of allocated
45 * memory, or NULL if no memory is allocated.
48 * A pointer to the formatted string is returned. If the supplied buffer
49 * was sufficient, *alloc_mem is set to NULL. If memory was allocated,
50 * *alloc_mem references it. The caller must free this memory after use.
53 dbg_fmt_isec_name2(const char *name
, Word scnndx
, dbg_isec_name_buf_t buf
,
59 * If the section index is 0, it's not a real section.
60 * Just use the name as is.
67 /* Format into the fixed buffer */
68 cnt
= snprintf(buf
, sizeof (dbg_isec_name_buf_t
),
69 MSG_ORIG(MSG_FMT_ISEC_NAME
), EC_WORD(scnndx
), name
);
72 * If the name was too long, try to allocate a dynamic buffer.
73 * Failing that, fall through and use the clipped one already
74 * formatted into buf, as that's better than nothing.
76 if ((cnt
>= sizeof (dbg_isec_name_buf_t
)) &&
77 ((*alloc_mem
= malloc(cnt
+ 1)) != NULL
)) {
78 (void) snprintf(*alloc_mem
, cnt
+ 1,
79 MSG_ORIG(MSG_FMT_ISEC_NAME
), EC_WORD(scnndx
), name
);
83 /* Return the caller supplied buffer */
88 dbg_fmt_isec_name(Is_desc
*isp
, dbg_isec_name_buf_t buf
, char **alloc_mem
)
90 return (dbg_fmt_isec_name2(isp
->is_name
, isp
->is_scnndx
, buf
,
95 Dbg_sec_strtab(Lm_list
*lml
, Os_desc
*osp
, Str_tbl
*stp
)
99 if (DBG_NOTCLASS(DBG_C_STRTAB
))
105 Dbg_util_nl(lml
, DBG_NL_STD
);
106 if (stp
->st_flags
& FLG_STTAB_COMPRESS
)
107 dbg_print(lml
, MSG_INTL(MSG_SEC_STRTAB_COMP
), osp
->os_name
,
108 EC_XWORD(stp
->st_fullstrsize
), EC_XWORD(stp
->st_strsize
));
110 dbg_print(lml
, MSG_INTL(MSG_SEC_STRTAB_STND
), osp
->os_name
,
111 EC_XWORD(stp
->st_fullstrsize
));
113 if ((DBG_NOTDETAIL()) ||
114 ((stp
->st_flags
& FLG_STTAB_COMPRESS
) == 0))
117 dbg_print(lml
, MSG_ORIG(MSG_STR_EMPTY
));
118 dbg_print(lml
, MSG_INTL(MSG_SEC_STRTAB_HD
), osp
->os_name
,
121 for (cnt
= 0; cnt
< stp
->st_hbckcnt
; cnt
++) {
122 Str_hash
*strhash
= stp
->st_hashbcks
[cnt
];
127 dbg_print(lml
, MSG_INTL(MSG_SEC_STRTAB_BCKT
), cnt
);
130 size_t stroff
= strhash
->hi_mstr
->sm_strlen
-
134 dbg_print(lml
, MSG_INTL(MSG_SEC_STRTAB_MSTR
),
135 EC_XWORD(strhash
->hi_refcnt
),
136 strhash
->hi_mstr
->sm_str
);
138 dbg_print(lml
, MSG_INTL(MSG_SEC_STRTAB_SUFSTR
),
139 EC_XWORD(strhash
->hi_refcnt
),
140 &strhash
->hi_mstr
->sm_str
[stroff
],
141 strhash
->hi_mstr
->sm_str
);
144 strhash
= strhash
->hi_next
;
150 Dbg_sec_genstr_compress(Lm_list
*lml
, const char *os_name
,
151 Xword raw_size
, Xword merge_size
)
153 if (DBG_NOTCLASS(DBG_C_SECTIONS
))
156 dbg_print(lml
, MSG_INTL(MSG_SEC_GENSTR_COMP
), os_name
,
157 EC_XWORD(raw_size
), EC_XWORD(merge_size
));
161 Dbg_sec_unsup_strmerge(Lm_list
*lml
, Is_desc
*isp
)
163 dbg_isec_name_buf_t buf
;
167 if (DBG_NOTCLASS(DBG_C_SECTIONS
))
171 * We can only merge string table sections with single byte
172 * (char) characters. For any other (wide) character types,
173 * issue a message so the user will understand why these
174 * sections are not being picked up.
176 if ((isp
->is_shdr
->sh_entsize
> 1) ||
177 (isp
->is_shdr
->sh_addralign
> 1)) {
178 str
= (isp
->is_file
!= NULL
) ? isp
->is_file
->ifl_name
:
179 MSG_INTL(MSG_STR_NULL
);
180 dbg_print(lml
, MSG_INTL(MSG_SEC_STRMERGE_UNSUP
),
181 dbg_fmt_isec_name(isp
, buf
, &alloc_mem
), str
,
182 EC_XWORD(isp
->is_shdr
->sh_addralign
),
183 EC_XWORD(isp
->is_shdr
->sh_entsize
));
189 Dbg_sec_backing(Lm_list
*lml
)
191 if (DBG_NOTCLASS(DBG_C_SECTIONS
))
194 Dbg_util_nl(lml
, DBG_NL_STD
);
195 dbg_print(lml
, MSG_INTL(MSG_SEC_BACKING
));
199 Dbg_sec_in(Lm_list
*lml
, Is_desc
*isp
)
201 if (DBG_NOTCLASS(DBG_C_SECTIONS
))
204 if (isp
->is_flags
& FLG_IS_GNSTRMRG
) {
206 * This section was generated because we have 1 or
207 * more SHF_MERGE|SHF_STRINGS input sections that we
208 * wish to merge. This new section will ultimately
209 * end up replacing those sections once it has been filled
210 * with their strings (merged and compressed) and relocations
211 * have been redirected.
213 dbg_print(lml
, MSG_INTL(MSG_SEC_INPUT_GENSTR
), isp
->is_name
);
214 } else if (isp
->is_file
== NULL
) {
215 /* Generated input section */
216 dbg_print(lml
, MSG_INTL(MSG_SEC_INPUT_GEN
), isp
->is_name
);
218 /* Standard input section */
219 dbg_isec_name_buf_t buf
;
222 dbg_print(lml
, MSG_INTL(MSG_SEC_INPUT
),
223 dbg_fmt_isec_name(isp
, buf
, &alloc_mem
),
224 isp
->is_file
->ifl_name
);
230 Dbg_sec_added(Lm_list
*lml
, Os_desc
*osp
, Sg_desc
*sgp
)
232 if (DBG_NOTCLASS(DBG_C_SECTIONS
))
235 dbg_print(lml
, MSG_INTL(MSG_SEC_ADDED
), osp
->os_name
,
236 (sgp
->sg_name
? sgp
->sg_name
: MSG_INTL(MSG_STR_NULL
)));
240 Dbg_sec_created(Lm_list
*lml
, Os_desc
*osp
, Sg_desc
*sgp
)
242 if (DBG_NOTCLASS(DBG_C_SECTIONS
))
245 dbg_print(lml
, MSG_INTL(MSG_SEC_CREATED
), osp
->os_name
,
246 (sgp
->sg_name
? sgp
->sg_name
: MSG_INTL(MSG_STR_NULL
)));
250 Dbg_sec_discarded(Lm_list
*lml
, Is_desc
*isp
, Is_desc
*disp
)
252 if (DBG_NOTCLASS(DBG_C_SECTIONS
| DBG_C_UNUSED
))
255 if ((isp
->is_flags
& FLG_IS_INSTRMRG
) &&
256 (disp
->is_flags
& FLG_IS_GNSTRMRG
)) {
258 * This SHF_MERGE|SHF_STRINGS input section is being
259 * discarded in favor of the generated merged string section.
261 dbg_isec_name_buf_t buf
;
264 dbg_print(lml
, MSG_INTL(MSG_SEC_STRMERGE_DISCARDED
),
265 dbg_fmt_isec_name(isp
, buf
, &alloc_mem
),
266 isp
->is_file
->ifl_name
);
269 /* Generic section discard */
270 dbg_isec_name_buf_t buf1
, buf2
;
271 char *alloc_mem1
, *alloc_mem2
;
273 dbg_print(lml
, MSG_INTL(MSG_SEC_DISCARDED
),
274 dbg_fmt_isec_name(isp
, buf1
, &alloc_mem1
),
275 isp
->is_file
->ifl_name
,
276 dbg_fmt_isec_name(disp
, buf2
, &alloc_mem2
),
277 disp
->is_file
->ifl_name
);
284 Dbg_sec_group(Lm_list
*lml
, Is_desc
*isp
, Group_desc
*gdp
)
286 dbg_isec_name_buf_t buf
;
288 const char *comdat
, *isp_str
;
290 if (DBG_NOTCLASS(DBG_C_SECTIONS
))
293 if (gdp
->gd_data
[0] & GRP_COMDAT
)
294 comdat
= MSG_ORIG(MSG_STR_COMDAT
);
296 comdat
= MSG_ORIG(MSG_STR_EMPTY
);
298 isp_str
= dbg_fmt_isec_name(isp
, buf
, &alloc_mem
);
300 if (isp
->is_shdr
->sh_type
== SHT_GROUP
) {
301 dbg_print(lml
, MSG_INTL(MSG_SEC_GRP_DEFINE
), isp_str
,
302 isp
->is_file
->ifl_name
, comdat
, gdp
->gd_name
);
304 dbg_print(lml
, MSG_INTL(MSG_SEC_GRP_MEMBER
), isp_str
,
305 isp
->is_file
->ifl_name
, comdat
, gdp
->gd_name
);
309 dbg_print(lml
, MSG_INTL(MSG_SEC_GRP_DISCARDED
), isp_str
,
310 isp
->is_file
->ifl_name
, gdp
->gd_name
,
311 gdp
->gd_oisc
->is_file
->ifl_name
);
318 Dbg_sec_order_list(Ofl_desc
*ofl
, int flag
)
323 Lm_list
*lml
= ofl
->ofl_lml
;
326 if (DBG_NOTCLASS(DBG_C_SECTIONS
))
331 Dbg_util_nl(lml
, DBG_NL_STD
);
334 * If the flag == 0, then the routine is called before sorting.
337 str
= MSG_INTL(MSG_ORD_SORT_BEFORE
);
339 str
= MSG_INTL(MSG_ORD_SORT_AFTER
);
341 for (APLIST_TRAVERSE(ofl
->ofl_ordered
, idx1
, osp
)) {
345 Dbg_util_nl(lml
, DBG_NL_STD
);
346 dbg_print(lml
, str
, osp
->os_name
);
347 dbg_print(lml
, MSG_INTL(MSG_ORD_HDR_1
),
348 EC_WORD(aplist_nitems(osp
->os_isdescs
[OS_ISD_BEFORE
])),
349 EC_WORD(aplist_nitems(osp
->os_isdescs
[OS_ISD_ORDERED
])),
350 EC_WORD(aplist_nitems(osp
->os_isdescs
[OS_ISD_DEFAULT
])),
351 EC_WORD(aplist_nitems(osp
->os_isdescs
[OS_ISD_AFTER
])));
353 OS_ISDESCS_TRAVERSE(os_isdescs_idx
, osp
, idx2
, isp1
) {
354 dbg_isec_name_buf_t buf
;
356 const char *isp1_str
;
358 Ifl_desc
*ifl
= isp1
->is_file
;
363 * An output segment that requires ordering might have
364 * as little as two sorted input sections. For example,
365 * the crt's can provide a SHN_BEGIN and SHN_AFTER, and
366 * only these two sections must be processed. Thus, if
367 * a input section is unordered, move on. Diagnosing
368 * any unsorted section can produce way too much noise.
370 if ((isp1
->is_flags
& FLG_IS_ORDERED
) == 0)
373 if (isp1
->is_shdr
->sh_flags
& SHF_ORDERED
) {
374 link
= isp1
->is_shdr
->sh_info
;
375 msg
= MSG_ORIG(MSG_SH_INFO
);
376 } else { /* SHF_LINK_ORDER */
377 link
= isp1
->is_shdr
->sh_link
;
378 msg
= MSG_ORIG(MSG_SH_LINK
);
381 isp1_str
= dbg_fmt_isec_name(isp1
, buf
, &alloc_mem
);
383 if (link
== SHN_BEFORE
) {
384 dbg_print(lml
, MSG_INTL(MSG_ORD_TITLE_1
), msg
,
385 isp1_str
, isp1
->is_file
->ifl_name
);
386 } else if (link
== SHN_AFTER
) {
387 dbg_print(lml
, MSG_INTL(MSG_ORD_TITLE_2
), msg
,
388 isp1_str
, isp1
->is_file
->ifl_name
);
390 isp2
= ifl
->ifl_isdesc
[link
];
391 dbg_print(lml
, MSG_INTL(MSG_ORD_TITLE_3
),
392 EC_WORD(isp2
->is_keyident
), isp1_str
,
393 ifl
->ifl_name
, msg
, isp2
->is_name
);
395 if (alloc_mem
!= NULL
)
399 Dbg_util_nl(lml
, DBG_NL_STD
);
403 * Error message string table.
405 static const Msg order_errors
[] = {
406 MSG_ORD_ERR_INFORANGE
, /* MSG_INTL(MSG_ORD_ERR_INFORANGE) */
407 MSG_ORD_ERR_ORDER
, /* MSG_INTL(MSG_ORD_ERR_ORDER) */
408 MSG_ORD_ERR_LINKRANGE
, /* MSG_INTL(MSG_ORD_ERR_LINKRANGE) */
409 MSG_ORD_ERR_FLAGS
, /* MSG_INTL(MSG_ORD_ERR_FLAGS) */
410 MSG_ORD_ERR_CYCLIC
, /* MSG_INTL(MSG_ORD_ERR_CYCLIC) */
411 MSG_ORD_ERR_LINKINV
/* MSG_INTL(MSG_ORD_ERR_LINKINV) */
415 Dbg_sec_order_error(Lm_list
*lml
, Ifl_desc
*ifl
, Word ndx
, int error
)
417 dbg_isec_name_buf_t buf
;
420 if (DBG_NOTCLASS(DBG_C_SECTIONS
))
428 dbg_print(lml
, MSG_INTL(MSG_ORD_ERR_TITLE
),
429 dbg_fmt_isec_name(ifl
->ifl_isdesc
[ndx
], buf
, &alloc_mem
),
434 dbg_print(lml
, MSG_INTL(order_errors
[error
- 1]));
438 Dbg_sec_redirected(Lm_list
*lml
, Is_desc
*isp
, const char *nname
)
440 dbg_isec_name_buf_t buf
;
443 if (DBG_NOTCLASS(DBG_C_SECTIONS
))
446 dbg_print(lml
, MSG_INTL(MSG_SEC_REDIRECTED
),
447 dbg_fmt_isec_name(isp
, buf
, &alloc_mem
), nname
);
452 Dbg_sec_gnu_comdat(Lm_list
*lml
, Is_desc
*isp
, Boolean comdat
, Boolean relax
)
454 dbg_isec_name_buf_t buf
;
458 if (DBG_NOTCLASS(DBG_C_SECTIONS
))
462 fmt
= MSG_INTL(MSG_SEC_GNU_COMDAT_1
);
464 fmt
= MSG_INTL(MSG_SEC_GNU_COMDAT_2
);
466 fmt
= MSG_INTL(MSG_SEC_GNU_COMDAT_3
);
468 dbg_print(lml
, fmt
, dbg_fmt_isec_name(isp
, buf
, &alloc_mem
));