files.c revision 11827:d7ef53deac3f
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 2010 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#include	<sys/auxv.h>
28#include	<string.h>
29#include	<unistd.h>
30#include	<fcntl.h>
31#include	<limits.h>
32#include	<stdio.h>
33#include	<libld.h>
34#include	<rtld.h>
35#include	<conv.h>
36#include	"msg.h"
37#include	"_debug.h"
38
39void
40Dbg_file_analyze(Rt_map *lmp)
41{
42	Conv_dl_mode_buf_t	dl_mode_buf;
43	Lm_list			*lml = LIST(lmp);
44
45	if (DBG_NOTCLASS(DBG_C_FILES))
46		return;
47
48	Dbg_util_nl(lml, DBG_NL_STD);
49	dbg_print(lml, MSG_INTL(MSG_FIL_ANALYZE), NAME(lmp),
50	    conv_dl_mode(MODE(lmp), 1, &dl_mode_buf));
51}
52
53void
54Dbg_file_mmapobj(Lm_list *lml, const char *name, mmapobj_result_t *ompp,
55    uint_t onum)
56{
57	mmapobj_result_t	*mpp;
58	uint_t			mnum;
59
60	if (DBG_NOTCLASS(DBG_C_FILES))
61		return;
62	if (DBG_NOTDETAIL())
63		return;
64
65	Dbg_util_nl(lml, DBG_NL_STD);
66	dbg_print(lml, MSG_INTL(MSG_FIL_MMAPOBJ), name, onum);
67
68	for (mnum = 0, mpp = ompp; mnum < onum; mnum++, mpp++) {
69		const char	*str;
70		uint_t		type = MR_GET_TYPE(mpp->mr_flags);
71
72		if (type == MR_PADDING)
73			str = MSG_ORIG(MSG_MR_PADDING);
74		else if (type == MR_HDR_ELF)
75			str = MSG_ORIG(MSG_MR_HDR_ELF);
76		else if (type == MR_HDR_AOUT)
77			str = MSG_ORIG(MSG_MR_HDR_AOUT);
78		else
79			str = MSG_ORIG(MSG_STR_EMPTY);
80
81		dbg_print(lml, MSG_INTL(MSG_FIL_MMAPOBJ_1), mnum,
82		    EC_NATPTR(mpp->mr_addr), EC_OFF(mpp->mr_fsize), str);
83		dbg_print(lml, MSG_INTL(MSG_FIL_MMAPOBJ_2),
84		    EC_OFF(mpp->mr_offset), EC_OFF(mpp->mr_msize));
85	}
86	Dbg_util_nl(lml, DBG_NL_STD);
87}
88
89void
90Dbg_file_aout(Lm_list *lml, const char *name, Addr addr, size_t size,
91    const char *lmid, Aliste lmco)
92{
93	if (DBG_NOTCLASS(DBG_C_FILES))
94		return;
95
96	dbg_print(lml, MSG_INTL(MSG_FIL_AOUT), name);
97	dbg_print(lml, MSG_INTL(MSG_FIL_DATA_AS), EC_ADDR(addr), EC_OFF(size));
98	dbg_print(lml, MSG_INTL(MSG_FIL_DATA_LL), lmid, EC_XWORD(lmco));
99}
100
101void
102Dbg_file_elf(Lm_list *lml, const char *name, Addr addr, size_t size,
103    const char *lmid, Aliste lmco)
104{
105	const char	*str;
106
107	if (DBG_NOTCLASS(DBG_C_FILES))
108		return;
109
110	if (addr == 0)
111		str = MSG_INTL(MSG_STR_TEMPORARY);
112	else
113		str = MSG_ORIG(MSG_STR_EMPTY);
114
115	dbg_print(lml, MSG_INTL(MSG_FIL_ELF), name, str);
116	dbg_print(lml, MSG_INTL(MSG_FIL_DATA_AS), EC_ADDR(addr), EC_OFF(size));
117	dbg_print(lml, MSG_INTL(MSG_FIL_DATA_LL), lmid, EC_XWORD(lmco));
118}
119
120void
121Dbg_file_ldso(Rt_map *lmp, char **envp, auxv_t *auxv, const char *lmid,
122    Aliste lmco)
123{
124	Lm_list	*lml = LIST(lmp);
125
126	if (DBG_NOTCLASS(DBG_C_FILES))
127		return;
128
129	Dbg_util_nl(lml, DBG_NL_STD);
130	dbg_print(lml, MSG_INTL(MSG_FIL_LDSO), PATHNAME(lmp));
131	dbg_print(lml, MSG_INTL(MSG_FIL_DATA_AS), EC_ADDR(ADDR(lmp)),
132	    EC_OFF(MSIZE(lmp)));
133	dbg_print(lml, MSG_INTL(MSG_FIL_DATA_EA), EC_NATPTR(envp),
134	    EC_NATPTR(auxv));
135	dbg_print(lml, MSG_INTL(MSG_FIL_DATA_LL), lmid, EC_XWORD(lmco));
136	Dbg_util_nl(lml, DBG_NL_STD);
137}
138
139
140void
141Dbg_file_prot(Rt_map *lmp, int prot)
142{
143	Lm_list	*lml = LIST(lmp);
144
145	if (DBG_NOTCLASS(DBG_C_FILES))
146		return;
147
148	Dbg_util_nl(lml, DBG_NL_STD);
149	dbg_print(lml, MSG_INTL(MSG_FIL_PROT), NAME(lmp), (prot ? '+' : '-'));
150}
151
152void
153Dbg_file_delete(Rt_map *lmp)
154{
155	Lm_list	*lml = LIST(lmp);
156
157	if (DBG_NOTCLASS(DBG_C_FILES))
158		return;
159
160	Dbg_util_nl(lml, DBG_NL_STD);
161	dbg_print(lml, MSG_INTL(MSG_FIL_DELETE), NAME(lmp));
162}
163
164static int	hdl_title = 0;
165static Msg	hdl_str = 0;
166
167void
168Dbg_file_hdl_title(int type)
169{
170	static const Msg titles[] = {
171		MSG_FIL_HDL_CREATE,	/* MSG_INTL(MSG_FIL_HDL_CREATE) */
172		MSG_FIL_HDL_ADD,	/* MSG_INTL(MSG_FIL_HDL_ADD) */
173		MSG_FIL_HDL_DELETE,	/* MSG_INTL(MSG_FIL_HDL_DELETE) */
174		MSG_FIL_HDL_ORPHAN,	/* MSG_INTL(MSG_FIL_HDL_ORPHAN) */
175		MSG_FIL_HDL_REINST,	/* MSG_INTL(MSG_FIL_HDL_REINST) */
176	};
177
178	if (DBG_NOTCLASS(DBG_C_FILES))
179		return;
180	if (DBG_NOTDETAIL())
181		return;
182
183	/*
184	 * Establish a binding title for later use in Dbg_file_hdl_action.
185	 */
186	if (type <= DBG_HDL_REINST) {
187		hdl_str = titles[type];
188		hdl_title = 1;
189	} else {
190		hdl_str = 0;
191		hdl_title = 0;
192	}
193}
194
195void
196Dbg_file_hdl_collect(Grp_hdl *ghp, const char *name)
197{
198	Conv_grphdl_flags_buf_t	grphdl_flags_buf;
199	Lm_list		*lml = ghp->gh_ownlml;
200	const char	*str;
201
202	if (DBG_NOTCLASS(DBG_C_FILES))
203		return;
204	if (DBG_NOTDETAIL())
205		return;
206
207	if (ghp->gh_ownlmp)
208		str = NAME(ghp->gh_ownlmp);
209	else
210		str = MSG_INTL(MSG_STR_ORPHAN);
211
212	if (hdl_title) {
213		hdl_title = 0;
214		Dbg_util_nl(lml, DBG_NL_STD);
215	}
216	if (name)
217		dbg_print(lml, MSG_INTL(MSG_FIL_HDL_RETAIN), str, name);
218	else
219		dbg_print(lml, MSG_INTL(MSG_FIL_HDL_COLLECT), str,
220		    conv_grphdl_flags(ghp->gh_flags, &grphdl_flags_buf));
221}
222
223void
224Dbg_file_hdl_action(Grp_hdl *ghp, Rt_map *lmp, int type, uint_t flags)
225{
226	Conv_grpdesc_flags_buf_t grpdesc_flags_buf;
227	const char	*mode, *group;
228	Lm_list		*lml = LIST(lmp);
229	Msg		str;
230
231	static const Msg fmt[] = {
232		MSG_FIL_DEP_ADD,	/* MSG_INTL(MSG_FIL_DEP_ADD) */
233		MSG_FIL_DEP_UPDATE,	/* MSG_INTL(MSG_FIL_DEP_UPDATE) */
234		MSG_FIL_DEP_DELETE,	/* MSG_INTL(MSG_FIL_DEP_DELETE) */
235		MSG_FIL_DEP_REMOVE,	/* MSG_INTL(MSG_FIL_DEP_REMOVE) */
236		MSG_FIL_DEP_REMAIN,	/* MSG_INTL(MSG_FIL_DEP_REMAIN) */
237		MSG_FIL_DEP_ORPHAN,	/* MSG_INTL(MSG_FIL_DEP_ORPHAN) */
238		MSG_FIL_DEP_REINST,	/* MSG_INTL(MSG_FIL_DEP_REINST) */
239	};
240	if (DBG_NOTCLASS(DBG_C_FILES))
241		return;
242	if (DBG_NOTDETAIL())
243		return;
244
245	if (hdl_title) {
246		Dbg_util_nl(lml, DBG_NL_STD);
247		if (hdl_str) {
248			Conv_grphdl_flags_buf_t grphdl_flags_buf;
249			const char	*name;
250
251			/*
252			 * Protect ourselves in case this handle has no
253			 * originating owner.
254			 */
255			if (ghp->gh_ownlmp)
256				name = NAME(ghp->gh_ownlmp);
257			else
258				name = MSG_INTL(MSG_STR_UNKNOWN);
259
260			dbg_print(lml, MSG_INTL(hdl_str), name,
261			    conv_grphdl_flags(ghp->gh_flags, &grphdl_flags_buf),
262			    EC_NATPTR(ghp));
263		}
264		hdl_title = 0;
265	}
266
267	/*
268	 * Establish a binding descriptor format string.
269	 */
270	if (type > DBG_DEP_REINST)
271		return;
272
273	str = fmt[type];
274
275	if (((type == DBG_DEP_ADD) || (type == DBG_DEP_UPDATE)) && flags)
276		group = conv_grpdesc_flags(flags, &grpdesc_flags_buf);
277	else
278		group = MSG_ORIG(MSG_STR_EMPTY);
279
280	if ((MODE(lmp) & (RTLD_GLOBAL | RTLD_NODELETE)) ==
281	    (RTLD_GLOBAL | RTLD_NODELETE))
282		mode = MSG_ORIG(MSG_MODE_GLOBNODEL);
283	else if (MODE(lmp) & RTLD_GLOBAL)
284		mode = MSG_ORIG(MSG_MODE_GLOB);
285	else if (MODE(lmp) & RTLD_NODELETE)
286		mode = MSG_ORIG(MSG_MODE_NODEL);
287	else
288		mode = MSG_ORIG(MSG_STR_EMPTY);
289
290	dbg_print(lml, MSG_INTL(str), NAME(lmp), mode, group);
291}
292
293void
294Dbg_file_bind_entry(Lm_list *lml, Bnd_desc *bdp)
295{
296	Conv_bnd_type_buf_t bnd_type_buf;
297
298	if (DBG_NOTCLASS(DBG_C_FILES))
299		return;
300	if (DBG_NOTDETAIL())
301		return;
302
303	/*
304	 * Print the dependency together with the modes of the binding.
305	 */
306	Dbg_util_nl(lml, DBG_NL_STD);
307	dbg_print(lml, MSG_INTL(MSG_FIL_BND_ADD), NAME(bdp->b_caller));
308	dbg_print(lml, MSG_INTL(MSG_FIL_BND_FILE), NAME(bdp->b_depend),
309	    conv_bnd_type(bdp->b_flags, &bnd_type_buf));
310}
311
312void
313Dbg_file_bindings(Rt_map *lmp, int flag)
314{
315	Conv_bnd_obj_buf_t	bnd_obj_buf;
316	Conv_bnd_type_buf_t	bnd_type_buf;
317	const char	*str;
318	Rt_map		*tlmp;
319	Lm_list		*lml = LIST(lmp);
320	int		next = 0;
321
322	if (DBG_NOTCLASS(DBG_C_INIT))
323		return;
324	if (DBG_NOTDETAIL())
325		return;
326
327	if (flag & RT_SORT_REV)
328		str = MSG_ORIG(MSG_SCN_INIT);
329	else
330		str = MSG_ORIG(MSG_SCN_FINI);
331
332	Dbg_util_nl(lml, DBG_NL_STD);
333	dbg_print(lml, MSG_INTL(MSG_FIL_DEP_TITLE), str,
334	    conv_bnd_obj(lml->lm_flags, &bnd_obj_buf));
335
336	/* LINTED */
337	for (tlmp = lmp; tlmp; tlmp = (Rt_map *)NEXT(tlmp)) {
338		Bnd_desc	*bdp;
339		Aliste		idx;
340
341		/*
342		 * For .init processing, only collect objects that have been
343		 * relocated and haven't already been collected.
344		 * For .fini processing, only collect objects that have had
345		 * their .init collected, and haven't already been .fini
346		 * collected.
347		 */
348		if (flag & RT_SORT_REV) {
349			if ((FLAGS(tlmp) & (FLG_RT_RELOCED |
350			    FLG_RT_INITCLCT)) != FLG_RT_RELOCED)
351				continue;
352
353		} else {
354			if ((flag & RT_SORT_DELETE) &&
355			    ((FLAGS(tlmp) & FLG_RT_DELETE) == 0))
356				continue;
357			if (((FLAGS(tlmp) &
358			    (FLG_RT_INITCLCT | FLG_RT_FINICLCT)) ==
359			    FLG_RT_INITCLCT) == 0)
360				continue;
361		}
362
363		if (next++)
364			Dbg_util_nl(lml, DBG_NL_STD);
365
366		if (DEPENDS(tlmp) == NULL)
367			dbg_print(lml, MSG_INTL(MSG_FIL_DEP_NONE), NAME(tlmp));
368		else {
369			dbg_print(lml, MSG_INTL(MSG_FIL_DEP_ENT), NAME(tlmp));
370
371			for (APLIST_TRAVERSE(DEPENDS(tlmp), idx, bdp)) {
372				dbg_print(lml, MSG_INTL(MSG_FIL_BND_FILE),
373				    NAME(bdp->b_depend),
374				    conv_bnd_type(bdp->b_flags,
375				    &bnd_type_buf));
376			}
377		}
378	}
379	Dbg_util_nl(lml, DBG_NL_STD);
380}
381
382void
383Dbg_file_bindings_done(Lm_list *lml)
384{
385	if (DBG_NOTCLASS(DBG_C_INIT))
386		return;
387	if (DBG_NOTDETAIL())
388		return;
389
390	DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD));
391}
392
393void
394Dbg_file_dlopen(Rt_map *clmp, const char *name, int *in_nfavl, int mode)
395{
396	Conv_dl_mode_buf_t	dl_mode_buf;
397	Lm_list			*lml = LIST(clmp);
398	const char		*retry;
399
400	if (DBG_NOTCLASS(DBG_C_FILES))
401		return;
402
403	/*
404	 * The core functionality of dlopen() can be called twice.  The first
405	 * attempt can be affected by path names that exist in the "not-found"
406	 * AVL tree.  Should a "not-found" path name be found, a second attempt
407	 * is made to locate the required file (in_nfavl is NULL).  This fall-
408	 * back provides for file system changes while a process executes.
409	 */
410	if (in_nfavl)
411		retry = MSG_ORIG(MSG_STR_EMPTY);
412	else
413		retry = MSG_INTL(MSG_STR_RETRY);
414
415	Dbg_util_nl(lml, DBG_NL_STD);
416	dbg_print(lml, MSG_INTL(MSG_FIL_DLOPEN), name, NAME(clmp), retry,
417	    conv_dl_mode(mode, 0, &dl_mode_buf));
418}
419
420void
421Dbg_file_dlclose(Lm_list *lml, const char *name, int flag)
422{
423	const char	*str;
424
425	if (DBG_NOTCLASS(DBG_C_FILES))
426		return;
427
428	if (flag == DBG_DLCLOSE_IGNORE)
429		str = MSG_INTL(MSG_STR_IGNORE);
430	else
431		str = MSG_ORIG(MSG_STR_EMPTY);
432
433	Dbg_util_nl(lml, DBG_NL_STD);
434	dbg_print(lml, MSG_INTL(MSG_FIL_DLCLOSE), name, str);
435}
436
437void
438Dbg_file_dldump(Rt_map *lmp, const char *path, int flags)
439{
440	Conv_dl_flag_buf_t	dl_flag_buf;
441	Lm_list			*lml = LIST(lmp);
442
443	if (DBG_NOTCLASS(DBG_C_FILES))
444		return;
445
446	Dbg_util_nl(lml, DBG_NL_STD);
447	dbg_print(lml, MSG_INTL(MSG_FIL_DLDUMP), NAME(lmp), path,
448	    conv_dl_flag(flags, 0, &dl_flag_buf));
449}
450
451void
452Dbg_file_lazyload(Rt_map *clmp, const char *fname, const char *sname)
453{
454	Lm_list	*lml = LIST(clmp);
455
456	if (DBG_NOTCLASS(DBG_C_FILES))
457		return;
458
459	Dbg_util_nl(lml, DBG_NL_STD);
460	dbg_print(lml, MSG_INTL(MSG_FIL_LAZYLOAD), fname, NAME(clmp),
461	    Dbg_demangle_name(sname));
462}
463
464void
465Dbg_file_preload(Lm_list *lml, const char *name)
466{
467	if (DBG_NOTCLASS(DBG_C_FILES))
468		return;
469
470	Dbg_util_nl(lml, DBG_NL_STD);
471	dbg_print(lml, MSG_INTL(MSG_FIL_PRELOAD), name);
472}
473
474void
475Dbg_file_needed(Rt_map *lmp, const char *name)
476{
477	Lm_list	*lml = LIST(lmp);
478
479	if (DBG_NOTCLASS(DBG_C_FILES))
480		return;
481
482	Dbg_util_nl(lml, DBG_NL_STD);
483	dbg_print(lml, MSG_INTL(MSG_FIL_NEEDED), name, NAME(lmp));
484}
485
486void
487Dbg_file_filter(Lm_list *lml, const char *filter, const char *filtee,
488    int config)
489{
490	if (DBG_NOTCLASS(DBG_C_FILES))
491		return;
492
493	Dbg_util_nl(lml, DBG_NL_STD);
494	if (config)
495		dbg_print(lml, MSG_INTL(MSG_FIL_FILTER_1), filter, filtee);
496	else
497		dbg_print(lml, MSG_INTL(MSG_FIL_FILTER_2), filter, filtee);
498}
499
500void
501Dbg_file_filtee(Lm_list *lml, const char *filter, const char *filtee, int audit)
502{
503	if (audit) {
504		if (DBG_NOTCLASS(DBG_C_AUDITING | DBG_C_FILES))
505			return;
506
507		Dbg_util_nl(lml, DBG_NL_STD);
508		dbg_print(lml, MSG_INTL(MSG_FIL_FILTEE_3), filtee);
509	} else {
510		if (DBG_NOTCLASS(DBG_C_FILES))
511			return;
512
513		Dbg_util_nl(lml, DBG_NL_STD);
514		if (filter)
515			dbg_print(lml, MSG_INTL(MSG_FIL_FILTEE_1), filtee,
516			    filter);
517		else
518			dbg_print(lml, MSG_INTL(MSG_FIL_FILTEE_2), filtee);
519	}
520}
521
522void
523Dbg_file_fixname(Lm_list *lml, const char *oname, const char *nname)
524{
525	if (DBG_NOTCLASS(DBG_C_FILES))
526		return;
527
528	Dbg_util_nl(lml, DBG_NL_STD);
529	dbg_print(lml, MSG_INTL(MSG_FIL_FIXNAME), oname, nname);
530}
531
532void
533Dbg_file_output(Ofl_desc *ofl)
534{
535	const char	*prefix = MSG_ORIG(MSG_PTH_OBJECT);
536	char		*oname, *nname, *ofile;
537	int		fd;
538
539	if (DBG_NOTCLASS(DBG_C_FILES))
540		return;
541	if (DBG_NOTDETAIL())
542		return;
543
544	/*
545	 * Obtain the present input object filename for concatenation to the
546	 * prefix name.
547	 */
548	oname = (char *)ofl->ofl_name;
549	if ((ofile = strrchr(oname, '/')) == NULL)
550		ofile = oname;
551	else
552		ofile++;
553
554	/*
555	 * Concatenate the prefix with the object filename, open the file and
556	 * write out the present Elf memory image.  As this is debugging we
557	 * ignore all errors.
558	 */
559	if ((nname = malloc(strlen(prefix) + strlen(ofile) + 1)) != 0) {
560		(void) strcpy(nname, prefix);
561		(void) strcat(nname, ofile);
562		if ((fd = open(nname, O_RDWR | O_CREAT | O_TRUNC,
563		    0666)) != -1) {
564			(void) write(fd, ofl->ofl_nehdr, ofl->ofl_size);
565			(void) close(fd);
566		}
567		free(nname);
568	}
569}
570
571void
572Dbg_file_config_dis(Lm_list *lml, const char *config, int features)
573{
574	Conv_config_feat_buf_t	config_feat_buf;
575	const char		*str;
576
577	if (features == 0)
578		return;
579
580	switch (features & ~CONF_FEATMSK) {
581	case DBG_CONF_IGNORE:
582		str = MSG_INTL(MSG_FIL_CONFIG_ERR_1);
583		break;
584	case DBG_CONF_VERSION:
585		str = MSG_INTL(MSG_FIL_CONFIG_ERR_2);
586		break;
587	case DBG_CONF_PRCFAIL:
588		str = MSG_INTL(MSG_FIL_CONFIG_ERR_3);
589		break;
590	case DBG_CONF_CORRUPT:
591		str = MSG_INTL(MSG_FIL_CONFIG_ERR_4);
592		break;
593	case DBG_CONF_ABIMISMATCH:
594		str = MSG_INTL(MSG_FIL_CONFIG_ERR_5);
595		break;
596	default:
597		str = conv_config_feat(features, &config_feat_buf);
598		break;
599	}
600
601	Dbg_util_nl(lml, DBG_NL_FRC);
602	dbg_print(lml, MSG_INTL(MSG_FIL_CONFIG_ERR), config, str);
603	Dbg_util_nl(lml, DBG_NL_FRC);
604}
605
606void
607Dbg_file_config_obj(Lm_list *lml, const char *dir, const char *file,
608    const char *config)
609{
610	char	*name, _name[PATH_MAX];
611
612	if (DBG_NOTCLASS(DBG_C_FILES))
613		return;
614
615	if (file) {
616		(void) snprintf(_name, PATH_MAX, MSG_ORIG(MSG_FMT_PATH),
617		    dir, file);
618		name = _name;
619	} else
620		name = (char *)dir;
621
622	dbg_print(lml, MSG_INTL(MSG_FIL_CONFIG), name, config);
623}
624
625void
626Dbg_file_del_rescan(Lm_list *lml)
627{
628	if (DBG_NOTCLASS(DBG_C_FILES))
629		return;
630
631	Dbg_util_nl(lml, DBG_NL_STD);
632	dbg_print(lml, MSG_INTL(MSG_FIL_DEL_RESCAN));
633}
634
635void
636Dbg_file_mode_promote(Rt_map *lmp, int mode)
637{
638	Conv_dl_mode_buf_t	dl_mode_buf;
639	Lm_list			*lml = LIST(lmp);
640
641	if (DBG_NOTCLASS(DBG_C_FILES))
642		return;
643
644	Dbg_util_nl(lml, DBG_NL_STD);
645	dbg_print(lml, MSG_INTL(MSG_FIL_PROMOTE), NAME(lmp),
646	    conv_dl_mode(mode, 0, &dl_mode_buf));
647	Dbg_util_nl(lml, DBG_NL_STD);
648}
649
650void
651Dbg_file_cntl(Lm_list *lml, Aliste flmco, Aliste tlmco)
652{
653	Lm_cntl	*lmc;
654	Aliste	off;
655
656	if (DBG_NOTCLASS(DBG_C_FILES))
657		return;
658	if (DBG_NOTDETAIL())
659		return;
660
661	Dbg_util_nl(lml, DBG_NL_STD);
662	dbg_print(lml, MSG_INTL(MSG_CNTL_TITLE), EC_XWORD(flmco),
663	    EC_XWORD(tlmco));
664
665	for (ALIST_TRAVERSE_BY_OFFSET(lml->lm_lists, off, lmc)) {
666		Rt_map	*lmp;
667
668		/* LINTED */
669		for (lmp = lmc->lc_head; lmp; lmp = (Rt_map *)NEXT(lmp))
670			dbg_print(lml, MSG_ORIG(MSG_CNTL_ENTRY), EC_XWORD(off),
671			    NAME(lmp));
672	}
673	Dbg_util_nl(lml, DBG_NL_STD);
674}
675
676/*
677 * Report archive rescan operation.
678 *	argv_start_ndx, argv_end_ndx - Index range of command line arguments
679 *		from which archives are to be reprocessed.
680 */
681void
682Dbg_file_ar_rescan(Lm_list *lml, int argv_start_ndx, int argv_end_ndx)
683{
684	if (DBG_NOTCLASS(DBG_C_FILES))
685		return;
686
687	Dbg_util_nl(lml, DBG_NL_STD);
688	dbg_print(lml, MSG_INTL(MSG_FIL_AR_RESCAN),
689	    argv_start_ndx, argv_end_ndx);
690	Dbg_util_nl(lml, DBG_NL_STD);
691}
692
693void
694Dbg_file_ar(Lm_list *lml, const char *name, int again)
695{
696	const char	*str;
697
698	if (DBG_NOTCLASS(DBG_C_FILES))
699		return;
700
701	if (again)
702		str = MSG_INTL(MSG_STR_AGAIN);
703	else
704		str = MSG_ORIG(MSG_STR_EMPTY);
705
706	Dbg_util_nl(lml, DBG_NL_STD);
707	dbg_print(lml, MSG_INTL(MSG_FIL_ARCHIVE), name, str);
708}
709
710void
711Dbg_file_generic(Lm_list *lml, Ifl_desc *ifl)
712{
713	Conv_inv_buf_t inv_buf;
714
715	if (DBG_NOTCLASS(DBG_C_FILES))
716		return;
717
718	Dbg_util_nl(lml, DBG_NL_STD);
719	dbg_print(lml, MSG_INTL(MSG_FIL_BASIC), ifl->ifl_name,
720	    conv_ehdr_type(ifl->ifl_ehdr->e_ident[EI_OSABI],
721	    ifl->ifl_ehdr->e_type, 0, &inv_buf));
722}
723
724static const Msg
725reject[] = {
726	MSG_STR_EMPTY,
727	MSG_REJ_MACH,		/* MSG_INTL(MSG_REJ_MACH) */
728	MSG_REJ_CLASS,		/* MSG_INTL(MSG_REJ_CLASS) */
729	MSG_REJ_DATA,		/* MSG_INTL(MSG_REJ_DATA) */
730	MSG_REJ_TYPE,		/* MSG_INTL(MSG_REJ_TYPE) */
731	MSG_REJ_BADFLAG,	/* MSG_INTL(MSG_REJ_BADFLAG) */
732	MSG_REJ_MISFLAG,	/* MSG_INTL(MSG_REJ_MISFLAG) */
733	MSG_REJ_VERSION,	/* MSG_INTL(MSG_REJ_VERSION) */
734	MSG_REJ_HAL,		/* MSG_INTL(MSG_REJ_HAL) */
735	MSG_REJ_US3,		/* MSG_INTL(MSG_REJ_US3) */
736	MSG_REJ_STR,		/* MSG_INTL(MSG_REJ_STR) */
737	MSG_REJ_UNKFILE,	/* MSG_INTL(MSG_REJ_UNKFILE) */
738	MSG_REJ_UNKCAP,		/* MSG_INTL(MSG_REJ_UNKCAP) */
739	MSG_REJ_HWCAP_1,	/* MSG_INTL(MSG_REJ_HWCAP_1) */
740	MSG_REJ_SFCAP_1,	/* MSG_INTL(MSG_REJ_SFCAP_1) */
741	MSG_REJ_MACHCAP,	/* MSG_INTL(MSG_REJ_MACHCAP) */
742	MSG_REJ_PLATCAP,	/* MSG_INTL(MSG_REJ_PLATCAP) */
743	MSG_REJ_HWCAP_2		/* MSG_INTL(MSG_REJ_HWCAP_2) */
744};
745
746void
747Dbg_file_rejected(Lm_list *lml, Rej_desc *rej, Half mach)
748{
749	Conv_reject_desc_buf_t rej_buf;
750
751	if (DBG_NOTCLASS(DBG_C_FILES))
752		return;
753
754	Dbg_util_nl(lml, DBG_NL_STD);
755	dbg_print(lml, MSG_INTL(reject[rej->rej_type]), rej->rej_name ?
756	    rej->rej_name : MSG_INTL(MSG_STR_UNKNOWN),
757	    conv_reject_desc(rej, &rej_buf, mach));
758	Dbg_util_nl(lml, DBG_NL_STD);
759}
760
761void
762Dbg_file_reuse(Lm_list *lml, const char *nname, const char *oname)
763{
764	if (DBG_NOTCLASS(DBG_C_FILES))
765		return;
766
767	dbg_print(lml, MSG_INTL(MSG_FIL_REUSE), nname, oname);
768}
769
770void
771Dbg_file_skip(Lm_list *lml, const char *oname, const char *nname)
772{
773	if (DBG_NOTCLASS(DBG_C_FILES))
774		return;
775
776	if (oname && strcmp(nname, oname))
777		dbg_print(lml, MSG_INTL(MSG_FIL_SKIP_1), nname, oname);
778	else
779		dbg_print(lml, MSG_INTL(MSG_FIL_SKIP_2), nname);
780}
781
782void
783Dbg_file_modified(Lm_list *lml, const char *obj, const char *oname,
784    const char *nname, int ofd, int nfd, Elf *oelf, Elf *nelf)
785{
786	const char	*str;
787
788	if (DBG_NOTCLASS(DBG_C_FILES | DBG_C_SUPPORT))
789		return;
790	if (DBG_NOTDETAIL())
791		return;
792
793	Dbg_util_nl(lml, DBG_NL_STD);
794	dbg_print(lml, MSG_INTL(MSG_FIL_MODIFIED), oname, obj);
795
796	if (nname != oname)
797		dbg_print(lml, MSG_INTL(MSG_FIL_NAMECHANGE), nname);
798	if (nfd != ofd) {
799		if (nfd == -1)
800			str = MSG_INTL(MSG_FIL_IGNORE);
801		else
802			str = MSG_ORIG(MSG_STR_EMPTY);
803		dbg_print(lml, MSG_INTL(MSG_FIL_FDCHANGE), ofd, nfd, str);
804	}
805	if (nelf != oelf) {
806		if (nelf == 0)
807			str = MSG_INTL(MSG_FIL_IGNORE);
808		else
809			str = MSG_ORIG(MSG_STR_EMPTY);
810		dbg_print(lml, MSG_INTL(MSG_FIL_ELFCHANGE), EC_NATPTR(oelf),
811		    EC_NATPTR(nelf), str);
812	}
813	Dbg_util_nl(lml, DBG_NL_STD);
814}
815
816void
817Dbg_file_cleanup(Lm_list *lml, const char *name, Aliste lmco)
818{
819	if (DBG_NOTCLASS(DBG_C_FILES))
820		return;
821
822	Dbg_util_nl(lml, DBG_NL_STD);
823	dbg_print(lml, MSG_INTL(MSG_FIL_CLEANUP), name, EC_XWORD(lmco));
824}
825