(linenum→info "unix/slp.c:2238")

glibc/2.7/elf/dl-misc.c

    1: /* Miscellaneous support functions for dynamic linker
    2:    Copyright (C) 1997-2002, 2003, 2004, 2006 Free Software Foundation, Inc.
    3:    This file is part of the GNU C Library.
    4: 
    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.
    9: 
   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.
   14: 
   15:    You should have received a copy of the GNU Lesser General Public
   16:    License along with the GNU C Library; if not, write to the Free
   17:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   18:    02111-1307 USA.  */
   19: 
   20: #include <assert.h>
   21: #include <fcntl.h>
   22: #include <ldsodefs.h>
   23: #include <limits.h>
   24: #include <link.h>
   25: #include <stdarg.h>
   26: #include <stdlib.h>
   27: #include <string.h>
   28: #include <unistd.h>
   29: #include <sys/mman.h>
   30: #include <sys/param.h>
   31: #include <sys/stat.h>
   32: #include <sys/uio.h>
   33: #include <sysdep.h>
   34: #include <stdio-common/_itoa.h>
   35: #include <bits/libc-lock.h>
   36: 
   37: #ifndef MAP_ANON
   38: /* This is the only dl-sysdep.c function that is actually needed at run-time
   39:    by _dl_map_object.  */
   40: 
   41: int
   42: _dl_sysdep_open_zero_fill (void)
   43: {
   44:   return __open ("/dev/zero", O_RDONLY);
   45: }
   46: #endif
   47: 
   48: /* Read the whole contents of FILE into new mmap'd space with given
   49:    protections.  *SIZEP gets the size of the file.  On error MAP_FAILED
   50:    is returned.  */
   51: 
   52: void *
   53: internal_function
   54: _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
   55: {
   56:   void *result = MAP_FAILED;
   57:   struct stat64 st;
   58:   int fd = __open (file, O_RDONLY);
   59:   if (fd >= 0)
   60:     {
   61:       if (__fxstat64 (_STAT_VER, fd, &st) >= 0)
   62:         {
   63:           *sizep = st.st_size;
   64: 
   65:           /* No need to map the file if it is empty.  */
   66:           if (*sizep != 0)
   67:             /* Map a copy of the file contents.  */
   68:             result = __mmap (NULL, *sizep, prot,
   69: #ifdef MAP_COPY
   70:                              MAP_COPY
   71: #else
   72:                              MAP_PRIVATE
   73: #endif
   74: #ifdef MAP_FILE
   75:                              | MAP_FILE
   76: #endif
   77:                              , fd, 0);
   78:         }
   79:       __close (fd);
   80:     }
   81:   return result;
   82: }
   83: 
   84: 
   85: /* Bare-bones printf implementation.  This function only knows about
   86:    the formats and flags needed and can handle only up to 64 stripes in
   87:    the output.  */
   88: static void
   89: _dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg)
   90: {
   91: # define NIOVMAX 64
   92:   struct iovec iov[NIOVMAX];
   93:   int niov = 0;
   94:   pid_t pid = 0;
   95:   char pidbuf[12];
   96: 
   97:   while (*fmt != '\0')
   98:     {
   99:       const char *startp = fmt;
  100: 
  101:       if (tag_p > 0)
  102:         {
  103:           /* Generate the tag line once.  It consists of the PID and a
  104:              colon followed by a tab.  */
  105:           if (pid == 0)
  106:             {
  107:               char *p;
  108:               pid = __getpid ();
  109:               assert (pid >= 0 && sizeof (pid_t) <= 4);
  110:               p = _itoa (pid, &pidbuf[10], 10, 0);
  111:               while (p > pidbuf)
  112:                 *--p = ' ';
  113:               pidbuf[10] = ':';
  114:               pidbuf[11] = '\t';
  115:             }
  116: 
  117:           /* Append to the output.  */
  118:           assert (niov < NIOVMAX);
  119:           iov[niov].iov_len = 12;
  120:           iov[niov++].iov_base = pidbuf;
  121: 
  122:           /* No more tags until we see the next newline.  */
  123:           tag_p = -1;
  124:         }
  125: 
  126:       /* Skip everything except % and \n (if tags are needed).  */
  127:       while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n'))
  128:         ++fmt;
  129: 
  130:       /* Append constant string.  */
  131:       assert (niov < NIOVMAX);
  132:       if ((iov[niov].iov_len = fmt - startp) != 0)
  133:         iov[niov++].iov_base = (char *) startp;
  134: 
  135:       if (*fmt == '%')
  136:         {
  137:           /* It is a format specifier.  */
  138:           char fill = ' ';
  139:           int width = -1;
  140:           int prec = -1;
  141: #if LONG_MAX != INT_MAX
  142:           int long_mod = 0;
  143: #endif
  144: 
  145:           /* Recognize zero-digit fill flag.  */
  146:           if (*++fmt == '0')
  147:             {
  148:               fill = '0';
  149:               ++fmt;
  150:             }
  151: 
  152:           /* See whether with comes from a parameter.  Note that no other
  153:              way to specify the width is implemented.  */
  154:           if (*fmt == '*')
  155:             {
  156:               width = va_arg (arg, int);
  157:               ++fmt;
  158:             }
  159: 
  160:           /* Handle precision.  */
  161:           if (*fmt == '.' && fmt[1] == '*')
  162:             {
  163:               prec = va_arg (arg, int);
  164:               fmt += 2;
  165:             }
  166: 
  167:           /* Recognize the l modifier.  It is only important on some
  168:              platforms where long and int have a different size.  We
  169:              can use the same code for size_t.  */
  170:           if (*fmt == 'l' || *fmt == 'Z')
  171:             {
  172: #if LONG_MAX != INT_MAX
  173:               long_mod = 1;
  174: #endif
  175:               ++fmt;
  176:             }
  177: 
  178:           switch (*fmt)
  179:             {
  180:               /* Integer formatting.  */
  181:             case 'u':
  182:             case 'x':
  183:               {
  184:                 /* We have to make a difference if long and int have a
  185:                    different size.  */
  186: #if LONG_MAX != INT_MAX
  187:                 unsigned long int num = (long_mod
  188:                                          ? va_arg (arg, unsigned long int)
  189:                                          : va_arg (arg, unsigned int));
  190: #else
  191:                 unsigned long int num = va_arg (arg, unsigned int);
  192: #endif
  193:                 /* We use alloca() to allocate the buffer with the most
  194:                    pessimistic guess for the size.  Using alloca() allows
  195:                    having more than one integer formatting in a call.  */
  196:                 char *buf = (char *) alloca (3 * sizeof (unsigned long int));
  197:                 char *endp = &buf[3 * sizeof (unsigned long int)];
  198:                 char *cp = _itoa (num, endp, *fmt == 'x' ? 16 : 10, 0);
  199: 
  200:                 /* Pad to the width the user specified.  */
  201:                 if (width != -1)
  202:                   while (endp - cp < width)
  203:                     *--cp = fill;
  204: 
  205:                 iov[niov].iov_base = cp;
  206:                 iov[niov].iov_len = endp - cp;
  207:                 ++niov;
  208:               }
  209:               break;
  210: 
  211:             case 's':
  212:               /* Get the string argument.  */
  213:               iov[niov].iov_base = va_arg (arg, char *);
  214:               iov[niov].iov_len = strlen (iov[niov].iov_base);
  215:               if (prec != -1)
  216:                 iov[niov].iov_len = MIN ((size_t) prec, iov[niov].iov_len);
  217:               ++niov;
  218:               break;
  219: 
  220:             case '%':
  221:               iov[niov].iov_base = (void *) fmt;
  222:               iov[niov].iov_len = 1;
  223:               ++niov;
  224:               break;
  225: 
  226:             default:
  227:               assert (! "invalid format specifier");
  228:             }
  229:           ++fmt;
  230:         }
  231:       else if (*fmt == '\n')
  232:         {
  233:           /* See whether we have to print a single newline character.  */
  234:           if (fmt == startp)
  235:             {
  236:               iov[niov].iov_base = (char *) startp;
  237:               iov[niov++].iov_len = 1;
  238:             }
  239:           else
  240:             /* No, just add it to the rest of the string.  */
  241:             ++iov[niov - 1].iov_len;
  242: 
  243:           /* Next line, print a tag again.  */
  244:           tag_p = 1;
  245:           ++fmt;
  246:         }
  247:     }
  248: 
  249:   /* Finally write the result.  */
  250: #ifdef HAVE_INLINED_SYSCALLS
  251:   INTERNAL_SYSCALL_DECL (err);
  252:   INTERNAL_SYSCALL (writev, err, 3, fd, &iov, niov);
  253: #elif RTLD_PRIVATE_ERRNO
  254:   /* We have to take this lock just to be sure we don't clobber the private
  255:      errno when it's being used by another thread that cares about it.
  256:      Yet we must be sure not to try calling the lock functions before
  257:      the thread library is fully initialized.  */
  258:   if (__builtin_expect (INTUSE (_dl_starting_up), 0))
  259:     __writev (fd, iov, niov);
  260:   else
  261:     {
  262:       __rtld_lock_lock_recursive (GL(dl_load_lock));
  263:       __writev (fd, iov, niov);
  264:       __rtld_lock_unlock_recursive (GL(dl_load_lock));
  265:     }
  266: #else
  267:   __writev (fd, iov, niov);
  268: #endif
  269: }
  270: 
  271: 
  272: /* Write to debug file.  */
  273: void
  274: _dl_debug_printf (const char *fmt, ...)
  275: {
  276:   va_list arg;
  277: 
  278:   va_start (arg, fmt);
  279:   _dl_debug_vdprintf (GLRO(dl_debug_fd), 1, fmt, arg);
  280:   va_end (arg);
  281: }
  282: 
  283: 
  284: /* Write to debug file but don't start with a tag.  */
  285: void
  286: _dl_debug_printf_c (const char *fmt, ...)
  287: {
  288:   va_list arg;
  289: 
  290:   va_start (arg, fmt);
  291:   _dl_debug_vdprintf (GLRO(dl_debug_fd), -1, fmt, arg);
  292:   va_end (arg);
  293: }
  294: 
  295: 
  296: /* Write the given file descriptor.  */
  297: void
  298: _dl_dprintf (int fd, const char *fmt, ...)
  299: {
  300:   va_list arg;
  301: 
  302:   va_start (arg, fmt);
  303:   _dl_debug_vdprintf (fd, 0, fmt, arg);
  304:   va_end (arg);
  305: }
  306: 
  307: 
  308: /* Test whether given NAME matches any of the names of the given object.  */
  309: int
  310: internal_function
  311: _dl_name_match_p (const char *name, const struct link_map *map)
  312: {
  313:   if (strcmp (name, map->l_name) == 0)
  314:     return 1;
  315: 
  316:   struct libname_list *runp = map->l_libname;
  317: 
  318:   while (runp != NULL)
  319:     if (strcmp (name, runp->name) == 0)
  320:       return 1;
  321:     else
  322:       runp = runp->next;
  323: 
  324:   return 0;
  325: }
Syntax (Markdown)