Back to index

glibc  2.9
Defines | Functions
dl-misc.c File Reference
#include <assert.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 <sys/mman.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/uio.h>
#include <sysdep.h>
#include <stdio-common/_itoa.h>
#include <bits/libc-lock.h>

Go to the source code of this file.

Defines

#define NIOVMAX   64

Functions

int _dl_sysdep_open_zero_fill (void)
void *internal_function _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
static void _dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg)
void _dl_debug_printf (const char *fmt,...)
void _dl_debug_printf_c (const char *fmt,...)
void _dl_dprintf (int fd, const char *fmt,...)
int internal_function _dl_name_match_p (const char *name, const struct link_map *map)

Define Documentation

#define NIOVMAX   64

Function Documentation

void _dl_debug_printf ( const char *  fmt,
  ... 
)

Definition at line 274 of file dl-misc.c.

{
  va_list arg;

  va_start (arg, fmt);
  _dl_debug_vdprintf (GLRO(dl_debug_fd), 1, fmt, arg);
  va_end (arg);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void _dl_debug_printf_c ( const char *  fmt,
  ... 
)

Definition at line 286 of file dl-misc.c.

{
  va_list arg;

  va_start (arg, fmt);
  _dl_debug_vdprintf (GLRO(dl_debug_fd), -1, fmt, arg);
  va_end (arg);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void _dl_debug_vdprintf ( int  fd,
int  tag_p,
const char *  fmt,
va_list  arg 
) [static]

Definition at line 89 of file dl-misc.c.

{
# 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 '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
              /* 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 (3 * sizeof (unsigned long int));
              char *endp = &buf[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;

              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.  */
#ifdef HAVE_INLINED_SYSCALLS
  INTERNAL_SYSCALL_DECL (err);
  INTERNAL_SYSCALL (writev, err, 3, fd, &iov, niov);
#elif RTLD_PRIVATE_ERRNO
  /* We have to take this lock just to be sure we don't clobber the private
     errno when it's being used by another thread that cares about it.
     Yet we must be sure not to try calling the lock functions before
     the thread library is fully initialized.  */
  if (__builtin_expect (INTUSE (_dl_starting_up), 0))
    __writev (fd, iov, niov);
  else
    {
      __rtld_lock_lock_recursive (GL(dl_load_lock));
      __writev (fd, iov, niov);
      __rtld_lock_unlock_recursive (GL(dl_load_lock));
    }
#else
  __writev (fd, iov, niov);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

void _dl_dprintf ( int  fd,
const char *  fmt,
  ... 
)

Definition at line 298 of file dl-misc.c.

{
  va_list arg;

  va_start (arg, fmt);
  _dl_debug_vdprintf (fd, 0, fmt, arg);
  va_end (arg);
}

Here is the call graph for this function:

int internal_function _dl_name_match_p ( const char *  name,
const struct link_map map 
)

Definition at line 311 of file dl-misc.c.

{
  if (strcmp (name, map->l_name) == 0)
    return 1;

  struct libname_list *runp = map->l_libname;

  while (runp != NULL)
    if (strcmp (name, runp->name) == 0)
      return 1;
    else
      runp = runp->next;

  return 0;
}

Here is the caller graph for this function:

Definition at line 42 of file dl-misc.c.

{
  return __open ("/dev/zero", O_RDONLY);
}

Here is the caller graph for this function:

void* internal_function _dl_sysdep_read_whole_file ( const char *  file,
size_t sizep,
int  prot 
)

Definition at line 54 of file dl-misc.c.

{
  void *result = MAP_FAILED;
  struct stat64 st;
  int fd = __open (file, O_RDONLY);
  if (fd >= 0)
    {
      if (__fxstat64 (_STAT_VER, fd, &st) >= 0)
       {
         *sizep = st.st_size;

         /* No need to map the file if it is empty.  */
         if (*sizep != 0)
           /* Map a copy of the file contents.  */
           result = __mmap (NULL, *sizep, prot,
#ifdef MAP_COPY
                          MAP_COPY
#else
                          MAP_PRIVATE
#endif
#ifdef MAP_FILE
                          | MAP_FILE
#endif
                          , fd, 0);
       }
      __close (fd);
    }
  return result;
}