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

glibc/2.7/elf/dl-reloc.c

    1: /* Relocate a shared object and resolve its references to other loaded objects.
    2:    Copyright (C) 1995-2004, 2005, 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 <errno.h>
   21: #include <libintl.h>
   22: #include <stdlib.h>
   23: #include <unistd.h>
   24: #include <ldsodefs.h>
   25: #include <sys/mman.h>
   26: #include <sys/param.h>
   27: #include <sys/types.h>
   28: #include "dynamic-link.h"
   29: 
   30: /* Statistics function.  */
   31: #ifdef SHARED
   32: # define bump_num_cache_relocations() ++GL(dl_num_cache_relocations)
   33: #else
   34: # define bump_num_cache_relocations() ((void) 0)
   35: #endif
   36: 
   37: 
   38: /* We are trying to perform a static TLS relocation in MAP, but it was
   39:    dynamically loaded.  This can only work if there is enough surplus in
   40:    the static TLS area already allocated for each running thread.  If this
   41:    object's TLS segment is too big to fit, we fail.  If it fits,
   42:    we set MAP->l_tls_offset and return.
   43:    This function intentionally does not return any value but signals error
   44:    directly, as static TLS should be rare and code handling it should
   45:    not be inlined as much as possible.  */
   46: void
   47: internal_function __attribute_noinline__
   48: _dl_allocate_static_tls (struct link_map *map)
   49: {
   50:   /* If the alignment requirements are too high fail.  */
   51:   if (map->l_tls_align > GL(dl_tls_static_align))
   52:     {
   53:     fail:
   54:       _dl_signal_error (0, map->l_name, NULL, N_("\
   55: cannot allocate memory in static TLS block"));
   56:     }
   57: 
   58: #if TLS_TCB_AT_TP
   59:   size_t freebytes;
   60:   size_t n;
   61:   size_t blsize;
   62: 
   63:   freebytes = GL(dl_tls_static_size) - GL(dl_tls_static_used) - TLS_TCB_SIZE;
   64: 
   65:   blsize = map->l_tls_blocksize + map->l_tls_firstbyte_offset;
   66:   if (freebytes < blsize)
   67:     goto fail;
   68: 
   69:   n = (freebytes - blsize) / map->l_tls_align;
   70: 
   71:   size_t offset = GL(dl_tls_static_used) + (freebytes - n * map->l_tls_align
   72:                                             - map->l_tls_firstbyte_offset);
   73: 
   74:   map->l_tls_offset = GL(dl_tls_static_used) = offset;
   75: #elif TLS_DTV_AT_TP
   76:   size_t used;
   77:   size_t check;
   78: 
   79:   size_t offset = roundup (GL(dl_tls_static_used), map->l_tls_align);
   80:   used = offset + map->l_tls_blocksize;
   81:   check = used;
   82:   /* dl_tls_static_used includes the TCB at the beginning.  */
   83: 
   84:   if (check > GL(dl_tls_static_size))
   85:     goto fail;
   86: 
   87:   map->l_tls_offset = offset;
   88:   GL(dl_tls_static_used) = used;
   89: #else
   90: # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
   91: #endif
   92: 
   93:   /* If the object is not yet relocated we cannot initialize the
   94:      static TLS region.  Delay it.  */
   95:   if (map->l_real->l_relocated)
   96:     {
   97: #ifdef SHARED
   98:       if (__builtin_expect (THREAD_DTV()[0].counter != GL(dl_tls_generation),
   99:                             0))
  100:         /* Update the slot information data for at least the generation of
  101:            the DSO we are allocating data for.  */
  102:         (void) _dl_update_slotinfo (map->l_tls_modid);
  103: #endif
  104: 
  105:       GL(dl_init_static_tls) (map);
  106:     }
  107:   else
  108:     map->l_need_tls_init = 1;
  109: }
  110: 
  111: /* Initialize static TLS area and DTV for current (only) thread.
  112:    libpthread implementations should provide their own hook
  113:    to handle all threads.  */
  114: void
  115: _dl_nothread_init_static_tls (struct link_map *map)
  116: {
  117: #if TLS_TCB_AT_TP
  118:   void *dest = (char *) THREAD_SELF - map->l_tls_offset;
  119: #elif TLS_DTV_AT_TP
  120:   void *dest = (char *) THREAD_SELF + map->l_tls_offset + TLS_PRE_TCB_SIZE;
  121: #else
  122: # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
  123: #endif
  124: 
  125:   /* Fill in the DTV slot so that a later LD/GD access will find it.  */
  126:   dtv_t *dtv = THREAD_DTV ();
  127:   assert (map->l_tls_modid <= dtv[-1].counter);
  128:   dtv[map->l_tls_modid].pointer.val = dest;
  129:   dtv[map->l_tls_modid].pointer.is_static = true;
  130: 
  131:   /* Initialize the memory.  */
  132:   memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size),
  133:           '\0', map->l_tls_blocksize - map->l_tls_initimage_size);
  134: }
  135: 
  136: 
  137: void
  138: _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
  139:                      int lazy, int consider_profiling)
  140: {
  141:   struct textrels
  142:   {
  143:     caddr_t start;
  144:     size_t len;
  145:     int prot;
  146:     struct textrels *next;
  147:   } *textrels = NULL;
  148:   /* Initialize it to make the compiler happy.  */
  149:   const char *errstring = NULL;
  150: 
  151: #ifdef SHARED
  152:   /* If we are auditing, install the same handlers we need for profiling.  */
  153:   consider_profiling |= GLRO(dl_audit) != NULL;
  154: #elif defined PROF
  155:   /* Never use dynamic linker profiling for gprof profiling code.  */
  156: # define consider_profiling 0
  157: #endif
  158: 
  159:   if (l->l_relocated)
  160:     return;
  161: 
  162:   /* If DT_BIND_NOW is set relocate all references in this object.  We
  163:      do not do this if we are profiling, of course.  */
  164:   // XXX Correct for auditing?
  165:   if (!consider_profiling
  166:       && __builtin_expect (l->l_info[DT_BIND_NOW] != NULL, 0))
  167:     lazy = 0;
  168: 
  169:   if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_RELOC, 0))
  170:     _dl_debug_printf ("\nrelocation processing: %s%s\n",
  171:                       l->l_name[0] ? l->l_name : rtld_progname,
  172:                       lazy ? " (lazy)" : "");
  173: 
  174:   /* DT_TEXTREL is now in level 2 and might phase out at some time.
  175:      But we rewrite the DT_FLAGS entry to a DT_TEXTREL entry to make
  176:      testing easier and therefore it will be available at all time.  */
  177:   if (__builtin_expect (l->l_info[DT_TEXTREL] != NULL, 0))
  178:     {
  179:       /* Bletch.  We must make read-only segments writable
  180:          long enough to relocate them.  */
  181:       const ElfW(Phdr) *ph;
  182:       for (ph = l->l_phdr; ph < &l->l_phdr[l->l_phnum]; ++ph)
  183:         if (ph->p_type == PT_LOAD && (ph->p_flags & PF_W) == 0)
  184:           {
  185:             struct textrels *newp;
  186: 
  187:             newp = (struct textrels *) alloca (sizeof (*newp));
  188:             newp->len = (((ph->p_vaddr + ph->p_memsz + GLRO(dl_pagesize) - 1)
  189:                           & ~(GLRO(dl_pagesize) - 1))
  190:                          - (ph->p_vaddr & ~(GLRO(dl_pagesize) - 1)));
  191:             newp->start = ((ph->p_vaddr & ~(GLRO(dl_pagesize) - 1))
  192:                            + (caddr_t) l->l_addr);
  193: 
  194:             if (__mprotect (newp->start, newp->len, PROT_READ|PROT_WRITE) < 0)
  195:               {
  196:                 errstring = N_("cannot make segment writable for relocation");
  197:               call_error:
  198:                 _dl_signal_error (errno, l->l_name, NULL, errstring);
  199:               }
  200: 
  201: #if (PF_R | PF_W | PF_X) == 7 && (PROT_READ | PROT_WRITE | PROT_EXEC) == 7
  202:             newp->prot = (PF_TO_PROT
  203:                           >> ((ph->p_flags & (PF_R | PF_W | PF_X)) * 4)) & 0xf;
  204: #else
  205:             newp->prot = 0;
  206:             if (ph->p_flags & PF_R)
  207:               newp->prot |= PROT_READ;
  208:             if (ph->p_flags & PF_W)
  209:               newp->prot |= PROT_WRITE;
  210:             if (ph->p_flags & PF_X)
  211:               newp->prot |= PROT_EXEC;
  212: #endif
  213:             newp->next = textrels;
  214:             textrels = newp;
  215:           }
  216:     }
  217: 
  218:   {
  219:     /* Do the actual relocation of the object's GOT and other data.  */
  220: 
  221:     /* String table object symbols.  */
  222:     const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
  223: 
  224:     /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */
  225: #define RESOLVE_MAP(ref, version, r_type) \
  226:     (ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL                             \
  227:      ? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0)                \
  228:          && elf_machine_type_class (r_type) == l->l_lookup_cache.type_class)  \
  229:         ? (bump_num_cache_relocations (),                                    \
  230:            (*ref) = l->l_lookup_cache.ret,                                   \
  231:            l->l_lookup_cache.value)                                          \
  232:         : ({ lookup_t _lr;                                                   \
  233:              int _tc = elf_machine_type_class (r_type);                              \
  234:              l->l_lookup_cache.type_class = _tc;                             \
  235:              l->l_lookup_cache.sym = (*ref);                                 \
  236:              const struct r_found_version *v = NULL;                         \
  237:              int flags = DL_LOOKUP_ADD_DEPENDENCY;                           \
  238:              if ((version) != NULL && (version)->hash != 0)                  \
  239:                {                                                             \
  240:                  v = (version);                                                     \
  241:                  flags = 0;                                                 \
  242:                }                                                             \
  243:              _lr = _dl_lookup_symbol_x (strtab + (*ref)->st_name, l, (ref),   \
  244:                                         scope, v, _tc, flags, NULL);             \
  245:              l->l_lookup_cache.ret = (*ref);                                 \
  246:              l->l_lookup_cache.value = _lr; }))                                      \
  247:      : l)
  248: 
  249:     /* This macro is used as a callback from elf_machine_rel{a,} when a
  250:        static TLS reloc is about to be performed.  Since (in dl-load.c) we
  251:        permit dynamic loading of objects that might use such relocs, we
  252:        have to check whether each use is actually doable.  If the object
  253:        whose TLS segment the reference resolves to was allocated space in
  254:        the static TLS block at startup, then it's ok.  Otherwise, we make
  255:        an attempt to allocate it in surplus space on the fly.  If that
  256:        can't be done, we fall back to the error that DF_STATIC_TLS is
  257:        intended to produce.  */
  258: #define CHECK_STATIC_TLS(map, sym_map)                                        \
  259:     do {                                                                      \
  260:       if (__builtin_expect ((sym_map)->l_tls_offset == NO_TLS_OFFSET, 0))     \
  261:         _dl_allocate_static_tls (sym_map);                                   \
  262:     } while (0)
  263: 
  264: #include "dynamic-link.h"
  265: 
  266:     ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling);
  267: 
  268: #ifndef PROF
  269:     if (__builtin_expect (consider_profiling, 0))
  270:       {
  271:         /* Allocate the array which will contain the already found
  272:            relocations.  If the shared object lacks a PLT (for example
  273:            if it only contains lead function) the l_info[DT_PLTRELSZ]
  274:            will be NULL.  */
  275:         if (l->l_info[DT_PLTRELSZ] == NULL)
  276:           {
  277:             errstring = N_("%s: no PLTREL found in object %s\n");
  278:           fatal:
  279:             _dl_fatal_printf (errstring,
  280:                               rtld_progname ?: "<program name unknown>",
  281:                               l->l_name);
  282:           }
  283: 
  284:         l->l_reloc_result = calloc (sizeof (l->l_reloc_result[0]),
  285:                                     l->l_info[DT_PLTRELSZ]->d_un.d_val);
  286:         if (l->l_reloc_result == NULL)
  287:           {
  288:             errstring = N_("\
  289: %s: out of memory to store relocation results for %s\n");
  290:             goto fatal;
  291:           }
  292:       }
  293: #endif
  294:   }
  295: 
  296:   /* Mark the object so we know this work has been done.  */
  297:   l->l_relocated = 1;
  298: 
  299:   /* Undo the segment protection changes.  */
  300:   while (__builtin_expect (textrels != NULL, 0))
  301:     {
  302:       if (__mprotect (textrels->start, textrels->len, textrels->prot) < 0)
  303:         {
  304:           errstring = N_("cannot restore segment prot after reloc");
  305:           goto call_error;
  306:         }
  307: 
  308:       textrels = textrels->next;
  309:     }
  310: 
  311:   /* In case we can protect the data now that the relocations are
  312:      done, do it.  */
  313:   if (l->l_relro_size != 0)
  314:     _dl_protect_relro (l);
  315: }
  316: 
  317: 
  318: void internal_function
  319: _dl_protect_relro (struct link_map *l)
  320: {
  321:   ElfW(Addr) start = ((l->l_addr + l->l_relro_addr)
  322:                       & ~(GLRO(dl_pagesize) - 1));
  323:   ElfW(Addr) end = ((l->l_addr + l->l_relro_addr + l->l_relro_size)
  324:                     & ~(GLRO(dl_pagesize) - 1));
  325: 
  326:   if (start != end
  327:       && __mprotect ((void *) start, end - start, PROT_READ) < 0)
  328:     {
  329:       static const char errstring[] = N_("\
  330: cannot apply additional memory protection after relocation");
  331:       _dl_signal_error (errno, l->l_name, NULL, errstring);
  332:     }
  333: }
  334: 
  335: void
  336: internal_function __attribute_noinline__
  337: _dl_reloc_bad_type (struct link_map *map, unsigned int type, int plt)
  338: {
  339:   extern const char INTUSE(_itoa_lower_digits)[] attribute_hidden;
  340: #define DIGIT(b)        INTUSE(_itoa_lower_digits)[(b) & 0xf];
  341: 
  342:   /* XXX We cannot translate these messages.  */
  343:   static const char msg[2][32
  344: #if __ELF_NATIVE_CLASS == 64
  345:                            + 6
  346: #endif
  347:   ] = { "unexpected reloc type 0x",
  348:         "unexpected PLT reloc type 0x" };
  349:   char msgbuf[sizeof (msg[0])];
  350:   char *cp;
  351: 
  352:   cp = __stpcpy (msgbuf, msg[plt]);
  353: #if __ELF_NATIVE_CLASS == 64
  354:   if (__builtin_expect(type > 0xff, 0))
  355:     {
  356:       *cp++ = DIGIT (type >> 28);
  357:       *cp++ = DIGIT (type >> 24);
  358:       *cp++ = DIGIT (type >> 20);
  359:       *cp++ = DIGIT (type >> 16);
  360:       *cp++ = DIGIT (type >> 12);
  361:       *cp++ = DIGIT (type >> 8);
  362:     }
  363: #endif
  364:   *cp++ = DIGIT (type >> 4);
  365:   *cp++ = DIGIT (type);
  366:   *cp = '\0';
  367: 
  368:   _dl_signal_error (0, map->l_name, NULL, msgbuf);
  369: }
Syntax (Markdown)