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