1 /* Print diagnostics data in ld.so.
2 Copyright (C) 2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 #include <gnu/lib-names.h>
24 #include <dl-diagnostics.h>
25 #include <dl-hwcaps.h>
27 #include <dl-procinfo.h>
28 #include <dl-sysdep.h>
30 #include "trusted-dirs.h"
33 /* Write CH to standard output. */
37 _dl_write (STDOUT_FILENO
, &ch
, 1);
40 /* Print CH to standard output, quoting it if necessary. */
42 print_quoted_char (char ch
)
44 if (ch
< ' ' || ch
> '~')
48 buf
[1] = '0' + ((ch
>> 6) & 7);
49 buf
[2] = '0' + ((ch
>> 6) & 7);
50 buf
[3] = '0' + (ch
& 7);
51 _dl_write (STDOUT_FILENO
, buf
, 4);
55 if (ch
== '\\' || ch
== '"')
61 /* Print S of LEN bytes to standard output, quoting characters as
64 print_string_length (const char *s
, size_t len
)
67 for (size_t i
= 0; i
< len
; ++i
)
68 print_quoted_char (s
[i
]);
73 _dl_diagnostics_print_string (const char *s
)
84 print_quoted_char (*s
);
91 _dl_diagnostics_print_labeled_string (const char *label
, const char *s
)
93 _dl_printf ("%s=", label
);
94 _dl_diagnostics_print_string (s
);
99 _dl_diagnostics_print_labeled_value (const char *label
, uint64_t value
)
101 if (sizeof (value
) == sizeof (unsigned long int))
102 /* _dl_printf can print 64-bit values directly. */
103 _dl_printf ("%s=0x%lx\n", label
, (unsigned long int) value
);
106 uint32_t high
= value
>> 32;
107 uint32_t low
= value
;
109 _dl_printf ("%s=0x%x\n", label
, low
);
111 _dl_printf ("%s=0x%x%08x\n", label
, high
, low
);
115 /* Return true if ENV is an unfiltered environment variable. */
117 unfiltered_envvar (const char *env
, size_t *name_length
)
119 char *env_equal
= strchr (env
, '=');
120 if (env_equal
== NULL
)
122 /* Always dump malformed entries. */
123 *name_length
= strlen (env
);
126 size_t envname_length
= env_equal
- env
;
127 *name_length
= envname_length
;
129 /* LC_ and LD_ variables. */
130 if (env
[0] == 'L' && (env
[1] == 'C' || env
[1] == 'D')
134 /* MALLOC_ variables. */
135 if (strncmp (env
, "MALLOC_", strlen ("MALLOC_")) == 0)
138 static const char unfiltered
[] =
144 "GMON_OUTPUT_PREFIX\0"
166 /* Two null bytes at the end to mark the end of the list via an
169 for (const char *candidate
= unfiltered
; *candidate
!= '\0'; )
171 size_t candidate_length
= strlen (candidate
);
172 if (candidate_length
== envname_length
173 && memcmp (candidate
, env
, candidate_length
) == 0)
175 candidate
+= candidate_length
+ 1;
181 /* Dump the process environment. */
183 print_environ (char **environ
)
185 unsigned int index
= 0;
186 for (char **envp
= environ
; *envp
!= NULL
; ++envp
)
190 bool unfiltered
= unfiltered_envvar (env
, &name_length
);
191 _dl_printf ("env%s[0x%x]=",
192 unfiltered
? "" : "_filtered", index
);
194 _dl_diagnostics_print_string (env
);
196 print_string_length (env
, name_length
);
202 /* Print configured paths and the built-in search path. */
206 _dl_diagnostics_print_labeled_string ("path.prefix", PREFIX
);
207 _dl_diagnostics_print_labeled_string ("path.rtld", RTLD
);
208 _dl_diagnostics_print_labeled_string ("path.sysconfdir", SYSCONFDIR
);
210 unsigned int index
= 0;
211 static const char *system_dirs
= SYSTEM_DIRS
"\0";
212 for (const char *e
= system_dirs
; *e
!= '\0'; )
214 size_t len
= strlen (e
);
215 _dl_printf ("path.system_dirs[0x%x]=", index
);
216 print_string_length (e
, len
);
223 /* Print information about the glibc version. */
227 _dl_diagnostics_print_labeled_string ("version.release", RELEASE
);
228 _dl_diagnostics_print_labeled_string ("version.version", VERSION
);
232 _dl_print_diagnostics (char **environ
)
234 #ifdef HAVE_DL_DISCOVER_OSVERSION
235 _dl_diagnostics_print_labeled_value
236 ("dl_discover_osversion", _dl_discover_osversion ());
238 _dl_diagnostics_print_labeled_string ("dl_dst_lib", DL_DST_LIB
);
239 _dl_diagnostics_print_labeled_value ("dl_hwcap", GLRO (dl_hwcap
));
240 _dl_diagnostics_print_labeled_value ("dl_hwcap_important", HWCAP_IMPORTANT
);
241 _dl_diagnostics_print_labeled_value ("dl_hwcap2", GLRO (dl_hwcap2
));
242 _dl_diagnostics_print_labeled_string
243 ("dl_hwcaps_subdirs", _dl_hwcaps_subdirs
);
244 _dl_diagnostics_print_labeled_value
245 ("dl_hwcaps_subdirs_active", _dl_hwcaps_subdirs_active ());
246 _dl_diagnostics_print_labeled_value ("dl_osversion", GLRO (dl_osversion
));
247 _dl_diagnostics_print_labeled_value ("dl_pagesize", GLRO (dl_pagesize
));
248 _dl_diagnostics_print_labeled_string ("dl_platform", GLRO (dl_platform
));
249 _dl_diagnostics_print_labeled_string
250 ("dl_profile_output", GLRO (dl_profile_output
));
251 _dl_diagnostics_print_labeled_value
252 ("dl_string_platform", _dl_string_platform ( GLRO (dl_platform
)));
254 _dl_diagnostics_print_labeled_string ("dso.ld", LD_SO
);
255 _dl_diagnostics_print_labeled_string ("dso.libc", LIBC_SO
);
257 print_environ (environ
);
261 _dl_diagnostics_kernel ();
262 _dl_diagnostics_cpu ();
264 _exit (EXIT_SUCCESS
);