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

glibc/2.7/elf/dl-sysdep.c

    1: /* Operating system support for run-time dynamic linker.  Generic Unix version.
    2:    Copyright (C) 1995-1998, 2000-2006, 2007 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 <elf.h>
   22: #include <errno.h>
   23: #include <fcntl.h>
   24: #include <libintl.h>
   25: #include <stdlib.h>
   26: #include <string.h>
   27: #include <unistd.h>
   28: #include <sys/types.h>
   29: #include <sys/stat.h>
   30: #include <sys/mman.h>
   31: #include <ldsodefs.h>
   32: #include <stdio-common/_itoa.h>
   33: #include <fpu_control.h>
   34: 
   35: #include <entry.h>
   36: #include <dl-machine.h>
   37: #include <dl-procinfo.h>
   38: #include <dl-osinfo.h>
   39: #include <hp-timing.h>
   40: #include <tls.h>
   41: 
   42: #ifdef _DL_FIRST_PLATFORM
   43: # define _DL_FIRST_EXTRA (_DL_FIRST_PLATFORM + _DL_PLATFORMS_COUNT)
   44: #else
   45: # define _DL_FIRST_EXTRA _DL_HWCAP_COUNT
   46: #endif
   47: 
   48: extern char **_environ attribute_hidden;
   49: extern void _end attribute_hidden;
   50: 
   51: /* Protect SUID program against misuse of file descriptors.  */
   52: extern void __libc_check_standard_fds (void);
   53: 
   54: #ifdef NEED_DL_BASE_ADDR
   55: ElfW(Addr) _dl_base_addr;
   56: #endif
   57: int __libc_enable_secure attribute_relro = 0;
   58: INTVARDEF(__libc_enable_secure)
   59: int __libc_multiple_libcs = 0;  /* Defining this here avoids the inclusion
   60:                                    of init-first.  */
   61: /* This variable contains the lowest stack address ever used.  */
   62: void *__libc_stack_end attribute_relro = NULL;
   63: rtld_hidden_data_def(__libc_stack_end)
   64: static ElfW(auxv_t) *_dl_auxv attribute_relro;
   65: 
   66: #ifndef DL_FIND_ARG_COMPONENTS
   67: # define DL_FIND_ARG_COMPONENTS(cookie, argc, argv, envp, auxp) \
   68:   do {                                                                        \
   69:     void **_tmp;                                                              \
   70:     (argc) = *(long int *) cookie;                                            \
   71:     (argv) = (char **) ((long int *) cookie + 1);                             \
   72:     (envp) = (argv) + (argc) + 1;                                             \
   73:     for (_tmp = (void **) (envp); *_tmp; ++_tmp)                              \
   74:       continue;                                                               \
   75:     (auxp) = (void *) ++_tmp;                                                 \
   76:   } while (0)
   77: #endif
   78: 
   79: #ifndef DL_STACK_END
   80: # define DL_STACK_END(cookie) ((void *) (cookie))
   81: #endif
   82: 
   83: ElfW(Addr)
   84: _dl_sysdep_start (void **start_argptr,
   85:                   void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
   86:                                    ElfW(Addr) *user_entry))
   87: {
   88:   const ElfW(Phdr) *phdr = NULL;
   89:   ElfW(Word) phnum = 0;
   90:   ElfW(Addr) user_entry;
   91:   ElfW(auxv_t) *av;
   92: #ifdef HAVE_AUX_SECURE
   93: # define set_seen(tag) (tag)    /* Evaluate for the side effects.  */
   94: # define set_seen_secure() ((void) 0)
   95: #else
   96:   uid_t uid = 0;
   97:   gid_t gid = 0;
   98:   unsigned int seen = 0;
   99: # define set_seen_secure() (seen = -1)
  100: # ifdef HAVE_AUX_XID
  101: #  define set_seen(tag) (tag)   /* Evaluate for the side effects.  */
  102: # else
  103: #  define M(type) (1 << (type))
  104: #  define set_seen(tag) seen |= M ((tag)->a_type)
  105: # endif
  106: #endif
  107: #ifdef NEED_DL_SYSINFO
  108:   uintptr_t new_sysinfo = 0;
  109: #endif
  110: 
  111:   __libc_stack_end = DL_STACK_END (start_argptr);
  112:   DL_FIND_ARG_COMPONENTS (start_argptr, _dl_argc, INTUSE(_dl_argv), _environ,
  113:                           _dl_auxv);
  114: 
  115:   user_entry = (ElfW(Addr)) ENTRY_POINT;
  116:   GLRO(dl_platform) = NULL; /* Default to nothing known about the platform.  */
  117: 
  118:   for (av = _dl_auxv; av->a_type != AT_NULL; set_seen (av++))
  119:     switch (av->a_type)
  120:       {
  121:       case AT_PHDR:
  122:         phdr = (void *) av->a_un.a_val;
  123:         break;
  124:       case AT_PHNUM:
  125:         phnum = av->a_un.a_val;
  126:         break;
  127:       case AT_PAGESZ:
  128:         GLRO(dl_pagesize) = av->a_un.a_val;
  129:         break;
  130:       case AT_ENTRY:
  131:         user_entry = av->a_un.a_val;
  132:         break;
  133: #ifdef NEED_DL_BASE_ADDR
  134:       case AT_BASE:
  135:         _dl_base_addr = av->a_un.a_val;
  136:         break;
  137: #endif
  138: #ifndef HAVE_AUX_SECURE
  139:       case AT_UID:
  140:       case AT_EUID:
  141:         uid ^= av->a_un.a_val;
  142:         break;
  143:       case AT_GID:
  144:       case AT_EGID:
  145:         gid ^= av->a_un.a_val;
  146:         break;
  147: #endif
  148:       case AT_SECURE:
  149: #ifndef HAVE_AUX_SECURE
  150:         seen = -1;
  151: #endif
  152:         INTUSE(__libc_enable_secure) = av->a_un.a_val;
  153:         break;
  154:       case AT_PLATFORM:
  155:         GLRO(dl_platform) = (void *) av->a_un.a_val;
  156:         break;
  157:       case AT_HWCAP:
  158:         GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val;
  159:         break;
  160:       case AT_CLKTCK:
  161:         GLRO(dl_clktck) = av->a_un.a_val;
  162:         break;
  163:       case AT_FPUCW:
  164:         GLRO(dl_fpu_control) = av->a_un.a_val;
  165:         break;
  166: #ifdef NEED_DL_SYSINFO
  167:       case AT_SYSINFO:
  168:         new_sysinfo = av->a_un.a_val;
  169:         break;
  170: #endif
  171: #if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
  172:       case AT_SYSINFO_EHDR:
  173:         GLRO(dl_sysinfo_dso) = (void *) av->a_un.a_val;
  174:         break;
  175: #endif
  176: #ifdef DL_PLATFORM_AUXV
  177:       DL_PLATFORM_AUXV
  178: #endif
  179:       }
  180: 
  181: #ifndef HAVE_AUX_SECURE
  182:   if (seen != -1)
  183:     {
  184:       /* Fill in the values we have not gotten from the kernel through the
  185:          auxiliary vector.  */
  186: # ifndef HAVE_AUX_XID
  187: #  define SEE(UID, var, uid) \
  188:    if ((seen & M (AT_##UID)) == 0) var ^= __get##uid ()
  189:       SEE (UID, uid, uid);
  190:       SEE (EUID, uid, euid);
  191:       SEE (GID, gid, gid);
  192:       SEE (EGID, gid, egid);
  193: # endif
  194: 
  195:       /* If one of the two pairs of IDs does not match this is a setuid
  196:          or setgid run.  */
  197:       INTUSE(__libc_enable_secure) = uid | gid;
  198:     }
  199: #endif
  200: 
  201: #ifndef HAVE_AUX_PAGESIZE
  202:   if (GLRO(dl_pagesize) == 0)
  203:     GLRO(dl_pagesize) = __getpagesize ();
  204: #endif
  205: 
  206: #if defined NEED_DL_SYSINFO
  207:   /* Only set the sysinfo value if we also have the vsyscall DSO.  */
  208:   if (GLRO(dl_sysinfo_dso) != 0 && new_sysinfo)
  209:     GLRO(dl_sysinfo) = new_sysinfo;
  210: #endif
  211: 
  212: #ifdef DL_SYSDEP_INIT
  213:   DL_SYSDEP_INIT;
  214: #endif
  215: 
  216: #ifdef DL_PLATFORM_INIT
  217:   DL_PLATFORM_INIT;
  218: #endif
  219: 
  220:   /* Determine the length of the platform name.  */
  221:   if (GLRO(dl_platform) != NULL)
  222:     GLRO(dl_platformlen) = strlen (GLRO(dl_platform));
  223: 
  224:   if (__sbrk (0) == &_end)
  225:     /* The dynamic linker was run as a program, and so the initial break
  226:        starts just after our bss, at &_end.  The malloc in dl-minimal.c
  227:        will consume the rest of this page, so tell the kernel to move the
  228:        break up that far.  When the user program examines its break, it
  229:        will see this new value and not clobber our data.  */
  230:     __sbrk (GLRO(dl_pagesize)
  231:             - ((&_end - (void *) 0) & (GLRO(dl_pagesize) - 1)));
  232: 
  233:   /* If this is a SUID program we make sure that FDs 0, 1, and 2 are
  234:      allocated.  If necessary we are doing it ourself.  If it is not
  235:      possible we stop the program.  */
  236:   if (__builtin_expect (INTUSE(__libc_enable_secure), 0))
  237:     __libc_check_standard_fds ();
  238: 
  239:   (*dl_main) (phdr, phnum, &user_entry);
  240:   return user_entry;
  241: }
  242: 
  243: void
  244: internal_function
  245: _dl_sysdep_start_cleanup (void)
  246: {
  247: }
  248: 
  249: void
  250: internal_function
  251: _dl_show_auxv (void)
  252: {
  253:   char buf[64];
  254:   ElfW(auxv_t) *av;
  255: 
  256:   /* Terminate string.  */
  257:   buf[63] = '\0';
  258: 
  259:   /* The following code assumes that the AT_* values are encoded
  260:      starting from 0 with AT_NULL, 1 for AT_IGNORE, and all other values
  261:      close by (otherwise the array will be too large).  In case we have
  262:      to support a platform where these requirements are not fulfilled
  263:      some alternative implementation has to be used.  */
  264:   for (av = _dl_auxv; av->a_type != AT_NULL; ++av)
  265:     {
  266:       static const struct
  267:       {
  268:         const char label[20];
  269:         enum { unknown = 0, dec, hex, str, ignore } form;
  270:       } auxvars[] =
  271:         {
  272:           [AT_EXECFD - 2] =            { "AT_EXECFD:       ", dec },
  273:           [AT_PHDR - 2] =              { "AT_PHDR:         0x", hex },
  274:           [AT_PHENT - 2] =             { "AT_PHENT:        ", dec },
  275:           [AT_PHNUM - 2] =             { "AT_PHNUM:        ", dec },
  276:           [AT_PAGESZ - 2] =            { "AT_PAGESZ:       ", dec },
  277:           [AT_BASE - 2] =              { "AT_BASE:         0x", hex },
  278:           [AT_FLAGS - 2] =             { "AT_FLAGS:        0x", hex },
  279:           [AT_ENTRY - 2] =             { "AT_ENTRY:        0x", hex },
  280:           [AT_NOTELF - 2] =            { "AT_NOTELF:       ", hex },
  281:           [AT_UID - 2] =               { "AT_UID:          ", dec },
  282:           [AT_EUID - 2] =              { "AT_EUID:         ", dec },
  283:           [AT_GID - 2] =               { "AT_GID:          ", dec },
  284:           [AT_EGID - 2] =              { "AT_EGID:         ", dec },
  285:           [AT_PLATFORM - 2] =          { "AT_PLATFORM:     ", str },
  286:           [AT_HWCAP - 2] =             { "AT_HWCAP:        ", hex },
  287:           [AT_CLKTCK - 2] =            { "AT_CLKTCK:       ", dec },
  288:           [AT_FPUCW - 2] =             { "AT_FPUCW:        ", hex },
  289:           [AT_DCACHEBSIZE - 2] =       { "AT_DCACHEBSIZE:  0x", hex },
  290:           [AT_ICACHEBSIZE - 2] =       { "AT_ICACHEBSIZE:  0x", hex },
  291:           [AT_UCACHEBSIZE - 2] =       { "AT_UCACHEBSIZE:  0x", hex },
  292:           [AT_IGNOREPPC - 2] =         { "AT_IGNOREPPC", ignore },
  293:           [AT_SECURE - 2] =            { "AT_SECURE:       ", dec },
  294:           [AT_SYSINFO - 2] =           { "AT_SYSINFO:      0x", hex },
  295:           [AT_SYSINFO_EHDR - 2] =      { "AT_SYSINFO_EHDR: 0x", hex },
  296:         };
  297:       unsigned int idx = (unsigned int) (av->a_type - 2);
  298: 
  299:       if ((unsigned int) av->a_type < 2u || auxvars[idx].form == ignore)
  300:         continue;
  301: 
  302:       assert (AT_NULL == 0);
  303:       assert (AT_IGNORE == 1);
  304: 
  305:       if (av->a_type == AT_HWCAP)
  306:         {
  307:           /* This is handled special.  */
  308:           if (_dl_procinfo (av->a_un.a_val) == 0)
  309:             continue;
  310:         }
  311: 
  312:       if (idx < sizeof (auxvars) / sizeof (auxvars[0])
  313:           && auxvars[idx].form != unknown)
  314:         {
  315:           const char *val = (char *) av->a_un.a_val;
  316: 
  317:           if (__builtin_expect (auxvars[idx].form, dec) == dec)
  318:             val = _itoa ((unsigned long int) av->a_un.a_val,
  319:                          buf + sizeof buf - 1, 10, 0);
  320:           else if (__builtin_expect (auxvars[idx].form, hex) == hex)
  321:             val = _itoa ((unsigned long int) av->a_un.a_val,
  322:                          buf + sizeof buf - 1, 16, 0);
  323: 
  324:           _dl_printf ("%s%s\n", auxvars[idx].label, val);
  325: 
  326:           continue;
  327:         }
  328: 
  329:       /* Unknown value: print a generic line.  */
  330:       char buf2[17];
  331:       buf[sizeof (buf2) - 1] = '\0';
  332:       const char *val2 = _itoa ((unsigned long int) av->a_un.a_val,
  333:                                 buf2 + sizeof buf2 - 1, 16, 0);
  334:       const char *val =  _itoa ((unsigned long int) av->a_type,
  335:                                 buf + sizeof buf - 1, 16, 0);
  336:       _dl_printf ("AT_??? (0x%s): 0x%s\n", val, val2);
  337:     }
  338: }
  339: 
  340: 
  341: /* Return an array of useful/necessary hardware capability names.  */
  342: const struct r_strlenpair *
  343: internal_function
  344: _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
  345:                       size_t *max_capstrlen)
  346: {
  347:   /* Determine how many important bits are set.  */
  348:   uint64_t masked = GLRO(dl_hwcap) & GLRO(dl_hwcap_mask);
  349:   size_t cnt = platform != NULL;
  350:   size_t n, m;
  351:   size_t total;
  352:   struct r_strlenpair *temp;
  353:   struct r_strlenpair *result;
  354:   struct r_strlenpair *rp;
  355:   char *cp;
  356: 
  357:   /* Count the number of bits set in the masked value.  */
  358:   for (n = 0; (~((1ULL << n) - 1) & masked) != 0; ++n)
  359:     if ((masked & (1ULL << n)) != 0)
  360:       ++cnt;
  361: 
  362: #if (defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO) && defined SHARED
  363:   /* The system-supplied DSO can contain a note of type 2, vendor "GNU".
  364:      This gives us a list of names to treat as fake hwcap bits.  */
  365: 
  366:   const char *dsocaps = NULL;
  367:   size_t dsocapslen = 0;
  368:   if (GLRO(dl_sysinfo_map) != NULL)
  369:     {
  370:       const ElfW(Phdr) *const phdr = GLRO(dl_sysinfo_map)->l_phdr;
  371:       const ElfW(Word) phnum = GLRO(dl_sysinfo_map)->l_phnum;
  372:       for (uint_fast16_t i = 0; i < phnum; ++i)
  373:         if (phdr[i].p_type == PT_NOTE)
  374:           {
  375:             const ElfW(Addr) start = (phdr[i].p_vaddr
  376:                                       + GLRO(dl_sysinfo_map)->l_addr);
  377:             const struct
  378:             {
  379:               ElfW(Word) vendorlen;
  380:               ElfW(Word) datalen;
  381:               ElfW(Word) type;
  382:             } *note = (const void *) start;
  383:             while ((ElfW(Addr)) (note + 1) - start < phdr[i].p_memsz)
  384:               {
  385: #define ROUND(len) (((len) + sizeof (ElfW(Word)) - 1) & -sizeof (ElfW(Word)))
  386:                 if (note->type == 2
  387:                     && note->vendorlen == sizeof "GNU"
  388:                     && !memcmp ((note + 1), "GNU", sizeof "GNU")
  389:                     && note->datalen > 2 * sizeof (ElfW(Word)) + 2)
  390:                   {
  391:                     const ElfW(Word) *p = ((const void *) (note + 1)
  392:                                            + ROUND (sizeof "GNU"));
  393:                     cnt += *p++;
  394:                     ++p;      /* Skip mask word.  */
  395:                     dsocaps = (const char *) p;
  396:                     dsocapslen = note->datalen - sizeof *p * 2;
  397:                     break;
  398:                   }
  399:                 note = ((const void *) (note + 1)
  400:                         + ROUND (note->vendorlen) + ROUND (note->datalen));
  401:               }
  402:             if (dsocaps != NULL)
  403:               break;
  404:           }
  405:     }
  406: #endif
  407: 
  408:   /* For TLS enabled builds always add 'tls'.  */
  409:   ++cnt;
  410: 
  411:   /* Create temporary data structure to generate result table.  */
  412:   temp = (struct r_strlenpair *) alloca (cnt * sizeof (*temp));
  413:   m = 0;
  414: #if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
  415:   if (dsocaps != NULL)
  416:     {
  417:       const ElfW(Word) mask = ((const ElfW(Word) *) dsocaps)[-1];
  418:       GLRO(dl_hwcap) |= (uint64_t) mask << _DL_FIRST_EXTRA;
  419:       size_t len;
  420:       for (const char *p = dsocaps; p < dsocaps + dsocapslen; p += len + 1)
  421:         {
  422:           uint_fast8_t bit = *p++;
  423:           len = strlen (p);
  424: 
  425:           /* Skip entries that are not enabled in the mask word.  */
  426:           if (__builtin_expect (mask & ((ElfW(Word)) 1 << bit), 1))
  427:             {
  428:               temp[m].str = p;
  429:               temp[m].len = len;
  430:               ++m;
  431:             }
  432:           else
  433:             --cnt;
  434:         }
  435:     }
  436: #endif
  437:   for (n = 0; masked != 0; ++n)
  438:     if ((masked & (1ULL << n)) != 0)
  439:       {
  440:         temp[m].str = _dl_hwcap_string (n);
  441:         temp[m].len = strlen (temp[m].str);
  442:         masked ^= 1ULL << n;
  443:         ++m;
  444:       }
  445:   if (platform != NULL)
  446:     {
  447:       temp[m].str = platform;
  448:       temp[m].len = platform_len;
  449:       ++m;
  450:     }
  451: 
  452:   temp[m].str = "tls";
  453:   temp[m].len = 3;
  454:   ++m;
  455: 
  456:   assert (m == cnt);
  457: 
  458:   /* Determine the total size of all strings together.  */
  459:   if (cnt == 1)
  460:     total = temp[0].len + 1;
  461:   else
  462:     {
  463:       total = temp[0].len + temp[cnt - 1].len + 2;
  464:       if (cnt > 2)
  465:         {
  466:           total <<= 1;
  467:           for (n = 1; n + 1 < cnt; ++n)
  468:             total += temp[n].len + 1;
  469:           if (cnt > 3
  470:               && (cnt >= sizeof (size_t) * 8
  471:                   || total + (sizeof (*result) << 3)
  472:                      >= (1UL << (sizeof (size_t) * 8 - cnt + 3))))
  473:             _dl_signal_error (ENOMEM, NULL, NULL,
  474:                               N_("cannot create capability list"));
  475: 
  476:           total <<= cnt - 3;
  477:         }
  478:     }
  479: 
  480:   /* The result structure: we use a very compressed way to store the
  481:      various combinations of capability names.  */
  482:   *sz = 1 << cnt;
  483:   result = (struct r_strlenpair *) malloc (*sz * sizeof (*result) + total);
  484:   if (result == NULL)
  485:     _dl_signal_error (ENOMEM, NULL, NULL,
  486:                       N_("cannot create capability list"));
  487: 
  488:   if (cnt == 1)
  489:     {
  490:       result[0].str = (char *) (result + *sz);
  491:       result[0].len = temp[0].len + 1;
  492:       result[1].str = (char *) (result + *sz);
  493:       result[1].len = 0;
  494:       cp = __mempcpy ((char *) (result + *sz), temp[0].str, temp[0].len);
  495:       *cp = '/';
  496:       *sz = 2;
  497:       *max_capstrlen = result[0].len;
  498: 
  499:       return result;
  500:     }
  501: 
  502:   /* Fill in the information.  This follows the following scheme
  503:      (indeces from TEMP for four strings):
  504:         entry #0: 0, 1, 2, 3   binary: 1111
  505:               #1: 0, 1, 3              1101
  506:               #2: 0, 2, 3              1011
  507:               #3: 0, 3                 1001
  508:      This allows the representation of all possible combinations of
  509:      capability names in the string.  First generate the strings.  */
  510:   result[1].str = result[0].str = cp = (char *) (result + *sz);
  511: #define add(idx) \
  512:       cp = __mempcpy (__mempcpy (cp, temp[idx].str, temp[idx].len), "/", 1);
  513:   if (cnt == 2)
  514:     {
  515:       add (1);
  516:       add (0);
  517:     }
  518:   else
  519:     {
  520:       n = 1 << (cnt - 1);
  521:       do
  522:         {
  523:           n -= 2;
  524: 
  525:           /* We always add the last string.  */