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