]> sourceware.org Git - glibc.git/commitdiff
elf: Split dl-printf.c from dl-misc.c
authorFlorian Weimer <fweimer@redhat.com>
Fri, 14 Jan 2022 19:16:05 +0000 (20:16 +0100)
committerFlorian Weimer <fweimer@redhat.com>
Fri, 14 Jan 2022 19:17:05 +0000 (20:17 +0100)
This allows to use different compiler flags for the diagnostics
code.

Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
elf/Makefile
elf/dl-misc.c
elf/dl-printf.c [new file with mode: 0644]

index 3065efc485380937392a8c3193bf548fc957f21f..3df49742ff249c4f3c6011583488aa5ea2b65908 100644 (file)
@@ -69,6 +69,7 @@ dl-routines = \
   dl-object \
   dl-open \
   dl-origin \
+  dl-printf \
   dl-profile \
   dl-reloc \
   dl-runtime \
index 452b79de4a0277c38d7cca5600cfdcde19de6fe9..6f40c288205438ea788614d6c47832aa2bba6c58 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <assert.h>
+#include <_itoa.h>
 #include <fcntl.h>
 #include <ldsodefs.h>
-#include <limits.h>
 #include <link.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
+#include <not-cancel.h>
 #include <stdint.h>
+#include <stdlib.h>
 #include <sys/mman.h>
-#include <sys/param.h>
 #include <sys/stat.h>
