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

glibc/2.7/elf/do-rel.h

    1: /* Do relocations for ELF dynamic linking.
    2:    Copyright (C) 1995-2003, 2004 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: /* This file may be included twice, to define both
   21:    `elf_dynamic_do_rel' and `elf_dynamic_do_rela'.  */
   22: 
   23: #ifdef DO_RELA
   24: # define elf_dynamic_do_rel             elf_dynamic_do_rela
   25: # define RELCOUNT_IDX                   VERSYMIDX (DT_RELACOUNT)
   26: # define Rel                            Rela
   27: # define elf_machine_rel                elf_machine_rela
   28: # define elf_machine_rel_relative       elf_machine_rela_relative
   29: #else
   30: # define RELCOUNT_IDX                   VERSYMIDX (DT_RELCOUNT)
   31: #endif
   32: 
   33: #ifndef DO_ELF_MACHINE_REL_RELATIVE
   34: # define DO_ELF_MACHINE_REL_RELATIVE(map, l_addr, relative) \
   35:   elf_machine_rel_relative (l_addr, relative,                                 \
   36:                             (void *) (l_addr + relative->r_offset))
   37: #endif
   38: 
   39: #ifndef VERSYMIDX
   40: # define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym))
   41: #endif
   42: #ifndef VALIDX
   43: # define VALIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
   44:                       + DT_EXTRANUM + DT_VALTAGIDX (tag))
   45: #endif
   46: 
   47: /* Perform the relocations in MAP on the running program image as specified
   48:    by RELTAG, SZTAG.  If LAZY is nonzero, this is the first pass on PLT
   49:    relocations; they should be set up to call _dl_runtime_resolve, rather
   50:    than fully resolved now.  */
   51: 
   52: auto inline void __attribute__ ((always_inline))
   53: elf_dynamic_do_rel (struct link_map *map,
   54:                     ElfW(Addr) reladdr, ElfW(Addr) relsize,
   55:                     int lazy)
   56: {
   57:   const ElfW(Rel) *r = (const void *) reladdr;
   58:   const ElfW(Rel) *end = (const void *) (reladdr + relsize);
   59:   ElfW(Addr) l_addr = map->l_addr;
   60: 
   61: #if (!defined DO_RELA || !defined ELF_MACHINE_PLT_REL) && !defined RTLD_BOOTSTRAP
   62:   /* We never bind lazily during ld.so bootstrap.  Unfortunately gcc is
   63:      not clever enough to see through all the function calls to realize
   64:      that.  */
   65:   if (lazy)
   66:     {
   67:       /* Doing lazy PLT relocations; they need very little info.  */
   68:       for (; r < end; ++r)
   69:         elf_machine_lazy_rel (map, l_addr, r);
   70:     }
   71:   else
   72: #endif
   73:     {
   74:       const ElfW(Sym) *const symtab =
   75:         (const void *) D_PTR (map, l_info[DT_SYMTAB]);
   76:       ElfW(Word) nrelative = (map->l_info[RELCOUNT_IDX] == NULL
   77:                               ? 0 : map->l_info[RELCOUNT_IDX]->d_un.d_val);
   78:       const ElfW(Rel) *relative = r;
   79:       r = r + MIN (nrelative, relsize / sizeof (ElfW(Rel)));
   80: 
   81: #ifndef RTLD_BOOTSTRAP
   82:       /* This is defined in rtld.c, but nowhere in the static libc.a; make
   83:          the reference weak so static programs can still link.  This
   84:          declaration cannot be done when compiling rtld.c (i.e. #ifdef
   85:          RTLD_BOOTSTRAP) because rtld.c contains the common defn for
   86:          _dl_rtld_map, which is incompatible with a weak decl in the same
   87:          file.  */
   88: # ifndef SHARED
   89:       weak_extern (GL(dl_rtld_map));
   90: # endif
   91:       if (map != &GL(dl_rtld_map)) /* Already done in rtld itself.  */
   92: # if !defined DO_RELA || defined ELF_MACHINE_REL_RELATIVE
   93:         /* Rela platforms get the offset from r_addend and this must
   94:            be copied in the relocation address.  Therefore we can skip
   95:            the relative relocations only if this is for rel
   96:            relocations or rela relocations if they are computed as
   97:            memory_loc += l_addr...  */
   98:         if (l_addr != 0)
   99: # else
  100:         /* ...or we know the object has been prelinked.  */
  101:         if (l_addr != 0 || ! map->l_info[VALIDX(DT_GNU_PRELINKED)])
  102: # endif
  103: #endif
  104:           for (; relative < r; ++relative)
  105:             DO_ELF_MACHINE_REL_RELATIVE (map, l_addr, relative);
  106: 
  107: #ifdef RTLD_BOOTSTRAP
  108:       /* The dynamic linker always uses versioning.  */
  109:       assert (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL);
  110: #else
  111:       if (map->l_info[VERSYMIDX (DT_VERSYM)])
  112: #endif
  113:         {
  114:           const ElfW(Half) *const version =
  115:             (const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
  116: 
  117:           for (; r < end; ++r)
  118:             {
  119:               ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
  120:               elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)],
  121:                                &map->l_versions[ndx],
  122:                                (void *) (l_addr + r->r_offset));
  123:             }
  124:         }
  125: #ifndef RTLD_BOOTSTRAP
  126:       else
  127:         for (; r < end; ++r)
  128:           elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
  129:                            (void *) (l_addr + r->r_offset));
  130: #endif
  131:     }
  132: }
  133: 
  134: #undef elf_dynamic_do_rel
  135: #undef Rel
  136: #undef elf_machine_rel
  137: #undef elf_machine_rel_relative
  138: #undef DO_ELF_MACHINE_REL_RELATIVE
  139: #undef RELCOUNT_IDX
Syntax (Markdown)