Fix Wundef warning for ELF_MACHINE_NO_RELA
[platform/upstream/linaro-glibc.git] / sysdeps / powerpc / powerpc64 / dl-machine.h
1 /* Machine-dependent ELF dynamic relocation inline functions.
2    PowerPC64 version.
3    Copyright 1995-2014 Free Software Foundation, Inc.
4    This file is part of the GNU C Library.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Library General Public License as
8    published by the Free Software Foundation; either version 2 of the
9    License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Library General Public License for more details.
15
16    You should have received a copy of the GNU Library General Public
17    License along with the GNU C Library; see the file COPYING.LIB.  If
18    not, see <http://www.gnu.org/licenses/>.  */
19
20 #ifndef dl_machine_h
21 #define dl_machine_h
22
23 #define ELF_MACHINE_NAME "powerpc64"
24
25 #include <assert.h>
26 #include <sys/param.h>
27 #include <dl-tls.h>
28 #include <sysdep.h>
29
30 /* Translate a processor specific dynamic tag to the index
31    in l_info array.  */
32 #define DT_PPC64(x) (DT_PPC64_##x - DT_LOPROC + DT_NUM)
33
34 #if _CALL_ELF != 2
35 /* A PowerPC64 function descriptor.  The .plt (procedure linkage
36    table) and .opd (official procedure descriptor) sections are
37    arrays of these.  */
38 typedef struct
39 {
40   Elf64_Addr fd_func;
41   Elf64_Addr fd_toc;
42   Elf64_Addr fd_aux;
43 } Elf64_FuncDesc;
44 #endif
45
46 #define ELF_MULT_MACHINES_SUPPORTED
47
48 /* Return nonzero iff ELF header is compatible with the running host.  */
49 static inline int
50 elf_machine_matches_host (const Elf64_Ehdr *ehdr)
51 {
52   /* Verify that the binary matches our ABI version.  */
53   if ((ehdr->e_flags & EF_PPC64_ABI) != 0)
54     {
55 #if _CALL_ELF != 2
56       if ((ehdr->e_flags & EF_PPC64_ABI) != 1)
57         return 0;
58 #else
59       if ((ehdr->e_flags & EF_PPC64_ABI) != 2)
60         return 0;
61 #endif
62     }
63
64   return ehdr->e_machine == EM_PPC64;
65 }
66
67 /* Return nonzero iff ELF header is compatible with the running host,
68    but not this loader.  */
69 static inline int
70 elf_host_tolerates_machine (const Elf64_Ehdr *ehdr)
71 {
72   return ehdr->e_machine == EM_PPC;
73 }
74
75 /* Return nonzero iff ELF header is compatible with the running host,
76    but not this loader.  */
77 static inline int
78 elf_host_tolerates_class (const Elf64_Ehdr *ehdr)
79 {
80   return ehdr->e_ident[EI_CLASS] == ELFCLASS32;
81 }
82
83
84 /* Return the run-time load address of the shared object, assuming it
85    was originally linked at zero.  */
86 static inline Elf64_Addr
87 elf_machine_load_address (void) __attribute__ ((const));
88
89 static inline Elf64_Addr
90 elf_machine_load_address (void)
91 {
92   Elf64_Addr ret;
93
94   /* The first entry in .got (and thus the first entry in .toc) is the
95      link-time TOC_base, ie. r2.  So the difference between that and
96      the current r2 set by the kernel is how far the shared lib has
97      moved.  */
98   asm ( "       ld      %0,-32768(2)\n"
99         "       subf    %0,%0,2\n"
100         : "=r"  (ret));
101   return ret;
102 }
103
104 /* Return the link-time address of _DYNAMIC.  */
105 static inline Elf64_Addr
106 elf_machine_dynamic (void)
107 {
108   Elf64_Addr runtime_dynamic;
109   /* It's easier to get the run-time address.  */
110   asm ( "       addis   %0,2,_DYNAMIC@toc@ha\n"
111         "       addi    %0,%0,_DYNAMIC@toc@l\n"
112         : "=b"  (runtime_dynamic));
113   /* Then subtract off the load address offset.  */
114   return runtime_dynamic - elf_machine_load_address() ;
115 }
116
117 #define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) /* nothing */
118
119 /* The PLT uses Elf64_Rela relocs.  */
120 #define elf_machine_relplt elf_machine_rela
121
122
123 #ifdef HAVE_INLINED_SYSCALLS
124 /* We do not need _dl_starting_up.  */
125 # define DL_STARTING_UP_DEF
126 #else
127 # define DL_STARTING_UP_DEF \
128 ".LC__dl_starting_up:\n"  \
129 "       .tc _dl_starting_up_internal[TC],_dl_starting_up_internal\n"
130 #endif
131
132
133 /* Initial entry point code for the dynamic linker.  The C function
134    `_dl_start' is the real entry point; its return value is the user
135    program's entry point.  */
136 #define RTLD_START \
137   asm (".pushsection \".text\"\n"                                       \
138 "       .align  2\n"                                                    \
139 "       " ENTRY_2(_start) "\n"                                          \
140 BODY_PREFIX "_start:\n"                                                 \
141 "       " LOCALENTRY(_start) "\n"                                               \
142 /* We start with the following on the stack, from top:                  \
143    argc (4 bytes);                                                      \
144    arguments for program (terminated by NULL);                          \
145    environment variables (terminated by NULL);                          \
146    arguments for the program loader.  */                                \
147 "       mr      3,1\n"                                                  \
148 "       li      4,0\n"                                                  \
149 "       stdu    4,-128(1)\n"                                            \
150 /* Call _dl_start with one parameter pointing at argc.  */              \
151 "       bl      " DOT_PREFIX "_dl_start\n"                              \
152 "       nop\n"                                                          \
153 /* Transfer control to _dl_start_user!  */                              \
154 "       b       " DOT_PREFIX "_dl_start_user\n"                         \
155 ".LT__start:\n"                                                         \
156 "       .long 0\n"                                                      \
157 "       .byte 0x00,0x0c,0x24,0x40,0x00,0x00,0x00,0x00\n"                \
158 "       .long .LT__start-" BODY_PREFIX "_start\n"                       \
159 "       .short .LT__start_name_end-.LT__start_name_start\n"             \
160 ".LT__start_name_start:\n"                                              \
161 "       .ascii \"_start\"\n"                                            \
162 ".LT__start_name_end:\n"                                                \
163 "       .align 2\n"                                                     \
164 "       " END_2(_start) "\n"                                            \
165 "       .pushsection    \".toc\",\"aw\"\n"                              \
166 DL_STARTING_UP_DEF                                                      \
167 ".LC__rtld_local:\n"                                                    \
168 "       .tc _rtld_local[TC],_rtld_local\n"                              \
169 ".LC__dl_argc:\n"                                                       \
170 "       .tc _dl_argc[TC],_dl_argc\n"                                    \
171 ".LC__dl_argv:\n"                                                       \
172 "       .tc _dl_argv_internal[TC],_dl_argv_internal\n"                  \
173 ".LC__dl_fini:\n"                                                       \
174 "       .tc _dl_fini[TC],_dl_fini\n"                                    \
175 "       .popsection\n"                                                  \
176 "       " ENTRY_2(_dl_start_user) "\n"                                  \
177 /* Now, we do our main work of calling initialisation procedures.       \
178    The ELF ABI doesn't say anything about parameters for these,         \
179    so we just pass argc, argv, and the environment.                     \
180    Changing these is strongly discouraged (not least because argc is    \
181    passed by value!).  */                                               \
182 BODY_PREFIX "_dl_start_user:\n"                                         \
183 "       " LOCALENTRY(_dl_start_user) "\n"                               \
184 /* the address of _start in r30.  */                                    \
185 "       mr      30,3\n"                                                 \
186 /* &_dl_argc in 29, &_dl_argv in 27, and _dl_loaded in 28.  */          \
187 "       ld      28,.LC__rtld_local@toc(2)\n"                            \
188 "       ld      29,.LC__dl_argc@toc(2)\n"                               \
189 "       ld      27,.LC__dl_argv@toc(2)\n"                               \
190 /* _dl_init (_dl_loaded, _dl_argc, _dl_argv, _dl_argv+_dl_argc+1).  */  \
191 "       ld      3,0(28)\n"                                              \
192 "       lwa     4,0(29)\n"                                              \
193 "       ld      5,0(27)\n"                                              \
194 "       sldi    6,4,3\n"                                                \
195 "       add     6,5,6\n"                                                \
196 "       addi    6,6,8\n"                                                \
197 "       bl      " DOT_PREFIX "_dl_init\n"                               \
198 "       nop\n"                                                          \
199 /* Now, to conform to the ELF ABI, we have to:                          \
200    Pass argc (actually _dl_argc) in r3;  */                             \
201 "       lwa     3,0(29)\n"                                              \
202 /* Pass argv (actually _dl_argv) in r4;  */                             \
203 "       ld      4,0(27)\n"                                              \
204 /* Pass argv+argc+1 in r5;  */                                          \
205 "       sldi    5,3,3\n"                                                \
206 "       add     6,4,5\n"                                                \
207 "       addi    5,6,8\n"                                                \
208 /* Pass the auxiliary vector in r6. This is passed to us just after     \
209    _envp.  */                                                           \
210 "2:     ldu     0,8(6)\n"                                               \
211 "       cmpdi   0,0\n"                                                  \
212 "       bne     2b\n"                                                   \
213 "       addi    6,6,8\n"                                                \
214 /* Pass a termination function pointer (in this case _dl_fini) in       \
215    r7.  */                                                              \
216 "       ld      7,.LC__dl_fini@toc(2)\n"                                \
217 /* Pass the stack pointer in r1 (so far so good), pointing to a NULL    \
218    value.  This lets our startup code distinguish between a program     \
219    linked statically, which linux will call with argc on top of the     \
220    stack which will hopefully never be zero, and a dynamically linked   \
221    program which will always have a NULL on the top of the stack.       \
222    Take the opportunity to clear LR, so anyone who accidentally         \
223    returns from _start gets SEGV.  Also clear the next few words of     \
224    the stack.  */                                                       \
225 "       li      31,0\n"                                                 \
226 "       std     31,0(1)\n"                                              \
227 "       mtlr    31\n"                                                   \
228 "       std     31,8(1)\n"                                              \
229 "       std     31,16(1)\n"                                             \
230 "       std     31,24(1)\n"                                             \
231 /* Now, call the start function descriptor at r30...  */                \
232 "       .globl  ._dl_main_dispatch\n"                                   \
233 "._dl_main_dispatch:\n"                                                 \
234 "       " PPC64_LOAD_FUNCPTR(30) "\n"                                   \
235 "       bctr\n"                                                         \
236 ".LT__dl_start_user:\n"                                                 \
237 "       .long 0\n"                                                      \
238 "       .byte 0x00,0x0c,0x24,0x40,0x00,0x00,0x00,0x00\n"                \
239 "       .long .LT__dl_start_user-" BODY_PREFIX "_dl_start_user\n"       \
240 "       .short .LT__dl_start_user_name_end-.LT__dl_start_user_name_start\n" \
241 ".LT__dl_start_user_name_start:\n"                                      \
242 "       .ascii \"_dl_start_user\"\n"                                    \
243 ".LT__dl_start_user_name_end:\n"                                        \
244 "       .align 2\n"                                                     \
245 "       " END_2(_dl_start_user) "\n"                                    \
246 "       .popsection");
247
248 /* ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to
249    one of the main executable's symbols, as for a COPY reloc.
250
251    To make function pointer comparisons work on most targets, the
252    relevant ABI states that the address of a non-local function in a
253    dynamically linked executable is the address of the PLT entry for
254    that function.  This is quite reasonable since using the real
255    function address in a non-PIC executable would typically require
256    dynamic relocations in .text, something to be avoided.  For such
257    functions, the linker emits a SHN_UNDEF symbol in the executable
258    with value equal to the PLT entry address.  Normally, SHN_UNDEF
259    symbols have a value of zero, so this is a clue to ld.so that it
260    should treat these symbols specially.  For relocations not in
261    ELF_RTYPE_CLASS_PLT (eg. those on function pointers), ld.so should
262    use the value of the executable SHN_UNDEF symbol, ie. the PLT entry
263    address.  For relocations in ELF_RTYPE_CLASS_PLT (eg. the relocs in
264    the PLT itself), ld.so should use the value of the corresponding
265    defined symbol in the object that defines the function, ie. the
266    real function address.  This complicates ld.so in that there are
267    now two possible values for a given symbol, and it gets even worse
268    because protected symbols need yet another set of rules.
269
270    On PowerPC64 we don't need any of this.  The linker won't emit
271    SHN_UNDEF symbols with non-zero values.  ld.so can make all
272    relocations behave "normally", ie. always use the real address
273    like PLT relocations.  So always set ELF_RTYPE_CLASS_PLT.  */
274
275 #if _CALL_ELF != 2
276 #define elf_machine_type_class(type) \
277   (ELF_RTYPE_CLASS_PLT | (((type) == R_PPC64_COPY) * ELF_RTYPE_CLASS_COPY))
278 #else
279 /* And now that you have read that large comment, you can disregard it
280    all for ELFv2.  ELFv2 does need the special SHN_UNDEF treatment.  */
281 #define IS_PPC64_TLS_RELOC(R)                                           \
282   (((R) >= R_PPC64_TLS && (R) <= R_PPC64_DTPREL16_HIGHESTA)             \
283    || ((R) >= R_PPC64_TPREL16_HIGH && (R) <= R_PPC64_DTPREL16_HIGHA))
284
285 #define elf_machine_type_class(type) \
286   ((((type) == R_PPC64_JMP_SLOT                                 \
287      || (type) == R_PPC64_ADDR24                                \
288      || IS_PPC64_TLS_RELOC (type)) * ELF_RTYPE_CLASS_PLT)       \
289    | (((type) == R_PPC64_COPY) * ELF_RTYPE_CLASS_COPY))
290 #endif
291
292 /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.  */
293 #define ELF_MACHINE_JMP_SLOT    R_PPC64_JMP_SLOT
294
295 /* The PowerPC never uses REL relocations.  */
296 #define ELF_MACHINE_NO_REL 1
297 #define ELF_MACHINE_NO_RELA 0
298
299 /* Stuff for the PLT.  */
300 #if _CALL_ELF != 2
301 #define PLT_INITIAL_ENTRY_WORDS 3
302 #define PLT_ENTRY_WORDS 3
303 #define GLINK_INITIAL_ENTRY_WORDS 8
304 /* The first 32k entries of glink can set an index and branch using two
305    instructions; past that point, glink uses three instructions.  */
306 #define GLINK_ENTRY_WORDS(I) (((I) < 0x8000)? 2 : 3)
307 #else
308 #define PLT_INITIAL_ENTRY_WORDS 2
309 #define PLT_ENTRY_WORDS 1
310 #define GLINK_INITIAL_ENTRY_WORDS 8
311 #define GLINK_ENTRY_WORDS(I) 1
312 #endif
313
314 #define PPC_DCBST(where) asm volatile ("dcbst 0,%0" : : "r"(where) : "memory")
315 #define PPC_DCBT(where) asm volatile ("dcbt 0,%0" : : "r"(where) : "memory")
316 #define PPC_DCBF(where) asm volatile ("dcbf 0,%0" : : "r"(where) : "memory")
317 #define PPC_SYNC asm volatile ("sync" : : : "memory")
318 #define PPC_ISYNC asm volatile ("sync; isync" : : : "memory")
319 #define PPC_ICBI(where) asm volatile ("icbi 0,%0" : : "r"(where) : "memory")
320 #define PPC_DIE asm volatile ("tweq 0,0")
321 /* Use this when you've modified some code, but it won't be in the
322    instruction fetch queue (or when it doesn't matter if it is). */
323 #define MODIFIED_CODE_NOQUEUE(where) \
324      do { PPC_DCBST(where); PPC_SYNC; PPC_ICBI(where); } while (0)
325 /* Use this when it might be in the instruction queue. */
326 #define MODIFIED_CODE(where) \
327      do { PPC_DCBST(where); PPC_SYNC; PPC_ICBI(where); PPC_ISYNC; } while (0)
328
329 /* Set up the loaded object described by MAP so its unrelocated PLT
330    entries will jump to the on-demand fixup code in dl-runtime.c.  */
331 static inline int __attribute__ ((always_inline))
332 elf_machine_runtime_setup (struct link_map *map, int lazy, int profile)
333 {
334   if (map->l_info[DT_JMPREL])
335     {
336       Elf64_Word i;
337       Elf64_Word *glink = NULL;
338       Elf64_Xword *plt = (Elf64_Xword *) D_PTR (map, l_info[DT_PLTGOT]);
339       Elf64_Word num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
340                                     / sizeof (Elf64_Rela));
341       Elf64_Addr l_addr = map->l_addr;
342       Elf64_Dyn **info = map->l_info;
343       char *p;
344
345       extern void _dl_runtime_resolve (void);
346       extern void _dl_profile_resolve (void);
347
348       /* Relocate the DT_PPC64_GLINK entry in the _DYNAMIC section.
349          elf_get_dynamic_info takes care of the standard entries but
350          doesn't know exactly what to do with processor specific
351          entries.  */
352       if (info[DT_PPC64(GLINK)] != NULL)
353         info[DT_PPC64(GLINK)]->d_un.d_ptr += l_addr;
354
355       if (lazy)
356         {
357           Elf64_Word glink_offset;
358           Elf64_Word offset;
359           Elf64_Addr dlrr;
360
361           dlrr = (Elf64_Addr) (profile ? _dl_profile_resolve
362                                        : _dl_runtime_resolve);
363           if (profile && GLRO(dl_profile) != NULL
364               && _dl_name_match_p (GLRO(dl_profile), map))
365             /* This is the object we are looking for.  Say that we really
366                want profiling and the timers are started.  */
367             GL(dl_profile_map) = map;
368
369 #if _CALL_ELF != 2
370           /* We need to stuff the address/TOC of _dl_runtime_resolve
371              into doublewords 0 and 1 of plt_reserve.  Then we need to
372              stuff the map address into doubleword 2 of plt_reserve.
373              This allows the GLINK0 code to transfer control to the
374              correct trampoline which will transfer control to fixup
375              in dl-machine.c.  */
376           {
377             /* The plt_reserve area is the 1st 3 doublewords of the PLT.  */
378             Elf64_FuncDesc *plt_reserve = (Elf64_FuncDesc *) plt;
379             Elf64_FuncDesc *resolve_fd = (Elf64_FuncDesc *) dlrr;
380             plt_reserve->fd_func = resolve_fd->fd_func;
381             plt_reserve->fd_toc  = resolve_fd->fd_toc;
382             plt_reserve->fd_aux  = (Elf64_Addr) map;
383 #ifdef RTLD_BOOTSTRAP
384             /* When we're bootstrapping, the opd entry will not have
385                been relocated yet.  */
386             plt_reserve->fd_func += l_addr;
387             plt_reserve->fd_toc  += l_addr;
388 #endif
389           }
390 #else
391           /* When we don't have function descriptors, the first doubleword
392              of the PLT holds the address of _dl_runtime_resolve, and the
393              second doubleword holds the map address.  */
394           plt[0] = dlrr;
395           plt[1] = (Elf64_Addr) map;
396 #endif
397
398           /* Set up the lazy PLT entries.  */
399           glink = (Elf64_Word *) D_PTR (map, l_info[DT_PPC64(GLINK)]);
400           offset = PLT_INITIAL_ENTRY_WORDS;
401           glink_offset = GLINK_INITIAL_ENTRY_WORDS;
402           for (i = 0; i < num_plt_entries; i++)
403             {
404
405               plt[offset] = (Elf64_Xword) &glink[glink_offset];
406               offset += PLT_ENTRY_WORDS;
407               glink_offset += GLINK_ENTRY_WORDS (i);
408             }
409
410           /* Now, we've modified data.  We need to write the changes from
411              the data cache to a second-level unified cache, then make
412              sure that stale data in the instruction cache is removed.
413              (In a multiprocessor system, the effect is more complex.)
414              Most of the PLT shouldn't be in the instruction cache, but
415              there may be a little overlap at the start and the end.
416
417              Assumes that dcbst and icbi apply to lines of 16 bytes or
418              more.  Current known line sizes are 16, 32, and 128 bytes.  */
419
420           for (p = (char *) plt; p < (char *) &plt[offset]; p += 16)
421             PPC_DCBST (p);
422           PPC_SYNC;
423         }
424     }
425   return lazy;
426 }
427
428 #if _CALL_ELF == 2
429 /* If the PLT entry whose reloc is 'reloc' resolves to a function in
430    the same object, return the target function's local entry point
431    offset if usable.  */
432 static inline Elf64_Addr __attribute__ ((always_inline))
433 ppc64_local_entry_offset (struct link_map *map, lookup_t sym_map,
434                           const Elf64_Rela *reloc)
435 {
436   const Elf64_Sym *symtab;
437   const Elf64_Sym *sym;
438
439   /* If the target function is in a different object, we cannot
440      use the local entry point.  */
441   if (sym_map != map)
442     return 0;
443
444   /* If the linker inserted multiple TOCs, we cannot use the
445      local entry point.  */
446   if (map->l_info[DT_PPC64(OPT)]
447       && (map->l_info[DT_PPC64(OPT)]->d_un.d_val & PPC64_OPT_MULTI_TOC))
448     return 0;
449
450   /* Otherwise, we can use the local entry point.  Retrieve its offset
451      from the symbol's ELF st_other field.  */
452   symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
453   sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
454
455   /* If the target function is an ifunc then the local entry offset is
456      for the resolver, not the final destination.  */
457   if (__builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0))
458     return 0;
459
460   return PPC64_LOCAL_ENTRY_OFFSET (sym->st_other);
461 }
462 #endif
463
464 /* Change the PLT entry whose reloc is 'reloc' to call the actual
465    routine.  */
466 static inline Elf64_Addr __attribute__ ((always_inline))
467 elf_machine_fixup_plt (struct link_map *map, lookup_t sym_map,
468                        const Elf64_Rela *reloc,
469                        Elf64_Addr *reloc_addr, Elf64_Addr finaladdr)
470 {
471 #if _CALL_ELF != 2
472   Elf64_FuncDesc *plt = (Elf64_FuncDesc *) reloc_addr;
473   Elf64_FuncDesc *rel = (Elf64_FuncDesc *) finaladdr;
474   Elf64_Addr offset = 0;
475
476   PPC_DCBT (&plt->fd_aux);
477   PPC_DCBT (&plt->fd_func);
478   PPC_DCBT (&rel->fd_aux);
479   PPC_DCBT (&rel->fd_func);
480
481   /* If sym_map is NULL, it's a weak undefined sym;  Leave the plt zero.  */
482   if (sym_map == NULL)
483     return 0;
484
485   /* If the opd entry is not yet relocated (because it's from a shared
486      object that hasn't been processed yet), then manually reloc it.  */
487   if (map != sym_map && !sym_map->l_relocated
488 #if !defined RTLD_BOOTSTRAP && defined SHARED
489       /* Bootstrap map doesn't have l_relocated set for it.  */
490       && sym_map != &GL(dl_rtld_map)
491 #endif
492       )
493     offset = sym_map->l_addr;
494
495   /* For PPC64, fixup_plt copies the function descriptor from opd
496      over the corresponding PLT entry.
497      Initially, PLT Entry[i] is set up for lazy linking, or is zero.
498      For lazy linking, the fd_toc and fd_aux entries are irrelevant,
499      so for thread safety we write them before changing fd_func.  */
500
501   plt->fd_aux = rel->fd_aux + offset;
502   plt->fd_toc = rel->fd_toc + offset;
503   PPC_DCBF (&plt->fd_toc);
504   PPC_ISYNC;
505
506   plt->fd_func = rel->fd_func + offset;
507   PPC_DCBST (&plt->fd_func);
508   PPC_ISYNC;
509 #else
510   finaladdr += ppc64_local_entry_offset (map, sym_map, reloc);
511   *reloc_addr = finaladdr;
512 #endif
513
514   return finaladdr;
515 }
516
517 static inline void __attribute__ ((always_inline))
518 elf_machine_plt_conflict (struct link_map *map, lookup_t sym_map,
519                           const Elf64_Rela *reloc,
520                           Elf64_Addr *reloc_addr, Elf64_Addr finaladdr)
521 {
522 #if _CALL_ELF != 2
523   Elf64_FuncDesc *plt = (Elf64_FuncDesc *) reloc_addr;
524   Elf64_FuncDesc *rel = (Elf64_FuncDesc *) finaladdr;
525
526   plt->fd_func = rel->fd_func;
527   plt->fd_aux = rel->fd_aux;
528   plt->fd_toc = rel->fd_toc;
529   PPC_DCBST (&plt->fd_func);
530   PPC_DCBST (&plt->fd_aux);
531   PPC_DCBST (&plt->fd_toc);
532   PPC_SYNC;
533 #else
534   finaladdr += ppc64_local_entry_offset (map, sym_map, reloc);
535   *reloc_addr = finaladdr;
536 #endif
537 }
538
539 /* Return the final value of a plt relocation.  */
540 static inline Elf64_Addr
541 elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
542                        Elf64_Addr value)
543 {
544   return value + reloc->r_addend;
545 }
546
547
548 /* Names of the architecture-specific auditing callback functions.  */
549 #if _CALL_ELF != 2
550 #define ARCH_LA_PLTENTER ppc64_gnu_pltenter
551 #define ARCH_LA_PLTEXIT ppc64_gnu_pltexit
552 #else
553 #define ARCH_LA_PLTENTER ppc64v2_gnu_pltenter
554 #define ARCH_LA_PLTEXIT ppc64v2_gnu_pltexit
555 #endif
556
557 #endif /* dl_machine_h */
558
559 #ifdef RESOLVE_MAP
560
561 #define PPC_LO(v) ((v) & 0xffff)
562 #define PPC_HI(v) (((v) >> 16) & 0xffff)
563 #define PPC_HA(v) PPC_HI ((v) + 0x8000)
564 #define PPC_HIGHER(v) (((v) >> 32) & 0xffff)
565 #define PPC_HIGHERA(v) PPC_HIGHER ((v) + 0x8000)
566 #define PPC_HIGHEST(v) (((v) >> 48) & 0xffff)
567 #define PPC_HIGHESTA(v) PPC_HIGHEST ((v) + 0x8000)
568 #define BIT_INSERT(var, val, mask) \
569   ((var) = ((var) & ~(Elf64_Addr) (mask)) | ((val) & (mask)))
570
571 #define dont_expect(X) __builtin_expect ((X), 0)
572
573 extern void _dl_reloc_overflow (struct link_map *map,
574                                 const char *name,
575                                 Elf64_Addr *const reloc_addr,
576                                 const Elf64_Sym *refsym)
577                                 attribute_hidden;
578
579 auto inline void __attribute__ ((always_inline))
580 elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
581                            void *const reloc_addr_arg)
582 {
583   Elf64_Addr *const reloc_addr = reloc_addr_arg;
584   *reloc_addr = l_addr + reloc->r_addend;
585 }
586
587 /* This computes the value used by TPREL* relocs.  */
588 auto inline Elf64_Addr __attribute__ ((always_inline, const))
589 elf_machine_tprel (struct link_map *map,
590                    struct link_map *sym_map,
591                    const Elf64_Sym *sym,
592                    const Elf64_Rela *reloc)
593 {
594 #ifndef RTLD_BOOTSTRAP
595   if (sym_map)
596     {
597       CHECK_STATIC_TLS (map, sym_map);
598 #endif
599       return TLS_TPREL_VALUE (sym_map, sym, reloc);
600 #ifndef RTLD_BOOTSTRAP
601     }
602 #endif
603   return 0;
604 }
605
606 /* Call function at address VALUE (an OPD entry) to resolve ifunc relocs.  */
607 auto inline Elf64_Addr __attribute__ ((always_inline))
608 resolve_ifunc (Elf64_Addr value,
609                const struct link_map *map, const struct link_map *sym_map)
610 {
611 #if _CALL_ELF != 2
612 #ifndef RESOLVE_CONFLICT_FIND_MAP
613   /* The function we are calling may not yet have its opd entry relocated.  */
614   Elf64_FuncDesc opd;
615   if (map != sym_map
616 # if !defined RTLD_BOOTSTRAP && defined SHARED
617       /* Bootstrap map doesn't have l_relocated set for it.  */
618       && sym_map != &GL(dl_rtld_map)
619 # endif
620       && !sym_map->l_relocated)
621     {
622       Elf64_FuncDesc *func = (Elf64_FuncDesc *) value;
623       opd.fd_func = func->fd_func + sym_map->l_addr;
624       opd.fd_toc = func->fd_toc + sym_map->l_addr;
625       opd.fd_aux = func->fd_aux;
626       value = (Elf64_Addr) &opd;
627     }
628 #endif
629 #endif
630   return ((Elf64_Addr (*) (unsigned long int)) value) (GLRO(dl_hwcap));
631 }
632
633 /* Perform the relocation specified by RELOC and SYM (which is fully
634    resolved).  MAP is the object containing the reloc.  */
635 auto inline void __attribute__ ((always_inline))
636 elf_machine_rela (struct link_map *map,
637                   const Elf64_Rela *reloc,
638                   const Elf64_Sym *sym,
639                   const struct r_found_version *version,
640                   void *const reloc_addr_arg,
641                   int skip_ifunc)
642 {
643   Elf64_Addr *const reloc_addr = reloc_addr_arg;
644   const int r_type = ELF64_R_TYPE (reloc->r_info);
645   const Elf64_Sym *const refsym = sym;
646   union unaligned
647     {
648       uint16_t u2;
649       uint32_t u4;
650       uint64_t u8;
651     } __attribute__ ((__packed__));
652
653   if (r_type == R_PPC64_RELATIVE)
654     {
655       *reloc_addr = map->l_addr + reloc->r_addend;
656       return;
657     }
658
659   if (__glibc_unlikely (r_type == R_PPC64_NONE))
660     return;
661
662   /* We need SYM_MAP even in the absence of TLS, for elf_machine_fixup_plt
663      and STT_GNU_IFUNC.  */
664   struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
665   Elf64_Addr value = ((sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value)
666                       + reloc->r_addend);
667
668   if (sym != NULL
669       && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)
670       && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1)
671       && __builtin_expect (!skip_ifunc, 1))
672     value = resolve_ifunc (value, map, sym_map);
673
674   /* For relocs that don't edit code, return.
675      For relocs that might edit instructions, break from the switch.  */
676   switch (r_type)
677     {
678     case R_PPC64_ADDR64:
679     case R_PPC64_GLOB_DAT:
680       *reloc_addr = value;
681       return;
682
683     case R_PPC64_IRELATIVE:
684       if (__glibc_likely (!skip_ifunc))
685         value = resolve_ifunc (value, map, sym_map);
686       *reloc_addr = value;
687       return;
688
689     case R_PPC64_JMP_IREL:
690       if (__glibc_likely (!skip_ifunc))
691         value = resolve_ifunc (value, map, sym_map);
692       /* Fall thru */
693     case R_PPC64_JMP_SLOT:
694 #ifdef RESOLVE_CONFLICT_FIND_MAP
695       elf_machine_plt_conflict (map, sym_map, reloc, reloc_addr, value);
696 #else
697       elf_machine_fixup_plt (map, sym_map, reloc, reloc_addr, value);
698 #endif
699       return;
700
701     case R_PPC64_DTPMOD64:
702 #ifdef RTLD_BOOTSTRAP
703       /* During startup the dynamic linker is always index 1.  */
704       *reloc_addr = 1;
705 #else
706       /* Get the information from the link map returned by the
707          resolve function.  */
708       if (sym_map != NULL)
709         *reloc_addr = sym_map->l_tls_modid;
710 #endif
711       return;
712
713     case R_PPC64_DTPREL64:
714       /* During relocation all TLS symbols are defined and used.
715          Therefore the offset is already correct.  */
716 #ifndef RTLD_BOOTSTRAP
717       if (sym_map != NULL)
718         *reloc_addr = TLS_DTPREL_VALUE (sym, reloc);
719 #endif
720       return;
721
722     case R_PPC64_TPREL64:
723       *reloc_addr = elf_machine_tprel (map, sym_map, sym, reloc);
724       return;
725
726     case R_PPC64_TPREL16_LO_DS:
727       value = elf_machine_tprel (map, sym_map, sym, reloc);
728       if (dont_expect ((value & 3) != 0))
729         _dl_reloc_overflow (map, "R_PPC64_TPREL16_LO_DS", reloc_addr, refsym);
730       BIT_INSERT (*(Elf64_Half *) reloc_addr, value, 0xfffc);
731       break;
732
733     case R_PPC64_TPREL16_DS:
734       value = elf_machine_tprel (map, sym_map, sym, reloc);
735       if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0))
736         _dl_reloc_overflow (map, "R_PPC64_TPREL16_DS", reloc_addr, refsym);
737       BIT_INSERT (*(Elf64_Half *) reloc_addr, value, 0xfffc);
738       break;
739
740     case R_PPC64_TPREL16:
741       value = elf_machine_tprel (map, sym_map, sym, reloc);
742       if (dont_expect ((value + 0x8000) >= 0x10000))
743         _dl_reloc_overflow (map, "R_PPC64_TPREL16", reloc_addr, refsym);
744       *(Elf64_Half *) reloc_addr = PPC_LO (value);
745       break;
746
747     case R_PPC64_TPREL16_LO:
748       value = elf_machine_tprel (map, sym_map, sym, reloc);
749       *(Elf64_Half *) reloc_addr = PPC_LO (value);
750       break;
751
752     case R_PPC64_TPREL16_HI:
753       value = elf_machine_tprel (map, sym_map, sym, reloc);
754       if (dont_expect (value + 0x80000000 >= 0x100000000LL))
755         _dl_reloc_overflow (map, "R_PPC64_TPREL16_HI", reloc_addr, refsym);
756       *(Elf64_Half *) reloc_addr = PPC_HI (value);
757       break;
758
759     case R_PPC64_TPREL16_HIGH:
760       value = elf_machine_tprel (map, sym_map, sym, reloc);
761       *(Elf64_Half *) reloc_addr = PPC_HI (value);
762       break;
763
764     case R_PPC64_TPREL16_HA:
765       value = elf_machine_tprel (map, sym_map, sym, reloc);
766       if (dont_expect (value + 0x80008000 >= 0x100000000LL))
767         _dl_reloc_overflow (map, "R_PPC64_TPREL16_HA", reloc_addr, refsym);
768       *(Elf64_Half *) reloc_addr = PPC_HA (value);
769       break;
770
771     case R_PPC64_TPREL16_HIGHA:
772       value = elf_machine_tprel (map, sym_map, sym, reloc);
773       *(Elf64_Half *) reloc_addr = PPC_HA (value);
774       break;
775
776     case R_PPC64_TPREL16_HIGHER:
777       value = elf_machine_tprel (map, sym_map, sym, reloc);
778       *(Elf64_Half *) reloc_addr = PPC_HIGHER (value);
779       break;
780
781     case R_PPC64_TPREL16_HIGHEST:
782       value = elf_machine_tprel (map, sym_map, sym, reloc);
783       *(Elf64_Half *) reloc_addr = PPC_HIGHEST (value);
784       break;
785
786     case R_PPC64_TPREL16_HIGHERA:
787       value = elf_machine_tprel (map, sym_map, sym, reloc);
788       *(Elf64_Half *) reloc_addr = PPC_HIGHERA (value);
789       break;
790
791     case R_PPC64_TPREL16_HIGHESTA:
792       value = elf_machine_tprel (map, sym_map, sym, reloc);
793       *(Elf64_Half *) reloc_addr = PPC_HIGHESTA (value);
794       break;
795
796 #ifndef RTLD_BOOTSTRAP /* None of the following appear in ld.so */
797     case R_PPC64_ADDR16_LO_DS:
798       if (dont_expect ((value & 3) != 0))
799         _dl_reloc_overflow (map, "R_PPC64_ADDR16_LO_DS", reloc_addr, refsym);
800       BIT_INSERT (*(Elf64_Half *) reloc_addr, value, 0xfffc);
801       break;
802
803     case R_PPC64_ADDR16_LO:
804       *(Elf64_Half *) reloc_addr = PPC_LO (value);
805       break;
806
807     case R_PPC64_ADDR16_HI:
808       if (dont_expect (value + 0x80000000 >= 0x100000000LL))
809         _dl_reloc_overflow (map, "R_PPC64_ADDR16_HI", reloc_addr, refsym);
810     case R_PPC64_ADDR16_HIGH:
811       *(Elf64_Half *) reloc_addr = PPC_HI (value);
812       break;
813
814     case R_PPC64_ADDR16_HA:
815       if (dont_expect (value + 0x80008000 >= 0x100000000LL))
816         _dl_reloc_overflow (map, "R_PPC64_ADDR16_HA", reloc_addr, refsym);
817     case R_PPC64_ADDR16_HIGHA:
818       *(Elf64_Half *) reloc_addr = PPC_HA (value);
819       break;
820
821     case R_PPC64_ADDR30:
822       {
823         Elf64_Addr delta = value - (Elf64_Xword) reloc_addr;
824         if (dont_expect ((delta + 0x80000000) >= 0x100000000LL
825                          || (delta & 3) != 0))
826           _dl_reloc_overflow (map, "R_PPC64_ADDR30", reloc_addr, refsym);
827         BIT_INSERT (*(Elf64_Word *) reloc_addr, delta, 0xfffffffc);
828       }
829       break;
830
831     case R_PPC64_COPY:
832       if (dont_expect (sym == NULL))
833         /* This can happen in trace mode when an object could not be found. */
834         return;
835       if (dont_expect (sym->st_size > refsym->st_size
836                        || (GLRO(dl_verbose)
837                            && sym->st_size < refsym->st_size)))
838         {
839           const char *strtab;
840
841           strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
842           _dl_error_printf ("%s: Symbol `%s' has different size" \
843                             " in shared object," \
844                             " consider re-linking\n",
845                             RTLD_PROGNAME, strtab + refsym->st_name);
846         }
847       memcpy (reloc_addr_arg, (char *) value,
848               MIN (sym->st_size, refsym->st_size));
849       return;
850
851     case R_PPC64_UADDR64:
852       ((union unaligned *) reloc_addr)->u8 = value;
853       return;
854
855     case R_PPC64_UADDR32:
856       ((union unaligned *) reloc_addr)->u4 = value;
857       return;
858
859     case R_PPC64_ADDR32:
860       if (dont_expect ((value + 0x80000000) >= 0x100000000LL))
861         _dl_reloc_overflow (map, "R_PPC64_ADDR32", reloc_addr, refsym);
862       *(Elf64_Word *) reloc_addr = value;
863       return;
864
865     case R_PPC64_ADDR24:
866       if (dont_expect ((value + 0x2000000) >= 0x4000000 || (value & 3) != 0))
867         _dl_reloc_overflow (map, "R_PPC64_ADDR24", reloc_addr, refsym);
868       BIT_INSERT (*(Elf64_Word *) reloc_addr, value, 0x3fffffc);
869       break;
870
871     case R_PPC64_ADDR16:
872       if (dont_expect ((value + 0x8000) >= 0x10000))
873         _dl_reloc_overflow (map, "R_PPC64_ADDR16", reloc_addr, refsym);
874       *(Elf64_Half *) reloc_addr = value;
875       break;
876
877     case R_PPC64_UADDR16:
878       if (dont_expect ((value + 0x8000) >= 0x10000))
879         _dl_reloc_overflow (map, "R_PPC64_UADDR16", reloc_addr, refsym);
880       ((union unaligned *) reloc_addr)->u2 = value;
881       return;
882
883     case R_PPC64_ADDR16_DS:
884       if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0))
885         _dl_reloc_overflow (map, "R_PPC64_ADDR16_DS", reloc_addr, refsym);
886       BIT_INSERT (*(Elf64_Half *) reloc_addr, value, 0xfffc);
887       break;
888
889     case R_PPC64_ADDR16_HIGHER:
890       *(Elf64_Half *) reloc_addr = PPC_HIGHER (value);
891       break;
892
893     case R_PPC64_ADDR16_HIGHEST:
894       *(Elf64_Half *) reloc_addr = PPC_HIGHEST (value);
895       break;
896
897     case R_PPC64_ADDR16_HIGHERA:
898       *(Elf64_Half *) reloc_addr = PPC_HIGHERA (value);
899       break;
900
901     case R_PPC64_ADDR16_HIGHESTA:
902       *(Elf64_Half *) reloc_addr = PPC_HIGHESTA (value);
903       break;
904
905     case R_PPC64_ADDR14:
906     case R_PPC64_ADDR14_BRTAKEN:
907     case R_PPC64_ADDR14_BRNTAKEN:
908       {
909         if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0))
910           _dl_reloc_overflow (map, "R_PPC64_ADDR14", reloc_addr, refsym);
911         Elf64_Word insn = *(Elf64_Word *) reloc_addr;
912         BIT_INSERT (insn, value, 0xfffc);
913         if (r_type != R_PPC64_ADDR14)
914           {
915             insn &= ~(1 << 21);
916             if (r_type == R_PPC64_ADDR14_BRTAKEN)
917               insn |= 1 << 21;
918             if ((insn & (0x14 << 21)) == (0x04 << 21))
919               insn |= 0x02 << 21;
920             else if ((insn & (0x14 << 21)) == (0x10 << 21))
921               insn |= 0x08 << 21;
922           }
923         *(Elf64_Word *) reloc_addr = insn;
924       }
925       break;
926
927     case R_PPC64_REL32:
928       *(Elf64_Word *) reloc_addr = value - (Elf64_Addr) reloc_addr;
929       return;
930
931     case R_PPC64_REL64:
932       *reloc_addr = value - (Elf64_Addr) reloc_addr;
933       return;
934 #endif /* !RTLD_BOOTSTRAP */
935
936     default:
937       _dl_reloc_bad_type (map, r_type, 0);
938       return;
939     }
940   MODIFIED_CODE_NOQUEUE (reloc_addr);
941 }
942
943 auto inline void __attribute__ ((always_inline))
944 elf_machine_lazy_rel (struct link_map *map,
945                       Elf64_Addr l_addr, const Elf64_Rela *reloc,
946                       int skip_ifunc)
947 {
948   /* elf_machine_runtime_setup handles this.  */
949 }
950
951
952 #endif /* RESOLVE */