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