-#include <sys/uio.h>
-#include <sysdep.h>
-#include <_itoa.h>
-#include <dl-writev.h>
-#include <not-cancel.h>
+#include <unistd.h>
 
 /* Read the whole contents of FILE into new mmap'd space with given
    protections.  *SIZEP gets the size of the file.  On error MAP_FAILED
@@ -70,270 +62,6 @@ _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
   return result;
 }
 
-
-/* Bare-bones printf implementation.  This function only knows about
-   the formats and flags needed and can handle only up to 64 stripes in
-   the output.  */
-static void
-_dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg)
-{
-# define NIOVMAX 64
-  struct iovec iov[NIOVMAX];
-  int niov = 0;
-  pid_t pid = 0;
-  char pidbuf[12];
-
-  while (*fmt != '\0')
-    {
-      const char *startp = fmt;
-
-      if (tag_p > 0)
-       {
-         /* Generate the tag line once.  It consists of the PID and a
-            colon followed by a tab.  */
-         if (pid == 0)
-           {
-             char *p;
-             pid = __getpid ();
-             assert (pid >= 0 && sizeof (pid_t) <= 4);
-             p = _itoa (pid, &pidbuf[10], 10, 0);
-             while (p > pidbuf)
-               *--p = ' ';
-             pidbuf[10] = ':';
-             pidbuf[11] = '\t';
-           }
-
-         /* Append to the output.  */
-         assert (niov < NIOVMAX);
-         iov[niov].iov_len = 12;
-         iov[niov++].iov_base = pidbuf;
-
-         /* No more tags until we see the next newline.  */
-         tag_p = -1;
-       }
-
-      /* Skip everything except % and \n (if tags are needed).  */
-      while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n'))
-       ++fmt;
-
-      /* Append constant string.  */
-      assert (niov < NIOVMAX);
-      if ((iov[niov].iov_len = fmt - startp) != 0)
-       iov[niov++].iov_base = (char *) startp;
-
-      if (*fmt == '%')
-       {
-         /* It is a format specifier.  */
-         char fill = ' ';
-         int width = -1;
-         int prec = -1;
-#if LONG_MAX != INT_MAX
-         int long_mod = 0;
-#endif
-
-         /* Recognize zero-digit fill flag.  */
-         if (*++fmt == '0')
-           {
-             fill = '0';
-             ++fmt;
-           }
-
-         /* See whether with comes from a parameter.  Note that no other
-            way to specify the width is implemented.  */
-         if (*fmt == '*')
-           {
-             width = va_arg (arg, int);
-             ++fmt;
-           }
-
-         /* Handle precision.  */
-         if (*fmt == '.' && fmt[1] == '*')
-           {
-             prec = va_arg (arg, int);
-             fmt += 2;
-           }
-
-         /* Recognize the l modifier.  It is only important on some
-            platforms where long and int have a different size.  We
-            can use the same code for size_t.  */
-         if (*fmt == 'l' || *fmt == 'Z')
-           {
-#if LONG_MAX != INT_MAX
-             long_mod = 1;
-#endif
-             ++fmt;
-           }
-
-         switch (*fmt)
-           {
-             /* Integer formatting.  */
-           case 'd':
-           case 'u':
-           case 'x':
-             {
-               /* We have to make a difference if long and int have a
-                  different size.  */
-#if LONG_MAX != INT_MAX
-               unsigned long int num = (long_mod
-                                        ? va_arg (arg, unsigned long int)
-                                        : va_arg (arg, unsigned int));
-#else
-               unsigned long int num = va_arg (arg, unsigned int);
-#endif
-               bool negative = false;
-               if (*fmt == 'd')
-                 {
-#if LONG_MAX != INT_MAX
-                   if (long_mod)
-                     {
-                       if ((long int) num < 0)
-                         negative = true;
-                     }
-                   else
-                     {
-                       if ((int) num < 0)
-                         {
-                           num = (unsigned int) num;
-                           negative = true;
-                         }
-                     }
-#else
-                   if ((int) num < 0)
-                     negative = true;
-#endif
-                 }
-
-               /* We use alloca() to allocate the buffer with the most
-                  pessimistic guess for the size.  Using alloca() allows
-                  having more than one integer formatting in a call.  */
-               char *buf = (char *) alloca (1 + 3 * sizeof (unsigned long int));
-               char *endp = &buf[1 + 3 * sizeof (unsigned long int)];
-               char *cp = _itoa (num, endp, *fmt == 'x' ? 16 : 10, 0);
-
-               /* Pad to the width the user specified.  */
-               if (width != -1)
-                 while (endp - cp < width)
-                   *--cp = fill;
-
-               if (negative)
-                 *--cp = '-';
-
-               iov[niov].iov_base = cp;
-               iov[niov].iov_len = endp - cp;
-               ++niov;
-             }
-             break;
-
-           case 's':
-             /* Get the string argument.  */
-             iov[niov].iov_base = va_arg (arg, char *);
-             iov[niov].iov_len = strlen (iov[niov].iov_base);
-             if (prec != -1)
-               iov[niov].iov_len = MIN ((size_t) prec, iov[niov].iov_len);
-             ++niov;
-             break;
-
-           case '%':
-             iov[niov].iov_base = (void *) fmt;
-             iov[niov].iov_len = 1;
-             ++niov;
-             break;
-
-           default:
-             assert (! "invalid format specifier");
-           }
-         ++fmt;
-       }
-      else if (*fmt == '\n')
-       {
-         /* See whether we have to print a single newline character.  */
-         if (fmt == startp)
-           {
-             iov[niov].iov_base = (char *) startp;
-             iov[niov++].iov_len = 1;
-           }
-         else
-           /* No, just add it to the rest of the string.  */
-           ++iov[niov - 1].iov_len;
-
-         /* Next line, print a tag again.  */
-         tag_p = 1;
-         ++fmt;
-       }
-    }
-
-  /* Finally write the result.  */
-  _dl_writev (fd, iov, niov);
-}
-
-
-/* Write to debug file.  */
-void
-_dl_debug_printf (const char *fmt, ...)
-{
-  va_list arg;
-
-  va_start (arg, fmt);
-  _dl_debug_vdprintf (GLRO(dl_debug_fd), 1, fmt, arg);
-  va_end (arg);
-}
-
-
-/* Write to debug file but don't start with a tag.  */
-void
-_dl_debug_printf_c (const char *fmt, ...)
-{
-  va_list arg;
-
-  va_start (arg, fmt);
-  _dl_debug_vdprintf (GLRO(dl_debug_fd), -1, fmt, arg);
-  va_end (arg);
-}
-
-
-/* Write the given file descriptor.  */
-void
-_dl_dprintf (int fd, const char *fmt, ...)
-{
-  va_list arg;
-
-  va_start (arg, fmt);
-  _dl_debug_vdprintf (fd, 0, fmt, arg);
-  va_end (arg);
-}
-
-void
-_dl_printf (const char *fmt, ...)
-{
-  va_list arg;
-
-  va_start (arg, fmt);
-  _dl_debug_vdprintf (STDOUT_FILENO, 0, fmt, arg);
-  va_end (arg);
-}
-
-void
-_dl_error_printf (const char *fmt, ...)
-{
-  va_list arg;
-
-  va_start (arg, fmt);
-  _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg);
-  va_end (arg);
-}
-
-void
-_dl_fatal_printf (const char *fmt, ...)
-{
-  va_list arg;
-
-  va_start (arg, fmt);
-  _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg);
-  va_end (arg);
-  _exit (127);
-}
-rtld_hidden_def (_dl_fatal_printf)
-
 /* Test whether given NAME matches any of the names of the given object.  */
 int
 _dl_name_match_p (const char *name, const struct link_map *map)
