773cb42610350e26c18e607764a34d7b7efe6d43
[platform/upstream/linaro-glibc.git] / elf / dl-runtime.c
1 /* On-demand PLT fixup for shared objects.
2    Copyright (C) 1995-2014 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, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #define IN_DL_RUNTIME 1         /* This can be tested in dl-machine.h.  */
20
21 #include <alloca.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <sys/param.h>
25 #include <ldsodefs.h>
26 #include <sysdep-cancel.h>
27 #include "dynamic-link.h"
28 #include <tls.h>
29 #include <dl-irel.h>
30
31
32 #if (!defined ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \
33     || ELF_MACHINE_NO_REL
34 # define PLTREL  ElfW(Rela)
35 #else
36 # define PLTREL  ElfW(Rel)
37 #endif
38
39 /* The fixup functions might have need special attributes.  If none
40    are provided define the macro as empty.  */
41 #ifndef ARCH_FIXUP_ATTRIBUTE
42 # define ARCH_FIXUP_ATTRIBUTE
43 #endif
44
45 #ifndef reloc_offset
46 # define reloc_offset reloc_arg
47 # define reloc_index  reloc_arg / sizeof (PLTREL)
48 #endif
49
50
51
52 /* This function is called through a special trampoline from the PLT the
53    first time each PLT entry is called.  We must perform the relocation
54    specified in the PLT of the given shared object, and return the resolved
55    function address to the trampoline, which will restart the original call
56    to that address.  Future calls will bounce directly from the PLT to the
57    function.  */
58
59 DL_FIXUP_VALUE_TYPE
60 __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
61 _dl_fixup (
62 # ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
63            ELF_MACHINE_RUNTIME_FIXUP_ARGS,
64 # endif
65            struct link_map *l, ElfW(Word) reloc_arg)
66 {
67   const ElfW(Sym) *const symtab
68     = (const void *) D_PTR (l, l_info[DT_SYMTAB]);
69   const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
70
71   const PLTREL *const reloc
72     = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
73   const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
74   void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
75   lookup_t result;
76   DL_FIXUP_VALUE_TYPE value;
77
78   /* Sanity check that we're really looking at a PLT relocation.  */
79   assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
80
81    /* Look up the target symbol.  If the normal lookup rules are not
82       used don't look in the global scope.  */
83   if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0)
84     {
85       const struct r_found_version *version = NULL;
86
87       if (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
88         {
89           const ElfW(Half) *vernum =
90             (const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]);
91           ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)] & 0x7fff;
92           version = &l->l_versions[ndx];
93           if (version->hash == 0)
94             version = NULL;
95         }
96
97       /* We need to keep the scope around so do some locking.  This is
98          not necessary for objects which cannot be unloaded or when
99          we are not using any threads (yet).  */
100       int flags = DL_LOOKUP_ADD_DEPENDENCY;
101       if (!RTLD_SINGLE_THREAD_P)
102         {
103           THREAD_GSCOPE_SET_FLAG ();
104           flags |= DL_LOOKUP_GSCOPE_LOCK;
105         }
106
107 #ifdef RTLD_ENABLE_FOREIGN_CALL
108       RTLD_ENABLE_FOREIGN_CALL;
109 #endif
110
111       result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym, l->l_scope,
112                                     version, ELF_RTYPE_CLASS_PLT, flags, NULL);
113
114       /* We are done with the global scope.  */
115       if (!RTLD_SINGLE_THREAD_P)
116         THREAD_GSCOPE_RESET_FLAG ();
117
118 #ifdef RTLD_FINALIZE_FOREIGN_CALL
119       RTLD_FINALIZE_FOREIGN_CALL;
120 #endif
121
122       /* Currently result contains the base load address (or link map)
123          of the object that defines sym.  Now add in the symbol
124          offset.  */
125       value = DL_FIXUP_MAKE_VALUE (result,
126                                    sym ? (LOOKUP_VALUE_ADDRESS (result)
127                                           + sym->st_value) : 0);
128     }
129   else
130     {
131       /* We already found the symbol.  The module (and therefore its load
132          address) is also known.  */
133       value = DL_FIXUP_MAKE_VALUE (l, l->l_addr + sym->st_value);
134       result = l;
135     }
136
137   /* And now perhaps the relocation addend.  */
138   value = elf_machine_plt_value (l, reloc, value);
139
140   if (sym != NULL
141       && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0))
142     value = elf_ifunc_invoke (DL_FIXUP_VALUE_ADDR (value));
143
144   /* Finally, fix up the plt itself.  */
145   if (__glibc_unlikely (GLRO(dl_bind_not)))
146     return value;
147
148   return elf_machine_fixup_plt (l, result, reloc, rel_addr, value);
149 }
150
151 #ifndef PROF
152 DL_FIXUP_VALUE_TYPE
153 __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
154 _dl_profile_fixup (
155 #ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
156                    ELF_MACHINE_RUNTIME_FIXUP_ARGS,
157 #endif
158                    struct link_map *l, ElfW(Word) reloc_arg,
159                    ElfW(Addr) retaddr, void *regs, long int *framesizep)
160 {
161   void (*mcount_fct) (ElfW(Addr), ElfW(Addr)) = INTUSE(_dl_mcount);
162
163   if (l->l_reloc_result == NULL)
164     {
165       /* BZ #14843: ELF_DYNAMIC_RELOCATE is called before l_reloc_result
166          is allocated.  We will get here if ELF_DYNAMIC_RELOCATE calls a
167          resolver function to resolve an IRELATIVE relocation and that
168          resolver calls a function that is not yet resolved (lazy).  For
169          example, the resolver in x86-64 libm.so calls __get_cpu_features
170          defined in libc.so.  Skip audit and resolve the external function
171          in this case.  */
172       *framesizep = -1;
173       return _dl_fixup (
174 # ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
175 #  ifndef ELF_MACHINE_RUNTIME_FIXUP_PARAMS
176 #   error Please define ELF_MACHINE_RUNTIME_FIXUP_PARAMS.
177 #  endif
178                         ELF_MACHINE_RUNTIME_FIXUP_PARAMS,
179 # endif
180                         l, reloc_arg);
181     }
182
183   /* This is the address in the array where we store the result of previous
184      relocations.  */
185   struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
186   DL_FIXUP_VALUE_TYPE *resultp = &reloc_result->addr;
187
188   DL_FIXUP_VALUE_TYPE value = *resultp;
189   if (DL_FIXUP_VALUE_CODE_ADDR (value) == 0)
190     {
191       /* This is the first time we have to relocate this object.  */
192       const ElfW(Sym) *const symtab
193         = (const void *) D_PTR (l, l_info[DT_SYMTAB]);
194       const char *strtab = (const char *) D_PTR (l, l_info[DT_STRTAB]);
195
196       const PLTREL *const reloc
197         = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
198       const ElfW(Sym) *refsym = &symtab[ELFW(R_SYM) (reloc->r_info)];
199       const ElfW(Sym) *defsym = refsym;
200       lookup_t result;
201
202       /* Sanity check that we're really looking at a PLT relocation.  */
203       assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
204
205       /* Look up the target symbol.  If the symbol is marked STV_PROTECTED
206          don't look in the global scope.  */
207       if (__builtin_expect (ELFW(ST_VISIBILITY) (refsym->st_other), 0) == 0)
208         {
209           const struct r_found_version *version = NULL;
210
211           if (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
212             {
213               const ElfW(Half) *vernum =
214                 (const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]);
215               ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)] & 0x7fff;
216               version = &l->l_versions[ndx];
217               if (version->hash == 0)
218                 version = NULL;
219             }
220
221           /* We need to keep the scope around so do some locking.  This is
222              not necessary for objects which cannot be unloaded or when
223              we are not using any threads (yet).  */
224           int flags = DL_LOOKUP_ADD_DEPENDENCY;
225           if (!RTLD_SINGLE_THREAD_P)
226             {
227               THREAD_GSCOPE_SET_FLAG ();
228               flags |= DL_LOOKUP_GSCOPE_LOCK;
229             }
230
231           result = _dl_lookup_symbol_x (strtab + refsym->st_name, l,
232                                         &defsym, l->l_scope, version,
233                                         ELF_RTYPE_CLASS_PLT, flags, NULL);
234
235           /* We are done with the global scope.  */
236           if (!RTLD_SINGLE_THREAD_P)
237             THREAD_GSCOPE_RESET_FLAG ();
238
239           /* Currently result contains the base load address (or link map)
240              of the object that defines sym.  Now add in the symbol
241              offset.  */
242           value = DL_FIXUP_MAKE_VALUE (result,
243                                        defsym != NULL
244                                        ? LOOKUP_VALUE_ADDRESS (result)
245                                          + defsym->st_value : 0);
246
247           if (defsym != NULL
248               && __builtin_expect (ELFW(ST_TYPE) (defsym->st_info)
249                                    == STT_GNU_IFUNC, 0))
250             value = elf_ifunc_invoke (DL_FIXUP_VALUE_ADDR (value));
251         }
252       else
253         {
254           /* We already found the symbol.  The module (and therefore its load
255              address) is also known.  */
256           value = DL_FIXUP_MAKE_VALUE (l, l->l_addr + refsym->st_value);
257
258           if (__builtin_expect (ELFW(ST_TYPE) (refsym->st_info)
259                                 == STT_GNU_IFUNC, 0))
260             value = elf_ifunc_invoke (DL_FIXUP_VALUE_ADDR (value));
261
262           result = l;
263         }
264       /* And now perhaps the relocation addend.  */
265       value = elf_machine_plt_value (l, reloc, value);
266
267 #ifdef SHARED
268       /* Auditing checkpoint: we have a new binding.  Provide the
269          auditing libraries the possibility to change the value and
270          tell us whether further auditing is wanted.  */
271       if (defsym != NULL && GLRO(dl_naudit) > 0)
272         {
273           reloc_result->bound = result;
274           /* Compute index of the symbol entry in the symbol table of
275              the DSO with the definition.  */
276           reloc_result->boundndx = (defsym
277                                     - (ElfW(Sym) *) D_PTR (result,
278                                                            l_info[DT_SYMTAB]));
279
280           /* Determine whether any of the two participating DSOs is
281              interested in auditing.  */
282           if ((l->l_audit_any_plt | result->l_audit_any_plt) != 0)
283             {
284               unsigned int flags = 0;
285               struct audit_ifaces *afct = GLRO(dl_audit);
286               /* Synthesize a symbol record where the st_value field is
287                  the result.  */
288               ElfW(Sym) sym = *defsym;
289               sym.st_value = DL_FIXUP_VALUE_ADDR (value);
290
291               /* Keep track whether there is any interest in tracing
292                  the call in the lower two bits.  */
293               assert (DL_NNS * 2 <= sizeof (reloc_result->flags) * 8);
294               assert ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) == 3);
295               reloc_result->enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT;
296
297               const char *strtab2 = (const void *) D_PTR (result,
298                                                           l_info[DT_STRTAB]);
299
300               for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
301                 {
302                   /* XXX Check whether both DSOs must request action or
303                      only one */
304                   if ((l->l_audit[cnt].bindflags & LA_FLG_BINDFROM) != 0
305                       && (result->l_audit[cnt].bindflags & LA_FLG_BINDTO) != 0)
306                     {
307                       if (afct->symbind != NULL)
308                         {
309                           uintptr_t new_value
310                             = afct->symbind (&sym, reloc_result->boundndx,
311                                              &l->l_audit[cnt].cookie,
312                                              &result->l_audit[cnt].cookie,
313                                              &flags,
314                                              strtab2 + defsym->st_name);
315                           if (new_value != (uintptr_t) sym.st_value)
316                             {
317                               flags |= LA_SYMB_ALTVALUE;
318                               sym.st_value = new_value;
319                             }
320                         }
321
322                       /* Remember the results for every audit library and
323                          store a summary in the first two bits.  */
324                       reloc_result->enterexit
325                         &= flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT);
326                       reloc_result->enterexit
327                         |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT))
328                             << ((cnt + 1) * 2));
329                     }
330                   else
331                     /* If the bind flags say this auditor is not interested,
332                        set the bits manually.  */
333                     reloc_result->enterexit
334                       |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)
335                           << ((cnt + 1) * 2));
336
337                   afct = afct->next;
338                 }
339
340               reloc_result->flags = flags;
341               value = DL_FIXUP_ADDR_VALUE (sym.st_value);
342             }
343           else
344             /* Set all bits since this symbol binding is not interesting.  */
345             reloc_result->enterexit = (1u << DL_NNS) - 1;
346         }
347 #endif
348
349       /* Store the result for later runs.  */
350       if (__glibc_likely (! GLRO(dl_bind_not)))
351         *resultp = value;
352     }
353
354   /* By default we do not call the pltexit function.  */
355   long int framesize = -1;
356
357 #ifdef SHARED
358   /* Auditing checkpoint: report the PLT entering and allow the
359      auditors to change the value.  */
360   if (DL_FIXUP_VALUE_CODE_ADDR (value) != 0 && GLRO(dl_naudit) > 0
361       /* Don't do anything if no auditor wants to intercept this call.  */
362       && (reloc_result->enterexit & LA_SYMB_NOPLTENTER) == 0)
363     {
364       ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
365                                                 l_info[DT_SYMTAB])
366                            + reloc_result->boundndx);
367
368       /* Set up the sym parameter.  */
369       ElfW(Sym) sym = *defsym;
370       sym.st_value = DL_FIXUP_VALUE_ADDR (value);
371
372       /* Get the symbol name.  */
373       const char *strtab = (const void *) D_PTR (reloc_result->bound,
374                                                  l_info[DT_STRTAB]);
375       const char *symname = strtab + sym.st_name;
376
377       /* Keep track of overwritten addresses.  */
378       unsigned int flags = reloc_result->flags;
379
380       struct audit_ifaces *afct = GLRO(dl_audit);
381       for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
382         {
383           if (afct->ARCH_LA_PLTENTER != NULL
384               && (reloc_result->enterexit
385                   & (LA_SYMB_NOPLTENTER << (2 * (cnt + 1)))) == 0)
386             {
387               long int new_framesize = -1;
388               uintptr_t new_value
389                 = afct->ARCH_LA_PLTENTER (&sym, reloc_result->boundndx,
390                                           &l->l_audit[cnt].cookie,
391                                           &reloc_result->bound->l_audit[cnt].cookie,
392                                           regs, &flags, symname,
393                                           &new_framesize);
394               if (new_value != (uintptr_t) sym.st_value)
395                 {
396                   flags |= LA_SYMB_ALTVALUE;
397                   sym.st_value = new_value;
398                 }
399
400               /* Remember the results for every audit library and
401                  store a summary in the first two bits.  */
402               reloc_result->enterexit
403                 |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT))
404                     << (2 * (cnt + 1)));
405
406               if ((reloc_result->enterexit & (LA_SYMB_NOPLTEXIT
407                                               << (2 * (cnt + 1))))
408                   == 0 && new_framesize != -1 && framesize != -2)
409                 {
410                   /* If this is the first call providing information,
411                      use it.  */
412                   if (framesize == -1)
413                     framesize = new_framesize;
414                   /* If two pltenter calls provide conflicting information,
415                      use the larger value.  */
416                   else if (new_framesize != framesize)
417                     framesize = MAX (new_framesize, framesize);
418                 }
419             }
420
421           afct = afct->next;
422         }
423
424       value = DL_FIXUP_ADDR_VALUE (sym.st_value);
425     }
426 #endif
427
428   /* Store the frame size information.  */
429   *framesizep = framesize;
430
431   (*mcount_fct) (retaddr, DL_FIXUP_VALUE_CODE_ADDR (value));
432
433   return value;
434 }
435
436 #endif /* PROF */
437
438
439 #include <stdio.h>
440 void
441 ARCH_FIXUP_ATTRIBUTE
442 _dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
443                   const void *inregs, void *outregs)
444 {
445 #ifdef SHARED
446   /* This is the address in the array where we store the result of previous
447      relocations.  */
448   // XXX Maybe the bound information must be stored on the stack since
449   // XXX with bind_not a new value could have been stored in the meantime.
450   struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
451   ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
452                                             l_info[DT_SYMTAB])
453                        + reloc_result->boundndx);
454
455   /* Set up the sym parameter.  */
456   ElfW(Sym) sym = *defsym;
457   sym.st_value = DL_FIXUP_VALUE_ADDR (reloc_result->addr);
458
459   /* Get the symbol name.  */
460   const char *strtab = (const void *) D_PTR (reloc_result->bound,
461                                              l_info[DT_STRTAB]);
462   const char *symname = strtab + sym.st_name;
463
464   struct audit_ifaces *afct = GLRO(dl_audit);
465   for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
466     {
467       if (afct->ARCH_LA_PLTEXIT != NULL
468           && (reloc_result->enterexit
469               & (LA_SYMB_NOPLTEXIT >> (2 * cnt))) == 0)
470         {
471           afct->ARCH_LA_PLTEXIT (&sym, reloc_result->boundndx,
472                                  &l->l_audit[cnt].cookie,
473                                  &reloc_result->bound->l_audit[cnt].cookie,
474                                  inregs, outregs, symname);
475         }
476
477       afct = afct->next;
478     }
479 #endif
480 }