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