@@ -354,7 +82,6 @@ _dl_name_match_p (const char *name, const struct link_map *map)
   return 0;
 }
 
-
 unsigned long int
 _dl_higher_prime_number (unsigned long int n)
 {
diff --git a/elf/dl-printf.c b/elf/dl-printf.c
new file mode 100644 (file)
index 0000000..d3264ba
--- /dev/null
@@ -0,0 +1,292 @@
+/* printf implementation for the dynamic loader.
+   Copyright (C) 1997-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <_itoa.h>
+#include <assert.h>
+#include <dl-writev.h>
+#include <ldsodefs.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/uio.h>
+#include <unistd.h>
+
+/* Bare-bones printf implementation.  This function only knows about
+   the formats and flags needed and can handle only up to 64 stripes in
+   the output.  */
+static void
+_dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg)
+{
+# define NIOVMAX 64
+  struct iovec iov[NIOVMAX];
+  int niov = 0;
+  pid_t pid = 0;
+  char pidbuf[12];
+
+  while (*fmt != '\0')
+    {
+      const char *startp = fmt;
+
+      if (tag_p > 0)
+       {
+         /* Generate the tag line once.  It consists of the PID and a
+            colon followed by a tab.  */
+         if (pid == 0)
+           {
+             char *p;
+             pid = __getpid ();
+             assert (pid >= 0 && sizeof (pid_t) <= 4);
+             p = _itoa (pid, &pidbuf[10], 10, 0);
+             while (p > pidbuf)
+               *--p = ' ';
+             pidbuf[10] = ':';
+             pidbuf[11] = '\t';
+           }
+
+         /* Append to the output.  */
+         assert (niov < NIOVMAX);
+         iov[niov].iov_len = 12;
+         iov[niov++].iov_base = pidbuf;
+
+         /* No more tags until we see the next newline.  */
+         tag_p = -1;
+       }
+
+      /* Skip everything except % and \n (if tags are needed).  */
+      while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n'))
+       ++fmt;
+
+      /* Append constant string.  */
+      assert (niov < NIOVMAX);
+      if ((iov[niov].iov_len = fmt - startp) != 0)
+       iov[niov++].iov_base = (char *) startp;
+
+      if (*fmt == '%')
+       {
+         /* It is a format specifier.  */
+         char fill = ' ';
+         int width = -1;
+         int prec = -1;
+#if LONG_MAX != INT_MAX
+         int long_mod = 0;
+#endif
+
+         /* Recognize zero-digit fill flag.  */
+         if (*++fmt == '0')
+           {
+             fill = '0';
+             ++fmt;
+           }
+
+         /* See whether with comes from a parameter.  Note that no other
+            way to specify the width is implemented.  */
+         if (*fmt == '*')
+           {
+             width = va_arg (arg, int);
+             ++fmt;
+           }
+
+         /* Handle precision.  */
+         if (*fmt == '.' && fmt[1] == '*')
+           {
+             prec = va_arg (arg, int);
+             fmt += 2;
+           }
+
+         /* Recognize the l modifier.  It is only important on some
+            platforms where long and int have a different size.  We
+            can use the same code for size_t.  */
+         if (*fmt == 'l' || *fmt == 'Z')
+           {
+#if LONG_MAX != INT_MAX
+             long_mod = 1;
+#endif
+             ++fmt;
+           }
+
+         switch (*fmt)
+           {
+             /* Integer formatting.  */
+           case 'd':
+           case 'u':
+           case 'x':
+             {
+               /* We have to make a difference if long and int have a
+                  different size.  */
+#if LONG_MAX != INT_MAX
+               unsigned long int num = (long_mod
+                                        ? va_arg (arg, unsigned long int)
+                                        : va_arg (arg, unsigned int));
+#else
+               unsigned long int num = va_arg (arg, unsigned int);
+#endif
+               bool negative = false;
+               if (*fmt == 'd')
+                 {
+#if LONG_MAX != INT_MAX
+                   if (long_mod)
+                     {
+                       if ((long int) num < 0)
+                         negative = true;
+                     }
+                   else
+                     {
+                       if ((int) num < 0)
+                         {
+                           num = (unsigned int) num;
+                           negative = true;
+                         }
+                     }
+#else
+                   if ((int) num < 0)
+                     negative = true;
+#endif
+                 }
+
+               /* We use alloca() to allocate the buffer with the most
+                  pessimistic guess for the size.  Using alloca() allows
+                  having more than one integer formatting in a call.  */
+               char *buf = (char *) alloca (1 + 3 * sizeof (unsigned long int));
+               char *endp = &buf[1 + 3 * sizeof (unsigned long int)];
+               char *cp = _itoa (num, endp, *fmt == 'x' ? 16 : 10, 0);
+
+               /* Pad to the width the user specified.  */
+               if (width != -1)
+                 while (endp - cp < width)
+                   *--cp = fill;
+
+               if (negative)
+                 *--cp = '-';
+
+               iov[niov].iov_base = cp;
+               iov[niov].iov_len = endp - cp;
+               ++niov;
+             }
+             break;
+
+           case 's':
+             /* Get the string argument.  */
+             iov[niov].iov_base = va_arg (arg, char *);
+             iov[niov].iov_len = strlen (iov[niov].iov_base);
+             if (prec != -1)
+               iov[niov].iov_len = MIN ((size_t) prec, iov[niov].iov_len);
+             ++niov;
+             break;
+
+           case '%':
+             iov[niov].iov_base = (void *) fmt;
+             iov[niov].iov_len = 1;
+             ++niov;
+             break;
+
+           default:
+             assert (! "invalid format specifier");
+           }
+         ++fmt;
+       }
+      else if (*fmt == '\n')
+       {
+         /* See whether we have to print a single newline character.  */
+         if (fmt == startp)
+           {
+             iov[niov].iov_base = (char *) startp;
+             iov[niov++].iov_len = 1;
+           }
+         else
+           /* No, just add it to the rest of the string.  */
+           ++iov[niov - 1].iov_len;
+
+         /* Next line, print a tag again.  */
+         tag_p = 1;
+         ++fmt;
+       }
+    }
+
+  /* Finally write the result.  */
+  _dl_writev (fd, iov, niov);
+}
+
+
+/* Write to debug file.  */
+void
+_dl_debug_printf (const char *fmt, ...)
+{
+  va_list arg;
+
+  va_start (arg, fmt);
+  _dl_debug_vdprintf (GLRO(dl_debug_fd), 1, fmt, arg);
+  va_end (arg);
+}
+
+
+/* Write to debug file but don't start with a tag.  */
+void
+_dl_debug_printf_c (const char *fmt, ...)
+{
+  va_list arg;
+
+  va_start (arg, fmt);
+  _dl_debug_vdprintf (GLRO(dl_debug_fd), -1, fmt, arg);
+  va_end (arg);
+}
+
+
+/* Write the given file descriptor.  */
+void
+_dl_dprintf (int fd, const char *fmt, ...)
+{
+  va_list arg;
+
+  va_start (arg, fmt);
+  _dl_debug_vdprintf (fd, 0, fmt, arg);
+  va_end (arg);
+}
+
+void
+_dl_printf (const char *fmt, ...)
+{
+  va_list arg;
+
+  va_start (arg, fmt);
+  _dl_debug_vdprintf (STDOUT_FILENO, 0, fmt, arg);
+  va_end (arg);
+}
+
+void
+_dl_error_printf (const char *fmt, ...)
+{
+  va_list arg;
+
+  va_start (arg, fmt);
+  _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg);
+  va_end (arg);
+}
+
+void
+_dl_fatal_printf (const char *fmt, ...)
+{
+  va_list arg;
+
+  va_start (arg, fmt);
+  _dl_debug_vdprintf (STDERR_FILENO, 0, fmt, arg);
+  va_end (arg);
+  _exit (127);
+}
+rtld_hidden_def (_dl_fatal_printf)
This page took 0.056731 seconds and 5 git commands to generate.