elf64-ppc.c revision 209867
189857Sobrien/* PowerPC64-specific support for 64-bit ELF.
2130561Sobrien   Copyright 1999, 2000, 2001, 2002, 2003, 2004
3130561Sobrien   Free Software Foundation, Inc.
489857Sobrien   Written by Linus Nordberg, Swox AB <info@swox.com>,
589857Sobrien   based on elf32-ppc.c by Ian Lance Taylor.
6130561Sobrien   Largely rewritten by Alan Modra <amodra@bigpond.net.au>
789857Sobrien
8130561Sobrien   This file is part of BFD, the Binary File Descriptor library.
989857Sobrien
10130561Sobrien   This program is free software; you can redistribute it and/or modify
11130561Sobrien   it under the terms of the GNU General Public License as published by
12130561Sobrien   the Free Software Foundation; either version 2 of the License, or
13130561Sobrien   (at your option) any later version.
1489857Sobrien
15130561Sobrien   This program is distributed in the hope that it will be useful,
16130561Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
17130561Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18130561Sobrien   GNU General Public License for more details.
1989857Sobrien
20130561Sobrien   You should have received a copy of the GNU General Public License along
21130561Sobrien   with this program; if not, write to the Free Software Foundation, Inc.,
22130561Sobrien   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
2389857Sobrien
24130561Sobrien/* The 64-bit PowerPC ELF ABI may be found at
25130561Sobrien   http://www.linuxbase.org/spec/ELF/ppc64/PPC-elf64abi.txt, and
26130561Sobrien   http://www.linuxbase.org/spec/ELF/ppc64/spec/book1.html  */
2789857Sobrien
2889857Sobrien#include "bfd.h"
2989857Sobrien#include "sysdep.h"
3089857Sobrien#include "bfdlink.h"
3189857Sobrien#include "libbfd.h"
3289857Sobrien#include "elf-bfd.h"
33130561Sobrien#include "elf/ppc64.h"
3489857Sobrien#include "elf64-ppc.h"
3589857Sobrien
3699461Sobrienstatic bfd_reloc_status_type ppc64_elf_ha_reloc
37130561Sobrien  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
3899461Sobrienstatic bfd_reloc_status_type ppc64_elf_brtaken_reloc
39130561Sobrien  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
4099461Sobrienstatic bfd_reloc_status_type ppc64_elf_sectoff_reloc
41130561Sobrien  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
4299461Sobrienstatic bfd_reloc_status_type ppc64_elf_sectoff_ha_reloc
43130561Sobrien  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
4499461Sobrienstatic bfd_reloc_status_type ppc64_elf_toc_reloc
45130561Sobrien  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
4699461Sobrienstatic bfd_reloc_status_type ppc64_elf_toc_ha_reloc
47130561Sobrien  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
4899461Sobrienstatic bfd_reloc_status_type ppc64_elf_toc64_reloc
49130561Sobrien  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
5099461Sobrienstatic bfd_reloc_status_type ppc64_elf_unhandled_reloc
51130561Sobrien  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
5289857Sobrien
5389857Sobrien
54130561Sobrien#define TARGET_LITTLE_SYM	bfd_elf64_powerpcle_vec
55130561Sobrien#define TARGET_LITTLE_NAME	"elf64-powerpcle"
56130561Sobrien#define TARGET_BIG_SYM		bfd_elf64_powerpc_vec
57130561Sobrien#define TARGET_BIG_NAME		"elf64-powerpc"
58130561Sobrien#define ELF_ARCH		bfd_arch_powerpc
59130561Sobrien#define ELF_MACHINE_CODE	EM_PPC64
60130561Sobrien#define ELF_MAXPAGESIZE		0x10000
61130561Sobrien#define elf_info_to_howto	ppc64_elf_info_to_howto
62130561Sobrien
63130561Sobrien#define elf_backend_want_got_sym 0
64130561Sobrien#define elf_backend_want_plt_sym 0
65130561Sobrien#define elf_backend_plt_alignment 3
66130561Sobrien#define elf_backend_plt_not_loaded 1
67130561Sobrien#define elf_backend_got_symbol_offset 0
68130561Sobrien#define elf_backend_got_header_size 8
69130561Sobrien#define elf_backend_can_gc_sections 1
70130561Sobrien#define elf_backend_can_refcount 1
71130561Sobrien#define elf_backend_rela_normal 1
72130561Sobrien
73130561Sobrien#define bfd_elf64_mkobject		      ppc64_elf_mkobject
74130561Sobrien#define bfd_elf64_bfd_reloc_type_lookup	      ppc64_elf_reloc_type_lookup
75130561Sobrien#define bfd_elf64_bfd_merge_private_bfd_data  ppc64_elf_merge_private_bfd_data
76130561Sobrien#define bfd_elf64_new_section_hook	      ppc64_elf_new_section_hook
77130561Sobrien#define bfd_elf64_bfd_link_hash_table_create  ppc64_elf_link_hash_table_create
78130561Sobrien#define bfd_elf64_bfd_link_hash_table_free    ppc64_elf_link_hash_table_free
79130561Sobrien
80130561Sobrien#define elf_backend_object_p		      ppc64_elf_object_p
81130561Sobrien#define elf_backend_grok_prstatus	      ppc64_elf_grok_prstatus
82130561Sobrien#define elf_backend_grok_psinfo		      ppc64_elf_grok_psinfo
83130561Sobrien#define elf_backend_create_dynamic_sections   ppc64_elf_create_dynamic_sections
84130561Sobrien#define elf_backend_copy_indirect_symbol      ppc64_elf_copy_indirect_symbol
85130561Sobrien#define elf_backend_add_symbol_hook	      ppc64_elf_add_symbol_hook
86130561Sobrien#define elf_backend_check_relocs	      ppc64_elf_check_relocs
87130561Sobrien#define elf_backend_gc_mark_hook	      ppc64_elf_gc_mark_hook
88130561Sobrien#define elf_backend_gc_sweep_hook	      ppc64_elf_gc_sweep_hook
89130561Sobrien#define elf_backend_adjust_dynamic_symbol     ppc64_elf_adjust_dynamic_symbol
90130561Sobrien#define elf_backend_hide_symbol		      ppc64_elf_hide_symbol
91130561Sobrien#define elf_backend_always_size_sections      ppc64_elf_func_desc_adjust
92130561Sobrien#define elf_backend_size_dynamic_sections     ppc64_elf_size_dynamic_sections
93130561Sobrien#define elf_backend_relocate_section	      ppc64_elf_relocate_section
94130561Sobrien#define elf_backend_finish_dynamic_symbol     ppc64_elf_finish_dynamic_symbol
95130561Sobrien#define elf_backend_reloc_type_class	      ppc64_elf_reloc_type_class
96130561Sobrien#define elf_backend_finish_dynamic_sections   ppc64_elf_finish_dynamic_sections
97130561Sobrien#define elf_backend_link_output_symbol_hook   ppc64_elf_output_symbol_hook
98130561Sobrien#define elf_backend_special_sections	      ppc64_elf_special_sections
99130561Sobrien
10089857Sobrien/* The name of the dynamic interpreter.  This is put in the .interp
10189857Sobrien   section.  */
10289857Sobrien#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
10389857Sobrien
10489857Sobrien/* The size in bytes of an entry in the procedure linkage table.  */
10589857Sobrien#define PLT_ENTRY_SIZE 24
10689857Sobrien
10789857Sobrien/* The initial size of the plt reserved for the dynamic linker.  */
10889857Sobrien#define PLT_INITIAL_ENTRY_SIZE PLT_ENTRY_SIZE
10989857Sobrien
11089857Sobrien/* TOC base pointers offset from start of TOC.  */
111130561Sobrien#define TOC_BASE_OFF	0x8000
11289857Sobrien
113130561Sobrien/* Offset of tp and dtp pointers from start of TLS block.  */
114130561Sobrien#define TP_OFFSET	0x7000
115130561Sobrien#define DTP_OFFSET	0x8000
116130561Sobrien
117130561Sobrien/* .plt call stub instructions.  The normal stub is like this, but
118130561Sobrien   sometimes the .plt entry crosses a 64k boundary and we need to
119130561Sobrien   insert an addis to adjust r12.  */
120130561Sobrien#define PLT_CALL_STUB_SIZE (7*4)
12189857Sobrien#define ADDIS_R12_R2	0x3d820000	/* addis %r12,%r2,xxx@ha     */
12289857Sobrien#define STD_R2_40R1	0xf8410028	/* std	 %r2,40(%r1)	     */
12389857Sobrien#define LD_R11_0R12	0xe96c0000	/* ld	 %r11,xxx+0@l(%r12)  */
12489857Sobrien#define LD_R2_0R12	0xe84c0000	/* ld	 %r2,xxx+8@l(%r12)   */
12589857Sobrien#define MTCTR_R11	0x7d6903a6	/* mtctr %r11		     */
12689857Sobrien					/* ld	 %r11,xxx+16@l(%r12) */
12789857Sobrien#define BCTR		0x4e800420	/* bctr			     */
12889857Sobrien
12989857Sobrien
130130561Sobrien#define ADDIS_R2_R2	0x3c420000	/* addis %r2,%r2,off@ha  */
131130561Sobrien#define ADDI_R2_R2	0x38420000	/* addi  %r2,%r2,off@l   */
13289857Sobrien
133130561Sobrien#define LD_R2_40R1	0xe8410028	/* ld    %r2,40(%r1)     */
13489857Sobrien
135130561Sobrien/* glink call stub instructions.  We enter with the index in R0, and the
136130561Sobrien   address of glink entry in CTR.  From that, we can calculate PLT0.  */
137130561Sobrien#define GLINK_CALL_STUB_SIZE (16*4)
138130561Sobrien#define MFCTR_R12	0x7d8902a6	/* mfctr  %r12			*/
139130561Sobrien#define SLDI_R11_R0_3	0x780b1f24	/* sldi	  %r11,%r0,3		*/
140130561Sobrien#define ADDIC_R2_R0_32K 0x34408000	/* addic. %r2,%r0,-32768	*/
141130561Sobrien#define SUB_R12_R12_R11 0x7d8b6050	/* sub	  %r12,%r12,%r11	*/
142130561Sobrien#define SRADI_R2_R2_63	0x7c42fe76	/* sradi  %r2,%r2,63		*/
143130561Sobrien#define SLDI_R11_R0_2	0x780b1764	/* sldi	  %r11,%r0,2		*/
144130561Sobrien#define AND_R2_R2_R11	0x7c425838	/* and	  %r2,%r2,%r11		*/
145130561Sobrien					/* sub	  %r12,%r12,%r11	*/
146130561Sobrien#define ADD_R12_R12_R2	0x7d8c1214	/* add	  %r12,%r12,%r2		*/
147130561Sobrien#define ADDIS_R12_R12	0x3d8c0000	/* addis  %r12,%r12,xxx@ha	*/
148130561Sobrien					/* ld	  %r11,xxx@l(%r12)	*/
149130561Sobrien#define ADDI_R12_R12	0x398c0000	/* addi	  %r12,%r12,xxx@l	*/
150130561Sobrien					/* ld	  %r2,8(%r12)		*/
151130561Sobrien					/* mtctr  %r11			*/
152130561Sobrien					/* ld	  %r11,16(%r12)		*/
153130561Sobrien					/* bctr				*/
15489857Sobrien
15589857Sobrien/* Pad with this.  */
15689857Sobrien#define NOP		0x60000000
15789857Sobrien
15899461Sobrien/* Some other nops.  */
15999461Sobrien#define CROR_151515	0x4def7b82
16099461Sobrien#define CROR_313131	0x4ffffb82
16199461Sobrien
162104834Sobrien/* .glink entries for the first 32k functions are two instructions.  */
16389857Sobrien#define LI_R0_0		0x38000000	/* li    %r0,0		*/
16489857Sobrien#define B_DOT		0x48000000	/* b     .		*/
16589857Sobrien
16689857Sobrien/* After that, we need two instructions to load the index, followed by
16789857Sobrien   a branch.  */
16889857Sobrien#define LIS_R0_0	0x3c000000	/* lis   %r0,0		*/
16989857Sobrien#define ORI_R0_R0_0	0x60000000	/* ori	 %r0,%r0,0	*/
17089857Sobrien
17192828Sobrien/* Instructions to save and restore floating point regs.  */
17292828Sobrien#define STFD_FR0_0R1	0xd8010000	/* stfd  %fr0,0(%r1)	*/
17392828Sobrien#define LFD_FR0_0R1	0xc8010000	/* lfd   %fr0,0(%r1)	*/
17492828Sobrien#define BLR		0x4e800020	/* blr			*/
17592828Sobrien
17689857Sobrien/* Since .opd is an array of descriptors and each entry will end up
17789857Sobrien   with identical R_PPC64_RELATIVE relocs, there is really no need to
17889857Sobrien   propagate .opd relocs;  The dynamic linker should be taught to
179104834Sobrien   relocate .opd without reloc entries.  */
18089857Sobrien#ifndef NO_OPD_RELOCS
18189857Sobrien#define NO_OPD_RELOCS 0
18289857Sobrien#endif
18389857Sobrien
184104834Sobrien#define ONES(n) (((bfd_vma) 1 << ((n) - 1) << 1) - 1)
185130561Sobrien
18689857Sobrien/* Relocation HOWTO's.  */
187130561Sobrienstatic reloc_howto_type *ppc64_elf_howto_table[(int) R_PPC64_max];
18889857Sobrien
18989857Sobrienstatic reloc_howto_type ppc64_elf_howto_raw[] = {
19089857Sobrien  /* This reloc does nothing.  */
19189857Sobrien  HOWTO (R_PPC64_NONE,		/* type */
19289857Sobrien	 0,			/* rightshift */
193130561Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
194130561Sobrien	 32,			/* bitsize */
195130561Sobrien	 FALSE,			/* pc_relative */
19689857Sobrien	 0,			/* bitpos */
197104834Sobrien	 complain_overflow_dont, /* complain_on_overflow */
19889857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
19989857Sobrien	 "R_PPC64_NONE",	/* name */
200130561Sobrien	 FALSE,			/* partial_inplace */
20189857Sobrien	 0,			/* src_mask */
20289857Sobrien	 0,			/* dst_mask */
203130561Sobrien	 FALSE),		/* pcrel_offset */
20489857Sobrien
20589857Sobrien  /* A standard 32 bit relocation.  */
20689857Sobrien  HOWTO (R_PPC64_ADDR32,	/* type */
20789857Sobrien	 0,			/* rightshift */
20889857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
20989857Sobrien	 32,			/* bitsize */
210130561Sobrien	 FALSE,			/* pc_relative */
21189857Sobrien	 0,			/* bitpos */
21289857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
21389857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
21489857Sobrien	 "R_PPC64_ADDR32",	/* name */
215130561Sobrien	 FALSE,			/* partial_inplace */
21689857Sobrien	 0,			/* src_mask */
21789857Sobrien	 0xffffffff,		/* dst_mask */
218130561Sobrien	 FALSE),		/* pcrel_offset */
21989857Sobrien
22089857Sobrien  /* An absolute 26 bit branch; the lower two bits must be zero.
22189857Sobrien     FIXME: we don't check that, we just clear them.  */
22289857Sobrien  HOWTO (R_PPC64_ADDR24,	/* type */
22389857Sobrien	 0,			/* rightshift */
22489857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
22589857Sobrien	 26,			/* bitsize */
226130561Sobrien	 FALSE,			/* pc_relative */
22789857Sobrien	 0,			/* bitpos */
22889857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
22989857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
23089857Sobrien	 "R_PPC64_ADDR24",	/* name */
231130561Sobrien	 FALSE,			/* partial_inplace */
23289857Sobrien	 0,			/* src_mask */
233104834Sobrien	 0x03fffffc,		/* dst_mask */
234130561Sobrien	 FALSE),		/* pcrel_offset */
23589857Sobrien
23689857Sobrien  /* A standard 16 bit relocation.  */
23789857Sobrien  HOWTO (R_PPC64_ADDR16,	/* type */
23889857Sobrien	 0,			/* rightshift */
23989857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
24089857Sobrien	 16,			/* bitsize */
241130561Sobrien	 FALSE,			/* pc_relative */
24289857Sobrien	 0,			/* bitpos */
24389857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
24489857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
24589857Sobrien	 "R_PPC64_ADDR16",	/* name */
246130561Sobrien	 FALSE,			/* partial_inplace */
24789857Sobrien	 0,			/* src_mask */
24889857Sobrien	 0xffff,		/* dst_mask */
249130561Sobrien	 FALSE),		/* pcrel_offset */
25089857Sobrien
25189857Sobrien  /* A 16 bit relocation without overflow.  */
25289857Sobrien  HOWTO (R_PPC64_ADDR16_LO,	/* type */
25389857Sobrien	 0,			/* rightshift */
25489857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
25589857Sobrien	 16,			/* bitsize */
256130561Sobrien	 FALSE,			/* pc_relative */
25789857Sobrien	 0,			/* bitpos */
25889857Sobrien	 complain_overflow_dont,/* complain_on_overflow */
25989857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
26089857Sobrien	 "R_PPC64_ADDR16_LO",	/* name */
261130561Sobrien	 FALSE,			/* partial_inplace */
26289857Sobrien	 0,			/* src_mask */
26389857Sobrien	 0xffff,		/* dst_mask */
264130561Sobrien	 FALSE),		/* pcrel_offset */
26589857Sobrien
26689857Sobrien  /* Bits 16-31 of an address.  */
26789857Sobrien  HOWTO (R_PPC64_ADDR16_HI,	/* type */
26889857Sobrien	 16,			/* rightshift */
26989857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
27089857Sobrien	 16,			/* bitsize */
271130561Sobrien	 FALSE,			/* pc_relative */
27289857Sobrien	 0,			/* bitpos */
27389857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
27489857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
27589857Sobrien	 "R_PPC64_ADDR16_HI",	/* name */
276130561Sobrien	 FALSE,			/* partial_inplace */
27789857Sobrien	 0,			/* src_mask */
27889857Sobrien	 0xffff,		/* dst_mask */
279130561Sobrien	 FALSE),		/* pcrel_offset */
28089857Sobrien
28189857Sobrien  /* Bits 16-31 of an address, plus 1 if the contents of the low 16
28289857Sobrien     bits, treated as a signed number, is negative.  */
28389857Sobrien  HOWTO (R_PPC64_ADDR16_HA,	/* type */
28489857Sobrien	 16,			/* rightshift */
28589857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
28689857Sobrien	 16,			/* bitsize */
287130561Sobrien	 FALSE,			/* pc_relative */
28889857Sobrien	 0,			/* bitpos */
28989857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
29099461Sobrien	 ppc64_elf_ha_reloc,	/* special_function */
29189857Sobrien	 "R_PPC64_ADDR16_HA",	/* name */
292130561Sobrien	 FALSE,			/* partial_inplace */
29389857Sobrien	 0,			/* src_mask */
29489857Sobrien	 0xffff,		/* dst_mask */
295130561Sobrien	 FALSE),		/* pcrel_offset */
29689857Sobrien
29789857Sobrien  /* An absolute 16 bit branch; the lower two bits must be zero.
29889857Sobrien     FIXME: we don't check that, we just clear them.  */
29989857Sobrien  HOWTO (R_PPC64_ADDR14,	/* type */
30089857Sobrien	 0,			/* rightshift */
30189857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
30289857Sobrien	 16,			/* bitsize */
303130561Sobrien	 FALSE,			/* pc_relative */
30489857Sobrien	 0,			/* bitpos */
30589857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
30689857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
30789857Sobrien	 "R_PPC64_ADDR14",	/* name */
308130561Sobrien	 FALSE,			/* partial_inplace */
30989857Sobrien	 0,			/* src_mask */
310104834Sobrien	 0x0000fffc,		/* dst_mask */
311130561Sobrien	 FALSE),		/* pcrel_offset */
31289857Sobrien
31389857Sobrien  /* An absolute 16 bit branch, for which bit 10 should be set to
31489857Sobrien     indicate that the branch is expected to be taken.  The lower two
31589857Sobrien     bits must be zero.  */
31689857Sobrien  HOWTO (R_PPC64_ADDR14_BRTAKEN, /* type */
31789857Sobrien	 0,			/* rightshift */
31889857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
31989857Sobrien	 16,			/* bitsize */
320130561Sobrien	 FALSE,			/* pc_relative */
32189857Sobrien	 0,			/* bitpos */
32289857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
32399461Sobrien	 ppc64_elf_brtaken_reloc, /* special_function */
32489857Sobrien	 "R_PPC64_ADDR14_BRTAKEN",/* name */
325130561Sobrien	 FALSE,			/* partial_inplace */
32689857Sobrien	 0,			/* src_mask */
327104834Sobrien	 0x0000fffc,		/* dst_mask */
328130561Sobrien	 FALSE),		/* pcrel_offset */
32989857Sobrien
33089857Sobrien  /* An absolute 16 bit branch, for which bit 10 should be set to
33189857Sobrien     indicate that the branch is not expected to be taken.  The lower
33289857Sobrien     two bits must be zero.  */
33389857Sobrien  HOWTO (R_PPC64_ADDR14_BRNTAKEN, /* type */
33489857Sobrien	 0,			/* rightshift */
33589857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
33689857Sobrien	 16,			/* bitsize */
337130561Sobrien	 FALSE,			/* pc_relative */
33889857Sobrien	 0,			/* bitpos */
33989857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
34099461Sobrien	 ppc64_elf_brtaken_reloc, /* special_function */
34189857Sobrien	 "R_PPC64_ADDR14_BRNTAKEN",/* name */
342130561Sobrien	 FALSE,			/* partial_inplace */
34389857Sobrien	 0,			/* src_mask */
344104834Sobrien	 0x0000fffc,		/* dst_mask */
345130561Sobrien	 FALSE),		/* pcrel_offset */
34689857Sobrien
34789857Sobrien  /* A relative 26 bit branch; the lower two bits must be zero.  */
34889857Sobrien  HOWTO (R_PPC64_REL24,		/* type */
34989857Sobrien	 0,			/* rightshift */
35089857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
35189857Sobrien	 26,			/* bitsize */
352130561Sobrien	 TRUE,			/* pc_relative */
35389857Sobrien	 0,			/* bitpos */
35489857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
35589857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
35689857Sobrien	 "R_PPC64_REL24",	/* name */
357130561Sobrien	 FALSE,			/* partial_inplace */
35889857Sobrien	 0,			/* src_mask */
359104834Sobrien	 0x03fffffc,		/* dst_mask */
360130561Sobrien	 TRUE),			/* pcrel_offset */
36189857Sobrien
36289857Sobrien  /* A relative 16 bit branch; the lower two bits must be zero.  */
36389857Sobrien  HOWTO (R_PPC64_REL14,		/* type */
36489857Sobrien	 0,			/* rightshift */
36589857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
36689857Sobrien	 16,			/* bitsize */
367130561Sobrien	 TRUE,			/* pc_relative */
36889857Sobrien	 0,			/* bitpos */
36989857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
37089857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
37189857Sobrien	 "R_PPC64_REL14",	/* name */
372130561Sobrien	 FALSE,			/* partial_inplace */
37389857Sobrien	 0,			/* src_mask */
374104834Sobrien	 0x0000fffc,		/* dst_mask */
375130561Sobrien	 TRUE),			/* pcrel_offset */
37689857Sobrien
37789857Sobrien  /* A relative 16 bit branch.  Bit 10 should be set to indicate that
37889857Sobrien     the branch is expected to be taken.  The lower two bits must be
37989857Sobrien     zero.  */
38089857Sobrien  HOWTO (R_PPC64_REL14_BRTAKEN,	/* type */
38189857Sobrien	 0,			/* rightshift */
38289857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
38389857Sobrien	 16,			/* bitsize */
384130561Sobrien	 TRUE,			/* pc_relative */
38589857Sobrien	 0,			/* bitpos */
38689857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
38799461Sobrien	 ppc64_elf_brtaken_reloc, /* special_function */
38889857Sobrien	 "R_PPC64_REL14_BRTAKEN", /* name */
389130561Sobrien	 FALSE,			/* partial_inplace */
39089857Sobrien	 0,			/* src_mask */
391104834Sobrien	 0x0000fffc,		/* dst_mask */
392130561Sobrien	 TRUE),			/* pcrel_offset */
39389857Sobrien
39489857Sobrien  /* A relative 16 bit branch.  Bit 10 should be set to indicate that
39589857Sobrien     the branch is not expected to be taken.  The lower two bits must
39689857Sobrien     be zero.  */
39789857Sobrien  HOWTO (R_PPC64_REL14_BRNTAKEN, /* type */
39889857Sobrien	 0,			/* rightshift */
39989857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
40089857Sobrien	 16,			/* bitsize */
401130561Sobrien	 TRUE,			/* pc_relative */
40289857Sobrien	 0,			/* bitpos */
40389857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
40499461Sobrien	 ppc64_elf_brtaken_reloc, /* special_function */
40589857Sobrien	 "R_PPC64_REL14_BRNTAKEN",/* name */
406130561Sobrien	 FALSE,			/* partial_inplace */
40789857Sobrien	 0,			/* src_mask */
408104834Sobrien	 0x0000fffc,		/* dst_mask */
409130561Sobrien	 TRUE),			/* pcrel_offset */
41089857Sobrien
41189857Sobrien  /* Like R_PPC64_ADDR16, but referring to the GOT table entry for the
41289857Sobrien     symbol.  */
41389857Sobrien  HOWTO (R_PPC64_GOT16,		/* type */
41489857Sobrien	 0,			/* rightshift */
41589857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
41689857Sobrien	 16,			/* bitsize */
417130561Sobrien	 FALSE,			/* pc_relative */
41889857Sobrien	 0,			/* bitpos */
41989857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
42099461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
42189857Sobrien	 "R_PPC64_GOT16",	/* name */
422130561Sobrien	 FALSE,			/* partial_inplace */
42389857Sobrien	 0,			/* src_mask */
42489857Sobrien	 0xffff,		/* dst_mask */
425130561Sobrien	 FALSE),		/* pcrel_offset */
42689857Sobrien
42789857Sobrien  /* Like R_PPC64_ADDR16_LO, but referring to the GOT table entry for
42889857Sobrien     the symbol.  */
42989857Sobrien  HOWTO (R_PPC64_GOT16_LO,	/* type */
43089857Sobrien	 0,			/* rightshift */
43189857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
43289857Sobrien	 16,			/* bitsize */
433130561Sobrien	 FALSE,			/* pc_relative */
43489857Sobrien	 0,			/* bitpos */
43589857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
43699461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
43789857Sobrien	 "R_PPC64_GOT16_LO",	/* name */
438130561Sobrien	 FALSE,			/* partial_inplace */
43989857Sobrien	 0,			/* src_mask */
44089857Sobrien	 0xffff,		/* dst_mask */
441130561Sobrien	 FALSE),		/* pcrel_offset */
44289857Sobrien
44389857Sobrien  /* Like R_PPC64_ADDR16_HI, but referring to the GOT table entry for
44489857Sobrien     the symbol.  */
44589857Sobrien  HOWTO (R_PPC64_GOT16_HI,	/* type */
44689857Sobrien	 16,			/* rightshift */
44789857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
44889857Sobrien	 16,			/* bitsize */
449130561Sobrien	 FALSE,			/* pc_relative */
45089857Sobrien	 0,			/* bitpos */
45189857Sobrien	 complain_overflow_dont,/* complain_on_overflow */
45299461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
45389857Sobrien	 "R_PPC64_GOT16_HI",	/* name */
454130561Sobrien	 FALSE,			/* partial_inplace */
45589857Sobrien	 0,			/* src_mask */
45689857Sobrien	 0xffff,		/* dst_mask */
457130561Sobrien	 FALSE),		/* pcrel_offset */
45889857Sobrien
45989857Sobrien  /* Like R_PPC64_ADDR16_HA, but referring to the GOT table entry for
46089857Sobrien     the symbol.  */
46189857Sobrien  HOWTO (R_PPC64_GOT16_HA,	/* type */
46289857Sobrien	 16,			/* rightshift */
46389857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
46489857Sobrien	 16,			/* bitsize */
465130561Sobrien	 FALSE,			/* pc_relative */
46689857Sobrien	 0,			/* bitpos */
46789857Sobrien	 complain_overflow_dont,/* complain_on_overflow */
46899461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
46989857Sobrien	 "R_PPC64_GOT16_HA",	/* name */
470130561Sobrien	 FALSE,			/* partial_inplace */
47189857Sobrien	 0,			/* src_mask */
47289857Sobrien	 0xffff,		/* dst_mask */
473130561Sobrien	 FALSE),		/* pcrel_offset */
47489857Sobrien
47589857Sobrien  /* This is used only by the dynamic linker.  The symbol should exist
47689857Sobrien     both in the object being run and in some shared library.  The
47789857Sobrien     dynamic linker copies the data addressed by the symbol from the
47889857Sobrien     shared library into the object, because the object being
47989857Sobrien     run has to have the data at some particular address.  */
48089857Sobrien  HOWTO (R_PPC64_COPY,		/* type */
48189857Sobrien	 0,			/* rightshift */
482104834Sobrien	 0,			/* this one is variable size */
483104834Sobrien	 0,			/* bitsize */
484130561Sobrien	 FALSE,			/* pc_relative */
48589857Sobrien	 0,			/* bitpos */
486104834Sobrien	 complain_overflow_dont, /* complain_on_overflow */
487104834Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
48889857Sobrien	 "R_PPC64_COPY",	/* name */
489130561Sobrien	 FALSE,			/* partial_inplace */
49089857Sobrien	 0,			/* src_mask */
49189857Sobrien	 0,			/* dst_mask */
492130561Sobrien	 FALSE),		/* pcrel_offset */
49389857Sobrien
49489857Sobrien  /* Like R_PPC64_ADDR64, but used when setting global offset table
49589857Sobrien     entries.  */
49689857Sobrien  HOWTO (R_PPC64_GLOB_DAT,	/* type */
49789857Sobrien	 0,			/* rightshift */
49889857Sobrien	 4,			/* size (0=byte, 1=short, 2=long, 4=64 bits) */
49989857Sobrien	 64,			/* bitsize */
500130561Sobrien	 FALSE,			/* pc_relative */
50189857Sobrien	 0,			/* bitpos */
50289857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
50399461Sobrien	 ppc64_elf_unhandled_reloc,  /* special_function */
50489857Sobrien	 "R_PPC64_GLOB_DAT",	/* name */
505130561Sobrien	 FALSE,			/* partial_inplace */
50689857Sobrien	 0,			/* src_mask */
507104834Sobrien	 ONES (64),		/* dst_mask */
508130561Sobrien	 FALSE),		/* pcrel_offset */
50989857Sobrien
51089857Sobrien  /* Created by the link editor.  Marks a procedure linkage table
51189857Sobrien     entry for a symbol.  */
51289857Sobrien  HOWTO (R_PPC64_JMP_SLOT,	/* type */
51389857Sobrien	 0,			/* rightshift */
51489857Sobrien	 0,			/* size (0 = byte, 1 = short, 2 = long) */
51589857Sobrien	 0,			/* bitsize */
516130561Sobrien	 FALSE,			/* pc_relative */
51789857Sobrien	 0,			/* bitpos */
51889857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
51999461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
52089857Sobrien	 "R_PPC64_JMP_SLOT",	/* name */
521130561Sobrien	 FALSE,			/* partial_inplace */
52289857Sobrien	 0,			/* src_mask */
52389857Sobrien	 0,			/* dst_mask */
524130561Sobrien	 FALSE),		/* pcrel_offset */
52589857Sobrien
52689857Sobrien  /* Used only by the dynamic linker.  When the object is run, this
52789857Sobrien     doubleword64 is set to the load address of the object, plus the
52889857Sobrien     addend.  */
52989857Sobrien  HOWTO (R_PPC64_RELATIVE,	/* type */
53089857Sobrien	 0,			/* rightshift */
53189857Sobrien	 4,			/* size (0=byte, 1=short, 2=long, 4=64 bits) */
53289857Sobrien	 64,			/* bitsize */
533130561Sobrien	 FALSE,			/* pc_relative */
53489857Sobrien	 0,			/* bitpos */
53589857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
53689857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
53789857Sobrien	 "R_PPC64_RELATIVE",	/* name */
538130561Sobrien	 FALSE,			/* partial_inplace */
53989857Sobrien	 0,			/* src_mask */
540104834Sobrien	 ONES (64),		/* dst_mask */
541130561Sobrien	 FALSE),		/* pcrel_offset */
54289857Sobrien
54389857Sobrien  /* Like R_PPC64_ADDR32, but may be unaligned.  */
54489857Sobrien  HOWTO (R_PPC64_UADDR32,	/* type */
54589857Sobrien	 0,			/* rightshift */
54689857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
54789857Sobrien	 32,			/* bitsize */
548130561Sobrien	 FALSE,			/* pc_relative */
54989857Sobrien	 0,			/* bitpos */
55089857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
55189857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
55289857Sobrien	 "R_PPC64_UADDR32",	/* name */
553130561Sobrien	 FALSE,			/* partial_inplace */
55489857Sobrien	 0,			/* src_mask */
55589857Sobrien	 0xffffffff,		/* dst_mask */
556130561Sobrien	 FALSE),		/* pcrel_offset */
55789857Sobrien
55889857Sobrien  /* Like R_PPC64_ADDR16, but may be unaligned.  */
55989857Sobrien  HOWTO (R_PPC64_UADDR16,	/* type */
56089857Sobrien	 0,			/* rightshift */
56189857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
56289857Sobrien	 16,			/* bitsize */
563130561Sobrien	 FALSE,			/* pc_relative */
56489857Sobrien	 0,			/* bitpos */
56589857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
56689857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
56789857Sobrien	 "R_PPC64_UADDR16",	/* name */
568130561Sobrien	 FALSE,			/* partial_inplace */
56989857Sobrien	 0,			/* src_mask */
57089857Sobrien	 0xffff,		/* dst_mask */
571130561Sobrien	 FALSE),		/* pcrel_offset */
57289857Sobrien
57389857Sobrien  /* 32-bit PC relative.  */
57489857Sobrien  HOWTO (R_PPC64_REL32,		/* type */
57589857Sobrien	 0,			/* rightshift */
57689857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
57789857Sobrien	 32,			/* bitsize */
578130561Sobrien	 TRUE,			/* pc_relative */
57989857Sobrien	 0,			/* bitpos */
580104834Sobrien	 /* FIXME: Verify.  Was complain_overflow_bitfield.  */
58189857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
58289857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
58389857Sobrien	 "R_PPC64_REL32",	/* name */
584130561Sobrien	 FALSE,			/* partial_inplace */
58589857Sobrien	 0,			/* src_mask */
58689857Sobrien	 0xffffffff,		/* dst_mask */
587130561Sobrien	 TRUE),			/* pcrel_offset */
58889857Sobrien
58989857Sobrien  /* 32-bit relocation to the symbol's procedure linkage table.  */
59089857Sobrien  HOWTO (R_PPC64_PLT32,		/* type */
59189857Sobrien	 0,			/* rightshift */
59289857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
59389857Sobrien	 32,			/* bitsize */
594130561Sobrien	 FALSE,			/* pc_relative */
59589857Sobrien	 0,			/* bitpos */
59689857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
59799461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
59889857Sobrien	 "R_PPC64_PLT32",	/* name */
599130561Sobrien	 FALSE,			/* partial_inplace */
60089857Sobrien	 0,			/* src_mask */
601104834Sobrien	 0xffffffff,		/* dst_mask */
602130561Sobrien	 FALSE),		/* pcrel_offset */
60389857Sobrien
60489857Sobrien  /* 32-bit PC relative relocation to the symbol's procedure linkage table.
60589857Sobrien     FIXME: R_PPC64_PLTREL32 not supported.  */
60689857Sobrien  HOWTO (R_PPC64_PLTREL32,	/* type */
60789857Sobrien	 0,			/* rightshift */
60889857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
60989857Sobrien	 32,			/* bitsize */
610130561Sobrien	 TRUE,			/* pc_relative */
61189857Sobrien	 0,			/* bitpos */
61289857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
61389857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
61489857Sobrien	 "R_PPC64_PLTREL32",	/* name */
615130561Sobrien	 FALSE,			/* partial_inplace */
61689857Sobrien	 0,			/* src_mask */
617104834Sobrien	 0xffffffff,		/* dst_mask */
618130561Sobrien	 TRUE),			/* pcrel_offset */
61989857Sobrien
62089857Sobrien  /* Like R_PPC64_ADDR16_LO, but referring to the PLT table entry for
62189857Sobrien     the symbol.  */
62289857Sobrien  HOWTO (R_PPC64_PLT16_LO,	/* type */
62389857Sobrien	 0,			/* rightshift */
62489857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
62589857Sobrien	 16,			/* bitsize */
626130561Sobrien	 FALSE,			/* pc_relative */
62789857Sobrien	 0,			/* bitpos */
62889857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
62999461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
63089857Sobrien	 "R_PPC64_PLT16_LO",	/* name */
631130561Sobrien	 FALSE,			/* partial_inplace */
63289857Sobrien	 0,			/* src_mask */
63389857Sobrien	 0xffff,		/* dst_mask */
634130561Sobrien	 FALSE),		/* pcrel_offset */
63589857Sobrien
63689857Sobrien  /* Like R_PPC64_ADDR16_HI, but referring to the PLT table entry for
63789857Sobrien     the symbol.  */
63889857Sobrien  HOWTO (R_PPC64_PLT16_HI,	/* type */
63989857Sobrien	 16,			/* rightshift */
64089857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
64189857Sobrien	 16,			/* bitsize */
642130561Sobrien	 FALSE,			/* pc_relative */
64389857Sobrien	 0,			/* bitpos */
64489857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
64599461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
64689857Sobrien	 "R_PPC64_PLT16_HI",	/* name */
647130561Sobrien	 FALSE,			/* partial_inplace */
64889857Sobrien	 0,			/* src_mask */
64989857Sobrien	 0xffff,		/* dst_mask */
650130561Sobrien	 FALSE),		/* pcrel_offset */
65189857Sobrien
65289857Sobrien  /* Like R_PPC64_ADDR16_HA, but referring to the PLT table entry for
65389857Sobrien     the symbol.  */
65489857Sobrien  HOWTO (R_PPC64_PLT16_HA,	/* type */
65589857Sobrien	 16,			/* rightshift */
65689857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
65789857Sobrien	 16,			/* bitsize */
658130561Sobrien	 FALSE,			/* pc_relative */
65989857Sobrien	 0,			/* bitpos */
66089857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
66199461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
66289857Sobrien	 "R_PPC64_PLT16_HA",	/* name */
663130561Sobrien	 FALSE,			/* partial_inplace */
66489857Sobrien	 0,			/* src_mask */
66589857Sobrien	 0xffff,		/* dst_mask */
666130561Sobrien	 FALSE),		/* pcrel_offset */
66789857Sobrien
66899461Sobrien  /* 16-bit section relative relocation.  */
66989857Sobrien  HOWTO (R_PPC64_SECTOFF,	/* type */
67089857Sobrien	 0,			/* rightshift */
67199461Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
67299461Sobrien	 16,			/* bitsize */
673130561Sobrien	 FALSE,			/* pc_relative */
67489857Sobrien	 0,			/* bitpos */
67589857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
67699461Sobrien	 ppc64_elf_sectoff_reloc, /* special_function */
67789857Sobrien	 "R_PPC64_SECTOFF",	/* name */
678130561Sobrien	 FALSE,			/* partial_inplace */
67989857Sobrien	 0,			/* src_mask */
68099461Sobrien	 0xffff,		/* dst_mask */
681130561Sobrien	 FALSE),		/* pcrel_offset */
68289857Sobrien
68399461Sobrien  /* Like R_PPC64_SECTOFF, but no overflow warning.  */
68489857Sobrien  HOWTO (R_PPC64_SECTOFF_LO,	/* type */
68589857Sobrien	 0,			/* rightshift */
68689857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
68789857Sobrien	 16,			/* bitsize */
688130561Sobrien	 FALSE,			/* pc_relative */
68989857Sobrien	 0,			/* bitpos */
69089857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
69199461Sobrien	 ppc64_elf_sectoff_reloc, /* special_function */
69289857Sobrien	 "R_PPC64_SECTOFF_LO",	/* name */
693130561Sobrien	 FALSE,			/* partial_inplace */
69489857Sobrien	 0,			/* src_mask */
69589857Sobrien	 0xffff,		/* dst_mask */
696130561Sobrien	 FALSE),		/* pcrel_offset */
69789857Sobrien
69889857Sobrien  /* 16-bit upper half section relative relocation.  */
69989857Sobrien  HOWTO (R_PPC64_SECTOFF_HI,	/* type */
70089857Sobrien	 16,			/* rightshift */
70189857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
70289857Sobrien	 16,			/* bitsize */
703130561Sobrien	 FALSE,			/* pc_relative */
70489857Sobrien	 0,			/* bitpos */
70589857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
70699461Sobrien	 ppc64_elf_sectoff_reloc, /* special_function */
70789857Sobrien	 "R_PPC64_SECTOFF_HI",	/* name */
708130561Sobrien	 FALSE,			/* partial_inplace */
70989857Sobrien	 0,			/* src_mask */
71089857Sobrien	 0xffff,		/* dst_mask */
711130561Sobrien	 FALSE),		/* pcrel_offset */
71289857Sobrien
71389857Sobrien  /* 16-bit upper half adjusted section relative relocation.  */
71489857Sobrien  HOWTO (R_PPC64_SECTOFF_HA,	/* type */
71589857Sobrien	 16,			/* rightshift */
71689857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
71789857Sobrien	 16,			/* bitsize */
718130561Sobrien	 FALSE,			/* pc_relative */
71989857Sobrien	 0,			/* bitpos */
72089857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
72199461Sobrien	 ppc64_elf_sectoff_ha_reloc, /* special_function */
72289857Sobrien	 "R_PPC64_SECTOFF_HA",	/* name */
723130561Sobrien	 FALSE,			/* partial_inplace */
72489857Sobrien	 0,			/* src_mask */
72589857Sobrien	 0xffff,		/* dst_mask */
726130561Sobrien	 FALSE),		/* pcrel_offset */
72789857Sobrien
728130561Sobrien  /* Like R_PPC64_REL24 without touching the two least significant bits.  */
729130561Sobrien  HOWTO (R_PPC64_REL30,		/* type */
73089857Sobrien	 2,			/* rightshift */
73189857Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
73289857Sobrien	 30,			/* bitsize */
733130561Sobrien	 TRUE,			/* pc_relative */
73489857Sobrien	 0,			/* bitpos */
73589857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
73689857Sobrien	 bfd_elf_generic_reloc, /* special_function */
737130561Sobrien	 "R_PPC64_REL30",	/* name */
738130561Sobrien	 FALSE,			/* partial_inplace */
73989857Sobrien	 0,			/* src_mask */
74089857Sobrien	 0xfffffffc,		/* dst_mask */
741130561Sobrien	 TRUE),			/* pcrel_offset */
74289857Sobrien
74389857Sobrien  /* Relocs in the 64-bit PowerPC ELF ABI, not in the 32-bit ABI.  */
74489857Sobrien
74589857Sobrien  /* A standard 64-bit relocation.  */
74689857Sobrien  HOWTO (R_PPC64_ADDR64,	/* type */
74789857Sobrien	 0,			/* rightshift */
74889857Sobrien	 4,			/* size (0=byte, 1=short, 2=long, 4=64 bits) */
74989857Sobrien	 64,			/* bitsize */
750130561Sobrien	 FALSE,			/* pc_relative */
75189857Sobrien	 0,			/* bitpos */
75289857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
75389857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
75489857Sobrien	 "R_PPC64_ADDR64",	/* name */
755130561Sobrien	 FALSE,			/* partial_inplace */
75689857Sobrien	 0,			/* src_mask */
757104834Sobrien	 ONES (64),		/* dst_mask */
758130561Sobrien	 FALSE),		/* pcrel_offset */
75989857Sobrien
76089857Sobrien  /* The bits 32-47 of an address.  */
76189857Sobrien  HOWTO (R_PPC64_ADDR16_HIGHER,	/* type */
76289857Sobrien	 32,			/* rightshift */
76389857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
76489857Sobrien	 16,			/* bitsize */
765130561Sobrien	 FALSE,			/* pc_relative */
76689857Sobrien	 0,			/* bitpos */
76789857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
76889857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
76989857Sobrien	 "R_PPC64_ADDR16_HIGHER", /* name */
770130561Sobrien	 FALSE,			/* partial_inplace */
77189857Sobrien	 0,			/* src_mask */
77289857Sobrien	 0xffff,		/* dst_mask */
773130561Sobrien	 FALSE),		/* pcrel_offset */
77489857Sobrien
77589857Sobrien  /* The bits 32-47 of an address, plus 1 if the contents of the low
77689857Sobrien     16 bits, treated as a signed number, is negative.  */
77789857Sobrien  HOWTO (R_PPC64_ADDR16_HIGHERA, /* type */
77889857Sobrien	 32,			/* rightshift */
77989857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
78089857Sobrien	 16,			/* bitsize */
781130561Sobrien	 FALSE,			/* pc_relative */
78289857Sobrien	 0,			/* bitpos */
78389857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
78499461Sobrien	 ppc64_elf_ha_reloc,	/* special_function */
78589857Sobrien	 "R_PPC64_ADDR16_HIGHERA", /* name */
786130561Sobrien	 FALSE,			/* partial_inplace */
78789857Sobrien	 0,			/* src_mask */
78889857Sobrien	 0xffff,		/* dst_mask */
789130561Sobrien	 FALSE),		/* pcrel_offset */
79089857Sobrien
79189857Sobrien  /* The bits 48-63 of an address.  */
79289857Sobrien  HOWTO (R_PPC64_ADDR16_HIGHEST,/* type */
79389857Sobrien	 48,			/* rightshift */
79489857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
79589857Sobrien	 16,			/* bitsize */
796130561Sobrien	 FALSE,			/* pc_relative */
79789857Sobrien	 0,			/* bitpos */
79889857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
79989857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
80089857Sobrien	 "R_PPC64_ADDR16_HIGHEST", /* name */
801130561Sobrien	 FALSE,			/* partial_inplace */
80289857Sobrien	 0,			/* src_mask */
80389857Sobrien	 0xffff,		/* dst_mask */
804130561Sobrien	 FALSE),		/* pcrel_offset */
80589857Sobrien
80689857Sobrien  /* The bits 48-63 of an address, plus 1 if the contents of the low
80789857Sobrien     16 bits, treated as a signed number, is negative.  */
80889857Sobrien  HOWTO (R_PPC64_ADDR16_HIGHESTA,/* type */
80989857Sobrien	 48,			/* rightshift */
81089857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
81189857Sobrien	 16,			/* bitsize */
812130561Sobrien	 FALSE,			/* pc_relative */
81389857Sobrien	 0,			/* bitpos */
81489857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
81599461Sobrien	 ppc64_elf_ha_reloc,	/* special_function */
81689857Sobrien	 "R_PPC64_ADDR16_HIGHESTA", /* name */
817130561Sobrien	 FALSE,			/* partial_inplace */
81889857Sobrien	 0,			/* src_mask */
81989857Sobrien	 0xffff,		/* dst_mask */
820130561Sobrien	 FALSE),		/* pcrel_offset */
82189857Sobrien
82289857Sobrien  /* Like ADDR64, but may be unaligned.  */
82389857Sobrien  HOWTO (R_PPC64_UADDR64,	/* type */
82489857Sobrien	 0,			/* rightshift */
82589857Sobrien	 4,			/* size (0=byte, 1=short, 2=long, 4=64 bits) */
82689857Sobrien	 64,			/* bitsize */
827130561Sobrien	 FALSE,			/* pc_relative */
82889857Sobrien	 0,			/* bitpos */
82989857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
83089857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
83189857Sobrien	 "R_PPC64_UADDR64",	/* name */
832130561Sobrien	 FALSE,			/* partial_inplace */
83389857Sobrien	 0,			/* src_mask */
834104834Sobrien	 ONES (64),		/* dst_mask */
835130561Sobrien	 FALSE),		/* pcrel_offset */
83689857Sobrien
83789857Sobrien  /* 64-bit relative relocation.  */
83889857Sobrien  HOWTO (R_PPC64_REL64,		/* type */
83989857Sobrien	 0,			/* rightshift */
84089857Sobrien	 4,			/* size (0=byte, 1=short, 2=long, 4=64 bits) */
84189857Sobrien	 64,			/* bitsize */
842130561Sobrien	 TRUE,			/* pc_relative */
84389857Sobrien	 0,			/* bitpos */
84489857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
84589857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
84689857Sobrien	 "R_PPC64_REL64",	/* name */
847130561Sobrien	 FALSE,			/* partial_inplace */
84889857Sobrien	 0,			/* src_mask */
849104834Sobrien	 ONES (64),		/* dst_mask */
850130561Sobrien	 TRUE),			/* pcrel_offset */
85189857Sobrien
852104834Sobrien  /* 64-bit relocation to the symbol's procedure linkage table.  */
85389857Sobrien  HOWTO (R_PPC64_PLT64,		/* type */
85489857Sobrien	 0,			/* rightshift */
85589857Sobrien	 4,			/* size (0=byte, 1=short, 2=long, 4=64 bits) */
85689857Sobrien	 64,			/* bitsize */
857130561Sobrien	 FALSE,			/* pc_relative */
85889857Sobrien	 0,			/* bitpos */
85989857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
86099461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
86189857Sobrien	 "R_PPC64_PLT64",	/* name */
862130561Sobrien	 FALSE,			/* partial_inplace */
86389857Sobrien	 0,			/* src_mask */
864104834Sobrien	 ONES (64),		/* dst_mask */
865130561Sobrien	 FALSE),		/* pcrel_offset */
86689857Sobrien
86789857Sobrien  /* 64-bit PC relative relocation to the symbol's procedure linkage
86889857Sobrien     table.  */
86989857Sobrien  /* FIXME: R_PPC64_PLTREL64 not supported.  */
87089857Sobrien  HOWTO (R_PPC64_PLTREL64,	/* type */
87189857Sobrien	 0,			/* rightshift */
87289857Sobrien	 4,			/* size (0=byte, 1=short, 2=long, 4=64 bits) */
87389857Sobrien	 64,			/* bitsize */
874130561Sobrien	 TRUE,			/* pc_relative */
87589857Sobrien	 0,			/* bitpos */
87689857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
87799461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
87889857Sobrien	 "R_PPC64_PLTREL64",	/* name */
879130561Sobrien	 FALSE,			/* partial_inplace */
88089857Sobrien	 0,			/* src_mask */
881104834Sobrien	 ONES (64),		/* dst_mask */
882130561Sobrien	 TRUE),			/* pcrel_offset */
88389857Sobrien
88489857Sobrien  /* 16 bit TOC-relative relocation.  */
88589857Sobrien
88689857Sobrien  /* R_PPC64_TOC16	  47	   half16*	S + A - .TOC.  */
88789857Sobrien  HOWTO (R_PPC64_TOC16,		/* type */
88889857Sobrien	 0,			/* rightshift */
88989857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
89089857Sobrien	 16,			/* bitsize */
891130561Sobrien	 FALSE,			/* pc_relative */
89289857Sobrien	 0,			/* bitpos */
89389857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
89499461Sobrien	 ppc64_elf_toc_reloc,	/* special_function */
89589857Sobrien	 "R_PPC64_TOC16",	/* name */
896130561Sobrien	 FALSE,			/* partial_inplace */
89789857Sobrien	 0,			/* src_mask */
89889857Sobrien	 0xffff,		/* dst_mask */
899130561Sobrien	 FALSE),		/* pcrel_offset */
90089857Sobrien
90189857Sobrien  /* 16 bit TOC-relative relocation without overflow.  */
90289857Sobrien
90389857Sobrien  /* R_PPC64_TOC16_LO	  48	   half16	 #lo (S + A - .TOC.)  */
90489857Sobrien  HOWTO (R_PPC64_TOC16_LO,	/* type */
90589857Sobrien	 0,			/* rightshift */
90689857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
90789857Sobrien	 16,			/* bitsize */
908130561Sobrien	 FALSE,			/* pc_relative */
90989857Sobrien	 0,			/* bitpos */
91089857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
91199461Sobrien	 ppc64_elf_toc_reloc,	/* special_function */
91289857Sobrien	 "R_PPC64_TOC16_LO",	/* name */
913130561Sobrien	 FALSE,			/* partial_inplace */
91489857Sobrien	 0,			/* src_mask */
91589857Sobrien	 0xffff,		/* dst_mask */
916130561Sobrien	 FALSE),		/* pcrel_offset */
91789857Sobrien
91889857Sobrien  /* 16 bit TOC-relative relocation, high 16 bits.  */
91989857Sobrien
92089857Sobrien  /* R_PPC64_TOC16_HI	  49	   half16	 #hi (S + A - .TOC.)  */
92189857Sobrien  HOWTO (R_PPC64_TOC16_HI,	/* type */
92289857Sobrien	 16,			/* rightshift */
92389857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
92489857Sobrien	 16,			/* bitsize */
925130561Sobrien	 FALSE,			/* pc_relative */
92689857Sobrien	 0,			/* bitpos */
92789857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
92899461Sobrien	 ppc64_elf_toc_reloc,	/* special_function */
92989857Sobrien	 "R_PPC64_TOC16_HI",	/* name */
930130561Sobrien	 FALSE,			/* partial_inplace */
93189857Sobrien	 0,			/* src_mask */
93289857Sobrien	 0xffff,		/* dst_mask */
933130561Sobrien	 FALSE),		/* pcrel_offset */
93489857Sobrien
93589857Sobrien  /* 16 bit TOC-relative relocation, high 16 bits, plus 1 if the
93689857Sobrien     contents of the low 16 bits, treated as a signed number, is
93789857Sobrien     negative.  */
93889857Sobrien
93989857Sobrien  /* R_PPC64_TOC16_HA	  50	   half16	 #ha (S + A - .TOC.)  */
94089857Sobrien  HOWTO (R_PPC64_TOC16_HA,	/* type */
94189857Sobrien	 16,			/* rightshift */
94289857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
94389857Sobrien	 16,			/* bitsize */
944130561Sobrien	 FALSE,			/* pc_relative */
94589857Sobrien	 0,			/* bitpos */
94689857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
94799461Sobrien	 ppc64_elf_toc_ha_reloc, /* special_function */
94889857Sobrien	 "R_PPC64_TOC16_HA",	/* name */
949130561Sobrien	 FALSE,			/* partial_inplace */
95089857Sobrien	 0,			/* src_mask */
95189857Sobrien	 0xffff,		/* dst_mask */
952130561Sobrien	 FALSE),		/* pcrel_offset */
95389857Sobrien
95489857Sobrien  /* 64-bit relocation; insert value of TOC base (.TOC.).  */
95589857Sobrien
95689857Sobrien  /* R_PPC64_TOC		  51	   doubleword64	 .TOC.  */
95789857Sobrien  HOWTO (R_PPC64_TOC,		/* type */
95889857Sobrien	 0,			/* rightshift */
95989857Sobrien	 4,			/* size (0=byte, 1=short, 2=long, 4=64 bits) */
96089857Sobrien	 64,			/* bitsize */
961130561Sobrien	 FALSE,			/* pc_relative */
96289857Sobrien	 0,			/* bitpos */
96389857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
96499461Sobrien	 ppc64_elf_toc64_reloc,	/* special_function */
96589857Sobrien	 "R_PPC64_TOC",		/* name */
966130561Sobrien	 FALSE,			/* partial_inplace */
96789857Sobrien	 0,			/* src_mask */
968104834Sobrien	 ONES (64),		/* dst_mask */
969130561Sobrien	 FALSE),		/* pcrel_offset */
97089857Sobrien
97189857Sobrien  /* Like R_PPC64_GOT16, but also informs the link editor that the
97289857Sobrien     value to relocate may (!) refer to a PLT entry which the link
97389857Sobrien     editor (a) may replace with the symbol value.  If the link editor
97489857Sobrien     is unable to fully resolve the symbol, it may (b) create a PLT
97589857Sobrien     entry and store the address to the new PLT entry in the GOT.
97689857Sobrien     This permits lazy resolution of function symbols at run time.
97789857Sobrien     The link editor may also skip all of this and just (c) emit a
97889857Sobrien     R_PPC64_GLOB_DAT to tie the symbol to the GOT entry.  */
97989857Sobrien  /* FIXME: R_PPC64_PLTGOT16 not implemented.  */
98089857Sobrien    HOWTO (R_PPC64_PLTGOT16,	/* type */
98189857Sobrien	 0,			/* rightshift */
98289857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
98389857Sobrien	 16,			/* bitsize */
984130561Sobrien	 FALSE,			/* pc_relative */
98589857Sobrien	 0,			/* bitpos */
98689857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
98799461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
98889857Sobrien	 "R_PPC64_PLTGOT16",	/* name */
989130561Sobrien	 FALSE,			/* partial_inplace */
99089857Sobrien	 0,			/* src_mask */
99189857Sobrien	 0xffff,		/* dst_mask */
992130561Sobrien	 FALSE),		/* pcrel_offset */
99389857Sobrien
99489857Sobrien  /* Like R_PPC64_PLTGOT16, but without overflow.  */
99589857Sobrien  /* FIXME: R_PPC64_PLTGOT16_LO not implemented.  */
99689857Sobrien  HOWTO (R_PPC64_PLTGOT16_LO,	/* type */
99789857Sobrien	 0,			/* rightshift */
99889857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
99989857Sobrien	 16,			/* bitsize */
1000130561Sobrien	 FALSE,			/* pc_relative */
100189857Sobrien	 0,			/* bitpos */
100289857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
100399461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
100489857Sobrien	 "R_PPC64_PLTGOT16_LO",	/* name */
1005130561Sobrien	 FALSE,			/* partial_inplace */
100689857Sobrien	 0,			/* src_mask */
100789857Sobrien	 0xffff,		/* dst_mask */
1008130561Sobrien	 FALSE),		/* pcrel_offset */
100989857Sobrien
101089857Sobrien  /* Like R_PPC64_PLT_GOT16, but using bits 16-31 of the address.  */
101189857Sobrien  /* FIXME: R_PPC64_PLTGOT16_HI not implemented.  */
101289857Sobrien  HOWTO (R_PPC64_PLTGOT16_HI,	/* type */
101389857Sobrien	 16,			/* rightshift */
101489857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
101589857Sobrien	 16,			/* bitsize */
1016130561Sobrien	 FALSE,			/* pc_relative */
101789857Sobrien	 0,			/* bitpos */
101889857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
101999461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
102089857Sobrien	 "R_PPC64_PLTGOT16_HI",	/* name */
1021130561Sobrien	 FALSE,			/* partial_inplace */
102289857Sobrien	 0,			/* src_mask */
102389857Sobrien	 0xffff,		/* dst_mask */
1024130561Sobrien	 FALSE),		/* pcrel_offset */
102589857Sobrien
102689857Sobrien  /* Like R_PPC64_PLT_GOT16, but using bits 16-31 of the address, plus
102789857Sobrien     1 if the contents of the low 16 bits, treated as a signed number,
102889857Sobrien     is negative.  */
102989857Sobrien  /* FIXME: R_PPC64_PLTGOT16_HA not implemented.  */
103089857Sobrien  HOWTO (R_PPC64_PLTGOT16_HA,	/* type */
103189857Sobrien	 16,			/* rightshift */
103289857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
103389857Sobrien	 16,			/* bitsize */
1034130561Sobrien	 FALSE,			/* pc_relative */
103589857Sobrien	 0,			/* bitpos */
103689857Sobrien	 complain_overflow_dont,/* complain_on_overflow */
103799461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
103889857Sobrien	 "R_PPC64_PLTGOT16_HA",	/* name */
1039130561Sobrien	 FALSE,			/* partial_inplace */
104089857Sobrien	 0,			/* src_mask */
104189857Sobrien	 0xffff,		/* dst_mask */
1042130561Sobrien	 FALSE),		/* pcrel_offset */
104389857Sobrien
104489857Sobrien  /* Like R_PPC64_ADDR16, but for instructions with a DS field.  */
104589857Sobrien  HOWTO (R_PPC64_ADDR16_DS,	/* type */
104689857Sobrien	 0,			/* rightshift */
104789857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
104889857Sobrien	 16,			/* bitsize */
1049130561Sobrien	 FALSE,			/* pc_relative */
105089857Sobrien	 0,			/* bitpos */
105189857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
105289857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
105389857Sobrien	 "R_PPC64_ADDR16_DS",	/* name */
1054130561Sobrien	 FALSE,			/* partial_inplace */
105589857Sobrien	 0,			/* src_mask */
105689857Sobrien	 0xfffc,		/* dst_mask */
1057130561Sobrien	 FALSE),		/* pcrel_offset */
105889857Sobrien
105989857Sobrien  /* Like R_PPC64_ADDR16_LO, but for instructions with a DS field.  */
106089857Sobrien  HOWTO (R_PPC64_ADDR16_LO_DS,	/* type */
106189857Sobrien	 0,			/* rightshift */
106289857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
106389857Sobrien	 16,			/* bitsize */
1064130561Sobrien	 FALSE,			/* pc_relative */
106589857Sobrien	 0,			/* bitpos */
106689857Sobrien	 complain_overflow_dont,/* complain_on_overflow */
106789857Sobrien	 bfd_elf_generic_reloc,	/* special_function */
106889857Sobrien	 "R_PPC64_ADDR16_LO_DS",/* name */
1069130561Sobrien	 FALSE,			/* partial_inplace */
107089857Sobrien	 0,			/* src_mask */
107189857Sobrien	 0xfffc,		/* dst_mask */
1072130561Sobrien	 FALSE),		/* pcrel_offset */
107389857Sobrien
107489857Sobrien  /* Like R_PPC64_GOT16, but for instructions with a DS field.  */
107589857Sobrien  HOWTO (R_PPC64_GOT16_DS,	/* type */
107689857Sobrien	 0,			/* rightshift */
107789857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
107889857Sobrien	 16,			/* bitsize */
1079130561Sobrien	 FALSE,			/* pc_relative */
108089857Sobrien	 0,			/* bitpos */
108189857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
108299461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
108389857Sobrien	 "R_PPC64_GOT16_DS",	/* name */
1084130561Sobrien	 FALSE,			/* partial_inplace */
108589857Sobrien	 0,			/* src_mask */
108689857Sobrien	 0xfffc,		/* dst_mask */
1087130561Sobrien	 FALSE),		/* pcrel_offset */
108889857Sobrien
108989857Sobrien  /* Like R_PPC64_GOT16_LO, but for instructions with a DS field.  */
109089857Sobrien  HOWTO (R_PPC64_GOT16_LO_DS,	/* type */
109189857Sobrien	 0,			/* rightshift */
109289857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
109389857Sobrien	 16,			/* bitsize */
1094130561Sobrien	 FALSE,			/* pc_relative */
109589857Sobrien	 0,			/* bitpos */
109689857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
109799461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
109889857Sobrien	 "R_PPC64_GOT16_LO_DS",	/* name */
1099130561Sobrien	 FALSE,			/* partial_inplace */
110089857Sobrien	 0,			/* src_mask */
110189857Sobrien	 0xfffc,		/* dst_mask */
1102130561Sobrien	 FALSE),		/* pcrel_offset */
110389857Sobrien
110489857Sobrien  /* Like R_PPC64_PLT16_LO, but for instructions with a DS field.  */
110589857Sobrien  HOWTO (R_PPC64_PLT16_LO_DS,	/* type */
110689857Sobrien	 0,			/* rightshift */
110789857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
110889857Sobrien	 16,			/* bitsize */
1109130561Sobrien	 FALSE,			/* pc_relative */
111089857Sobrien	 0,			/* bitpos */
111189857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
111299461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
111389857Sobrien	 "R_PPC64_PLT16_LO_DS",	/* name */
1114130561Sobrien	 FALSE,			/* partial_inplace */
111589857Sobrien	 0,			/* src_mask */
111689857Sobrien	 0xfffc,		/* dst_mask */
1117130561Sobrien	 FALSE),		/* pcrel_offset */
111889857Sobrien
111989857Sobrien  /* Like R_PPC64_SECTOFF, but for instructions with a DS field.  */
112089857Sobrien  HOWTO (R_PPC64_SECTOFF_DS,	/* type */
112189857Sobrien	 0,			/* rightshift */
112299461Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
112399461Sobrien	 16,			/* bitsize */
1124130561Sobrien	 FALSE,			/* pc_relative */
112589857Sobrien	 0,			/* bitpos */
112689857Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
112799461Sobrien	 ppc64_elf_sectoff_reloc, /* special_function */
112889857Sobrien	 "R_PPC64_SECTOFF_DS",	/* name */
1129130561Sobrien	 FALSE,			/* partial_inplace */
113089857Sobrien	 0,			/* src_mask */
113199461Sobrien	 0xfffc,		/* dst_mask */
1132130561Sobrien	 FALSE),		/* pcrel_offset */
113389857Sobrien
113489857Sobrien  /* Like R_PPC64_SECTOFF_LO, but for instructions with a DS field.  */
113589857Sobrien  HOWTO (R_PPC64_SECTOFF_LO_DS, /* type */
113689857Sobrien	 0,			/* rightshift */
113789857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
113889857Sobrien	 16,			/* bitsize */
1139130561Sobrien	 FALSE,			/* pc_relative */
114089857Sobrien	 0,			/* bitpos */
114189857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
114299461Sobrien	 ppc64_elf_sectoff_reloc, /* special_function */
114389857Sobrien	 "R_PPC64_SECTOFF_LO_DS",/* name */
1144130561Sobrien	 FALSE,			/* partial_inplace */
114589857Sobrien	 0,			/* src_mask */
114689857Sobrien	 0xfffc,		/* dst_mask */
1147130561Sobrien	 FALSE),		/* pcrel_offset */
114889857Sobrien
114989857Sobrien  /* Like R_PPC64_TOC16, but for instructions with a DS field.  */
115089857Sobrien  HOWTO (R_PPC64_TOC16_DS,	/* type */
115189857Sobrien	 0,			/* rightshift */
115289857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
115389857Sobrien	 16,			/* bitsize */
1154130561Sobrien	 FALSE,			/* pc_relative */
115589857Sobrien	 0,			/* bitpos */
115689857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
115799461Sobrien	 ppc64_elf_toc_reloc,	/* special_function */
115889857Sobrien	 "R_PPC64_TOC16_DS",	/* name */
1159130561Sobrien	 FALSE,			/* partial_inplace */
116089857Sobrien	 0,			/* src_mask */
116189857Sobrien	 0xfffc,		/* dst_mask */
1162130561Sobrien	 FALSE),		/* pcrel_offset */
116389857Sobrien
116489857Sobrien  /* Like R_PPC64_TOC16_LO, but for instructions with a DS field.  */
116589857Sobrien  HOWTO (R_PPC64_TOC16_LO_DS,	/* type */
116689857Sobrien	 0,			/* rightshift */
116789857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
116889857Sobrien	 16,			/* bitsize */
1169130561Sobrien	 FALSE,			/* pc_relative */
117089857Sobrien	 0,			/* bitpos */
117189857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
117299461Sobrien	 ppc64_elf_toc_reloc,	/* special_function */
117389857Sobrien	 "R_PPC64_TOC16_LO_DS",	/* name */
1174130561Sobrien	 FALSE,			/* partial_inplace */
117589857Sobrien	 0,			/* src_mask */
117689857Sobrien	 0xfffc,		/* dst_mask */
1177130561Sobrien	 FALSE),		/* pcrel_offset */
117889857Sobrien
117989857Sobrien  /* Like R_PPC64_PLTGOT16, but for instructions with a DS field.  */
118089857Sobrien  /* FIXME: R_PPC64_PLTGOT16_DS not implemented.  */
118189857Sobrien    HOWTO (R_PPC64_PLTGOT16_DS,	/* type */
118289857Sobrien	 0,			/* rightshift */
118389857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
118489857Sobrien	 16,			/* bitsize */
1185130561Sobrien	 FALSE,			/* pc_relative */
118689857Sobrien	 0,			/* bitpos */
118789857Sobrien	 complain_overflow_signed, /* complain_on_overflow */
118899461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
118989857Sobrien	 "R_PPC64_PLTGOT16_DS",	/* name */
1190130561Sobrien	 FALSE,			/* partial_inplace */
119189857Sobrien	 0,			/* src_mask */
119289857Sobrien	 0xfffc,		/* dst_mask */
1193130561Sobrien	 FALSE),		/* pcrel_offset */
119489857Sobrien
119589857Sobrien  /* Like R_PPC64_PLTGOT16_LO, but for instructions with a DS field.  */
119689857Sobrien  /* FIXME: R_PPC64_PLTGOT16_LO not implemented.  */
119789857Sobrien  HOWTO (R_PPC64_PLTGOT16_LO_DS,/* type */
119889857Sobrien	 0,			/* rightshift */
119989857Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
120089857Sobrien	 16,			/* bitsize */
1201130561Sobrien	 FALSE,			/* pc_relative */
120289857Sobrien	 0,			/* bitpos */
120389857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
120499461Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
120589857Sobrien	 "R_PPC64_PLTGOT16_LO_DS",/* name */
1206130561Sobrien	 FALSE,			/* partial_inplace */
120789857Sobrien	 0,			/* src_mask */
120889857Sobrien	 0xfffc,		/* dst_mask */
1209130561Sobrien	 FALSE),		/* pcrel_offset */
121089857Sobrien
1211130561Sobrien  /* Marker reloc for TLS.  */
1212130561Sobrien  HOWTO (R_PPC64_TLS,
1213130561Sobrien	 0,			/* rightshift */
1214130561Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1215130561Sobrien	 32,			/* bitsize */
1216130561Sobrien	 FALSE,			/* pc_relative */
1217130561Sobrien	 0,			/* bitpos */
1218130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1219130561Sobrien	 bfd_elf_generic_reloc,	/* special_function */
1220130561Sobrien	 "R_PPC64_TLS",		/* name */
1221130561Sobrien	 FALSE,			/* partial_inplace */
1222130561Sobrien	 0,			/* src_mask */
1223130561Sobrien	 0,			/* dst_mask */
1224130561Sobrien	 FALSE),		/* pcrel_offset */
1225130561Sobrien
1226130561Sobrien  /* Computes the load module index of the load module that contains the
1227130561Sobrien     definition of its TLS sym.  */
1228130561Sobrien  HOWTO (R_PPC64_DTPMOD64,
1229130561Sobrien	 0,			/* rightshift */
1230130561Sobrien	 4,			/* size (0 = byte, 1 = short, 2 = long) */
1231130561Sobrien	 64,			/* bitsize */
1232130561Sobrien	 FALSE,			/* pc_relative */
1233130561Sobrien	 0,			/* bitpos */
1234130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1235130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1236130561Sobrien	 "R_PPC64_DTPMOD64",	/* name */
1237130561Sobrien	 FALSE,			/* partial_inplace */
1238130561Sobrien	 0,			/* src_mask */
1239130561Sobrien	 ONES (64),		/* dst_mask */
1240130561Sobrien	 FALSE),		/* pcrel_offset */
1241130561Sobrien
1242130561Sobrien  /* Computes a dtv-relative displacement, the difference between the value
1243130561Sobrien     of sym+add and the base address of the thread-local storage block that
1244130561Sobrien     contains the definition of sym, minus 0x8000.  */
1245130561Sobrien  HOWTO (R_PPC64_DTPREL64,
1246130561Sobrien	 0,			/* rightshift */
1247130561Sobrien	 4,			/* size (0 = byte, 1 = short, 2 = long) */
1248130561Sobrien	 64,			/* bitsize */
1249130561Sobrien	 FALSE,			/* pc_relative */
1250130561Sobrien	 0,			/* bitpos */
1251130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1252130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1253130561Sobrien	 "R_PPC64_DTPREL64",	/* name */
1254130561Sobrien	 FALSE,			/* partial_inplace */
1255130561Sobrien	 0,			/* src_mask */
1256130561Sobrien	 ONES (64),		/* dst_mask */
1257130561Sobrien	 FALSE),		/* pcrel_offset */
1258130561Sobrien
1259130561Sobrien  /* A 16 bit dtprel reloc.  */
1260130561Sobrien  HOWTO (R_PPC64_DTPREL16,
1261130561Sobrien	 0,			/* rightshift */
1262130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1263130561Sobrien	 16,			/* bitsize */
1264130561Sobrien	 FALSE,			/* pc_relative */
1265130561Sobrien	 0,			/* bitpos */
1266130561Sobrien	 complain_overflow_signed, /* complain_on_overflow */
1267130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1268130561Sobrien	 "R_PPC64_DTPREL16",	/* name */
1269130561Sobrien	 FALSE,			/* partial_inplace */
1270130561Sobrien	 0,			/* src_mask */
1271130561Sobrien	 0xffff,		/* dst_mask */
1272130561Sobrien	 FALSE),		/* pcrel_offset */
1273130561Sobrien
1274130561Sobrien  /* Like DTPREL16, but no overflow.  */
1275130561Sobrien  HOWTO (R_PPC64_DTPREL16_LO,
1276130561Sobrien	 0,			/* rightshift */
1277130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1278130561Sobrien	 16,			/* bitsize */
1279130561Sobrien	 FALSE,			/* pc_relative */
1280130561Sobrien	 0,			/* bitpos */
1281130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1282130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1283130561Sobrien	 "R_PPC64_DTPREL16_LO",	/* name */
1284130561Sobrien	 FALSE,			/* partial_inplace */
1285130561Sobrien	 0,			/* src_mask */
1286130561Sobrien	 0xffff,		/* dst_mask */
1287130561Sobrien	 FALSE),		/* pcrel_offset */
1288130561Sobrien
1289130561Sobrien  /* Like DTPREL16_LO, but next higher group of 16 bits.  */
1290130561Sobrien  HOWTO (R_PPC64_DTPREL16_HI,
1291130561Sobrien	 16,			/* rightshift */
1292130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1293130561Sobrien	 16,			/* bitsize */
1294130561Sobrien	 FALSE,			/* pc_relative */
1295130561Sobrien	 0,			/* bitpos */
1296130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1297130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1298130561Sobrien	 "R_PPC64_DTPREL16_HI",	/* name */
1299130561Sobrien	 FALSE,			/* partial_inplace */
1300130561Sobrien	 0,			/* src_mask */
1301130561Sobrien	 0xffff,		/* dst_mask */
1302130561Sobrien	 FALSE),		/* pcrel_offset */
1303130561Sobrien
1304130561Sobrien  /* Like DTPREL16_HI, but adjust for low 16 bits.  */
1305130561Sobrien  HOWTO (R_PPC64_DTPREL16_HA,
1306130561Sobrien	 16,			/* rightshift */
1307130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1308130561Sobrien	 16,			/* bitsize */
1309130561Sobrien	 FALSE,			/* pc_relative */
1310130561Sobrien	 0,			/* bitpos */
1311130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1312130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1313130561Sobrien	 "R_PPC64_DTPREL16_HA",	/* name */
1314130561Sobrien	 FALSE,			/* partial_inplace */
1315130561Sobrien	 0,			/* src_mask */
1316130561Sobrien	 0xffff,		/* dst_mask */
1317130561Sobrien	 FALSE),		/* pcrel_offset */
1318130561Sobrien
1319130561Sobrien  /* Like DTPREL16_HI, but next higher group of 16 bits.  */
1320130561Sobrien  HOWTO (R_PPC64_DTPREL16_HIGHER,
1321130561Sobrien	 32,			/* rightshift */
1322130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1323130561Sobrien	 16,			/* bitsize */
1324130561Sobrien	 FALSE,			/* pc_relative */
1325130561Sobrien	 0,			/* bitpos */
1326130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1327130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1328130561Sobrien	 "R_PPC64_DTPREL16_HIGHER", /* name */
1329130561Sobrien	 FALSE,			/* partial_inplace */
1330130561Sobrien	 0,			/* src_mask */
1331130561Sobrien	 0xffff,		/* dst_mask */
1332130561Sobrien	 FALSE),		/* pcrel_offset */
1333130561Sobrien
1334130561Sobrien  /* Like DTPREL16_HIGHER, but adjust for low 16 bits.  */
1335130561Sobrien  HOWTO (R_PPC64_DTPREL16_HIGHERA,
1336130561Sobrien	 32,			/* rightshift */
1337130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1338130561Sobrien	 16,			/* bitsize */
1339130561Sobrien	 FALSE,			/* pc_relative */
1340130561Sobrien	 0,			/* bitpos */
1341130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1342130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1343130561Sobrien	 "R_PPC64_DTPREL16_HIGHERA", /* name */
1344130561Sobrien	 FALSE,			/* partial_inplace */
1345130561Sobrien	 0,			/* src_mask */
1346130561Sobrien	 0xffff,		/* dst_mask */
1347130561Sobrien	 FALSE),		/* pcrel_offset */
1348130561Sobrien
1349130561Sobrien  /* Like DTPREL16_HIGHER, but next higher group of 16 bits.  */
1350130561Sobrien  HOWTO (R_PPC64_DTPREL16_HIGHEST,
1351130561Sobrien	 48,			/* rightshift */
1352130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1353130561Sobrien	 16,			/* bitsize */
1354130561Sobrien	 FALSE,			/* pc_relative */
1355130561Sobrien	 0,			/* bitpos */
1356130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1357130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1358130561Sobrien	 "R_PPC64_DTPREL16_HIGHEST", /* name */
1359130561Sobrien	 FALSE,			/* partial_inplace */
1360130561Sobrien	 0,			/* src_mask */
1361130561Sobrien	 0xffff,		/* dst_mask */
1362130561Sobrien	 FALSE),		/* pcrel_offset */
1363130561Sobrien
1364130561Sobrien  /* Like DTPREL16_HIGHEST, but adjust for low 16 bits.  */
1365130561Sobrien  HOWTO (R_PPC64_DTPREL16_HIGHESTA,
1366130561Sobrien	 48,			/* rightshift */
1367130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1368130561Sobrien	 16,			/* bitsize */
1369130561Sobrien	 FALSE,			/* pc_relative */
1370130561Sobrien	 0,			/* bitpos */
1371130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1372130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1373130561Sobrien	 "R_PPC64_DTPREL16_HIGHESTA", /* name */
1374130561Sobrien	 FALSE,			/* partial_inplace */
1375130561Sobrien	 0,			/* src_mask */
1376130561Sobrien	 0xffff,		/* dst_mask */
1377130561Sobrien	 FALSE),		/* pcrel_offset */
1378130561Sobrien
1379130561Sobrien  /* Like DTPREL16, but for insns with a DS field.  */
1380130561Sobrien  HOWTO (R_PPC64_DTPREL16_DS,
1381130561Sobrien	 0,			/* rightshift */
1382130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1383130561Sobrien	 16,			/* bitsize */
1384130561Sobrien	 FALSE,			/* pc_relative */
1385130561Sobrien	 0,			/* bitpos */
1386130561Sobrien	 complain_overflow_signed, /* complain_on_overflow */
1387130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1388130561Sobrien	 "R_PPC64_DTPREL16_DS",	/* name */
1389130561Sobrien	 FALSE,			/* partial_inplace */
1390130561Sobrien	 0,			/* src_mask */
1391130561Sobrien	 0xfffc,		/* dst_mask */
1392130561Sobrien	 FALSE),		/* pcrel_offset */
1393130561Sobrien
1394130561Sobrien  /* Like DTPREL16_DS, but no overflow.  */
1395130561Sobrien  HOWTO (R_PPC64_DTPREL16_LO_DS,
1396130561Sobrien	 0,			/* rightshift */
1397130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1398130561Sobrien	 16,			/* bitsize */
1399130561Sobrien	 FALSE,			/* pc_relative */
1400130561Sobrien	 0,			/* bitpos */
1401130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1402130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1403130561Sobrien	 "R_PPC64_DTPREL16_LO_DS", /* name */
1404130561Sobrien	 FALSE,			/* partial_inplace */
1405130561Sobrien	 0,			/* src_mask */
1406130561Sobrien	 0xfffc,		/* dst_mask */
1407130561Sobrien	 FALSE),		/* pcrel_offset */
1408130561Sobrien
1409130561Sobrien  /* Computes a tp-relative displacement, the difference between the value of
1410130561Sobrien     sym+add and the value of the thread pointer (r13).  */
1411130561Sobrien  HOWTO (R_PPC64_TPREL64,
1412130561Sobrien	 0,			/* rightshift */
1413130561Sobrien	 4,			/* size (0 = byte, 1 = short, 2 = long) */
1414130561Sobrien	 64,			/* bitsize */
1415130561Sobrien	 FALSE,			/* pc_relative */
1416130561Sobrien	 0,			/* bitpos */
1417130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1418130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1419130561Sobrien	 "R_PPC64_TPREL64",	/* name */
1420130561Sobrien	 FALSE,			/* partial_inplace */
1421130561Sobrien	 0,			/* src_mask */
1422130561Sobrien	 ONES (64),		/* dst_mask */
1423130561Sobrien	 FALSE),		/* pcrel_offset */
1424130561Sobrien
1425130561Sobrien  /* A 16 bit tprel reloc.  */
1426130561Sobrien  HOWTO (R_PPC64_TPREL16,
1427130561Sobrien	 0,			/* rightshift */
1428130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1429130561Sobrien	 16,			/* bitsize */
1430130561Sobrien	 FALSE,			/* pc_relative */
1431130561Sobrien	 0,			/* bitpos */
1432130561Sobrien	 complain_overflow_signed, /* complain_on_overflow */
1433130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1434130561Sobrien	 "R_PPC64_TPREL16",	/* name */
1435130561Sobrien	 FALSE,			/* partial_inplace */
1436130561Sobrien	 0,			/* src_mask */
1437130561Sobrien	 0xffff,		/* dst_mask */
1438130561Sobrien	 FALSE),		/* pcrel_offset */
1439130561Sobrien
1440130561Sobrien  /* Like TPREL16, but no overflow.  */
1441130561Sobrien  HOWTO (R_PPC64_TPREL16_LO,
1442130561Sobrien	 0,			/* rightshift */
1443130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1444130561Sobrien	 16,			/* bitsize */
1445130561Sobrien	 FALSE,			/* pc_relative */
1446130561Sobrien	 0,			/* bitpos */
1447130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1448130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1449130561Sobrien	 "R_PPC64_TPREL16_LO",	/* name */
1450130561Sobrien	 FALSE,			/* partial_inplace */
1451130561Sobrien	 0,			/* src_mask */
1452130561Sobrien	 0xffff,		/* dst_mask */
1453130561Sobrien	 FALSE),		/* pcrel_offset */
1454130561Sobrien
1455130561Sobrien  /* Like TPREL16_LO, but next higher group of 16 bits.  */
1456130561Sobrien  HOWTO (R_PPC64_TPREL16_HI,
1457130561Sobrien	 16,			/* rightshift */
1458130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1459130561Sobrien	 16,			/* bitsize */
1460130561Sobrien	 FALSE,			/* pc_relative */
1461130561Sobrien	 0,			/* bitpos */
1462130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1463130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1464130561Sobrien	 "R_PPC64_TPREL16_HI",	/* name */
1465130561Sobrien	 FALSE,			/* partial_inplace */
1466130561Sobrien	 0,			/* src_mask */
1467130561Sobrien	 0xffff,		/* dst_mask */
1468130561Sobrien	 FALSE),		/* pcrel_offset */
1469130561Sobrien
1470130561Sobrien  /* Like TPREL16_HI, but adjust for low 16 bits.  */
1471130561Sobrien  HOWTO (R_PPC64_TPREL16_HA,
1472130561Sobrien	 16,			/* rightshift */
1473130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1474130561Sobrien	 16,			/* bitsize */
1475130561Sobrien	 FALSE,			/* pc_relative */
1476130561Sobrien	 0,			/* bitpos */
1477130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1478130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1479130561Sobrien	 "R_PPC64_TPREL16_HA",	/* name */
1480130561Sobrien	 FALSE,			/* partial_inplace */
1481130561Sobrien	 0,			/* src_mask */
1482130561Sobrien	 0xffff,		/* dst_mask */
1483130561Sobrien	 FALSE),		/* pcrel_offset */
1484130561Sobrien
1485130561Sobrien  /* Like TPREL16_HI, but next higher group of 16 bits.  */
1486130561Sobrien  HOWTO (R_PPC64_TPREL16_HIGHER,
1487130561Sobrien	 32,			/* rightshift */
1488130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1489130561Sobrien	 16,			/* bitsize */
1490130561Sobrien	 FALSE,			/* pc_relative */
1491130561Sobrien	 0,			/* bitpos */
1492130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1493130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1494130561Sobrien	 "R_PPC64_TPREL16_HIGHER",	/* name */
1495130561Sobrien	 FALSE,			/* partial_inplace */
1496130561Sobrien	 0,			/* src_mask */
1497130561Sobrien	 0xffff,		/* dst_mask */
1498130561Sobrien	 FALSE),		/* pcrel_offset */
1499130561Sobrien
1500130561Sobrien  /* Like TPREL16_HIGHER, but adjust for low 16 bits.  */
1501130561Sobrien  HOWTO (R_PPC64_TPREL16_HIGHERA,
1502130561Sobrien	 32,			/* rightshift */
1503130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1504130561Sobrien	 16,			/* bitsize */
1505130561Sobrien	 FALSE,			/* pc_relative */
1506130561Sobrien	 0,			/* bitpos */
1507130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1508130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1509130561Sobrien	 "R_PPC64_TPREL16_HIGHERA", /* name */
1510130561Sobrien	 FALSE,			/* partial_inplace */
1511130561Sobrien	 0,			/* src_mask */
1512130561Sobrien	 0xffff,		/* dst_mask */
1513130561Sobrien	 FALSE),		/* pcrel_offset */
1514130561Sobrien
1515130561Sobrien  /* Like TPREL16_HIGHER, but next higher group of 16 bits.  */
1516130561Sobrien  HOWTO (R_PPC64_TPREL16_HIGHEST,
1517130561Sobrien	 48,			/* rightshift */
1518130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1519130561Sobrien	 16,			/* bitsize */
1520130561Sobrien	 FALSE,			/* pc_relative */
1521130561Sobrien	 0,			/* bitpos */
1522130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1523130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1524130561Sobrien	 "R_PPC64_TPREL16_HIGHEST", /* name */
1525130561Sobrien	 FALSE,			/* partial_inplace */
1526130561Sobrien	 0,			/* src_mask */
1527130561Sobrien	 0xffff,		/* dst_mask */
1528130561Sobrien	 FALSE),		/* pcrel_offset */
1529130561Sobrien
1530130561Sobrien  /* Like TPREL16_HIGHEST, but adjust for low 16 bits.  */
1531130561Sobrien  HOWTO (R_PPC64_TPREL16_HIGHESTA,
1532130561Sobrien	 48,			/* rightshift */
1533130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1534130561Sobrien	 16,			/* bitsize */
1535130561Sobrien	 FALSE,			/* pc_relative */
1536130561Sobrien	 0,			/* bitpos */
1537130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1538130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1539130561Sobrien	 "R_PPC64_TPREL16_HIGHESTA", /* name */
1540130561Sobrien	 FALSE,			/* partial_inplace */
1541130561Sobrien	 0,			/* src_mask */
1542130561Sobrien	 0xffff,		/* dst_mask */
1543130561Sobrien	 FALSE),		/* pcrel_offset */
1544130561Sobrien
1545130561Sobrien  /* Like TPREL16, but for insns with a DS field.  */
1546130561Sobrien  HOWTO (R_PPC64_TPREL16_DS,
1547130561Sobrien	 0,			/* rightshift */
1548130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1549130561Sobrien	 16,			/* bitsize */
1550130561Sobrien	 FALSE,			/* pc_relative */
1551130561Sobrien	 0,			/* bitpos */
1552130561Sobrien	 complain_overflow_signed, /* complain_on_overflow */
1553130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1554130561Sobrien	 "R_PPC64_TPREL16_DS",	/* name */
1555130561Sobrien	 FALSE,			/* partial_inplace */
1556130561Sobrien	 0,			/* src_mask */
1557130561Sobrien	 0xfffc,		/* dst_mask */
1558130561Sobrien	 FALSE),		/* pcrel_offset */
1559130561Sobrien
1560130561Sobrien  /* Like TPREL16_DS, but no overflow.  */
1561130561Sobrien  HOWTO (R_PPC64_TPREL16_LO_DS,
1562130561Sobrien	 0,			/* rightshift */
1563130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1564130561Sobrien	 16,			/* bitsize */
1565130561Sobrien	 FALSE,			/* pc_relative */
1566130561Sobrien	 0,			/* bitpos */
1567130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1568130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1569130561Sobrien	 "R_PPC64_TPREL16_LO_DS", /* name */
1570130561Sobrien	 FALSE,			/* partial_inplace */
1571130561Sobrien	 0,			/* src_mask */
1572130561Sobrien	 0xfffc,		/* dst_mask */
1573130561Sobrien	 FALSE),		/* pcrel_offset */
1574130561Sobrien
1575130561Sobrien  /* Allocates two contiguous entries in the GOT to hold a tls_index structure,
1576130561Sobrien     with values (sym+add)@dtpmod and (sym+add)@dtprel, and computes the offset
1577130561Sobrien     to the first entry relative to the TOC base (r2).  */
1578130561Sobrien  HOWTO (R_PPC64_GOT_TLSGD16,
1579130561Sobrien	 0,			/* rightshift */
1580130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1581130561Sobrien	 16,			/* bitsize */
1582130561Sobrien	 FALSE,			/* pc_relative */
1583130561Sobrien	 0,			/* bitpos */
1584130561Sobrien	 complain_overflow_signed, /* complain_on_overflow */
1585130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1586130561Sobrien	 "R_PPC64_GOT_TLSGD16",	/* name */
1587130561Sobrien	 FALSE,			/* partial_inplace */
1588130561Sobrien	 0,			/* src_mask */
1589130561Sobrien	 0xffff,		/* dst_mask */
1590130561Sobrien	 FALSE),		/* pcrel_offset */
1591130561Sobrien
1592130561Sobrien  /* Like GOT_TLSGD16, but no overflow.  */
1593130561Sobrien  HOWTO (R_PPC64_GOT_TLSGD16_LO,
1594130561Sobrien	 0,			/* rightshift */
1595130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1596130561Sobrien	 16,			/* bitsize */
1597130561Sobrien	 FALSE,			/* pc_relative */
1598130561Sobrien	 0,			/* bitpos */
1599130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1600130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1601130561Sobrien	 "R_PPC64_GOT_TLSGD16_LO", /* name */
1602130561Sobrien	 FALSE,			/* partial_inplace */
1603130561Sobrien	 0,			/* src_mask */
1604130561Sobrien	 0xffff,		/* dst_mask */
1605130561Sobrien	 FALSE),		/* pcrel_offset */
1606130561Sobrien
1607130561Sobrien  /* Like GOT_TLSGD16_LO, but next higher group of 16 bits.  */
1608130561Sobrien  HOWTO (R_PPC64_GOT_TLSGD16_HI,
1609130561Sobrien	 16,			/* rightshift */
1610130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1611130561Sobrien	 16,			/* bitsize */
1612130561Sobrien	 FALSE,			/* pc_relative */
1613130561Sobrien	 0,			/* bitpos */
1614130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1615130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1616130561Sobrien	 "R_PPC64_GOT_TLSGD16_HI", /* name */
1617130561Sobrien	 FALSE,			/* partial_inplace */
1618130561Sobrien	 0,			/* src_mask */
1619130561Sobrien	 0xffff,		/* dst_mask */
1620130561Sobrien	 FALSE),		/* pcrel_offset */
1621130561Sobrien
1622130561Sobrien  /* Like GOT_TLSGD16_HI, but adjust for low 16 bits.  */
1623130561Sobrien  HOWTO (R_PPC64_GOT_TLSGD16_HA,
1624130561Sobrien	 16,			/* rightshift */
1625130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1626130561Sobrien	 16,			/* bitsize */
1627130561Sobrien	 FALSE,			/* pc_relative */
1628130561Sobrien	 0,			/* bitpos */
1629130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1630130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1631130561Sobrien	 "R_PPC64_GOT_TLSGD16_HA", /* name */
1632130561Sobrien	 FALSE,			/* partial_inplace */
1633130561Sobrien	 0,			/* src_mask */
1634130561Sobrien	 0xffff,		/* dst_mask */
1635130561Sobrien	 FALSE),		/* pcrel_offset */
1636130561Sobrien
1637130561Sobrien  /* Allocates two contiguous entries in the GOT to hold a tls_index structure,
1638130561Sobrien     with values (sym+add)@dtpmod and zero, and computes the offset to the
1639130561Sobrien     first entry relative to the TOC base (r2).  */
1640130561Sobrien  HOWTO (R_PPC64_GOT_TLSLD16,
1641130561Sobrien	 0,			/* rightshift */
1642130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1643130561Sobrien	 16,			/* bitsize */
1644130561Sobrien	 FALSE,			/* pc_relative */
1645130561Sobrien	 0,			/* bitpos */
1646130561Sobrien	 complain_overflow_signed, /* complain_on_overflow */
1647130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1648130561Sobrien	 "R_PPC64_GOT_TLSLD16",	/* name */
1649130561Sobrien	 FALSE,			/* partial_inplace */
1650130561Sobrien	 0,			/* src_mask */
1651130561Sobrien	 0xffff,		/* dst_mask */
1652130561Sobrien	 FALSE),		/* pcrel_offset */
1653130561Sobrien
1654130561Sobrien  /* Like GOT_TLSLD16, but no overflow.  */
1655130561Sobrien  HOWTO (R_PPC64_GOT_TLSLD16_LO,
1656130561Sobrien	 0,			/* rightshift */
1657130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1658130561Sobrien	 16,			/* bitsize */
1659130561Sobrien	 FALSE,			/* pc_relative */
1660130561Sobrien	 0,			/* bitpos */
1661130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1662130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1663130561Sobrien	 "R_PPC64_GOT_TLSLD16_LO", /* name */
1664130561Sobrien	 FALSE,			/* partial_inplace */
1665130561Sobrien	 0,			/* src_mask */
1666130561Sobrien	 0xffff,		/* dst_mask */
1667130561Sobrien	 FALSE),		/* pcrel_offset */
1668130561Sobrien
1669130561Sobrien  /* Like GOT_TLSLD16_LO, but next higher group of 16 bits.  */
1670130561Sobrien  HOWTO (R_PPC64_GOT_TLSLD16_HI,
1671130561Sobrien	 16,			/* rightshift */
1672130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1673130561Sobrien	 16,			/* bitsize */
1674130561Sobrien	 FALSE,			/* pc_relative */
1675130561Sobrien	 0,			/* bitpos */
1676130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1677130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1678130561Sobrien	 "R_PPC64_GOT_TLSLD16_HI", /* name */
1679130561Sobrien	 FALSE,			/* partial_inplace */
1680130561Sobrien	 0,			/* src_mask */
1681130561Sobrien	 0xffff,		/* dst_mask */
1682130561Sobrien	 FALSE),		/* pcrel_offset */
1683130561Sobrien
1684130561Sobrien  /* Like GOT_TLSLD16_HI, but adjust for low 16 bits.  */
1685130561Sobrien  HOWTO (R_PPC64_GOT_TLSLD16_HA,
1686130561Sobrien	 16,			/* rightshift */
1687130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1688130561Sobrien	 16,			/* bitsize */
1689130561Sobrien	 FALSE,			/* pc_relative */
1690130561Sobrien	 0,			/* bitpos */
1691130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1692130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1693130561Sobrien	 "R_PPC64_GOT_TLSLD16_HA", /* name */
1694130561Sobrien	 FALSE,			/* partial_inplace */
1695130561Sobrien	 0,			/* src_mask */
1696130561Sobrien	 0xffff,		/* dst_mask */
1697130561Sobrien	 FALSE),		/* pcrel_offset */
1698130561Sobrien
1699130561Sobrien  /* Allocates an entry in the GOT with value (sym+add)@dtprel, and computes
1700130561Sobrien     the offset to the entry relative to the TOC base (r2).  */
1701130561Sobrien  HOWTO (R_PPC64_GOT_DTPREL16_DS,
1702130561Sobrien	 0,			/* rightshift */
1703130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1704130561Sobrien	 16,			/* bitsize */
1705130561Sobrien	 FALSE,			/* pc_relative */
1706130561Sobrien	 0,			/* bitpos */
1707130561Sobrien	 complain_overflow_signed, /* complain_on_overflow */
1708130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1709130561Sobrien	 "R_PPC64_GOT_DTPREL16_DS", /* name */
1710130561Sobrien	 FALSE,			/* partial_inplace */
1711130561Sobrien	 0,			/* src_mask */
1712130561Sobrien	 0xfffc,		/* dst_mask */
1713130561Sobrien	 FALSE),		/* pcrel_offset */
1714130561Sobrien
1715130561Sobrien  /* Like GOT_DTPREL16_DS, but no overflow.  */
1716130561Sobrien  HOWTO (R_PPC64_GOT_DTPREL16_LO_DS,
1717130561Sobrien	 0,			/* rightshift */
1718130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1719130561Sobrien	 16,			/* bitsize */
1720130561Sobrien	 FALSE,			/* pc_relative */
1721130561Sobrien	 0,			/* bitpos */
1722130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1723130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1724130561Sobrien	 "R_PPC64_GOT_DTPREL16_LO_DS", /* name */
1725130561Sobrien	 FALSE,			/* partial_inplace */
1726130561Sobrien	 0,			/* src_mask */
1727130561Sobrien	 0xfffc,		/* dst_mask */
1728130561Sobrien	 FALSE),		/* pcrel_offset */
1729130561Sobrien
1730130561Sobrien  /* Like GOT_DTPREL16_LO_DS, but next higher group of 16 bits.  */
1731130561Sobrien  HOWTO (R_PPC64_GOT_DTPREL16_HI,
1732130561Sobrien	 16,			/* rightshift */
1733130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1734130561Sobrien	 16,			/* bitsize */
1735130561Sobrien	 FALSE,			/* pc_relative */
1736130561Sobrien	 0,			/* bitpos */
1737130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1738130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1739130561Sobrien	 "R_PPC64_GOT_DTPREL16_HI", /* name */
1740130561Sobrien	 FALSE,			/* partial_inplace */
1741130561Sobrien	 0,			/* src_mask */
1742130561Sobrien	 0xffff,		/* dst_mask */
1743130561Sobrien	 FALSE),		/* pcrel_offset */
1744130561Sobrien
1745130561Sobrien  /* Like GOT_DTPREL16_HI, but adjust for low 16 bits.  */
1746130561Sobrien  HOWTO (R_PPC64_GOT_DTPREL16_HA,
1747130561Sobrien	 16,			/* rightshift */
1748130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1749130561Sobrien	 16,			/* bitsize */
1750130561Sobrien	 FALSE,			/* pc_relative */
1751130561Sobrien	 0,			/* bitpos */
1752130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1753130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1754130561Sobrien	 "R_PPC64_GOT_DTPREL16_HA", /* name */
1755130561Sobrien	 FALSE,			/* partial_inplace */
1756130561Sobrien	 0,			/* src_mask */
1757130561Sobrien	 0xffff,		/* dst_mask */
1758130561Sobrien	 FALSE),		/* pcrel_offset */
1759130561Sobrien
1760130561Sobrien  /* Allocates an entry in the GOT with value (sym+add)@tprel, and computes the
1761130561Sobrien     offset to the entry relative to the TOC base (r2).  */
1762130561Sobrien  HOWTO (R_PPC64_GOT_TPREL16_DS,
1763130561Sobrien	 0,			/* rightshift */
1764130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1765130561Sobrien	 16,			/* bitsize */
1766130561Sobrien	 FALSE,			/* pc_relative */
1767130561Sobrien	 0,			/* bitpos */
1768130561Sobrien	 complain_overflow_signed, /* complain_on_overflow */
1769130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1770130561Sobrien	 "R_PPC64_GOT_TPREL16_DS", /* name */
1771130561Sobrien	 FALSE,			/* partial_inplace */
1772130561Sobrien	 0,			/* src_mask */
1773130561Sobrien	 0xfffc,		/* dst_mask */
1774130561Sobrien	 FALSE),		/* pcrel_offset */
1775130561Sobrien
1776130561Sobrien  /* Like GOT_TPREL16_DS, but no overflow.  */
1777130561Sobrien  HOWTO (R_PPC64_GOT_TPREL16_LO_DS,
1778130561Sobrien	 0,			/* rightshift */
1779130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1780130561Sobrien	 16,			/* bitsize */
1781130561Sobrien	 FALSE,			/* pc_relative */
1782130561Sobrien	 0,			/* bitpos */
1783130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1784130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1785130561Sobrien	 "R_PPC64_GOT_TPREL16_LO_DS", /* name */
1786130561Sobrien	 FALSE,			/* partial_inplace */
1787130561Sobrien	 0,			/* src_mask */
1788130561Sobrien	 0xfffc,		/* dst_mask */
1789130561Sobrien	 FALSE),		/* pcrel_offset */
1790130561Sobrien
1791130561Sobrien  /* Like GOT_TPREL16_LO_DS, but next higher group of 16 bits.  */
1792130561Sobrien  HOWTO (R_PPC64_GOT_TPREL16_HI,
1793130561Sobrien	 16,			/* rightshift */
1794130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1795130561Sobrien	 16,			/* bitsize */
1796130561Sobrien	 FALSE,			/* pc_relative */
1797130561Sobrien	 0,			/* bitpos */
1798130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1799130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1800130561Sobrien	 "R_PPC64_GOT_TPREL16_HI", /* name */
1801130561Sobrien	 FALSE,			/* partial_inplace */
1802130561Sobrien	 0,			/* src_mask */
1803130561Sobrien	 0xffff,		/* dst_mask */
1804130561Sobrien	 FALSE),		/* pcrel_offset */
1805130561Sobrien
1806130561Sobrien  /* Like GOT_TPREL16_HI, but adjust for low 16 bits.  */
1807130561Sobrien  HOWTO (R_PPC64_GOT_TPREL16_HA,
1808130561Sobrien	 16,			/* rightshift */
1809130561Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1810130561Sobrien	 16,			/* bitsize */
1811130561Sobrien	 FALSE,			/* pc_relative */
1812130561Sobrien	 0,			/* bitpos */
1813130561Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1814130561Sobrien	 ppc64_elf_unhandled_reloc, /* special_function */
1815130561Sobrien	 "R_PPC64_GOT_TPREL16_HA", /* name */
1816130561Sobrien	 FALSE,			/* partial_inplace */
1817130561Sobrien	 0,			/* src_mask */
1818130561Sobrien	 0xffff,		/* dst_mask */
1819130561Sobrien	 FALSE),		/* pcrel_offset */
1820130561Sobrien
182189857Sobrien  /* GNU extension to record C++ vtable hierarchy.  */
182289857Sobrien  HOWTO (R_PPC64_GNU_VTINHERIT,	/* type */
182389857Sobrien	 0,			/* rightshift */
182489857Sobrien	 0,			/* size (0 = byte, 1 = short, 2 = long) */
182589857Sobrien	 0,			/* bitsize */
1826130561Sobrien	 FALSE,			/* pc_relative */
182789857Sobrien	 0,			/* bitpos */
182889857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
182989857Sobrien	 NULL,			/* special_function */
183089857Sobrien	 "R_PPC64_GNU_VTINHERIT", /* name */
1831130561Sobrien	 FALSE,			/* partial_inplace */
183289857Sobrien	 0,			/* src_mask */
183389857Sobrien	 0,			/* dst_mask */
1834130561Sobrien	 FALSE),		/* pcrel_offset */
183589857Sobrien
183689857Sobrien  /* GNU extension to record C++ vtable member usage.  */
183789857Sobrien  HOWTO (R_PPC64_GNU_VTENTRY,	/* type */
183889857Sobrien	 0,			/* rightshift */
183989857Sobrien	 0,			/* size (0 = byte, 1 = short, 2 = long) */
184089857Sobrien	 0,			/* bitsize */
1841130561Sobrien	 FALSE,			/* pc_relative */
184289857Sobrien	 0,			/* bitpos */
184389857Sobrien	 complain_overflow_dont, /* complain_on_overflow */
184489857Sobrien	 NULL,			/* special_function */
184589857Sobrien	 "R_PPC64_GNU_VTENTRY",	/* name */
1846130561Sobrien	 FALSE,			/* partial_inplace */
184789857Sobrien	 0,			/* src_mask */
184889857Sobrien	 0,			/* dst_mask */
1849130561Sobrien	 FALSE),		/* pcrel_offset */
185089857Sobrien};
185189857Sobrien
185289857Sobrien
185389857Sobrien/* Initialize the ppc64_elf_howto_table, so that linear accesses can
185489857Sobrien   be done.  */
185589857Sobrien
185689857Sobrienstatic void
1857130561Sobrienppc_howto_init (void)
185889857Sobrien{
185989857Sobrien  unsigned int i, type;
186089857Sobrien
186189857Sobrien  for (i = 0;
186289857Sobrien       i < sizeof (ppc64_elf_howto_raw) / sizeof (ppc64_elf_howto_raw[0]);
186389857Sobrien       i++)
186489857Sobrien    {
186589857Sobrien      type = ppc64_elf_howto_raw[i].type;
186689857Sobrien      BFD_ASSERT (type < (sizeof (ppc64_elf_howto_table)
186789857Sobrien			  / sizeof (ppc64_elf_howto_table[0])));
186889857Sobrien      ppc64_elf_howto_table[type] = &ppc64_elf_howto_raw[i];
186989857Sobrien    }
187089857Sobrien}
187189857Sobrien
187289857Sobrienstatic reloc_howto_type *
1873130561Sobrienppc64_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1874130561Sobrien			     bfd_reloc_code_real_type code)
187589857Sobrien{
1876130561Sobrien  enum elf_ppc64_reloc_type r = R_PPC64_NONE;
187789857Sobrien
187889857Sobrien  if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
187989857Sobrien    /* Initialize howto table if needed.  */
188089857Sobrien    ppc_howto_init ();
188189857Sobrien
1882130561Sobrien  switch (code)
188389857Sobrien    {
188489857Sobrien    default:
1885130561Sobrien      return NULL;
188689857Sobrien
1887130561Sobrien    case BFD_RELOC_NONE:			r = R_PPC64_NONE;
188889857Sobrien      break;
1889130561Sobrien    case BFD_RELOC_32:				r = R_PPC64_ADDR32;
189089857Sobrien      break;
1891130561Sobrien    case BFD_RELOC_PPC_BA26:			r = R_PPC64_ADDR24;
189289857Sobrien      break;
1893130561Sobrien    case BFD_RELOC_16:				r = R_PPC64_ADDR16;
189489857Sobrien      break;
1895130561Sobrien    case BFD_RELOC_LO16:			r = R_PPC64_ADDR16_LO;
189689857Sobrien      break;
1897130561Sobrien    case BFD_RELOC_HI16:			r = R_PPC64_ADDR16_HI;
189889857Sobrien      break;
1899130561Sobrien    case BFD_RELOC_HI16_S:			r = R_PPC64_ADDR16_HA;
190089857Sobrien      break;
1901130561Sobrien    case BFD_RELOC_PPC_BA16:			r = R_PPC64_ADDR14;
190289857Sobrien      break;
1903130561Sobrien    case BFD_RELOC_PPC_BA16_BRTAKEN:		r = R_PPC64_ADDR14_BRTAKEN;
190489857Sobrien      break;
1905130561Sobrien    case BFD_RELOC_PPC_BA16_BRNTAKEN:		r = R_PPC64_ADDR14_BRNTAKEN;
190689857Sobrien      break;
1907130561Sobrien    case BFD_RELOC_PPC_B26:			r = R_PPC64_REL24;
190889857Sobrien      break;
1909130561Sobrien    case BFD_RELOC_PPC_B16:			r = R_PPC64_REL14;
191089857Sobrien      break;
1911130561Sobrien    case BFD_RELOC_PPC_B16_BRTAKEN:		r = R_PPC64_REL14_BRTAKEN;
191289857Sobrien      break;
1913130561Sobrien    case BFD_RELOC_PPC_B16_BRNTAKEN:		r = R_PPC64_REL14_BRNTAKEN;
191489857Sobrien      break;
1915130561Sobrien    case BFD_RELOC_16_GOTOFF:			r = R_PPC64_GOT16;
191689857Sobrien      break;
1917130561Sobrien    case BFD_RELOC_LO16_GOTOFF:			r = R_PPC64_GOT16_LO;
191889857Sobrien      break;
1919130561Sobrien    case BFD_RELOC_HI16_GOTOFF:			r = R_PPC64_GOT16_HI;
192089857Sobrien      break;
1921130561Sobrien    case BFD_RELOC_HI16_S_GOTOFF:		r = R_PPC64_GOT16_HA;
192289857Sobrien      break;
1923130561Sobrien    case BFD_RELOC_PPC_COPY:			r = R_PPC64_COPY;
192489857Sobrien      break;
1925130561Sobrien    case BFD_RELOC_PPC_GLOB_DAT:		r = R_PPC64_GLOB_DAT;
192689857Sobrien      break;
1927130561Sobrien    case BFD_RELOC_32_PCREL:			r = R_PPC64_REL32;
192889857Sobrien      break;
1929130561Sobrien    case BFD_RELOC_32_PLTOFF:			r = R_PPC64_PLT32;
193089857Sobrien      break;
1931130561Sobrien    case BFD_RELOC_32_PLT_PCREL:		r = R_PPC64_PLTREL32;
193289857Sobrien      break;
1933130561Sobrien    case BFD_RELOC_LO16_PLTOFF:			r = R_PPC64_PLT16_LO;
193489857Sobrien      break;
1935130561Sobrien    case BFD_RELOC_HI16_PLTOFF:			r = R_PPC64_PLT16_HI;
193689857Sobrien      break;
1937130561Sobrien    case BFD_RELOC_HI16_S_PLTOFF:		r = R_PPC64_PLT16_HA;
193889857Sobrien      break;
1939130561Sobrien    case BFD_RELOC_16_BASEREL:			r = R_PPC64_SECTOFF;
194089857Sobrien      break;
1941130561Sobrien    case BFD_RELOC_LO16_BASEREL:		r = R_PPC64_SECTOFF_LO;
194289857Sobrien      break;
1943130561Sobrien    case BFD_RELOC_HI16_BASEREL:		r = R_PPC64_SECTOFF_HI;
194489857Sobrien      break;
1945130561Sobrien    case BFD_RELOC_HI16_S_BASEREL:		r = R_PPC64_SECTOFF_HA;
194689857Sobrien      break;
1947130561Sobrien    case BFD_RELOC_CTOR:			r = R_PPC64_ADDR64;
194889857Sobrien      break;
1949130561Sobrien    case BFD_RELOC_64:				r = R_PPC64_ADDR64;
195089857Sobrien      break;
1951130561Sobrien    case BFD_RELOC_PPC64_HIGHER:		r = R_PPC64_ADDR16_HIGHER;
195289857Sobrien      break;
1953130561Sobrien    case BFD_RELOC_PPC64_HIGHER_S:		r = R_PPC64_ADDR16_HIGHERA;
195489857Sobrien      break;
1955130561Sobrien    case BFD_RELOC_PPC64_HIGHEST:		r = R_PPC64_ADDR16_HIGHEST;
195689857Sobrien      break;
1957130561Sobrien    case BFD_RELOC_PPC64_HIGHEST_S:		r = R_PPC64_ADDR16_HIGHESTA;
195889857Sobrien      break;
1959130561Sobrien    case BFD_RELOC_64_PCREL:			r = R_PPC64_REL64;
196089857Sobrien      break;
1961130561Sobrien    case BFD_RELOC_64_PLTOFF:			r = R_PPC64_PLT64;
196289857Sobrien      break;
1963130561Sobrien    case BFD_RELOC_64_PLT_PCREL:		r = R_PPC64_PLTREL64;
196489857Sobrien      break;
1965130561Sobrien    case BFD_RELOC_PPC_TOC16:			r = R_PPC64_TOC16;
196689857Sobrien      break;
1967130561Sobrien    case BFD_RELOC_PPC64_TOC16_LO:		r = R_PPC64_TOC16_LO;
196889857Sobrien      break;
1969130561Sobrien    case BFD_RELOC_PPC64_TOC16_HI:		r = R_PPC64_TOC16_HI;
197089857Sobrien      break;
1971130561Sobrien    case BFD_RELOC_PPC64_TOC16_HA:		r = R_PPC64_TOC16_HA;
197289857Sobrien      break;
1973130561Sobrien    case BFD_RELOC_PPC64_TOC:			r = R_PPC64_TOC;
197489857Sobrien      break;
1975130561Sobrien    case BFD_RELOC_PPC64_PLTGOT16:		r = R_PPC64_PLTGOT16;
197689857Sobrien      break;
1977130561Sobrien    case BFD_RELOC_PPC64_PLTGOT16_LO:		r = R_PPC64_PLTGOT16_LO;
197889857Sobrien      break;
1979130561Sobrien    case BFD_RELOC_PPC64_PLTGOT16_HI:		r = R_PPC64_PLTGOT16_HI;
198089857Sobrien      break;
1981130561Sobrien    case BFD_RELOC_PPC64_PLTGOT16_HA:		r = R_PPC64_PLTGOT16_HA;
198289857Sobrien      break;
1983130561Sobrien    case BFD_RELOC_PPC64_ADDR16_DS:		r = R_PPC64_ADDR16_DS;
198489857Sobrien      break;
1985130561Sobrien    case BFD_RELOC_PPC64_ADDR16_LO_DS:		r = R_PPC64_ADDR16_LO_DS;
198689857Sobrien      break;
1987130561Sobrien    case BFD_RELOC_PPC64_GOT16_DS:		r = R_PPC64_GOT16_DS;
198889857Sobrien      break;
1989130561Sobrien    case BFD_RELOC_PPC64_GOT16_LO_DS:		r = R_PPC64_GOT16_LO_DS;
199089857Sobrien      break;
1991130561Sobrien    case BFD_RELOC_PPC64_PLT16_LO_DS:		r = R_PPC64_PLT16_LO_DS;
199289857Sobrien      break;
1993130561Sobrien    case BFD_RELOC_PPC64_SECTOFF_DS:		r = R_PPC64_SECTOFF_DS;
199489857Sobrien      break;
1995130561Sobrien    case BFD_RELOC_PPC64_SECTOFF_LO_DS:		r = R_PPC64_SECTOFF_LO_DS;
199689857Sobrien      break;
1997130561Sobrien    case BFD_RELOC_PPC64_TOC16_DS:		r = R_PPC64_TOC16_DS;
199889857Sobrien      break;
1999130561Sobrien    case BFD_RELOC_PPC64_TOC16_LO_DS:		r = R_PPC64_TOC16_LO_DS;
200089857Sobrien      break;
2001130561Sobrien    case BFD_RELOC_PPC64_PLTGOT16_DS:		r = R_PPC64_PLTGOT16_DS;
200289857Sobrien      break;
2003130561Sobrien    case BFD_RELOC_PPC64_PLTGOT16_LO_DS:	r = R_PPC64_PLTGOT16_LO_DS;
200489857Sobrien      break;
2005130561Sobrien    case BFD_RELOC_PPC_TLS:			r = R_PPC64_TLS;
200689857Sobrien      break;
2007130561Sobrien    case BFD_RELOC_PPC_DTPMOD:			r = R_PPC64_DTPMOD64;
200889857Sobrien      break;
2009130561Sobrien    case BFD_RELOC_PPC_TPREL16:			r = R_PPC64_TPREL16;
2010130561Sobrien      break;
2011130561Sobrien    case BFD_RELOC_PPC_TPREL16_LO:		r = R_PPC64_TPREL16_LO;
2012130561Sobrien      break;
2013130561Sobrien    case BFD_RELOC_PPC_TPREL16_HI:		r = R_PPC64_TPREL16_HI;
2014130561Sobrien      break;
2015130561Sobrien    case BFD_RELOC_PPC_TPREL16_HA:		r = R_PPC64_TPREL16_HA;
2016130561Sobrien      break;
2017130561Sobrien    case BFD_RELOC_PPC_TPREL:			r = R_PPC64_TPREL64;
2018130561Sobrien      break;
2019130561Sobrien    case BFD_RELOC_PPC_DTPREL16:		r = R_PPC64_DTPREL16;
2020130561Sobrien      break;
2021130561Sobrien    case BFD_RELOC_PPC_DTPREL16_LO:		r = R_PPC64_DTPREL16_LO;
2022130561Sobrien      break;
2023130561Sobrien    case BFD_RELOC_PPC_DTPREL16_HI:		r = R_PPC64_DTPREL16_HI;
2024130561Sobrien      break;
2025130561Sobrien    case BFD_RELOC_PPC_DTPREL16_HA:		r = R_PPC64_DTPREL16_HA;
2026130561Sobrien      break;
2027130561Sobrien    case BFD_RELOC_PPC_DTPREL:			r = R_PPC64_DTPREL64;
2028130561Sobrien      break;
2029130561Sobrien    case BFD_RELOC_PPC_GOT_TLSGD16:		r = R_PPC64_GOT_TLSGD16;
2030130561Sobrien      break;
2031130561Sobrien    case BFD_RELOC_PPC_GOT_TLSGD16_LO:		r = R_PPC64_GOT_TLSGD16_LO;
2032130561Sobrien      break;
2033130561Sobrien    case BFD_RELOC_PPC_GOT_TLSGD16_HI:		r = R_PPC64_GOT_TLSGD16_HI;
2034130561Sobrien      break;
2035130561Sobrien    case BFD_RELOC_PPC_GOT_TLSGD16_HA:		r = R_PPC64_GOT_TLSGD16_HA;
2036130561Sobrien      break;
2037130561Sobrien    case BFD_RELOC_PPC_GOT_TLSLD16:		r = R_PPC64_GOT_TLSLD16;
2038130561Sobrien      break;
2039130561Sobrien    case BFD_RELOC_PPC_GOT_TLSLD16_LO:		r = R_PPC64_GOT_TLSLD16_LO;
2040130561Sobrien      break;
2041130561Sobrien    case BFD_RELOC_PPC_GOT_TLSLD16_HI:		r = R_PPC64_GOT_TLSLD16_HI;
2042130561Sobrien      break;
2043130561Sobrien    case BFD_RELOC_PPC_GOT_TLSLD16_HA:		r = R_PPC64_GOT_TLSLD16_HA;
2044130561Sobrien      break;
2045130561Sobrien    case BFD_RELOC_PPC_GOT_TPREL16:		r = R_PPC64_GOT_TPREL16_DS;
2046130561Sobrien      break;
2047130561Sobrien    case BFD_RELOC_PPC_GOT_TPREL16_LO:		r = R_PPC64_GOT_TPREL16_LO_DS;
2048130561Sobrien      break;
2049130561Sobrien    case BFD_RELOC_PPC_GOT_TPREL16_HI:		r = R_PPC64_GOT_TPREL16_HI;
2050130561Sobrien      break;
2051130561Sobrien    case BFD_RELOC_PPC_GOT_TPREL16_HA:		r = R_PPC64_GOT_TPREL16_HA;
2052130561Sobrien      break;
2053130561Sobrien    case BFD_RELOC_PPC_GOT_DTPREL16:		r = R_PPC64_GOT_DTPREL16_DS;
2054130561Sobrien      break;
2055130561Sobrien    case BFD_RELOC_PPC_GOT_DTPREL16_LO:		r = R_PPC64_GOT_DTPREL16_LO_DS;
2056130561Sobrien      break;
2057130561Sobrien    case BFD_RELOC_PPC_GOT_DTPREL16_HI:		r = R_PPC64_GOT_DTPREL16_HI;
2058130561Sobrien      break;
2059130561Sobrien    case BFD_RELOC_PPC_GOT_DTPREL16_HA:		r = R_PPC64_GOT_DTPREL16_HA;
2060130561Sobrien      break;
2061130561Sobrien    case BFD_RELOC_PPC64_TPREL16_DS:		r = R_PPC64_TPREL16_DS;
2062130561Sobrien      break;
2063130561Sobrien    case BFD_RELOC_PPC64_TPREL16_LO_DS:		r = R_PPC64_TPREL16_LO_DS;
2064130561Sobrien      break;
2065130561Sobrien    case BFD_RELOC_PPC64_TPREL16_HIGHER:	r = R_PPC64_TPREL16_HIGHER;
2066130561Sobrien      break;
2067130561Sobrien    case BFD_RELOC_PPC64_TPREL16_HIGHERA:	r = R_PPC64_TPREL16_HIGHERA;
2068130561Sobrien      break;
2069130561Sobrien    case BFD_RELOC_PPC64_TPREL16_HIGHEST:	r = R_PPC64_TPREL16_HIGHEST;
2070130561Sobrien      break;
2071130561Sobrien    case BFD_RELOC_PPC64_TPREL16_HIGHESTA:	r = R_PPC64_TPREL16_HIGHESTA;
2072130561Sobrien      break;
2073130561Sobrien    case BFD_RELOC_PPC64_DTPREL16_DS:		r = R_PPC64_DTPREL16_DS;
2074130561Sobrien      break;
2075130561Sobrien    case BFD_RELOC_PPC64_DTPREL16_LO_DS:	r = R_PPC64_DTPREL16_LO_DS;
2076130561Sobrien      break;
2077130561Sobrien    case BFD_RELOC_PPC64_DTPREL16_HIGHER:	r = R_PPC64_DTPREL16_HIGHER;
2078130561Sobrien      break;
2079130561Sobrien    case BFD_RELOC_PPC64_DTPREL16_HIGHERA:	r = R_PPC64_DTPREL16_HIGHERA;
2080130561Sobrien      break;
2081130561Sobrien    case BFD_RELOC_PPC64_DTPREL16_HIGHEST:	r = R_PPC64_DTPREL16_HIGHEST;
2082130561Sobrien      break;
2083130561Sobrien    case BFD_RELOC_PPC64_DTPREL16_HIGHESTA:	r = R_PPC64_DTPREL16_HIGHESTA;
2084130561Sobrien      break;
2085130561Sobrien    case BFD_RELOC_VTABLE_INHERIT:		r = R_PPC64_GNU_VTINHERIT;
2086130561Sobrien      break;
2087130561Sobrien    case BFD_RELOC_VTABLE_ENTRY:		r = R_PPC64_GNU_VTENTRY;
2088130561Sobrien      break;
208989857Sobrien    }
209089857Sobrien
2091130561Sobrien  return ppc64_elf_howto_table[r];
209289857Sobrien};
209389857Sobrien
209489857Sobrien/* Set the howto pointer for a PowerPC ELF reloc.  */
209589857Sobrien
209689857Sobrienstatic void
2097130561Sobrienppc64_elf_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
2098130561Sobrien			 Elf_Internal_Rela *dst)
209989857Sobrien{
210089857Sobrien  unsigned int type;
210189857Sobrien
2102104834Sobrien  /* Initialize howto table if needed.  */
210389857Sobrien  if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
210489857Sobrien    ppc_howto_init ();
210589857Sobrien
210689857Sobrien  type = ELF64_R_TYPE (dst->r_info);
210789857Sobrien  BFD_ASSERT (type < (sizeof (ppc64_elf_howto_table)
210889857Sobrien		      / sizeof (ppc64_elf_howto_table[0])));
210989857Sobrien  cache_ptr->howto = ppc64_elf_howto_table[type];
211089857Sobrien}
211189857Sobrien
2112130561Sobrien/* Handle the R_PPC64_ADDR16_HA and similar relocs.  */
211389857Sobrien
211489857Sobrienstatic bfd_reloc_status_type
2115130561Sobrienppc64_elf_ha_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2116130561Sobrien		    void *data, asection *input_section,
2117130561Sobrien		    bfd *output_bfd, char **error_message)
211889857Sobrien{
211999461Sobrien  /* If this is a relocatable link (output_bfd test tells us), just
212099461Sobrien     call the generic function.  Any adjustment will be done at final
212199461Sobrien     link time.  */
212299461Sobrien  if (output_bfd != NULL)
2123104834Sobrien    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
212499461Sobrien				  input_section, output_bfd, error_message);
212589857Sobrien
212699461Sobrien  /* Adjust the addend for sign extension of the low 16 bits.
212799461Sobrien     We won't actually be using the low 16 bits, so trashing them
212899461Sobrien     doesn't matter.  */
212999461Sobrien  reloc_entry->addend += 0x8000;
213099461Sobrien  return bfd_reloc_continue;
213199461Sobrien}
213299461Sobrien
213399461Sobrienstatic bfd_reloc_status_type
2134130561Sobrienppc64_elf_brtaken_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2135130561Sobrien			 void *data, asection *input_section,
2136130561Sobrien			 bfd *output_bfd, char **error_message)
213799461Sobrien{
213899461Sobrien  long insn;
2139130561Sobrien  enum elf_ppc64_reloc_type r_type;
214099461Sobrien  bfd_size_type octets;
214199461Sobrien  /* Disabled until we sort out how ld should choose 'y' vs 'at'.  */
2142130561Sobrien  bfd_boolean is_power4 = FALSE;
214399461Sobrien
214499461Sobrien  /* If this is a relocatable link (output_bfd test tells us), just
214599461Sobrien     call the generic function.  Any adjustment will be done at final
214699461Sobrien     link time.  */
214789857Sobrien  if (output_bfd != NULL)
2148104834Sobrien    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
214999461Sobrien				  input_section, output_bfd, error_message);
215099461Sobrien
215199461Sobrien  octets = reloc_entry->address * bfd_octets_per_byte (abfd);
215299461Sobrien  insn = bfd_get_32 (abfd, (bfd_byte *) data + octets);
215399461Sobrien  insn &= ~(0x01 << 21);
2154130561Sobrien  r_type = reloc_entry->howto->type;
215599461Sobrien  if (r_type == R_PPC64_ADDR14_BRTAKEN
215699461Sobrien      || r_type == R_PPC64_REL14_BRTAKEN)
2157104834Sobrien    insn |= 0x01 << 21; /* 'y' or 't' bit, lowest bit of BO field.  */
215899461Sobrien
215999461Sobrien  if (is_power4)
216089857Sobrien    {
216199461Sobrien      /* Set 'a' bit.  This is 0b00010 in BO field for branch
216299461Sobrien	 on CR(BI) insns (BO == 001at or 011at), and 0b01000
216399461Sobrien	 for branch on CTR insns (BO == 1a00t or 1a01t).  */
216499461Sobrien      if ((insn & (0x14 << 21)) == (0x04 << 21))
216599461Sobrien	insn |= 0x02 << 21;
216699461Sobrien      else if ((insn & (0x14 << 21)) == (0x10 << 21))
216799461Sobrien	insn |= 0x08 << 21;
216899461Sobrien      else
216999461Sobrien	return bfd_reloc_continue;
217089857Sobrien    }
217199461Sobrien  else
217299461Sobrien    {
217399461Sobrien      bfd_vma target = 0;
217499461Sobrien      bfd_vma from;
217589857Sobrien
217699461Sobrien      if (!bfd_is_com_section (symbol->section))
217799461Sobrien	target = symbol->value;
217899461Sobrien      target += symbol->section->output_section->vma;
217999461Sobrien      target += symbol->section->output_offset;
218099461Sobrien      target += reloc_entry->addend;
218189857Sobrien
218299461Sobrien      from = (reloc_entry->address
218399461Sobrien	      + input_section->output_offset
218499461Sobrien	      + input_section->output_section->vma);
218589857Sobrien
218699461Sobrien      /* Invert 'y' bit if not the default.  */
218799461Sobrien      if ((bfd_signed_vma) (target - from) < 0)
218899461Sobrien	insn ^= 0x01 << 21;
218999461Sobrien    }
2190130561Sobrien  bfd_put_32 (abfd, insn, (bfd_byte *) data + octets);
219199461Sobrien  return bfd_reloc_continue;
219299461Sobrien}
219389857Sobrien
219499461Sobrienstatic bfd_reloc_status_type
2195130561Sobrienppc64_elf_sectoff_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2196130561Sobrien			 void *data, asection *input_section,
2197130561Sobrien			 bfd *output_bfd, char **error_message)
219899461Sobrien{
219999461Sobrien  /* If this is a relocatable link (output_bfd test tells us), just
220099461Sobrien     call the generic function.  Any adjustment will be done at final
220199461Sobrien     link time.  */
220299461Sobrien  if (output_bfd != NULL)
2203104834Sobrien    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
220499461Sobrien				  input_section, output_bfd, error_message);
220589857Sobrien
220699461Sobrien  /* Subtract the symbol section base address.  */
220799461Sobrien  reloc_entry->addend -= symbol->section->output_section->vma;
220889857Sobrien  return bfd_reloc_continue;
220989857Sobrien}
221089857Sobrien
221199461Sobrienstatic bfd_reloc_status_type
2212130561Sobrienppc64_elf_sectoff_ha_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2213130561Sobrien			    void *data, asection *input_section,
2214130561Sobrien			    bfd *output_bfd, char **error_message)
221599461Sobrien{
221699461Sobrien  /* If this is a relocatable link (output_bfd test tells us), just
221799461Sobrien     call the generic function.  Any adjustment will be done at final
221899461Sobrien     link time.  */
221999461Sobrien  if (output_bfd != NULL)
2220104834Sobrien    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
222199461Sobrien				  input_section, output_bfd, error_message);
222299461Sobrien
222399461Sobrien  /* Subtract the symbol section base address.  */
222499461Sobrien  reloc_entry->addend -= symbol->section->output_section->vma;
222599461Sobrien
222699461Sobrien  /* Adjust the addend for sign extension of the low 16 bits.  */
222799461Sobrien  reloc_entry->addend += 0x8000;
222899461Sobrien  return bfd_reloc_continue;
222999461Sobrien}
223099461Sobrien
223199461Sobrienstatic bfd_reloc_status_type
2232130561Sobrienppc64_elf_toc_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2233130561Sobrien		     void *data, asection *input_section,
2234130561Sobrien		     bfd *output_bfd, char **error_message)
223599461Sobrien{
223699461Sobrien  bfd_vma TOCstart;
223799461Sobrien
223899461Sobrien  /* If this is a relocatable link (output_bfd test tells us), just
223999461Sobrien     call the generic function.  Any adjustment will be done at final
224099461Sobrien     link time.  */
224199461Sobrien  if (output_bfd != NULL)
2242104834Sobrien    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
224399461Sobrien				  input_section, output_bfd, error_message);
224499461Sobrien
224599461Sobrien  TOCstart = _bfd_get_gp_value (input_section->output_section->owner);
224699461Sobrien  if (TOCstart == 0)
224799461Sobrien    TOCstart = ppc64_elf_toc (input_section->output_section->owner);
224899461Sobrien
224999461Sobrien  /* Subtract the TOC base address.  */
225099461Sobrien  reloc_entry->addend -= TOCstart + TOC_BASE_OFF;
225199461Sobrien  return bfd_reloc_continue;
225299461Sobrien}
225399461Sobrien
225499461Sobrienstatic bfd_reloc_status_type
2255130561Sobrienppc64_elf_toc_ha_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2256130561Sobrien			void *data, asection *input_section,
2257130561Sobrien			bfd *output_bfd, char **error_message)
225899461Sobrien{
225999461Sobrien  bfd_vma TOCstart;
226099461Sobrien
226199461Sobrien  /* If this is a relocatable link (output_bfd test tells us), just
226299461Sobrien     call the generic function.  Any adjustment will be done at final
226399461Sobrien     link time.  */
226499461Sobrien  if (output_bfd != NULL)
2265104834Sobrien    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
226699461Sobrien				  input_section, output_bfd, error_message);
226799461Sobrien
226899461Sobrien  TOCstart = _bfd_get_gp_value (input_section->output_section->owner);
226999461Sobrien  if (TOCstart == 0)
227099461Sobrien    TOCstart = ppc64_elf_toc (input_section->output_section->owner);
227199461Sobrien
227299461Sobrien  /* Subtract the TOC base address.  */
227399461Sobrien  reloc_entry->addend -= TOCstart + TOC_BASE_OFF;
227499461Sobrien
227599461Sobrien  /* Adjust the addend for sign extension of the low 16 bits.  */
227699461Sobrien  reloc_entry->addend += 0x8000;
227799461Sobrien  return bfd_reloc_continue;
227899461Sobrien}
227999461Sobrien
228099461Sobrienstatic bfd_reloc_status_type
2281130561Sobrienppc64_elf_toc64_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2282130561Sobrien		       void *data, asection *input_section,
2283130561Sobrien		       bfd *output_bfd, char **error_message)
228499461Sobrien{
228599461Sobrien  bfd_vma TOCstart;
228699461Sobrien  bfd_size_type octets;
228799461Sobrien
228899461Sobrien  /* If this is a relocatable link (output_bfd test tells us), just
228999461Sobrien     call the generic function.  Any adjustment will be done at final
229099461Sobrien     link time.  */
229199461Sobrien  if (output_bfd != NULL)
2292104834Sobrien    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
229399461Sobrien				  input_section, output_bfd, error_message);
229499461Sobrien
229599461Sobrien  TOCstart = _bfd_get_gp_value (input_section->output_section->owner);
229699461Sobrien  if (TOCstart == 0)
229799461Sobrien    TOCstart = ppc64_elf_toc (input_section->output_section->owner);
229899461Sobrien
229999461Sobrien  octets = reloc_entry->address * bfd_octets_per_byte (abfd);
230099461Sobrien  bfd_put_64 (abfd, TOCstart + TOC_BASE_OFF, (bfd_byte *) data + octets);
230199461Sobrien  return bfd_reloc_ok;
230299461Sobrien}
230399461Sobrien
230499461Sobrienstatic bfd_reloc_status_type
2305130561Sobrienppc64_elf_unhandled_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2306130561Sobrien			   void *data, asection *input_section,
2307130561Sobrien			   bfd *output_bfd, char **error_message)
230899461Sobrien{
230999461Sobrien  /* If this is a relocatable link (output_bfd test tells us), just
231099461Sobrien     call the generic function.  Any adjustment will be done at final
231199461Sobrien     link time.  */
231299461Sobrien  if (output_bfd != NULL)
2313104834Sobrien    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
231499461Sobrien				  input_section, output_bfd, error_message);
231599461Sobrien
231699461Sobrien  if (error_message != NULL)
231799461Sobrien    {
231899461Sobrien      static char buf[60];
231999461Sobrien      sprintf (buf, "generic linker can't handle %s",
232099461Sobrien	       reloc_entry->howto->name);
232199461Sobrien      *error_message = buf;
232299461Sobrien    }
232399461Sobrien  return bfd_reloc_dangerous;
232499461Sobrien}
232599461Sobrien
2326130561Sobrienstruct ppc64_elf_obj_tdata
2327130561Sobrien{
2328130561Sobrien  struct elf_obj_tdata elf;
2329130561Sobrien
2330130561Sobrien  /* Shortcuts to dynamic linker sections.  */
2331130561Sobrien  asection *got;
2332130561Sobrien  asection *relgot;
2333130561Sobrien
2334130561Sobrien  /* TLS local dynamic got entry handling.  Suppose for multiple GOT
2335130561Sobrien     sections means we potentially need one of these for each input bfd.  */
2336130561Sobrien  union {
2337130561Sobrien    bfd_signed_vma refcount;
2338130561Sobrien    bfd_vma offset;
2339130561Sobrien  } tlsld_got;
2340130561Sobrien};
2341130561Sobrien
2342130561Sobrien#define ppc64_elf_tdata(bfd) \
2343130561Sobrien  ((struct ppc64_elf_obj_tdata *) (bfd)->tdata.any)
2344130561Sobrien
2345130561Sobrien#define ppc64_tlsld_got(bfd) \
2346130561Sobrien  (&ppc64_elf_tdata (bfd)->tlsld_got)
2347130561Sobrien
2348130561Sobrien/* Override the generic function because we store some extras.  */
2349130561Sobrien
2350130561Sobrienstatic bfd_boolean
2351130561Sobrienppc64_elf_mkobject (bfd *abfd)
2352130561Sobrien{
2353130561Sobrien  bfd_size_type amt = sizeof (struct ppc64_elf_obj_tdata);
2354130561Sobrien  abfd->tdata.any = bfd_zalloc (abfd, amt);
2355130561Sobrien  if (abfd->tdata.any == NULL)
2356130561Sobrien    return FALSE;
2357130561Sobrien  return TRUE;
2358130561Sobrien}
2359130561Sobrien
2360104834Sobrien/* Fix bad default arch selected for a 64 bit input bfd when the
2361104834Sobrien   default is 32 bit.  */
236289857Sobrien
2363130561Sobrienstatic bfd_boolean
2364130561Sobrienppc64_elf_object_p (bfd *abfd)
236589857Sobrien{
2366104834Sobrien  if (abfd->arch_info->the_default && abfd->arch_info->bits_per_word == 32)
2367104834Sobrien    {
2368104834Sobrien      Elf_Internal_Ehdr *i_ehdr = elf_elfheader (abfd);
236989857Sobrien
2370104834Sobrien      if (i_ehdr->e_ident[EI_CLASS] == ELFCLASS64)
2371104834Sobrien	{
2372104834Sobrien	  /* Relies on arch after 32 bit default being 64 bit default.  */
2373104834Sobrien	  abfd->arch_info = abfd->arch_info->next;
2374104834Sobrien	  BFD_ASSERT (abfd->arch_info->bits_per_word == 64);
2375104834Sobrien	}
2376104834Sobrien    }
2377130561Sobrien  return TRUE;
237889857Sobrien}
237989857Sobrien
2380130561Sobrien/* Support for core dump NOTE sections.  */
2381130561Sobrien
2382130561Sobrienstatic bfd_boolean
2383130561Sobrienppc64_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
2384130561Sobrien{
2385130561Sobrien  size_t offset, raw_size;
2386130561Sobrien
2387130561Sobrien  if (note->descsz != 504)
2388130561Sobrien    return FALSE;
2389130561Sobrien
2390130561Sobrien  /* pr_cursig */
2391130561Sobrien  elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
2392130561Sobrien
2393130561Sobrien  /* pr_pid */
2394130561Sobrien  elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 32);
2395130561Sobrien
2396130561Sobrien  /* pr_reg */
2397130561Sobrien  offset = 112;
2398130561Sobrien  raw_size = 384;
2399130561Sobrien
2400130561Sobrien  /* Make a ".reg/999" section.  */
2401130561Sobrien  return _bfd_elfcore_make_pseudosection (abfd, ".reg",
2402130561Sobrien					  raw_size, note->descpos + offset);
2403130561Sobrien}
2404130561Sobrien
2405130561Sobrienstatic bfd_boolean
2406130561Sobrienppc64_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
2407130561Sobrien{
2408130561Sobrien  if (note->descsz != 136)
2409130561Sobrien    return FALSE;
2410130561Sobrien
2411130561Sobrien  elf_tdata (abfd)->core_program
2412130561Sobrien    = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
2413130561Sobrien  elf_tdata (abfd)->core_command
2414130561Sobrien    = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
2415130561Sobrien
2416130561Sobrien  return TRUE;
2417130561Sobrien}
2418130561Sobrien
241989857Sobrien/* Merge backend specific data from an object file to the output
242089857Sobrien   object file when linking.  */
2421104834Sobrien
2422130561Sobrienstatic bfd_boolean
2423130561Sobrienppc64_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
242489857Sobrien{
242589857Sobrien  /* Check if we have the same endianess.  */
242689857Sobrien  if (ibfd->xvec->byteorder != obfd->xvec->byteorder
2427107492Sobrien      && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
242889857Sobrien      && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
242989857Sobrien    {
243089857Sobrien      const char *msg;
243189857Sobrien
243289857Sobrien      if (bfd_big_endian (ibfd))
2433130561Sobrien	msg = _("%s: compiled for a big endian system "
2434130561Sobrien		"and target is little endian");
243589857Sobrien      else
2436130561Sobrien	msg = _("%s: compiled for a little endian system "
2437130561Sobrien		"and target is big endian");
243889857Sobrien
243989857Sobrien      (*_bfd_error_handler) (msg, bfd_archive_filename (ibfd));
244089857Sobrien
244189857Sobrien      bfd_set_error (bfd_error_wrong_format);
2442130561Sobrien      return FALSE;
244389857Sobrien    }
244489857Sobrien
2445130561Sobrien  return TRUE;
244689857Sobrien}
2447130561Sobrien
2448130561Sobrien/* Add extra PPC sections.  */
2449130561Sobrien
2450130561Sobrienstatic struct bfd_elf_special_section const ppc64_elf_special_sections[]=
2451130561Sobrien{
2452130561Sobrien  { ".sdata",   6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
2453130561Sobrien  { ".sbss",    5, -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
2454130561Sobrien  { ".plt",     4,  0, SHT_NOBITS,   0 },
2455130561Sobrien  { ".toc",     4,  0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
2456130561Sobrien  { ".toc1",    5,  0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
2457130561Sobrien  { ".tocbss",  7,  0, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
2458130561Sobrien  { NULL,       0,  0, 0,            0 }
2459130561Sobrien};
2460130561Sobrien
2461130561Sobrienstruct _ppc64_elf_section_data
2462130561Sobrien{
2463130561Sobrien  struct bfd_elf_section_data elf;
2464130561Sobrien
2465130561Sobrien  /* An array with one entry for each opd function descriptor.  */
2466130561Sobrien  union
2467130561Sobrien  {
2468130561Sobrien    /* Points to the function code section for local opd entries.  */
2469130561Sobrien    asection **func_sec;
2470130561Sobrien    /* After editing .opd, adjust references to opd local syms.  */
2471130561Sobrien    long *adjust;
2472130561Sobrien  } opd;
2473130561Sobrien
2474130561Sobrien  /* An array for toc sections, indexed by offset/8.
2475130561Sobrien     Specifies the relocation symbol index used at a given toc offset.  */
2476130561Sobrien  unsigned *t_symndx;
2477130561Sobrien};
2478130561Sobrien
2479130561Sobrien#define ppc64_elf_section_data(sec) \
2480130561Sobrien  ((struct _ppc64_elf_section_data *) elf_section_data (sec))
2481130561Sobrien
2482130561Sobrienstatic bfd_boolean
2483130561Sobrienppc64_elf_new_section_hook (bfd *abfd, asection *sec)
2484130561Sobrien{
2485130561Sobrien  struct _ppc64_elf_section_data *sdata;
2486130561Sobrien  bfd_size_type amt = sizeof (*sdata);
2487130561Sobrien
2488130561Sobrien  sdata = bfd_zalloc (abfd, amt);
2489130561Sobrien  if (sdata == NULL)
2490130561Sobrien    return FALSE;
2491130561Sobrien  sec->used_by_bfd = sdata;
2492130561Sobrien
2493130561Sobrien  return _bfd_elf_new_section_hook (abfd, sec);
2494130561Sobrien}
249589857Sobrien
249689857Sobrien/* The following functions are specific to the ELF linker, while
249789857Sobrien   functions above are used generally.  Those named ppc64_elf_* are
249889857Sobrien   called by the main ELF linker code.  They appear in this file more
249989857Sobrien   or less in the order in which they are called.  eg.
250089857Sobrien   ppc64_elf_check_relocs is called early in the link process,
250189857Sobrien   ppc64_elf_finish_dynamic_sections is one of the last functions
250289857Sobrien   called.
250389857Sobrien
250489857Sobrien   PowerPC64-ELF uses a similar scheme to PowerPC64-XCOFF in that
250589857Sobrien   functions have both a function code symbol and a function descriptor
250689857Sobrien   symbol.  A call to foo in a relocatable object file looks like:
250789857Sobrien
250889857Sobrien   .		.text
250989857Sobrien   .	x:
251089857Sobrien   .		bl	.foo
251189857Sobrien   .		nop
251289857Sobrien
251389857Sobrien   The function definition in another object file might be:
251489857Sobrien
251589857Sobrien   .		.section .opd
251689857Sobrien   .	foo:	.quad	.foo
251789857Sobrien   .		.quad	.TOC.@tocbase
251889857Sobrien   .		.quad	0
251989857Sobrien   .
252089857Sobrien   .		.text
252189857Sobrien   .	.foo:	blr
252289857Sobrien
252389857Sobrien   When the linker resolves the call during a static link, the branch
252489857Sobrien   unsurprisingly just goes to .foo and the .opd information is unused.
252589857Sobrien   If the function definition is in a shared library, things are a little
252689857Sobrien   different:  The call goes via a plt call stub, the opd information gets
252789857Sobrien   copied to the plt, and the linker patches the nop.
252889857Sobrien
252989857Sobrien   .	x:
253089857Sobrien   .		bl	.foo_stub
253189857Sobrien   .		ld	2,40(1)
253289857Sobrien   .
253389857Sobrien   .
253489857Sobrien   .	.foo_stub:
253589857Sobrien   .		addis	12,2,Lfoo@toc@ha	# in practice, the call stub
2536130561Sobrien   .		addi	12,12,Lfoo@toc@l	# is slightly optimized, but
253789857Sobrien   .		std	2,40(1)			# this is the general idea
253889857Sobrien   .		ld	11,0(12)
253989857Sobrien   .		ld	2,8(12)
254089857Sobrien   .		mtctr	11
254189857Sobrien   .		ld	11,16(12)
254289857Sobrien   .		bctr
254389857Sobrien   .
254489857Sobrien   .		.section .plt
254589857Sobrien   .	Lfoo:	reloc (R_PPC64_JMP_SLOT, foo)
254689857Sobrien
254789857Sobrien   The "reloc ()" notation is supposed to indicate that the linker emits
254889857Sobrien   an R_PPC64_JMP_SLOT reloc against foo.  The dynamic linker does the opd
254989857Sobrien   copying.
255089857Sobrien
255189857Sobrien   What are the difficulties here?  Well, firstly, the relocations
255289857Sobrien   examined by the linker in check_relocs are against the function code
255389857Sobrien   sym .foo, while the dynamic relocation in the plt is emitted against
255489857Sobrien   the function descriptor symbol, foo.  Somewhere along the line, we need
255589857Sobrien   to carefully copy dynamic link information from one symbol to the other.
255689857Sobrien   Secondly, the generic part of the elf linker will make .foo a dynamic
255789857Sobrien   symbol as is normal for most other backends.  We need foo dynamic
255889857Sobrien   instead, at least for an application final link.  However, when
255989857Sobrien   creating a shared library containing foo, we need to have both symbols
256089857Sobrien   dynamic so that references to .foo are satisfied during the early
256189857Sobrien   stages of linking.  Otherwise the linker might decide to pull in a
256289857Sobrien   definition from some other object, eg. a static library.  */
256389857Sobrien
256489857Sobrien/* The linker needs to keep track of the number of relocs that it
256589857Sobrien   decides to copy as dynamic relocs in check_relocs for each symbol.
256689857Sobrien   This is so that it can later discard them if they are found to be
256789857Sobrien   unnecessary.  We store the information in a field extending the
256889857Sobrien   regular ELF linker hash table.  */
256989857Sobrien
257089857Sobrienstruct ppc_dyn_relocs
257189857Sobrien{
257289857Sobrien  struct ppc_dyn_relocs *next;
257389857Sobrien
257489857Sobrien  /* The input section of the reloc.  */
257589857Sobrien  asection *sec;
257689857Sobrien
257789857Sobrien  /* Total number of relocs copied for the input section.  */
257889857Sobrien  bfd_size_type count;
257989857Sobrien
258089857Sobrien  /* Number of pc-relative relocs copied for the input section.  */
258189857Sobrien  bfd_size_type pc_count;
258289857Sobrien};
258389857Sobrien
2584130561Sobrien/* Track GOT entries needed for a given symbol.  We might need more
2585130561Sobrien   than one got entry per symbol.  */
2586130561Sobrienstruct got_entry
2587130561Sobrien{
2588130561Sobrien  struct got_entry *next;
2589130561Sobrien
2590130561Sobrien  /* The symbol addend that we'll be placing in the GOT.  */
2591130561Sobrien  bfd_vma addend;
2592130561Sobrien
2593130561Sobrien  /* Unlike other ELF targets, we use separate GOT entries for the same
2594130561Sobrien     symbol referenced from different input files.  This is to support
2595130561Sobrien     automatic multiple TOC/GOT sections, where the TOC base can vary
2596130561Sobrien     from one input file to another.
2597130561Sobrien
2598130561Sobrien     Point to the BFD owning this GOT entry.  */
2599130561Sobrien  bfd *owner;
2600130561Sobrien
2601130561Sobrien  /* Zero for non-tls entries, or TLS_TLS and one of TLS_GD, TLS_LD,
2602130561Sobrien     TLS_TPREL or TLS_DTPREL for tls entries.  */
2603130561Sobrien  char tls_type;
2604130561Sobrien
2605130561Sobrien  /* Reference count until size_dynamic_sections, GOT offset thereafter.  */
2606130561Sobrien  union
2607130561Sobrien    {
2608130561Sobrien      bfd_signed_vma refcount;
2609130561Sobrien      bfd_vma offset;
2610130561Sobrien    } got;
2611130561Sobrien};
2612130561Sobrien
2613130561Sobrien/* The same for PLT.  */
2614130561Sobrienstruct plt_entry
2615130561Sobrien{
2616130561Sobrien  struct plt_entry *next;
2617130561Sobrien
2618130561Sobrien  bfd_vma addend;
2619130561Sobrien
2620130561Sobrien  union
2621130561Sobrien    {
2622130561Sobrien      bfd_signed_vma refcount;
2623130561Sobrien      bfd_vma offset;
2624130561Sobrien    } plt;
2625130561Sobrien};
2626130561Sobrien
262789857Sobrien/* Of those relocs that might be copied as dynamic relocs, this macro
2628130561Sobrien   selects those that must be copied when linking a shared library,
2629130561Sobrien   even when the symbol is local.  */
263089857Sobrien
2631130561Sobrien#define MUST_BE_DYN_RELOC(RTYPE)		\
2632104834Sobrien  ((RTYPE) != R_PPC64_REL32			\
2633104834Sobrien   && (RTYPE) != R_PPC64_REL64			\
2634130561Sobrien   && (RTYPE) != R_PPC64_REL30)
263589857Sobrien
2636130561Sobrien/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
2637130561Sobrien   copying dynamic variables from a shared lib into an app's dynbss
2638130561Sobrien   section, and instead use a dynamic relocation to point into the
2639130561Sobrien   shared lib.  With code that gcc generates, it's vital that this be
2640130561Sobrien   enabled;  In the PowerPC64 ABI, the address of a function is actually
2641130561Sobrien   the address of a function descriptor, which resides in the .opd
2642130561Sobrien   section.  gcc uses the descriptor directly rather than going via the
2643130561Sobrien   GOT as some other ABI's do, which means that initialized function
2644130561Sobrien   pointers must reference the descriptor.  Thus, a function pointer
2645130561Sobrien   initialized to the address of a function in a shared library will
2646130561Sobrien   either require a copy reloc, or a dynamic reloc.  Using a copy reloc
2647130561Sobrien   redefines the function descriptor symbol to point to the copy.  This
2648130561Sobrien   presents a problem as a plt entry for that function is also
2649130561Sobrien   initialized from the function descriptor symbol and the copy reloc
2650130561Sobrien   may not be initialized first.  */
2651130561Sobrien#define ELIMINATE_COPY_RELOCS 1
2652130561Sobrien
2653104834Sobrien/* Section name for stubs is the associated section name plus this
2654104834Sobrien   string.  */
2655104834Sobrien#define STUB_SUFFIX ".stub"
265689857Sobrien
2657104834Sobrien/* Linker stubs.
2658104834Sobrien   ppc_stub_long_branch:
2659104834Sobrien   Used when a 14 bit branch (or even a 24 bit branch) can't reach its
2660104834Sobrien   destination, but a 24 bit branch in a stub section will reach.
2661104834Sobrien   .	b	dest
2662104834Sobrien
2663104834Sobrien   ppc_stub_plt_branch:
2664104834Sobrien   Similar to the above, but a 24 bit branch in the stub section won't
2665104834Sobrien   reach its destination.
2666107492Sobrien   .	addis	%r12,%r2,xxx@toc@ha
2667107492Sobrien   .	ld	%r11,xxx@toc@l(%r12)
2668104834Sobrien   .	mtctr	%r11
2669104834Sobrien   .	bctr
2670104834Sobrien
2671104834Sobrien   ppc_stub_plt_call:
2672104834Sobrien   Used to call a function in a shared library.
2673107492Sobrien   .	addis	%r12,%r2,xxx@toc@ha
2674104834Sobrien   .	std	%r2,40(%r1)
2675107492Sobrien   .	ld	%r11,xxx+0@toc@l(%r12)
2676107492Sobrien   .	ld	%r2,xxx+8@toc@l(%r12)
2677104834Sobrien   .	mtctr	%r11
2678107492Sobrien   .	ld	%r11,xxx+16@toc@l(%r12)
2679104834Sobrien   .	bctr
2680130561Sobrien
2681130561Sobrien   ppc_stub_long_branch and ppc_stub_plt_branch may also have additional
2682130561Sobrien   code to adjust the value and save r2 to support multiple toc sections.
2683130561Sobrien   A ppc_stub_long_branch with an r2 offset looks like:
2684130561Sobrien   .	std	%r2,40(%r1)
2685130561Sobrien   .	addis	%r2,%r2,off@ha
2686130561Sobrien   .	addi	%r2,%r2,off@l
2687130561Sobrien   .	b	dest
2688130561Sobrien
2689130561Sobrien   A ppc_stub_plt_branch with an r2 offset looks like:
2690130561Sobrien   .	std	%r2,40(%r1)
2691130561Sobrien   .	addis	%r12,%r2,xxx@toc@ha
2692130561Sobrien   .	ld	%r11,xxx@toc@l(%r12)
2693130561Sobrien   .	addis	%r2,%r2,off@ha
2694130561Sobrien   .	addi	%r2,%r2,off@l
2695130561Sobrien   .	mtctr	%r11
2696130561Sobrien   .	bctr
2697104834Sobrien*/
2698104834Sobrien
2699104834Sobrienenum ppc_stub_type {
2700104834Sobrien  ppc_stub_none,
2701104834Sobrien  ppc_stub_long_branch,
2702130561Sobrien  ppc_stub_long_branch_r2off,
2703104834Sobrien  ppc_stub_plt_branch,
2704130561Sobrien  ppc_stub_plt_branch_r2off,
2705104834Sobrien  ppc_stub_plt_call
2706104834Sobrien};
2707104834Sobrien
2708104834Sobrienstruct ppc_stub_hash_entry {
2709104834Sobrien
2710104834Sobrien  /* Base hash table entry structure.  */
2711104834Sobrien  struct bfd_hash_entry root;
2712104834Sobrien
2713130561Sobrien  enum ppc_stub_type stub_type;
2714130561Sobrien
2715104834Sobrien  /* The stub section.  */
2716104834Sobrien  asection *stub_sec;
2717104834Sobrien
2718104834Sobrien  /* Offset within stub_sec of the beginning of this stub.  */
2719104834Sobrien  bfd_vma stub_offset;
2720104834Sobrien
2721104834Sobrien  /* Given the symbol's value and its section we can determine its final
2722104834Sobrien     value when building the stubs (so the stub knows where to jump.  */
2723104834Sobrien  bfd_vma target_value;
2724104834Sobrien  asection *target_section;
2725104834Sobrien
2726104834Sobrien  /* The symbol table entry, if any, that this was derived from.  */
2727104834Sobrien  struct ppc_link_hash_entry *h;
2728104834Sobrien
2729130561Sobrien  /* And the reloc addend that this was derived from.  */
2730130561Sobrien  bfd_vma addend;
2731130561Sobrien
2732104834Sobrien  /* Where this stub is being called from, or, in the case of combined
2733104834Sobrien     stub sections, the first input section in the group.  */
2734104834Sobrien  asection *id_sec;
2735104834Sobrien};
2736104834Sobrien
2737104834Sobrienstruct ppc_branch_hash_entry {
2738104834Sobrien
2739104834Sobrien  /* Base hash table entry structure.  */
2740104834Sobrien  struct bfd_hash_entry root;
2741104834Sobrien
2742104834Sobrien  /* Offset within .branch_lt.  */
2743104834Sobrien  unsigned int offset;
2744104834Sobrien
2745104834Sobrien  /* Generation marker.  */
2746104834Sobrien  unsigned int iter;
2747104834Sobrien};
2748104834Sobrien
274989857Sobrienstruct ppc_link_hash_entry
275089857Sobrien{
275189857Sobrien  struct elf_link_hash_entry elf;
275289857Sobrien
2753104834Sobrien  /* A pointer to the most recently used stub hash entry against this
2754104834Sobrien     symbol.  */
2755104834Sobrien  struct ppc_stub_hash_entry *stub_cache;
2756104834Sobrien
275789857Sobrien  /* Track dynamic relocs copied for this symbol.  */
275889857Sobrien  struct ppc_dyn_relocs *dyn_relocs;
275989857Sobrien
2760104834Sobrien  /* Link between function code and descriptor symbols.  */
2761104834Sobrien  struct elf_link_hash_entry *oh;
2762104834Sobrien
276389857Sobrien  /* Flag function code and descriptor symbols.  */
276489857Sobrien  unsigned int is_func:1;
276589857Sobrien  unsigned int is_func_descriptor:1;
2766104834Sobrien  unsigned int is_entry:1;
2767130561Sobrien
2768130561Sobrien  /* Whether global opd sym has been adjusted or not.  */
2769130561Sobrien  unsigned int adjust_done:1;
2770130561Sobrien
2771130561Sobrien  /* Contexts in which symbol is used in the GOT (or TOC).
2772130561Sobrien     TLS_GD .. TLS_EXPLICIT bits are or'd into the mask as the
2773130561Sobrien     corresponding relocs are encountered during check_relocs.
2774130561Sobrien     tls_optimize clears TLS_GD .. TLS_TPREL when optimizing to
2775130561Sobrien     indicate the corresponding GOT entry type is not needed.
2776130561Sobrien     tls_optimize may also set TLS_TPRELGD when a GD reloc turns into
2777130561Sobrien     a TPREL one.  We use a separate flag rather than setting TPREL
2778130561Sobrien     just for convenience in distinguishing the two cases.  */
2779130561Sobrien#define TLS_GD		 1	/* GD reloc. */
2780130561Sobrien#define TLS_LD		 2	/* LD reloc. */
2781130561Sobrien#define TLS_TPREL	 4	/* TPREL reloc, => IE. */
2782130561Sobrien#define TLS_DTPREL	 8	/* DTPREL reloc, => LD. */
2783130561Sobrien#define TLS_TLS		16	/* Any TLS reloc.  */
2784130561Sobrien#define TLS_EXPLICIT	32	/* Marks TOC section TLS relocs. */
2785130561Sobrien#define TLS_TPRELGD	64	/* TPREL reloc resulting from GD->IE. */
2786130561Sobrien  char tls_mask;
278789857Sobrien};
278889857Sobrien
278989857Sobrien/* ppc64 ELF linker hash table.  */
279089857Sobrien
279189857Sobrienstruct ppc_link_hash_table
279289857Sobrien{
279389857Sobrien  struct elf_link_hash_table elf;
279489857Sobrien
2795104834Sobrien  /* The stub hash table.  */
2796104834Sobrien  struct bfd_hash_table stub_hash_table;
2797104834Sobrien
2798104834Sobrien  /* Another hash table for plt_branch stubs.  */
2799104834Sobrien  struct bfd_hash_table branch_hash_table;
2800104834Sobrien
2801104834Sobrien  /* Linker stub bfd.  */
2802104834Sobrien  bfd *stub_bfd;
2803104834Sobrien
2804104834Sobrien  /* Linker call-backs.  */
2805130561Sobrien  asection * (*add_stub_section) (const char *, asection *);
2806130561Sobrien  void (*layout_sections_again) (void);
2807104834Sobrien
2808104834Sobrien  /* Array to keep track of which stub sections have been created, and
2809104834Sobrien     information on stub grouping.  */
2810104834Sobrien  struct map_stub {
2811104834Sobrien    /* This is the section to which stubs in the group will be attached.  */
2812104834Sobrien    asection *link_sec;
2813104834Sobrien    /* The stub section.  */
2814104834Sobrien    asection *stub_sec;
2815130561Sobrien    /* Along with elf_gp, specifies the TOC pointer used in this group.  */
2816130561Sobrien    bfd_vma toc_off;
2817104834Sobrien  } *stub_group;
2818104834Sobrien
2819130561Sobrien  /* Support for multiple toc sections.  */
2820130561Sobrien  unsigned int no_multi_toc;
2821130561Sobrien  unsigned int multi_toc_needed;
2822130561Sobrien
2823130561Sobrien  /* Temp used when calculating TOC pointers.  */
2824130561Sobrien  bfd_vma toc_curr;
2825130561Sobrien
2826130561Sobrien  /* Highest input section id.  */
2827130561Sobrien  int top_id;
2828130561Sobrien
2829130561Sobrien  /* Highest output section index.  */
2830104834Sobrien  int top_index;
2831130561Sobrien
2832130561Sobrien  /* List of input sections for each output section.  */
2833104834Sobrien  asection **input_list;
2834104834Sobrien
283589857Sobrien  /* Short-cuts to get to dynamic linker sections.  */
2836130561Sobrien  asection *got;
2837130561Sobrien  asection *plt;
2838130561Sobrien  asection *relplt;
2839130561Sobrien  asection *dynbss;
2840130561Sobrien  asection *relbss;
2841130561Sobrien  asection *glink;
284292828Sobrien  asection *sfpr;
2843130561Sobrien  asection *brlt;
2844130561Sobrien  asection *relbrlt;
284589857Sobrien
2846130561Sobrien  /* Shortcut to .__tls_get_addr.  */
2847130561Sobrien  struct elf_link_hash_entry *tls_get_addr;
2848130561Sobrien
2849130561Sobrien  /* Statistics.  */
2850130561Sobrien  unsigned long stub_count[ppc_stub_plt_call];
2851130561Sobrien
2852130561Sobrien  /* Set if we should emit symbols for stubs.  */
2853130561Sobrien  unsigned int emit_stub_syms;
2854130561Sobrien
285589857Sobrien  /* Set on error.  */
2856104834Sobrien  unsigned int stub_error;
285789857Sobrien
2858104834Sobrien  /* Flag set when small branches are detected.  Used to
2859104834Sobrien     select suitable defaults for the stub group size.  */
2860104834Sobrien  unsigned int has_14bit_branch;
2861104834Sobrien
286299461Sobrien  /* Set if we detect a reference undefined weak symbol.  */
286399461Sobrien  unsigned int have_undefweak;
286499461Sobrien
2865104834Sobrien  /* Incremented every time we size stubs.  */
2866104834Sobrien  unsigned int stub_iteration;
2867104834Sobrien
286889857Sobrien  /* Small local sym to section mapping cache.  */
286989857Sobrien  struct sym_sec_cache sym_sec;
287089857Sobrien};
287189857Sobrien
287289857Sobrien/* Get the ppc64 ELF linker hash table from a link_info structure.  */
287389857Sobrien
287489857Sobrien#define ppc_hash_table(p) \
287589857Sobrien  ((struct ppc_link_hash_table *) ((p)->hash))
287689857Sobrien
2877104834Sobrien#define ppc_stub_hash_lookup(table, string, create, copy) \
2878104834Sobrien  ((struct ppc_stub_hash_entry *) \
2879104834Sobrien   bfd_hash_lookup ((table), (string), (create), (copy)))
2880104834Sobrien
2881104834Sobrien#define ppc_branch_hash_lookup(table, string, create, copy) \
2882104834Sobrien  ((struct ppc_branch_hash_entry *) \
2883104834Sobrien   bfd_hash_lookup ((table), (string), (create), (copy)))
2884104834Sobrien
2885104834Sobrien/* Create an entry in the stub hash table.  */
2886104834Sobrien
2887104834Sobrienstatic struct bfd_hash_entry *
2888130561Sobrienstub_hash_newfunc (struct bfd_hash_entry *entry,
2889130561Sobrien		   struct bfd_hash_table *table,
2890130561Sobrien		   const char *string)
2891104834Sobrien{
2892104834Sobrien  /* Allocate the structure if it has not already been allocated by a
2893104834Sobrien     subclass.  */
2894104834Sobrien  if (entry == NULL)
2895104834Sobrien    {
2896104834Sobrien      entry = bfd_hash_allocate (table, sizeof (struct ppc_stub_hash_entry));
2897104834Sobrien      if (entry == NULL)
2898104834Sobrien	return entry;
2899104834Sobrien    }
2900104834Sobrien
2901104834Sobrien  /* Call the allocation method of the superclass.  */
2902104834Sobrien  entry = bfd_hash_newfunc (entry, table, string);
2903104834Sobrien  if (entry != NULL)
2904104834Sobrien    {
2905104834Sobrien      struct ppc_stub_hash_entry *eh;
2906104834Sobrien
2907104834Sobrien      /* Initialize the local fields.  */
2908104834Sobrien      eh = (struct ppc_stub_hash_entry *) entry;
2909130561Sobrien      eh->stub_type = ppc_stub_none;
2910104834Sobrien      eh->stub_sec = NULL;
2911104834Sobrien      eh->stub_offset = 0;
2912104834Sobrien      eh->target_value = 0;
2913104834Sobrien      eh->target_section = NULL;
2914104834Sobrien      eh->h = NULL;
2915104834Sobrien      eh->id_sec = NULL;
2916104834Sobrien    }
2917104834Sobrien
2918104834Sobrien  return entry;
2919104834Sobrien}
2920104834Sobrien
2921104834Sobrien/* Create an entry in the branch hash table.  */
2922104834Sobrien
2923104834Sobrienstatic struct bfd_hash_entry *
2924130561Sobrienbranch_hash_newfunc (struct bfd_hash_entry *entry,
2925130561Sobrien		     struct bfd_hash_table *table,
2926130561Sobrien		     const char *string)
2927104834Sobrien{
2928104834Sobrien  /* Allocate the structure if it has not already been allocated by a
2929104834Sobrien     subclass.  */
2930104834Sobrien  if (entry == NULL)
2931104834Sobrien    {
2932104834Sobrien      entry = bfd_hash_allocate (table, sizeof (struct ppc_branch_hash_entry));
2933104834Sobrien      if (entry == NULL)
2934104834Sobrien	return entry;
2935104834Sobrien    }
2936104834Sobrien
2937104834Sobrien  /* Call the allocation method of the superclass.  */
2938104834Sobrien  entry = bfd_hash_newfunc (entry, table, string);
2939104834Sobrien  if (entry != NULL)
2940104834Sobrien    {
2941104834Sobrien      struct ppc_branch_hash_entry *eh;
2942104834Sobrien
2943104834Sobrien      /* Initialize the local fields.  */
2944104834Sobrien      eh = (struct ppc_branch_hash_entry *) entry;
2945104834Sobrien      eh->offset = 0;
2946104834Sobrien      eh->iter = 0;
2947104834Sobrien    }
2948104834Sobrien
2949104834Sobrien  return entry;
2950104834Sobrien}
2951104834Sobrien
295289857Sobrien/* Create an entry in a ppc64 ELF linker hash table.  */
295389857Sobrien
295489857Sobrienstatic struct bfd_hash_entry *
2955130561Sobrienlink_hash_newfunc (struct bfd_hash_entry *entry,
2956130561Sobrien		   struct bfd_hash_table *table,
2957130561Sobrien		   const char *string)
295889857Sobrien{
295989857Sobrien  /* Allocate the structure if it has not already been allocated by a
296089857Sobrien     subclass.  */
296189857Sobrien  if (entry == NULL)
296289857Sobrien    {
296389857Sobrien      entry = bfd_hash_allocate (table, sizeof (struct ppc_link_hash_entry));
296489857Sobrien      if (entry == NULL)
296589857Sobrien	return entry;
296689857Sobrien    }
296789857Sobrien
296889857Sobrien  /* Call the allocation method of the superclass.  */
296989857Sobrien  entry = _bfd_elf_link_hash_newfunc (entry, table, string);
297089857Sobrien  if (entry != NULL)
297189857Sobrien    {
297289857Sobrien      struct ppc_link_hash_entry *eh = (struct ppc_link_hash_entry *) entry;
297389857Sobrien
2974104834Sobrien      eh->stub_cache = NULL;
297589857Sobrien      eh->dyn_relocs = NULL;
2976104834Sobrien      eh->oh = NULL;
297789857Sobrien      eh->is_func = 0;
297889857Sobrien      eh->is_func_descriptor = 0;
2979104834Sobrien      eh->is_entry = 0;
2980130561Sobrien      eh->adjust_done = 0;
2981130561Sobrien      eh->tls_mask = 0;
298289857Sobrien    }
298389857Sobrien
298489857Sobrien  return entry;
298589857Sobrien}
298689857Sobrien
298789857Sobrien/* Create a ppc64 ELF linker hash table.  */
298889857Sobrien
298989857Sobrienstatic struct bfd_link_hash_table *
2990130561Sobrienppc64_elf_link_hash_table_create (bfd *abfd)
299189857Sobrien{
299289857Sobrien  struct ppc_link_hash_table *htab;
299389857Sobrien  bfd_size_type amt = sizeof (struct ppc_link_hash_table);
299489857Sobrien
2995130561Sobrien  htab = bfd_zmalloc (amt);
299689857Sobrien  if (htab == NULL)
299789857Sobrien    return NULL;
299889857Sobrien
299989857Sobrien  if (! _bfd_elf_link_hash_table_init (&htab->elf, abfd, link_hash_newfunc))
300089857Sobrien    {
3001104834Sobrien      free (htab);
300289857Sobrien      return NULL;
300389857Sobrien    }
300489857Sobrien
3005104834Sobrien  /* Init the stub hash table too.  */
3006104834Sobrien  if (!bfd_hash_table_init (&htab->stub_hash_table, stub_hash_newfunc))
3007104834Sobrien    return NULL;
3008104834Sobrien
3009104834Sobrien  /* And the branch hash table.  */
3010104834Sobrien  if (!bfd_hash_table_init (&htab->branch_hash_table, branch_hash_newfunc))
3011104834Sobrien    return NULL;
3012104834Sobrien
3013130561Sobrien  /* Initializing two fields of the union is just cosmetic.  We really
3014130561Sobrien     only care about glist, but when compiled on a 32-bit host the
3015130561Sobrien     bfd_vma fields are larger.  Setting the bfd_vma to zero makes
3016130561Sobrien     debugger inspection of these fields look nicer.  */
3017130561Sobrien  htab->elf.init_refcount.refcount = 0;
3018130561Sobrien  htab->elf.init_refcount.glist = NULL;
3019130561Sobrien  htab->elf.init_offset.offset = 0;
3020130561Sobrien  htab->elf.init_offset.glist = NULL;
302189857Sobrien
302289857Sobrien  return &htab->elf.root;
302389857Sobrien}
302489857Sobrien
3025104834Sobrien/* Free the derived linker hash table.  */
3026104834Sobrien
3027104834Sobrienstatic void
3028130561Sobrienppc64_elf_link_hash_table_free (struct bfd_link_hash_table *hash)
3029104834Sobrien{
3030104834Sobrien  struct ppc_link_hash_table *ret = (struct ppc_link_hash_table *) hash;
3031104834Sobrien
3032104834Sobrien  bfd_hash_table_free (&ret->stub_hash_table);
3033104834Sobrien  bfd_hash_table_free (&ret->branch_hash_table);
3034104834Sobrien  _bfd_generic_link_hash_table_free (hash);
3035104834Sobrien}
3036104834Sobrien
3037130561Sobrien/* Satisfy the ELF linker by filling in some fields in our fake bfd.  */
3038130561Sobrien
3039130561Sobrienvoid
3040130561Sobrienppc64_elf_init_stub_bfd (bfd *abfd, struct bfd_link_info *info)
3041130561Sobrien{
3042130561Sobrien  struct ppc_link_hash_table *htab;
3043130561Sobrien
3044130561Sobrien  elf_elfheader (abfd)->e_ident[EI_CLASS] = ELFCLASS64;
3045130561Sobrien
3046130561Sobrien/* Always hook our dynamic sections into the first bfd, which is the
3047130561Sobrien   linker created stub bfd.  This ensures that the GOT header is at
3048130561Sobrien   the start of the output TOC section.  */
3049130561Sobrien  htab = ppc_hash_table (info);
3050130561Sobrien  htab->stub_bfd = abfd;
3051130561Sobrien  htab->elf.dynobj = abfd;
3052130561Sobrien}
3053130561Sobrien
3054104834Sobrien/* Build a name for an entry in the stub hash table.  */
3055104834Sobrien
3056104834Sobrienstatic char *
3057130561Sobrienppc_stub_name (const asection *input_section,
3058130561Sobrien	       const asection *sym_sec,
3059130561Sobrien	       const struct ppc_link_hash_entry *h,
3060130561Sobrien	       const Elf_Internal_Rela *rel)
3061104834Sobrien{
3062104834Sobrien  char *stub_name;
3063104834Sobrien  bfd_size_type len;
3064104834Sobrien
3065104834Sobrien  /* rel->r_addend is actually 64 bit, but who uses more than +/- 2^31
3066104834Sobrien     offsets from a sym as a branch target?  In fact, we could
3067104834Sobrien     probably assume the addend is always zero.  */
3068104834Sobrien  BFD_ASSERT (((int) rel->r_addend & 0xffffffff) == rel->r_addend);
3069104834Sobrien
3070104834Sobrien  if (h)
3071104834Sobrien    {
3072104834Sobrien      len = 8 + 1 + strlen (h->elf.root.root.string) + 1 + 8 + 1;
3073104834Sobrien      stub_name = bfd_malloc (len);
3074104834Sobrien      if (stub_name != NULL)
3075104834Sobrien	{
3076130561Sobrien	  sprintf (stub_name, "%08x.%s+%x",
3077104834Sobrien		   input_section->id & 0xffffffff,
3078104834Sobrien		   h->elf.root.root.string,
3079104834Sobrien		   (int) rel->r_addend & 0xffffffff);
3080104834Sobrien	}
3081104834Sobrien    }
3082104834Sobrien  else
3083104834Sobrien    {
3084130561Sobrien      len = 8 + 1 + 8 + 1 + 8 + 1 + 8 + 1;
3085104834Sobrien      stub_name = bfd_malloc (len);
3086104834Sobrien      if (stub_name != NULL)
3087104834Sobrien	{
3088130561Sobrien	  sprintf (stub_name, "%08x.%x:%x+%x",
3089104834Sobrien		   input_section->id & 0xffffffff,
3090104834Sobrien		   sym_sec->id & 0xffffffff,
3091104834Sobrien		   (int) ELF64_R_SYM (rel->r_info) & 0xffffffff,
3092104834Sobrien		   (int) rel->r_addend & 0xffffffff);
3093104834Sobrien	}
3094104834Sobrien    }
3095104834Sobrien  return stub_name;
3096104834Sobrien}
3097104834Sobrien
3098104834Sobrien/* Look up an entry in the stub hash.  Stub entries are cached because
3099104834Sobrien   creating the stub name takes a bit of time.  */
3100104834Sobrien
3101104834Sobrienstatic struct ppc_stub_hash_entry *
3102130561Sobrienppc_get_stub_entry (const asection *input_section,
3103130561Sobrien		    const asection *sym_sec,
3104130561Sobrien		    struct elf_link_hash_entry *hash,
3105130561Sobrien		    const Elf_Internal_Rela *rel,
3106130561Sobrien		    struct ppc_link_hash_table *htab)
3107104834Sobrien{
3108104834Sobrien  struct ppc_stub_hash_entry *stub_entry;
3109104834Sobrien  struct ppc_link_hash_entry *h = (struct ppc_link_hash_entry *) hash;
3110104834Sobrien  const asection *id_sec;
3111104834Sobrien
3112104834Sobrien  /* If this input section is part of a group of sections sharing one
3113104834Sobrien     stub section, then use the id of the first section in the group.
3114104834Sobrien     Stub names need to include a section id, as there may well be
3115104834Sobrien     more than one stub used to reach say, printf, and we need to
3116104834Sobrien     distinguish between them.  */
3117104834Sobrien  id_sec = htab->stub_group[input_section->id].link_sec;
3118104834Sobrien
3119104834Sobrien  if (h != NULL && h->stub_cache != NULL
3120104834Sobrien      && h->stub_cache->h == h
3121104834Sobrien      && h->stub_cache->id_sec == id_sec)
3122104834Sobrien    {
3123104834Sobrien      stub_entry = h->stub_cache;
3124104834Sobrien    }
3125104834Sobrien  else
3126104834Sobrien    {
3127104834Sobrien      char *stub_name;
3128104834Sobrien
3129104834Sobrien      stub_name = ppc_stub_name (id_sec, sym_sec, h, rel);
3130104834Sobrien      if (stub_name == NULL)
3131104834Sobrien	return NULL;
3132104834Sobrien
3133104834Sobrien      stub_entry = ppc_stub_hash_lookup (&htab->stub_hash_table,
3134130561Sobrien					 stub_name, FALSE, FALSE);
3135104834Sobrien      if (h != NULL)
3136104834Sobrien	h->stub_cache = stub_entry;
3137104834Sobrien
3138104834Sobrien      free (stub_name);
3139104834Sobrien    }
3140104834Sobrien
3141104834Sobrien  return stub_entry;
3142104834Sobrien}
3143104834Sobrien
3144104834Sobrien/* Add a new stub entry to the stub hash.  Not all fields of the new
3145104834Sobrien   stub entry are initialised.  */
3146104834Sobrien
3147104834Sobrienstatic struct ppc_stub_hash_entry *
3148130561Sobrienppc_add_stub (const char *stub_name,
3149130561Sobrien	      asection *section,
3150130561Sobrien	      struct ppc_link_hash_table *htab)
3151104834Sobrien{
3152104834Sobrien  asection *link_sec;
3153104834Sobrien  asection *stub_sec;
3154104834Sobrien  struct ppc_stub_hash_entry *stub_entry;
3155104834Sobrien
3156104834Sobrien  link_sec = htab->stub_group[section->id].link_sec;
3157104834Sobrien  stub_sec = htab->stub_group[section->id].stub_sec;
3158104834Sobrien  if (stub_sec == NULL)
3159104834Sobrien    {
3160104834Sobrien      stub_sec = htab->stub_group[link_sec->id].stub_sec;
3161104834Sobrien      if (stub_sec == NULL)
3162104834Sobrien	{
3163104834Sobrien	  size_t namelen;
3164104834Sobrien	  bfd_size_type len;
3165104834Sobrien	  char *s_name;
3166104834Sobrien
3167104834Sobrien	  namelen = strlen (link_sec->name);
3168104834Sobrien	  len = namelen + sizeof (STUB_SUFFIX);
3169104834Sobrien	  s_name = bfd_alloc (htab->stub_bfd, len);
3170104834Sobrien	  if (s_name == NULL)
3171104834Sobrien	    return NULL;
3172104834Sobrien
3173104834Sobrien	  memcpy (s_name, link_sec->name, namelen);
3174104834Sobrien	  memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
3175104834Sobrien	  stub_sec = (*htab->add_stub_section) (s_name, link_sec);
3176104834Sobrien	  if (stub_sec == NULL)
3177104834Sobrien	    return NULL;
3178104834Sobrien	  htab->stub_group[link_sec->id].stub_sec = stub_sec;
3179104834Sobrien	}
3180104834Sobrien      htab->stub_group[section->id].stub_sec = stub_sec;
3181104834Sobrien    }
3182104834Sobrien
3183104834Sobrien  /* Enter this entry into the linker stub hash table.  */
3184104834Sobrien  stub_entry = ppc_stub_hash_lookup (&htab->stub_hash_table, stub_name,
3185130561Sobrien				     TRUE, FALSE);
3186104834Sobrien  if (stub_entry == NULL)
3187104834Sobrien    {
3188104834Sobrien      (*_bfd_error_handler) (_("%s: cannot create stub entry %s"),
3189104834Sobrien			     bfd_archive_filename (section->owner),
3190104834Sobrien			     stub_name);
3191104834Sobrien      return NULL;
3192104834Sobrien    }
3193104834Sobrien
3194104834Sobrien  stub_entry->stub_sec = stub_sec;
3195104834Sobrien  stub_entry->stub_offset = 0;
3196104834Sobrien  stub_entry->id_sec = link_sec;
3197104834Sobrien  return stub_entry;
3198104834Sobrien}
3199104834Sobrien
320092828Sobrien/* Create sections for linker generated code.  */
320192828Sobrien
3202130561Sobrienstatic bfd_boolean
3203130561Sobriencreate_linkage_sections (bfd *dynobj, struct bfd_link_info *info)
320492828Sobrien{
320592828Sobrien  struct ppc_link_hash_table *htab;
320692828Sobrien  flagword flags;
320792828Sobrien
320892828Sobrien  htab = ppc_hash_table (info);
320992828Sobrien
321092828Sobrien  /* Create .sfpr for code to save and restore fp regs.  */
321192828Sobrien  flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY
321292828Sobrien	   | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
3213104834Sobrien  htab->sfpr = bfd_make_section_anyway (dynobj, ".sfpr");
321492828Sobrien  if (htab->sfpr == NULL
321592828Sobrien      || ! bfd_set_section_flags (dynobj, htab->sfpr, flags)
321692828Sobrien      || ! bfd_set_section_alignment (dynobj, htab->sfpr, 2))
3217130561Sobrien    return FALSE;
321892828Sobrien
3219104834Sobrien  /* Create .glink for lazy dynamic linking support.  */
3220130561Sobrien  htab->glink = bfd_make_section_anyway (dynobj, ".glink");
3221130561Sobrien  if (htab->glink == NULL
3222130561Sobrien      || ! bfd_set_section_flags (dynobj, htab->glink, flags)
3223130561Sobrien      || ! bfd_set_section_alignment (dynobj, htab->glink, 2))
3224130561Sobrien    return FALSE;
322592828Sobrien
3226104834Sobrien  /* Create .branch_lt for plt_branch stubs.  */
3227104834Sobrien  flags = (SEC_ALLOC | SEC_LOAD
3228104834Sobrien	   | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
3229130561Sobrien  htab->brlt = bfd_make_section_anyway (dynobj, ".branch_lt");
3230130561Sobrien  if (htab->brlt == NULL
3231130561Sobrien      || ! bfd_set_section_flags (dynobj, htab->brlt, flags)
3232130561Sobrien      || ! bfd_set_section_alignment (dynobj, htab->brlt, 3))
3233130561Sobrien    return FALSE;
3234104834Sobrien
3235104834Sobrien  if (info->shared)
3236104834Sobrien    {
3237104834Sobrien      flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
3238104834Sobrien	       | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
3239130561Sobrien      htab->relbrlt = bfd_make_section_anyway (dynobj, ".rela.branch_lt");
3240130561Sobrien      if (!htab->relbrlt
3241130561Sobrien	  || ! bfd_set_section_flags (dynobj, htab->relbrlt, flags)
3242130561Sobrien	  || ! bfd_set_section_alignment (dynobj, htab->relbrlt, 3))
3243130561Sobrien	return FALSE;
3244104834Sobrien    }
3245130561Sobrien  return TRUE;
324692828Sobrien}
324792828Sobrien
3248130561Sobrien/* Create .got and .rela.got sections in ABFD, and .got in dynobj if
3249130561Sobrien   not already done.  */
325089857Sobrien
3251130561Sobrienstatic bfd_boolean
3252130561Sobriencreate_got_section (bfd *abfd, struct bfd_link_info *info)
325389857Sobrien{
3254130561Sobrien  asection *got, *relgot;
3255130561Sobrien  flagword flags;
3256130561Sobrien  struct ppc_link_hash_table *htab = ppc_hash_table (info);
325789857Sobrien
3258130561Sobrien  if (!htab->got)
3259130561Sobrien    {
3260130561Sobrien      if (! _bfd_elf_create_got_section (htab->elf.dynobj, info))
3261130561Sobrien	return FALSE;
326289857Sobrien
3263130561Sobrien      htab->got = bfd_get_section_by_name (htab->elf.dynobj, ".got");
3264130561Sobrien      if (!htab->got)
3265130561Sobrien	abort ();
3266130561Sobrien    }
326789857Sobrien
3268130561Sobrien  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
3269130561Sobrien	   | SEC_LINKER_CREATED);
3270130561Sobrien
3271209867Snwhitehorn  got = bfd_make_section_anyway (abfd, ".got");
3272130561Sobrien  if (!got
3273130561Sobrien      || !bfd_set_section_flags (abfd, got, flags)
3274130561Sobrien      || !bfd_set_section_alignment (abfd, got, 3))
3275130561Sobrien    return FALSE;
3276130561Sobrien
3277209867Snwhitehorn  relgot = bfd_make_section_anyway (abfd, ".rela.got");
3278130561Sobrien  if (!relgot
3279130561Sobrien      || ! bfd_set_section_flags (abfd, relgot, flags | SEC_READONLY)
3280130561Sobrien      || ! bfd_set_section_alignment (abfd, relgot, 3))
3281130561Sobrien    return FALSE;
3282130561Sobrien
3283130561Sobrien  ppc64_elf_tdata (abfd)->got = got;
3284130561Sobrien  ppc64_elf_tdata (abfd)->relgot = relgot;
3285130561Sobrien  return TRUE;
328689857Sobrien}
328789857Sobrien
328892828Sobrien/* Create the dynamic sections, and set up shortcuts.  */
328989857Sobrien
3290130561Sobrienstatic bfd_boolean
3291130561Sobrienppc64_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
329289857Sobrien{
329389857Sobrien  struct ppc_link_hash_table *htab;
329489857Sobrien
329589857Sobrien  if (!_bfd_elf_create_dynamic_sections (dynobj, info))
3296130561Sobrien    return FALSE;
329789857Sobrien
3298130561Sobrien  htab = ppc_hash_table (info);
3299130561Sobrien  if (!htab->got)
3300130561Sobrien    htab->got = bfd_get_section_by_name (dynobj, ".got");
3301130561Sobrien  htab->plt = bfd_get_section_by_name (dynobj, ".plt");
3302130561Sobrien  htab->relplt = bfd_get_section_by_name (dynobj, ".rela.plt");
3303130561Sobrien  htab->dynbss = bfd_get_section_by_name (dynobj, ".dynbss");
330489857Sobrien  if (!info->shared)
3305130561Sobrien    htab->relbss = bfd_get_section_by_name (dynobj, ".rela.bss");
330689857Sobrien
3307130561Sobrien  if (!htab->got || !htab->plt || !htab->relplt || !htab->dynbss
3308130561Sobrien      || (!info->shared && !htab->relbss))
330989857Sobrien    abort ();
331089857Sobrien
3311130561Sobrien  return TRUE;
331289857Sobrien}
331389857Sobrien
331489857Sobrien/* Copy the extra info we tack onto an elf_link_hash_entry.  */
331589857Sobrien
331689857Sobrienstatic void
3317130561Sobrienppc64_elf_copy_indirect_symbol
3318130561Sobrien  (const struct elf_backend_data *bed ATTRIBUTE_UNUSED,
3319130561Sobrien   struct elf_link_hash_entry *dir,
3320130561Sobrien   struct elf_link_hash_entry *ind)
332189857Sobrien{
332289857Sobrien  struct ppc_link_hash_entry *edir, *eind;
3323130561Sobrien  flagword mask;
332489857Sobrien
332589857Sobrien  edir = (struct ppc_link_hash_entry *) dir;
332689857Sobrien  eind = (struct ppc_link_hash_entry *) ind;
332789857Sobrien
3328130561Sobrien  /* Copy over any dynamic relocs we may have on the indirect sym.  */
332989857Sobrien  if (eind->dyn_relocs != NULL)
333089857Sobrien    {
333189857Sobrien      if (edir->dyn_relocs != NULL)
333289857Sobrien	{
333389857Sobrien	  struct ppc_dyn_relocs **pp;
333489857Sobrien	  struct ppc_dyn_relocs *p;
333589857Sobrien
3336130561Sobrien	  if (eind->elf.root.type == bfd_link_hash_indirect)
333789857Sobrien	    abort ();
333889857Sobrien
333989857Sobrien	  /* Add reloc counts against the weak sym to the strong sym
334089857Sobrien	     list.  Merge any entries against the same section.  */
334189857Sobrien	  for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
334289857Sobrien	    {
334389857Sobrien	      struct ppc_dyn_relocs *q;
334489857Sobrien
334589857Sobrien	      for (q = edir->dyn_relocs; q != NULL; q = q->next)
334689857Sobrien		if (q->sec == p->sec)
334789857Sobrien		  {
334889857Sobrien		    q->pc_count += p->pc_count;
334989857Sobrien		    q->count += p->count;
335089857Sobrien		    *pp = p->next;
335189857Sobrien		    break;
335289857Sobrien		  }
335389857Sobrien	      if (q == NULL)
335489857Sobrien		pp = &p->next;
335589857Sobrien	    }
335689857Sobrien	  *pp = edir->dyn_relocs;
335789857Sobrien	}
335889857Sobrien
335989857Sobrien      edir->dyn_relocs = eind->dyn_relocs;
336089857Sobrien      eind->dyn_relocs = NULL;
336189857Sobrien    }
336289857Sobrien
336389857Sobrien  edir->is_func |= eind->is_func;
336489857Sobrien  edir->is_func_descriptor |= eind->is_func_descriptor;
3365104834Sobrien  edir->is_entry |= eind->is_entry;
3366130561Sobrien  edir->tls_mask |= eind->tls_mask;
336789857Sobrien
3368130561Sobrien  mask = (ELF_LINK_HASH_REF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR
3369130561Sobrien	  | ELF_LINK_HASH_REF_REGULAR_NONWEAK | ELF_LINK_NON_GOT_REF
3370130561Sobrien	  | ELF_LINK_HASH_NEEDS_PLT);
3371130561Sobrien  /* If called to transfer flags for a weakdef during processing
3372130561Sobrien     of elf_adjust_dynamic_symbol, don't copy ELF_LINK_NON_GOT_REF.
3373130561Sobrien     We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
3374130561Sobrien  if (ELIMINATE_COPY_RELOCS
3375130561Sobrien      && eind->elf.root.type != bfd_link_hash_indirect
3376130561Sobrien      && (edir->elf.elf_link_hash_flags & ELF_LINK_HASH_DYNAMIC_ADJUSTED) != 0)
3377130561Sobrien    mask &= ~ELF_LINK_NON_GOT_REF;
3378130561Sobrien
3379130561Sobrien  edir->elf.elf_link_hash_flags |= eind->elf.elf_link_hash_flags & mask;
3380130561Sobrien
3381130561Sobrien  /* If we were called to copy over info for a weak sym, that's all.  */
3382130561Sobrien  if (eind->elf.root.type != bfd_link_hash_indirect)
3383130561Sobrien    return;
3384130561Sobrien
3385130561Sobrien  /* Copy over got entries that we may have already seen to the
3386130561Sobrien     symbol which just became indirect.  */
3387130561Sobrien  if (eind->elf.got.glist != NULL)
3388130561Sobrien    {
3389130561Sobrien      if (edir->elf.got.glist != NULL)
3390130561Sobrien	{
3391130561Sobrien	  struct got_entry **entp;
3392130561Sobrien	  struct got_entry *ent;
3393130561Sobrien
3394130561Sobrien	  for (entp = &eind->elf.got.glist; (ent = *entp) != NULL; )
3395130561Sobrien	    {
3396130561Sobrien	      struct got_entry *dent;
3397130561Sobrien
3398130561Sobrien	      for (dent = edir->elf.got.glist; dent != NULL; dent = dent->next)
3399130561Sobrien		if (dent->addend == ent->addend
3400130561Sobrien		    && dent->owner == ent->owner
3401130561Sobrien		    && dent->tls_type == ent->tls_type)
3402130561Sobrien		  {
3403130561Sobrien		    dent->got.refcount += ent->got.refcount;
3404130561Sobrien		    *entp = ent->next;
3405130561Sobrien		    break;
3406130561Sobrien		  }
3407130561Sobrien	      if (dent == NULL)
3408130561Sobrien		entp = &ent->next;
3409130561Sobrien	    }
3410130561Sobrien	  *entp = edir->elf.got.glist;
3411130561Sobrien	}
3412130561Sobrien
3413130561Sobrien      edir->elf.got.glist = eind->elf.got.glist;
3414130561Sobrien      eind->elf.got.glist = NULL;
3415130561Sobrien    }
3416130561Sobrien
3417130561Sobrien  /* And plt entries.  */
3418130561Sobrien  if (eind->elf.plt.plist != NULL)
3419130561Sobrien    {
3420130561Sobrien      if (edir->elf.plt.plist != NULL)
3421130561Sobrien	{
3422130561Sobrien	  struct plt_entry **entp;
3423130561Sobrien	  struct plt_entry *ent;
3424130561Sobrien
3425130561Sobrien	  for (entp = &eind->elf.plt.plist; (ent = *entp) != NULL; )
3426130561Sobrien	    {
3427130561Sobrien	      struct plt_entry *dent;
3428130561Sobrien
3429130561Sobrien	      for (dent = edir->elf.plt.plist; dent != NULL; dent = dent->next)
3430130561Sobrien		if (dent->addend == ent->addend)
3431130561Sobrien		  {
3432130561Sobrien		    dent->plt.refcount += ent->plt.refcount;
3433130561Sobrien		    *entp = ent->next;
3434130561Sobrien		    break;
3435130561Sobrien		  }
3436130561Sobrien	      if (dent == NULL)
3437130561Sobrien		entp = &ent->next;
3438130561Sobrien	    }
3439130561Sobrien	  *entp = edir->elf.plt.plist;
3440130561Sobrien	}
3441130561Sobrien
3442130561Sobrien      edir->elf.plt.plist = eind->elf.plt.plist;
3443130561Sobrien      eind->elf.plt.plist = NULL;
3444130561Sobrien    }
3445130561Sobrien
3446130561Sobrien  if (edir->elf.dynindx == -1)
3447130561Sobrien    {
3448130561Sobrien      edir->elf.dynindx = eind->elf.dynindx;
3449130561Sobrien      edir->elf.dynstr_index = eind->elf.dynstr_index;
3450130561Sobrien      eind->elf.dynindx = -1;
3451130561Sobrien      eind->elf.dynstr_index = 0;
3452130561Sobrien    }
3453130561Sobrien  else
3454130561Sobrien    BFD_ASSERT (eind->elf.dynindx == -1);
345589857Sobrien}
345689857Sobrien
3457104834Sobrien/* Set a flag, used by ppc64_elf_gc_mark_hook, on the entry symbol and
3458104834Sobrien   symbols undefined on the command-line.  */
3459104834Sobrien
3460130561Sobrienbfd_boolean
3461130561Sobrienppc64_elf_mark_entry_syms (struct bfd_link_info *info)
3462104834Sobrien{
3463104834Sobrien  struct ppc_link_hash_table *htab;
3464104834Sobrien  struct bfd_sym_chain *sym;
3465104834Sobrien
3466104834Sobrien  htab = ppc_hash_table (info);
3467104834Sobrien  for (sym = info->gc_sym_list; sym; sym = sym->next)
3468104834Sobrien    {
3469104834Sobrien      struct elf_link_hash_entry *h;
3470104834Sobrien
3471130561Sobrien      h = elf_link_hash_lookup (&htab->elf, sym->name, FALSE, FALSE, FALSE);
3472104834Sobrien      if (h != NULL)
3473104834Sobrien	((struct ppc_link_hash_entry *) h)->is_entry = 1;
3474104834Sobrien    }
3475130561Sobrien  return TRUE;
3476104834Sobrien}
3477104834Sobrien
3478130561Sobrien/* Hack symbols defined in .opd sections to be function type.  */
3479130561Sobrien
3480130561Sobrienstatic bfd_boolean
3481130561Sobrienppc64_elf_add_symbol_hook (bfd *ibfd ATTRIBUTE_UNUSED,
3482130561Sobrien			   struct bfd_link_info *info ATTRIBUTE_UNUSED,
3483130561Sobrien			   Elf_Internal_Sym *isym,
3484130561Sobrien			   const char **name ATTRIBUTE_UNUSED,
3485130561Sobrien			   flagword *flags ATTRIBUTE_UNUSED,
3486130561Sobrien			   asection **sec,
3487130561Sobrien			   bfd_vma *value ATTRIBUTE_UNUSED)
3488130561Sobrien{
3489130561Sobrien  if (strcmp (bfd_get_section_name (ibfd, *sec), ".opd") == 0)
3490130561Sobrien    isym->st_info = ELF_ST_INFO (ELF_ST_BIND (isym->st_info), STT_FUNC);
3491130561Sobrien  return TRUE;
3492130561Sobrien}
3493130561Sobrien
3494130561Sobrienstatic bfd_boolean
3495130561Sobrienupdate_local_sym_info (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
3496130561Sobrien		       unsigned long r_symndx, bfd_vma r_addend, int tls_type)
3497130561Sobrien{
3498130561Sobrien  struct got_entry **local_got_ents = elf_local_got_ents (abfd);
3499130561Sobrien  char *local_got_tls_masks;
3500130561Sobrien
3501130561Sobrien  if (local_got_ents == NULL)
3502130561Sobrien    {
3503130561Sobrien      bfd_size_type size = symtab_hdr->sh_info;
3504130561Sobrien
3505130561Sobrien      size *= sizeof (*local_got_ents) + sizeof (*local_got_tls_masks);
3506130561Sobrien      local_got_ents = bfd_zalloc (abfd, size);
3507130561Sobrien      if (local_got_ents == NULL)
3508130561Sobrien	return FALSE;
3509130561Sobrien      elf_local_got_ents (abfd) = local_got_ents;
3510130561Sobrien    }
3511130561Sobrien
3512130561Sobrien  if ((tls_type & TLS_EXPLICIT) == 0)
3513130561Sobrien    {
3514130561Sobrien      struct got_entry *ent;
3515130561Sobrien
3516130561Sobrien      for (ent = local_got_ents[r_symndx]; ent != NULL; ent = ent->next)
3517130561Sobrien	if (ent->addend == r_addend
3518130561Sobrien	    && ent->owner == abfd
3519130561Sobrien	    && ent->tls_type == tls_type)
3520130561Sobrien	  break;
3521130561Sobrien      if (ent == NULL)
3522130561Sobrien	{
3523130561Sobrien	  bfd_size_type amt = sizeof (*ent);
3524130561Sobrien	  ent = bfd_alloc (abfd, amt);
3525130561Sobrien	  if (ent == NULL)
3526130561Sobrien	    return FALSE;
3527130561Sobrien	  ent->next = local_got_ents[r_symndx];
3528130561Sobrien	  ent->addend = r_addend;
3529130561Sobrien	  ent->owner = abfd;
3530130561Sobrien	  ent->tls_type = tls_type;
3531130561Sobrien	  ent->got.refcount = 0;
3532130561Sobrien	  local_got_ents[r_symndx] = ent;
3533130561Sobrien	}
3534130561Sobrien      ent->got.refcount += 1;
3535130561Sobrien    }
3536130561Sobrien
3537130561Sobrien  local_got_tls_masks = (char *) (local_got_ents + symtab_hdr->sh_info);
3538130561Sobrien  local_got_tls_masks[r_symndx] |= tls_type;
3539130561Sobrien  return TRUE;
3540130561Sobrien}
3541130561Sobrien
3542130561Sobrienstatic bfd_boolean
3543130561Sobrienupdate_plt_info (bfd *abfd, struct ppc_link_hash_entry *eh, bfd_vma addend)
3544130561Sobrien{
3545130561Sobrien  struct plt_entry *ent;
3546130561Sobrien
3547130561Sobrien  for (ent = eh->elf.plt.plist; ent != NULL; ent = ent->next)
3548130561Sobrien    if (ent->addend == addend)
3549130561Sobrien      break;
3550130561Sobrien  if (ent == NULL)
3551130561Sobrien    {
3552130561Sobrien      bfd_size_type amt = sizeof (*ent);
3553130561Sobrien      ent = bfd_alloc (abfd, amt);
3554130561Sobrien      if (ent == NULL)
3555130561Sobrien	return FALSE;
3556130561Sobrien      ent->next = eh->elf.plt.plist;
3557130561Sobrien      ent->addend = addend;
3558130561Sobrien      ent->plt.refcount = 0;
3559130561Sobrien      eh->elf.plt.plist = ent;
3560130561Sobrien    }
3561130561Sobrien  ent->plt.refcount += 1;
3562130561Sobrien  eh->elf.elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
3563130561Sobrien  eh->is_func = 1;
3564130561Sobrien  return TRUE;
3565130561Sobrien}
3566130561Sobrien
3567130561Sobrien/* Find the function descriptor hash entry from the given function code
3568130561Sobrien   hash entry FH.  Link the entries via their OH fields.  */
3569130561Sobrienstatic struct ppc_link_hash_entry *
3570130561Sobrienget_fdh (struct ppc_link_hash_entry *fh, struct ppc_link_hash_table *htab)
3571130561Sobrien{
3572130561Sobrien  struct ppc_link_hash_entry *fdh = (struct ppc_link_hash_entry *) fh->oh;
3573130561Sobrien
3574130561Sobrien  if (fdh == NULL)
3575130561Sobrien    {
3576130561Sobrien      const char *fd_name = fh->elf.root.root.string + 1;
3577130561Sobrien
3578130561Sobrien      fdh = (struct ppc_link_hash_entry *)
3579130561Sobrien	elf_link_hash_lookup (&htab->elf, fd_name, FALSE, FALSE, FALSE);
3580130561Sobrien      if (fdh != NULL)
3581130561Sobrien	{
3582130561Sobrien	  fdh->is_func_descriptor = 1;
3583130561Sobrien	  fdh->oh = &fh->elf;
3584130561Sobrien	  fh->is_func = 1;
3585130561Sobrien	  fh->oh = &fdh->elf;
3586130561Sobrien	}
3587130561Sobrien    }
3588130561Sobrien
3589130561Sobrien  return fdh;
3590130561Sobrien}
3591130561Sobrien
359289857Sobrien/* Look through the relocs for a section during the first phase, and
359389857Sobrien   calculate needed space in the global offset table, procedure
359489857Sobrien   linkage table, and dynamic reloc sections.  */
359589857Sobrien
3596130561Sobrienstatic bfd_boolean
3597130561Sobrienppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
3598130561Sobrien			asection *sec, const Elf_Internal_Rela *relocs)
359989857Sobrien{
360089857Sobrien  struct ppc_link_hash_table *htab;
360189857Sobrien  Elf_Internal_Shdr *symtab_hdr;
360289857Sobrien  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
360389857Sobrien  const Elf_Internal_Rela *rel;
360489857Sobrien  const Elf_Internal_Rela *rel_end;
360589857Sobrien  asection *sreloc;
3606104834Sobrien  asection **opd_sym_map;
360789857Sobrien
3608130561Sobrien  if (info->relocatable)
3609130561Sobrien    return TRUE;
361089857Sobrien
3611130561Sobrien  /* Don't do anything special with non-loaded, non-alloced sections.
3612130561Sobrien     In particular, any relocs in such sections should not affect GOT
3613130561Sobrien     and PLT reference counting (ie. we don't allow them to create GOT
3614130561Sobrien     or PLT entries), there's no possibility or desire to optimize TLS
3615130561Sobrien     relocs, and there's not much point in propagating relocs to shared
3616130561Sobrien     libs that the dynamic linker won't relocate.  */
3617130561Sobrien  if ((sec->flags & SEC_ALLOC) == 0)
3618130561Sobrien    return TRUE;
3619130561Sobrien
362089857Sobrien  htab = ppc_hash_table (info);
362189857Sobrien  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
362289857Sobrien
362389857Sobrien  sym_hashes = elf_sym_hashes (abfd);
362489857Sobrien  sym_hashes_end = (sym_hashes
3625104834Sobrien		    + symtab_hdr->sh_size / sizeof (Elf64_External_Sym)
3626104834Sobrien		    - symtab_hdr->sh_info);
362789857Sobrien
362889857Sobrien  sreloc = NULL;
3629104834Sobrien  opd_sym_map = NULL;
3630104834Sobrien  if (strcmp (bfd_get_section_name (abfd, sec), ".opd") == 0)
3631104834Sobrien    {
3632104834Sobrien      /* Garbage collection needs some extra help with .opd sections.
3633104834Sobrien	 We don't want to necessarily keep everything referenced by
3634104834Sobrien	 relocs in .opd, as that would keep all functions.  Instead,
3635104834Sobrien	 if we reference an .opd symbol (a function descriptor), we
3636104834Sobrien	 want to keep the function code symbol's section.  This is
3637104834Sobrien	 easy for global symbols, but for local syms we need to keep
3638104834Sobrien	 information about the associated function section.  Later, if
3639104834Sobrien	 edit_opd deletes entries, we'll use this array to adjust
3640104834Sobrien	 local syms in .opd.  */
3641104834Sobrien      union opd_info {
3642104834Sobrien	asection *func_section;
3643104834Sobrien	long entry_adjust;
3644104834Sobrien      };
3645104834Sobrien      bfd_size_type amt;
364689857Sobrien
3647104834Sobrien      amt = sec->_raw_size * sizeof (union opd_info) / 24;
3648130561Sobrien      opd_sym_map = bfd_zalloc (abfd, amt);
3649104834Sobrien      if (opd_sym_map == NULL)
3650130561Sobrien	return FALSE;
3651130561Sobrien      ppc64_elf_section_data (sec)->opd.func_sec = opd_sym_map;
3652104834Sobrien    }
3653104834Sobrien
365492828Sobrien  if (htab->sfpr == NULL
365592828Sobrien      && !create_linkage_sections (htab->elf.dynobj, info))
3656130561Sobrien    return FALSE;
365792828Sobrien
365889857Sobrien  rel_end = relocs + sec->reloc_count;
365989857Sobrien  for (rel = relocs; rel < rel_end; rel++)
366089857Sobrien    {
366189857Sobrien      unsigned long r_symndx;
366289857Sobrien      struct elf_link_hash_entry *h;
3663130561Sobrien      enum elf_ppc64_reloc_type r_type;
3664130561Sobrien      int tls_type = 0;
366589857Sobrien
366689857Sobrien      r_symndx = ELF64_R_SYM (rel->r_info);
366789857Sobrien      if (r_symndx < symtab_hdr->sh_info)
366889857Sobrien	h = NULL;
366989857Sobrien      else
367089857Sobrien	h = sym_hashes[r_symndx - symtab_hdr->sh_info];
367189857Sobrien
3672130561Sobrien      r_type = ELF64_R_TYPE (rel->r_info);
367389857Sobrien      switch (r_type)
367489857Sobrien	{
3675130561Sobrien	case R_PPC64_GOT_TLSLD16:
3676130561Sobrien	case R_PPC64_GOT_TLSLD16_LO:
3677130561Sobrien	case R_PPC64_GOT_TLSLD16_HI:
3678130561Sobrien	case R_PPC64_GOT_TLSLD16_HA:
3679130561Sobrien	  ppc64_tlsld_got (abfd)->refcount += 1;
3680130561Sobrien	  tls_type = TLS_TLS | TLS_LD;
3681130561Sobrien	  goto dogottls;
3682130561Sobrien
3683130561Sobrien	case R_PPC64_GOT_TLSGD16:
3684130561Sobrien	case R_PPC64_GOT_TLSGD16_LO:
3685130561Sobrien	case R_PPC64_GOT_TLSGD16_HI:
3686130561Sobrien	case R_PPC64_GOT_TLSGD16_HA:
3687130561Sobrien	  tls_type = TLS_TLS | TLS_GD;
3688130561Sobrien	  goto dogottls;
3689130561Sobrien
3690130561Sobrien	case R_PPC64_GOT_TPREL16_DS:
3691130561Sobrien	case R_PPC64_GOT_TPREL16_LO_DS:
3692130561Sobrien	case R_PPC64_GOT_TPREL16_HI:
3693130561Sobrien	case R_PPC64_GOT_TPREL16_HA:
3694130561Sobrien	  if (info->shared)
3695130561Sobrien	    info->flags |= DF_STATIC_TLS;
3696130561Sobrien	  tls_type = TLS_TLS | TLS_TPREL;
3697130561Sobrien	  goto dogottls;
3698130561Sobrien
3699130561Sobrien	case R_PPC64_GOT_DTPREL16_DS:
3700130561Sobrien	case R_PPC64_GOT_DTPREL16_LO_DS:
3701130561Sobrien	case R_PPC64_GOT_DTPREL16_HI:
3702130561Sobrien	case R_PPC64_GOT_DTPREL16_HA:
3703130561Sobrien	  tls_type = TLS_TLS | TLS_DTPREL;
3704130561Sobrien	dogottls:
3705130561Sobrien	  sec->has_tls_reloc = 1;
3706130561Sobrien	  /* Fall thru */
3707130561Sobrien
370889857Sobrien	case R_PPC64_GOT16:
370989857Sobrien	case R_PPC64_GOT16_DS:
371089857Sobrien	case R_PPC64_GOT16_HA:
371189857Sobrien	case R_PPC64_GOT16_HI:
371289857Sobrien	case R_PPC64_GOT16_LO:
371389857Sobrien	case R_PPC64_GOT16_LO_DS:
371489857Sobrien	  /* This symbol requires a global offset table entry.  */
3715130561Sobrien	  sec->has_gp_reloc = 1;
3716130561Sobrien	  if (ppc64_elf_tdata (abfd)->got == NULL
3717130561Sobrien	      && !create_got_section (abfd, info))
3718130561Sobrien	    return FALSE;
371989857Sobrien
372089857Sobrien	  if (h != NULL)
372189857Sobrien	    {
3722130561Sobrien	      struct ppc_link_hash_entry *eh;
3723130561Sobrien	      struct got_entry *ent;
372489857Sobrien
3725130561Sobrien	      eh = (struct ppc_link_hash_entry *) h;
3726130561Sobrien	      for (ent = eh->elf.got.glist; ent != NULL; ent = ent->next)
3727130561Sobrien		if (ent->addend == rel->r_addend
3728130561Sobrien		    && ent->owner == abfd
3729130561Sobrien		    && ent->tls_type == tls_type)
3730130561Sobrien		  break;
3731130561Sobrien	      if (ent == NULL)
373289857Sobrien		{
3733130561Sobrien		  bfd_size_type amt = sizeof (*ent);
3734130561Sobrien		  ent = bfd_alloc (abfd, amt);
3735130561Sobrien		  if (ent == NULL)
3736130561Sobrien		    return FALSE;
3737130561Sobrien		  ent->next = eh->elf.got.glist;
3738130561Sobrien		  ent->addend = rel->r_addend;
3739130561Sobrien		  ent->owner = abfd;
3740130561Sobrien		  ent->tls_type = tls_type;
3741130561Sobrien		  ent->got.refcount = 0;
3742130561Sobrien		  eh->elf.got.glist = ent;
374389857Sobrien		}
3744130561Sobrien	      ent->got.refcount += 1;
3745130561Sobrien	      eh->tls_mask |= tls_type;
374689857Sobrien	    }
3747130561Sobrien	  else
3748130561Sobrien	    /* This is a global offset table entry for a local symbol.  */
3749130561Sobrien	    if (!update_local_sym_info (abfd, symtab_hdr, r_symndx,
3750130561Sobrien					rel->r_addend, tls_type))
3751130561Sobrien	      return FALSE;
375289857Sobrien	  break;
375389857Sobrien
375489857Sobrien	case R_PPC64_PLT16_HA:
375589857Sobrien	case R_PPC64_PLT16_HI:
375689857Sobrien	case R_PPC64_PLT16_LO:
375789857Sobrien	case R_PPC64_PLT32:
375889857Sobrien	case R_PPC64_PLT64:
375989857Sobrien	  /* This symbol requires a procedure linkage table entry.  We
3760104834Sobrien	     actually build the entry in adjust_dynamic_symbol,
3761104834Sobrien	     because this might be a case of linking PIC code without
3762104834Sobrien	     linking in any dynamic objects, in which case we don't
3763104834Sobrien	     need to generate a procedure linkage table after all.  */
376489857Sobrien	  if (h == NULL)
376589857Sobrien	    {
376689857Sobrien	      /* It does not make sense to have a procedure linkage
3767104834Sobrien		 table entry for a local symbol.  */
376889857Sobrien	      bfd_set_error (bfd_error_bad_value);
3769130561Sobrien	      return FALSE;
377089857Sobrien	    }
3771130561Sobrien	  else
3772130561Sobrien	    if (!update_plt_info (abfd, (struct ppc_link_hash_entry *) h,
3773130561Sobrien				  rel->r_addend))
3774130561Sobrien	      return FALSE;
377589857Sobrien	  break;
377689857Sobrien
377789857Sobrien	  /* The following relocations don't need to propagate the
377889857Sobrien	     relocation if linking a shared object since they are
377989857Sobrien	     section relative.  */
378089857Sobrien	case R_PPC64_SECTOFF:
378189857Sobrien	case R_PPC64_SECTOFF_LO:
378289857Sobrien	case R_PPC64_SECTOFF_HI:
378389857Sobrien	case R_PPC64_SECTOFF_HA:
378489857Sobrien	case R_PPC64_SECTOFF_DS:
378589857Sobrien	case R_PPC64_SECTOFF_LO_DS:
3786130561Sobrien	case R_PPC64_DTPREL16:
3787130561Sobrien	case R_PPC64_DTPREL16_LO:
3788130561Sobrien	case R_PPC64_DTPREL16_HI:
3789130561Sobrien	case R_PPC64_DTPREL16_HA:
3790130561Sobrien	case R_PPC64_DTPREL16_DS:
3791130561Sobrien	case R_PPC64_DTPREL16_LO_DS:
3792130561Sobrien	case R_PPC64_DTPREL16_HIGHER:
3793130561Sobrien	case R_PPC64_DTPREL16_HIGHERA:
3794130561Sobrien	case R_PPC64_DTPREL16_HIGHEST:
3795130561Sobrien	case R_PPC64_DTPREL16_HIGHESTA:
3796130561Sobrien	  break;
3797130561Sobrien
3798130561Sobrien	  /* Nor do these.  */
379989857Sobrien	case R_PPC64_TOC16:
380089857Sobrien	case R_PPC64_TOC16_LO:
380189857Sobrien	case R_PPC64_TOC16_HI:
380289857Sobrien	case R_PPC64_TOC16_HA:
380389857Sobrien	case R_PPC64_TOC16_DS:
380489857Sobrien	case R_PPC64_TOC16_LO_DS:
3805130561Sobrien	  sec->has_gp_reloc = 1;
380689857Sobrien	  break;
380789857Sobrien
380889857Sobrien	  /* This relocation describes the C++ object vtable hierarchy.
380989857Sobrien	     Reconstruct it for later use during GC.  */
381089857Sobrien	case R_PPC64_GNU_VTINHERIT:
3811130561Sobrien	  if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
3812130561Sobrien	    return FALSE;
381389857Sobrien	  break;
381489857Sobrien
381589857Sobrien	  /* This relocation describes which C++ vtable entries are actually
381689857Sobrien	     used.  Record for later use during GC.  */
381789857Sobrien	case R_PPC64_GNU_VTENTRY:
3818130561Sobrien	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
3819130561Sobrien	    return FALSE;
382089857Sobrien	  break;
382189857Sobrien
3822104834Sobrien	case R_PPC64_REL14:
3823104834Sobrien	case R_PPC64_REL14_BRTAKEN:
3824104834Sobrien	case R_PPC64_REL14_BRNTAKEN:
3825104834Sobrien	  htab->has_14bit_branch = 1;
3826104834Sobrien	  /* Fall through.  */
3827104834Sobrien
382889857Sobrien	case R_PPC64_REL24:
382989857Sobrien	  if (h != NULL
383089857Sobrien	      && h->root.root.string[0] == '.'
383189857Sobrien	      && h->root.root.string[1] != 0)
383289857Sobrien	    {
383389857Sobrien	      /* We may need a .plt entry if the function this reloc
383489857Sobrien		 refers to is in a shared lib.  */
3835130561Sobrien	      if (!update_plt_info (abfd, (struct ppc_link_hash_entry *) h,
3836130561Sobrien				    rel->r_addend))
3837130561Sobrien		return FALSE;
3838130561Sobrien	      if (h == htab->tls_get_addr)
3839130561Sobrien		sec->has_tls_reloc = 1;
3840130561Sobrien	      else if ((strncmp (h->root.root.string, ".__tls_get_addr", 15)
3841130561Sobrien			== 0)
3842130561Sobrien		       && (h->root.root.string[15] == 0
3843130561Sobrien			   || h->root.root.string[15] == '@'))
3844130561Sobrien		{
3845130561Sobrien		  htab->tls_get_addr = h;
3846130561Sobrien		  sec->has_tls_reloc = 1;
3847130561Sobrien		}
384889857Sobrien	    }
384989857Sobrien	  break;
385089857Sobrien
3851130561Sobrien	case R_PPC64_TPREL64:
3852130561Sobrien	  tls_type = TLS_EXPLICIT | TLS_TLS | TLS_TPREL;
3853130561Sobrien	  if (info->shared)
3854130561Sobrien	    info->flags |= DF_STATIC_TLS;
3855130561Sobrien	  goto dotlstoc;
3856130561Sobrien
3857130561Sobrien	case R_PPC64_DTPMOD64:
3858130561Sobrien	  if (rel + 1 < rel_end
3859130561Sobrien	      && rel[1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_DTPREL64)
3860130561Sobrien	      && rel[1].r_offset == rel->r_offset + 8)
3861130561Sobrien	    tls_type = TLS_EXPLICIT | TLS_TLS | TLS_GD;
3862130561Sobrien	  else
3863130561Sobrien	    tls_type = TLS_EXPLICIT | TLS_TLS | TLS_LD;
3864130561Sobrien	  goto dotlstoc;
3865130561Sobrien
3866130561Sobrien	case R_PPC64_DTPREL64:
3867130561Sobrien	  tls_type = TLS_EXPLICIT | TLS_TLS | TLS_DTPREL;
3868130561Sobrien	  if (rel != relocs
3869130561Sobrien	      && rel[-1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_DTPMOD64)
3870130561Sobrien	      && rel[-1].r_offset == rel->r_offset - 8)
3871130561Sobrien	    /* This is the second reloc of a dtpmod, dtprel pair.
3872130561Sobrien	       Don't mark with TLS_DTPREL.  */
3873130561Sobrien	    goto dodyn;
3874130561Sobrien
3875130561Sobrien	dotlstoc:
3876130561Sobrien	  sec->has_tls_reloc = 1;
3877130561Sobrien	  if (h != NULL)
3878130561Sobrien	    {
3879130561Sobrien	      struct ppc_link_hash_entry *eh;
3880130561Sobrien	      eh = (struct ppc_link_hash_entry *) h;
3881130561Sobrien	      eh->tls_mask |= tls_type;
3882130561Sobrien	    }
3883130561Sobrien	  else
3884130561Sobrien	    if (!update_local_sym_info (abfd, symtab_hdr, r_symndx,
3885130561Sobrien					rel->r_addend, tls_type))
3886130561Sobrien	      return FALSE;
3887130561Sobrien
3888130561Sobrien	  if (ppc64_elf_section_data (sec)->t_symndx == NULL)
3889130561Sobrien	    {
3890130561Sobrien	      /* One extra to simplify get_tls_mask.  */
3891130561Sobrien	      bfd_size_type amt = sec->_raw_size * sizeof (unsigned) / 8 + 1;
3892130561Sobrien	      ppc64_elf_section_data (sec)->t_symndx = bfd_zalloc (abfd, amt);
3893130561Sobrien	      if (ppc64_elf_section_data (sec)->t_symndx == NULL)
3894130561Sobrien		return FALSE;
3895130561Sobrien	    }
3896130561Sobrien	  BFD_ASSERT (rel->r_offset % 8 == 0);
3897130561Sobrien	  ppc64_elf_section_data (sec)->t_symndx[rel->r_offset / 8] = r_symndx;
3898130561Sobrien
3899130561Sobrien	  /* Mark the second slot of a GD or LD entry.
3900130561Sobrien	     -1 to indicate GD and -2 to indicate LD.  */
3901130561Sobrien	  if (tls_type == (TLS_EXPLICIT | TLS_TLS | TLS_GD))
3902130561Sobrien	    ppc64_elf_section_data (sec)->t_symndx[rel->r_offset / 8 + 1] = -1;
3903130561Sobrien	  else if (tls_type == (TLS_EXPLICIT | TLS_TLS | TLS_LD))
3904130561Sobrien	    ppc64_elf_section_data (sec)->t_symndx[rel->r_offset / 8 + 1] = -2;
3905130561Sobrien	  goto dodyn;
3906130561Sobrien
3907130561Sobrien	case R_PPC64_TPREL16:
3908130561Sobrien	case R_PPC64_TPREL16_LO:
3909130561Sobrien	case R_PPC64_TPREL16_HI:
3910130561Sobrien	case R_PPC64_TPREL16_HA:
3911130561Sobrien	case R_PPC64_TPREL16_DS:
3912130561Sobrien	case R_PPC64_TPREL16_LO_DS:
3913130561Sobrien	case R_PPC64_TPREL16_HIGHER:
3914130561Sobrien	case R_PPC64_TPREL16_HIGHERA:
3915130561Sobrien	case R_PPC64_TPREL16_HIGHEST:
3916130561Sobrien	case R_PPC64_TPREL16_HIGHESTA:
3917130561Sobrien	  if (info->shared)
3918130561Sobrien	    {
3919130561Sobrien	      info->flags |= DF_STATIC_TLS;
3920130561Sobrien	      goto dodyn;
3921130561Sobrien	    }
3922130561Sobrien	  break;
3923130561Sobrien
392489857Sobrien	case R_PPC64_ADDR64:
3925104834Sobrien	  if (opd_sym_map != NULL
392689857Sobrien	      && h != NULL
392789857Sobrien	      && h->root.root.string[0] == '.'
392889857Sobrien	      && h->root.root.string[1] != 0)
3929130561Sobrien	    get_fdh ((struct ppc_link_hash_entry *) h, htab);
393089857Sobrien
3931104834Sobrien	  if (opd_sym_map != NULL
3932104834Sobrien	      && h == NULL
3933104834Sobrien	      && rel + 1 < rel_end
3934130561Sobrien	      && ELF64_R_TYPE ((rel + 1)->r_info) == R_PPC64_TOC)
3935104834Sobrien	    {
3936104834Sobrien	      asection *s;
3937104834Sobrien
3938104834Sobrien	      s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, sec,
3939104834Sobrien					     r_symndx);
3940104834Sobrien	      if (s == NULL)
3941130561Sobrien		return FALSE;
3942104834Sobrien	      else if (s != sec)
3943104834Sobrien		opd_sym_map[rel->r_offset / 24] = s;
3944104834Sobrien	    }
394589857Sobrien	  /* Fall through.  */
394689857Sobrien
3947130561Sobrien	case R_PPC64_REL30:
3948130561Sobrien	case R_PPC64_REL32:
394989857Sobrien	case R_PPC64_REL64:
395089857Sobrien	case R_PPC64_ADDR14:
395189857Sobrien	case R_PPC64_ADDR14_BRNTAKEN:
395289857Sobrien	case R_PPC64_ADDR14_BRTAKEN:
395389857Sobrien	case R_PPC64_ADDR16:
395489857Sobrien	case R_PPC64_ADDR16_DS:
395589857Sobrien	case R_PPC64_ADDR16_HA:
395689857Sobrien	case R_PPC64_ADDR16_HI:
395789857Sobrien	case R_PPC64_ADDR16_HIGHER:
395889857Sobrien	case R_PPC64_ADDR16_HIGHERA:
395989857Sobrien	case R_PPC64_ADDR16_HIGHEST:
396089857Sobrien	case R_PPC64_ADDR16_HIGHESTA:
396189857Sobrien	case R_PPC64_ADDR16_LO:
396289857Sobrien	case R_PPC64_ADDR16_LO_DS:
396389857Sobrien	case R_PPC64_ADDR24:
396489857Sobrien	case R_PPC64_ADDR32:
396589857Sobrien	case R_PPC64_UADDR16:
396689857Sobrien	case R_PPC64_UADDR32:
396789857Sobrien	case R_PPC64_UADDR64:
396889857Sobrien	case R_PPC64_TOC:
3969130561Sobrien	  if (h != NULL && !info->shared)
3970130561Sobrien	    /* We may need a copy reloc.  */
3971130561Sobrien	    h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
3972130561Sobrien
397389857Sobrien	  /* Don't propagate .opd relocs.  */
3974104834Sobrien	  if (NO_OPD_RELOCS && opd_sym_map != NULL)
397589857Sobrien	    break;
397689857Sobrien
397789857Sobrien	  /* If we are creating a shared library, and this is a reloc
397889857Sobrien	     against a global symbol, or a non PC relative reloc
397989857Sobrien	     against a local symbol, then we need to copy the reloc
398089857Sobrien	     into the shared library.  However, if we are linking with
398189857Sobrien	     -Bsymbolic, we do not need to copy a reloc against a
398289857Sobrien	     global symbol which is defined in an object we are
398389857Sobrien	     including in the link (i.e., DEF_REGULAR is set).  At
398489857Sobrien	     this point we have not seen all the input files, so it is
398589857Sobrien	     possible that DEF_REGULAR is not set now but will be set
398689857Sobrien	     later (it is never cleared).  In case of a weak definition,
398789857Sobrien	     DEF_REGULAR may be cleared later by a strong definition in
398889857Sobrien	     a shared library.  We account for that possibility below by
3989130561Sobrien	     storing information in the dyn_relocs field of the hash
399089857Sobrien	     table entry.  A similar situation occurs when creating
399189857Sobrien	     shared libraries and symbol visibility changes render the
399289857Sobrien	     symbol local.
399389857Sobrien
399489857Sobrien	     If on the other hand, we are creating an executable, we
399589857Sobrien	     may need to keep relocations for symbols satisfied by a
399689857Sobrien	     dynamic library if we manage to avoid copy relocs for the
399789857Sobrien	     symbol.  */
3998130561Sobrien	dodyn:
399989857Sobrien	  if ((info->shared
4000130561Sobrien	       && (MUST_BE_DYN_RELOC (r_type)
400189857Sobrien		   || (h != NULL
400289857Sobrien		       && (! info->symbolic
400389857Sobrien			   || h->root.type == bfd_link_hash_defweak
400489857Sobrien			   || (h->elf_link_hash_flags
400589857Sobrien			       & ELF_LINK_HASH_DEF_REGULAR) == 0))))
4006130561Sobrien	      || (ELIMINATE_COPY_RELOCS
4007130561Sobrien		  && !info->shared
400889857Sobrien		  && h != NULL
400989857Sobrien		  && (h->root.type == bfd_link_hash_defweak
401089857Sobrien		      || (h->elf_link_hash_flags
401189857Sobrien			  & ELF_LINK_HASH_DEF_REGULAR) == 0)))
401289857Sobrien	    {
401389857Sobrien	      struct ppc_dyn_relocs *p;
401489857Sobrien	      struct ppc_dyn_relocs **head;
401589857Sobrien
401689857Sobrien	      /* We must copy these reloc types into the output file.
401789857Sobrien		 Create a reloc section in dynobj and make room for
401889857Sobrien		 this reloc.  */
401989857Sobrien	      if (sreloc == NULL)
402089857Sobrien		{
402189857Sobrien		  const char *name;
402289857Sobrien		  bfd *dynobj;
402389857Sobrien
402489857Sobrien		  name = (bfd_elf_string_from_elf_section
402589857Sobrien			  (abfd,
402689857Sobrien			   elf_elfheader (abfd)->e_shstrndx,
402789857Sobrien			   elf_section_data (sec)->rel_hdr.sh_name));
402889857Sobrien		  if (name == NULL)
4029130561Sobrien		    return FALSE;
403089857Sobrien
403189857Sobrien		  if (strncmp (name, ".rela", 5) != 0
403289857Sobrien		      || strcmp (bfd_get_section_name (abfd, sec),
403389857Sobrien				 name + 5) != 0)
403489857Sobrien		    {
403589857Sobrien		      (*_bfd_error_handler)
403689857Sobrien			(_("%s: bad relocation section name `%s\'"),
403789857Sobrien			 bfd_archive_filename (abfd), name);
403889857Sobrien		      bfd_set_error (bfd_error_bad_value);
403989857Sobrien		    }
404089857Sobrien
404189857Sobrien		  dynobj = htab->elf.dynobj;
404289857Sobrien		  sreloc = bfd_get_section_by_name (dynobj, name);
404389857Sobrien		  if (sreloc == NULL)
404489857Sobrien		    {
404589857Sobrien		      flagword flags;
404689857Sobrien
404789857Sobrien		      sreloc = bfd_make_section (dynobj, name);
404889857Sobrien		      flags = (SEC_HAS_CONTENTS | SEC_READONLY
404989857Sobrien			       | SEC_IN_MEMORY | SEC_LINKER_CREATED);
405089857Sobrien		      if ((sec->flags & SEC_ALLOC) != 0)
405189857Sobrien			flags |= SEC_ALLOC | SEC_LOAD;
405289857Sobrien		      if (sreloc == NULL
405389857Sobrien			  || ! bfd_set_section_flags (dynobj, sreloc, flags)
405489857Sobrien			  || ! bfd_set_section_alignment (dynobj, sreloc, 3))
4055130561Sobrien			return FALSE;
405689857Sobrien		    }
405789857Sobrien		  elf_section_data (sec)->sreloc = sreloc;
405889857Sobrien		}
405989857Sobrien
406089857Sobrien	      /* If this is a global symbol, we count the number of
406189857Sobrien		 relocations we need for this symbol.  */
406289857Sobrien	      if (h != NULL)
406389857Sobrien		{
406489857Sobrien		  head = &((struct ppc_link_hash_entry *) h)->dyn_relocs;
406589857Sobrien		}
406689857Sobrien	      else
406789857Sobrien		{
406889857Sobrien		  /* Track dynamic relocs needed for local syms too.
406989857Sobrien		     We really need local syms available to do this
407089857Sobrien		     easily.  Oh well.  */
407189857Sobrien
407289857Sobrien		  asection *s;
407389857Sobrien		  s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
407489857Sobrien						 sec, r_symndx);
407589857Sobrien		  if (s == NULL)
4076130561Sobrien		    return FALSE;
407789857Sobrien
407889857Sobrien		  head = ((struct ppc_dyn_relocs **)
407989857Sobrien			  &elf_section_data (s)->local_dynrel);
408089857Sobrien		}
408189857Sobrien
408289857Sobrien	      p = *head;
408389857Sobrien	      if (p == NULL || p->sec != sec)
408489857Sobrien		{
4085130561Sobrien		  p = bfd_alloc (htab->elf.dynobj, sizeof *p);
408689857Sobrien		  if (p == NULL)
4087130561Sobrien		    return FALSE;
408889857Sobrien		  p->next = *head;
408989857Sobrien		  *head = p;
409089857Sobrien		  p->sec = sec;
409189857Sobrien		  p->count = 0;
409289857Sobrien		  p->pc_count = 0;
409389857Sobrien		}
409489857Sobrien
409589857Sobrien	      p->count += 1;
4096130561Sobrien	      if (!MUST_BE_DYN_RELOC (r_type))
409789857Sobrien		p->pc_count += 1;
409889857Sobrien	    }
409989857Sobrien	  break;
410089857Sobrien
410189857Sobrien	default:
410292828Sobrien	  break;
410389857Sobrien	}
410489857Sobrien    }
410589857Sobrien
4106130561Sobrien  return TRUE;
410789857Sobrien}
410889857Sobrien
410989857Sobrien/* Return the section that should be marked against GC for a given
411089857Sobrien   relocation.  */
411189857Sobrien
411289857Sobrienstatic asection *
4113130561Sobrienppc64_elf_gc_mark_hook (asection *sec,
4114130561Sobrien			struct bfd_link_info *info ATTRIBUTE_UNUSED,
4115130561Sobrien			Elf_Internal_Rela *rel,
4116130561Sobrien			struct elf_link_hash_entry *h,
4117130561Sobrien			Elf_Internal_Sym *sym)
411889857Sobrien{
4119104834Sobrien  asection *rsec = NULL;
4120104834Sobrien
412189857Sobrien  if (h != NULL)
412289857Sobrien    {
4123130561Sobrien      enum elf_ppc64_reloc_type r_type;
4124104834Sobrien      struct ppc_link_hash_entry *fdh;
412589857Sobrien
4126130561Sobrien      r_type = ELF64_R_TYPE (rel->r_info);
412789857Sobrien      switch (r_type)
412889857Sobrien	{
412989857Sobrien	case R_PPC64_GNU_VTINHERIT:
413089857Sobrien	case R_PPC64_GNU_VTENTRY:
413189857Sobrien	  break;
413289857Sobrien
413389857Sobrien	default:
413489857Sobrien	  switch (h->root.type)
413589857Sobrien	    {
413689857Sobrien	    case bfd_link_hash_defined:
413789857Sobrien	    case bfd_link_hash_defweak:
4138104834Sobrien	      fdh = (struct ppc_link_hash_entry *) h;
413989857Sobrien
4140104834Sobrien	      /* Function descriptor syms cause the associated
4141104834Sobrien		 function code sym section to be marked.  */
4142104834Sobrien	      if (fdh->is_func_descriptor)
4143104834Sobrien		rsec = fdh->oh->root.u.def.section;
4144104834Sobrien
4145104834Sobrien	      /* Function entry syms return NULL if they are in .opd
4146104834Sobrien		 and are not ._start (or others undefined on the ld
4147104834Sobrien		 command line).  Thus we avoid marking all function
4148130561Sobrien		 sections, as all functions are referenced in .opd.  */
4149104834Sobrien	      else if ((fdh->oh != NULL
4150104834Sobrien			&& ((struct ppc_link_hash_entry *) fdh->oh)->is_entry)
4151130561Sobrien		       || ppc64_elf_section_data (sec)->opd.func_sec == NULL)
4152104834Sobrien		rsec = h->root.u.def.section;
4153104834Sobrien	      break;
4154104834Sobrien
415589857Sobrien	    case bfd_link_hash_common:
4156104834Sobrien	      rsec = h->root.u.c.p->section;
4157104834Sobrien	      break;
415889857Sobrien
415989857Sobrien	    default:
416089857Sobrien	      break;
416189857Sobrien	    }
416289857Sobrien	}
416389857Sobrien    }
416489857Sobrien  else
416589857Sobrien    {
4166104834Sobrien      asection **opd_sym_section;
4167104834Sobrien
4168104834Sobrien      rsec = bfd_section_from_elf_index (sec->owner, sym->st_shndx);
4169130561Sobrien      opd_sym_section = ppc64_elf_section_data (rsec)->opd.func_sec;
4170104834Sobrien      if (opd_sym_section != NULL)
4171104834Sobrien	rsec = opd_sym_section[sym->st_value / 24];
4172130561Sobrien      else if (ppc64_elf_section_data (sec)->opd.func_sec != NULL)
4173104834Sobrien	rsec = NULL;
417489857Sobrien    }
417589857Sobrien
4176104834Sobrien  return rsec;
417789857Sobrien}
417889857Sobrien
417989857Sobrien/* Update the .got, .plt. and dynamic reloc reference counts for the
418089857Sobrien   section being removed.  */
418189857Sobrien
4182130561Sobrienstatic bfd_boolean
4183130561Sobrienppc64_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
4184130561Sobrien			 asection *sec, const Elf_Internal_Rela *relocs)
418589857Sobrien{
4186130561Sobrien  struct ppc_link_hash_table *htab;
418789857Sobrien  Elf_Internal_Shdr *symtab_hdr;
418889857Sobrien  struct elf_link_hash_entry **sym_hashes;
4189130561Sobrien  struct got_entry **local_got_ents;
419089857Sobrien  const Elf_Internal_Rela *rel, *relend;
419189857Sobrien
4192130561Sobrien  if ((sec->flags & SEC_ALLOC) == 0)
4193130561Sobrien    return TRUE;
4194130561Sobrien
419589857Sobrien  elf_section_data (sec)->local_dynrel = NULL;
419689857Sobrien
4197130561Sobrien  htab = ppc_hash_table (info);
419889857Sobrien  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
419989857Sobrien  sym_hashes = elf_sym_hashes (abfd);
4200130561Sobrien  local_got_ents = elf_local_got_ents (abfd);
420189857Sobrien
420289857Sobrien  relend = relocs + sec->reloc_count;
420389857Sobrien  for (rel = relocs; rel < relend; rel++)
420489857Sobrien    {
420589857Sobrien      unsigned long r_symndx;
4206130561Sobrien      enum elf_ppc64_reloc_type r_type;
4207130561Sobrien      struct elf_link_hash_entry *h = NULL;
4208130561Sobrien      char tls_type = 0;
420989857Sobrien
421089857Sobrien      r_symndx = ELF64_R_SYM (rel->r_info);
4211130561Sobrien      r_type = ELF64_R_TYPE (rel->r_info);
4212130561Sobrien      if (r_symndx >= symtab_hdr->sh_info)
4213130561Sobrien	{
4214130561Sobrien	  struct ppc_link_hash_entry *eh;
4215130561Sobrien	  struct ppc_dyn_relocs **pp;
4216130561Sobrien	  struct ppc_dyn_relocs *p;
4217130561Sobrien
4218130561Sobrien	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
4219130561Sobrien	  eh = (struct ppc_link_hash_entry *) h;
4220130561Sobrien
4221130561Sobrien	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
4222130561Sobrien	    if (p->sec == sec)
4223130561Sobrien	      {
4224130561Sobrien		/* Everything must go for SEC.  */
4225130561Sobrien		*pp = p->next;
4226130561Sobrien		break;
4227130561Sobrien	      }
4228130561Sobrien	}
4229130561Sobrien
423089857Sobrien      switch (r_type)
423189857Sobrien	{
4232130561Sobrien	case R_PPC64_GOT_TLSLD16:
4233130561Sobrien	case R_PPC64_GOT_TLSLD16_LO:
4234130561Sobrien	case R_PPC64_GOT_TLSLD16_HI:
4235130561Sobrien	case R_PPC64_GOT_TLSLD16_HA:
4236130561Sobrien	  ppc64_tlsld_got (abfd)->refcount -= 1;
4237130561Sobrien	  tls_type = TLS_TLS | TLS_LD;
4238130561Sobrien	  goto dogot;
4239130561Sobrien
4240130561Sobrien	case R_PPC64_GOT_TLSGD16:
4241130561Sobrien	case R_PPC64_GOT_TLSGD16_LO:
4242130561Sobrien	case R_PPC64_GOT_TLSGD16_HI:
4243130561Sobrien	case R_PPC64_GOT_TLSGD16_HA:
4244130561Sobrien	  tls_type = TLS_TLS | TLS_GD;
4245130561Sobrien	  goto dogot;
4246130561Sobrien
4247130561Sobrien	case R_PPC64_GOT_TPREL16_DS:
4248130561Sobrien	case R_PPC64_GOT_TPREL16_LO_DS:
4249130561Sobrien	case R_PPC64_GOT_TPREL16_HI:
4250130561Sobrien	case R_PPC64_GOT_TPREL16_HA:
4251130561Sobrien	  tls_type = TLS_TLS | TLS_TPREL;
4252130561Sobrien	  goto dogot;
4253130561Sobrien
4254130561Sobrien	case R_PPC64_GOT_DTPREL16_DS:
4255130561Sobrien	case R_PPC64_GOT_DTPREL16_LO_DS:
4256130561Sobrien	case R_PPC64_GOT_DTPREL16_HI:
4257130561Sobrien	case R_PPC64_GOT_DTPREL16_HA:
4258130561Sobrien	  tls_type = TLS_TLS | TLS_DTPREL;
4259130561Sobrien	  goto dogot;
4260130561Sobrien
426189857Sobrien	case R_PPC64_GOT16:
426289857Sobrien	case R_PPC64_GOT16_DS:
426389857Sobrien	case R_PPC64_GOT16_HA:
426489857Sobrien	case R_PPC64_GOT16_HI:
426589857Sobrien	case R_PPC64_GOT16_LO:
426689857Sobrien	case R_PPC64_GOT16_LO_DS:
4267130561Sobrien	dogot:
4268130561Sobrien	  {
4269130561Sobrien	    struct got_entry *ent;
4270130561Sobrien
4271130561Sobrien	    if (h != NULL)
4272130561Sobrien	      ent = h->got.glist;
4273130561Sobrien	    else
4274130561Sobrien	      ent = local_got_ents[r_symndx];
4275130561Sobrien
4276130561Sobrien	    for (; ent != NULL; ent = ent->next)
4277130561Sobrien	      if (ent->addend == rel->r_addend
4278130561Sobrien		  && ent->owner == abfd
4279130561Sobrien		  && ent->tls_type == tls_type)
4280130561Sobrien		break;
4281130561Sobrien	    if (ent == NULL)
4282130561Sobrien	      abort ();
4283130561Sobrien	    if (ent->got.refcount > 0)
4284130561Sobrien	      ent->got.refcount -= 1;
4285130561Sobrien	  }
428689857Sobrien	  break;
428789857Sobrien
428889857Sobrien	case R_PPC64_PLT16_HA:
428989857Sobrien	case R_PPC64_PLT16_HI:
429089857Sobrien	case R_PPC64_PLT16_LO:
429189857Sobrien	case R_PPC64_PLT32:
429289857Sobrien	case R_PPC64_PLT64:
4293104834Sobrien	case R_PPC64_REL14:
4294104834Sobrien	case R_PPC64_REL14_BRNTAKEN:
4295104834Sobrien	case R_PPC64_REL14_BRTAKEN:
429689857Sobrien	case R_PPC64_REL24:
4297130561Sobrien	  if (h != NULL)
429889857Sobrien	    {
4299130561Sobrien	      struct plt_entry *ent;
430089857Sobrien
4301130561Sobrien	      for (ent = h->plt.plist; ent != NULL; ent = ent->next)
4302130561Sobrien		if (ent->addend == rel->r_addend)
4303130561Sobrien		  break;
4304130561Sobrien	      if (ent == NULL)
4305130561Sobrien		abort ();
4306130561Sobrien	      if (ent->plt.refcount > 0)
4307130561Sobrien		ent->plt.refcount -= 1;
430889857Sobrien	    }
430989857Sobrien	  break;
431089857Sobrien
431189857Sobrien	default:
431289857Sobrien	  break;
431389857Sobrien	}
431489857Sobrien    }
4315130561Sobrien  return TRUE;
431689857Sobrien}
431789857Sobrien
431889857Sobrien/* Called via elf_link_hash_traverse to transfer dynamic linking
431989857Sobrien   information on function code symbol entries to their corresponding
432089857Sobrien   function descriptor symbol entries.  */
4321130561Sobrienstatic bfd_boolean
4322130561Sobrienfunc_desc_adjust (struct elf_link_hash_entry *h, void *inf)
432389857Sobrien{
432489857Sobrien  struct bfd_link_info *info;
432589857Sobrien  struct ppc_link_hash_table *htab;
4326130561Sobrien  struct plt_entry *ent;
4327130561Sobrien  struct ppc_link_hash_entry *fh;
4328130561Sobrien  struct ppc_link_hash_entry *fdh;
4329130561Sobrien  bfd_boolean force_local;
433089857Sobrien
4331130561Sobrien  fh = (struct ppc_link_hash_entry *) h;
4332130561Sobrien  if (fh->elf.root.type == bfd_link_hash_indirect)
4333130561Sobrien    return TRUE;
433489857Sobrien
4335130561Sobrien  if (fh->elf.root.type == bfd_link_hash_warning)
4336130561Sobrien    fh = (struct ppc_link_hash_entry *) fh->elf.root.u.i.link;
433794536Sobrien
4338130561Sobrien  info = inf;
433989857Sobrien  htab = ppc_hash_table (info);
434089857Sobrien
434189857Sobrien  /* If this is a function code symbol, transfer dynamic linking
434289857Sobrien     information to the function descriptor symbol.  */
4343130561Sobrien  if (!fh->is_func)
4344130561Sobrien    return TRUE;
434589857Sobrien
4346130561Sobrien  if (fh->elf.root.type == bfd_link_hash_undefweak
4347130561Sobrien      && (fh->elf.elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR))
4348130561Sobrien    htab->have_undefweak = TRUE;
434999461Sobrien
4350130561Sobrien  for (ent = fh->elf.plt.plist; ent != NULL; ent = ent->next)
4351130561Sobrien    if (ent->plt.refcount > 0)
4352130561Sobrien      break;
4353130561Sobrien  if (ent == NULL
4354130561Sobrien      || fh->elf.root.root.string[0] != '.'
4355130561Sobrien      || fh->elf.root.root.string[1] == '\0')
4356130561Sobrien    return TRUE;
435789857Sobrien
4358130561Sobrien  /* Find the corresponding function descriptor symbol.  Create it
4359130561Sobrien     as undefined if necessary.  */
436089857Sobrien
4361130561Sobrien  fdh = get_fdh (fh, htab);
4362130561Sobrien  if (fdh != NULL)
4363130561Sobrien    while (fdh->elf.root.type == bfd_link_hash_indirect
4364130561Sobrien	   || fdh->elf.root.type == bfd_link_hash_warning)
4365130561Sobrien      fdh = (struct ppc_link_hash_entry *) fdh->elf.root.u.i.link;
436689857Sobrien
4367130561Sobrien  if (fdh == NULL
4368130561Sobrien      && info->shared
4369130561Sobrien      && (fh->elf.root.type == bfd_link_hash_undefined
4370130561Sobrien	  || fh->elf.root.type == bfd_link_hash_undefweak))
4371130561Sobrien    {
4372130561Sobrien      bfd *abfd;
4373130561Sobrien      asymbol *newsym;
4374130561Sobrien      struct bfd_link_hash_entry *bh;
437589857Sobrien
4376130561Sobrien      abfd = fh->elf.root.u.undef.abfd;
4377130561Sobrien      newsym = bfd_make_empty_symbol (abfd);
4378130561Sobrien      newsym->name = fh->elf.root.root.string + 1;
4379130561Sobrien      newsym->section = bfd_und_section_ptr;
4380130561Sobrien      newsym->value = 0;
4381130561Sobrien      newsym->flags = BSF_OBJECT;
4382130561Sobrien      if (fh->elf.root.type == bfd_link_hash_undefweak)
4383130561Sobrien	newsym->flags |= BSF_WEAK;
438489857Sobrien
4385130561Sobrien      bh = &fdh->elf.root;
4386130561Sobrien      if ( !(_bfd_generic_link_add_one_symbol
4387130561Sobrien	     (info, abfd, newsym->name, newsym->flags,
4388130561Sobrien	      newsym->section, newsym->value, NULL, FALSE, FALSE, &bh)))
4389130561Sobrien	{
4390130561Sobrien	  return FALSE;
439189857Sobrien	}
4392130561Sobrien      fdh = (struct ppc_link_hash_entry *) bh;
4393130561Sobrien      fdh->elf.elf_link_hash_flags &= ~ELF_LINK_NON_ELF;
4394130561Sobrien      fdh->elf.size = 24;
4395130561Sobrien      fdh->elf.type = STT_OBJECT;
4396130561Sobrien    }
439789857Sobrien
4398130561Sobrien  if (fdh != NULL
4399130561Sobrien      && (fdh->elf.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0
4400130561Sobrien      && (info->shared
4401130561Sobrien	  || (fdh->elf.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
4402130561Sobrien	  || (fdh->elf.elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0
4403130561Sobrien	  || (fdh->elf.root.type == bfd_link_hash_undefweak
4404130561Sobrien	      && ELF_ST_VISIBILITY (fdh->elf.other) == STV_DEFAULT)))
4405130561Sobrien    {
4406130561Sobrien      if (fdh->elf.dynindx == -1)
4407130561Sobrien	if (! bfd_elf_link_record_dynamic_symbol (info, &fdh->elf))
4408130561Sobrien	  return FALSE;
4409130561Sobrien      fdh->elf.elf_link_hash_flags
4410130561Sobrien	|= (fh->elf.elf_link_hash_flags & (ELF_LINK_HASH_REF_REGULAR
4411130561Sobrien				      | ELF_LINK_HASH_REF_DYNAMIC
4412130561Sobrien				      | ELF_LINK_HASH_REF_REGULAR_NONWEAK
4413130561Sobrien				      | ELF_LINK_NON_GOT_REF));
4414130561Sobrien      if (ELF_ST_VISIBILITY (fh->elf.other) == STV_DEFAULT)
441589857Sobrien	{
4416130561Sobrien	  fdh->elf.plt.plist = fh->elf.plt.plist;
4417130561Sobrien	  fdh->elf.elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
441889857Sobrien	}
4419130561Sobrien      fdh->is_func_descriptor = 1;
4420130561Sobrien      fdh->oh = &fh->elf;
4421130561Sobrien      fh->oh = &fdh->elf;
442289857Sobrien    }
442389857Sobrien
4424130561Sobrien  /* Now that the info is on the function descriptor, clear the
4425130561Sobrien     function code sym info.  Any function code syms for which we
4426130561Sobrien     don't have a definition in a regular file, we force local.
4427130561Sobrien     This prevents a shared library from exporting syms that have
4428130561Sobrien     been imported from another library.  Function code syms that
4429130561Sobrien     are really in the library we must leave global to prevent the
4430130561Sobrien     linker dragging in a definition from a static library.  */
4431130561Sobrien  force_local
4432130561Sobrien    = (info->shared
4433130561Sobrien       && ((fh->elf.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
4434130561Sobrien	   || fdh == NULL
4435130561Sobrien	   || (fdh->elf.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
4436130561Sobrien	   || (fdh->elf.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0));
4437130561Sobrien  _bfd_elf_link_hash_hide_symbol (info, &fh->elf, force_local);
4438130561Sobrien
4439130561Sobrien  return TRUE;
444089857Sobrien}
444189857Sobrien
444292828Sobrien#define MIN_SAVE_FPR 14
444392828Sobrien#define MAX_SAVE_FPR 31
444492828Sobrien
444589857Sobrien/* Called near the start of bfd_elf_size_dynamic_sections.  We use
444692828Sobrien   this hook to a) provide some gcc support functions, and b) transfer
444792828Sobrien   dynamic linking information gathered so far on function code symbol
444892828Sobrien   entries, to their corresponding function descriptor symbol entries.  */
4449130561Sobrienstatic bfd_boolean
4450130561Sobrienppc64_elf_func_desc_adjust (bfd *obfd ATTRIBUTE_UNUSED,
4451130561Sobrien			    struct bfd_link_info *info)
445289857Sobrien{
445389857Sobrien  struct ppc_link_hash_table *htab;
445492828Sobrien  unsigned int lowest_savef = MAX_SAVE_FPR + 2;
445592828Sobrien  unsigned int lowest_restf = MAX_SAVE_FPR + 2;
445692828Sobrien  unsigned int i;
445792828Sobrien  struct elf_link_hash_entry *h;
445899461Sobrien  bfd_byte *p;
445992828Sobrien  char sym[10];
446089857Sobrien
446189857Sobrien  htab = ppc_hash_table (info);
446292828Sobrien
446392828Sobrien  if (htab->sfpr == NULL)
446492828Sobrien    /* We don't have any relocs.  */
4465130561Sobrien    return TRUE;
446692828Sobrien
446792828Sobrien  /* First provide any missing ._savef* and ._restf* functions.  */
446892828Sobrien  memcpy (sym, "._savef14", 10);
446992828Sobrien  for (i = MIN_SAVE_FPR; i <= MAX_SAVE_FPR; i++)
447092828Sobrien    {
447192828Sobrien      sym[7] = i / 10 + '0';
447292828Sobrien      sym[8] = i % 10 + '0';
4473130561Sobrien      h = elf_link_hash_lookup (&htab->elf, sym, FALSE, FALSE, TRUE);
447492828Sobrien      if (h != NULL
4475130561Sobrien	  && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
447692828Sobrien	{
447792828Sobrien	  if (lowest_savef > i)
447892828Sobrien	    lowest_savef = i;
447992828Sobrien	  h->root.type = bfd_link_hash_defined;
448092828Sobrien	  h->root.u.def.section = htab->sfpr;
448192828Sobrien	  h->root.u.def.value = (i - lowest_savef) * 4;
448292828Sobrien	  h->type = STT_FUNC;
448392828Sobrien	  h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
4484130561Sobrien	  _bfd_elf_link_hash_hide_symbol (info, h, TRUE);
448592828Sobrien	}
448692828Sobrien    }
448792828Sobrien
448892828Sobrien  memcpy (sym, "._restf14", 10);
448992828Sobrien  for (i = MIN_SAVE_FPR; i <= MAX_SAVE_FPR; i++)
449092828Sobrien    {
449192828Sobrien      sym[7] = i / 10 + '0';
449292828Sobrien      sym[8] = i % 10 + '0';
4493130561Sobrien      h = elf_link_hash_lookup (&htab->elf, sym, FALSE, FALSE, TRUE);
449492828Sobrien      if (h != NULL
4495130561Sobrien	  && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
449692828Sobrien	{
449792828Sobrien	  if (lowest_restf > i)
449892828Sobrien	    lowest_restf = i;
449992828Sobrien	  h->root.type = bfd_link_hash_defined;
450092828Sobrien	  h->root.u.def.section = htab->sfpr;
450192828Sobrien	  h->root.u.def.value = ((MAX_SAVE_FPR + 2 - lowest_savef) * 4
450292828Sobrien				 + (i - lowest_restf) * 4);
450392828Sobrien	  h->type = STT_FUNC;
450492828Sobrien	  h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
4505130561Sobrien	  _bfd_elf_link_hash_hide_symbol (info, h, TRUE);
450692828Sobrien	}
450792828Sobrien    }
450892828Sobrien
4509130561Sobrien  elf_link_hash_traverse (&htab->elf, func_desc_adjust, info);
451099461Sobrien
451192828Sobrien  htab->sfpr->_raw_size = ((MAX_SAVE_FPR + 2 - lowest_savef) * 4
451292828Sobrien			   + (MAX_SAVE_FPR + 2 - lowest_restf) * 4);
451392828Sobrien
451492828Sobrien  if (htab->sfpr->_raw_size == 0)
451592828Sobrien    {
451699461Sobrien      if (!htab->have_undefweak)
451799461Sobrien	{
451899461Sobrien	  _bfd_strip_section_from_output (info, htab->sfpr);
4519130561Sobrien	  return TRUE;
452099461Sobrien	}
452199461Sobrien
452299461Sobrien      htab->sfpr->_raw_size = 4;
452392828Sobrien    }
452499461Sobrien
4525130561Sobrien  p = bfd_alloc (htab->elf.dynobj, htab->sfpr->_raw_size);
452699461Sobrien  if (p == NULL)
4527130561Sobrien    return FALSE;
452899461Sobrien  htab->sfpr->contents = p;
452999461Sobrien
453099461Sobrien  for (i = lowest_savef; i <= MAX_SAVE_FPR; i++)
453192828Sobrien    {
453299461Sobrien      unsigned int fpr = i << 21;
453399461Sobrien      unsigned int stackoff = (1 << 16) - (MAX_SAVE_FPR + 1 - i) * 8;
453499461Sobrien      bfd_put_32 (htab->elf.dynobj, STFD_FR0_0R1 + fpr + stackoff, p);
453599461Sobrien      p += 4;
453699461Sobrien    }
453799461Sobrien  if (lowest_savef <= MAX_SAVE_FPR)
453899461Sobrien    {
453992828Sobrien      bfd_put_32 (htab->elf.dynobj, BLR, p);
454092828Sobrien      p += 4;
454199461Sobrien    }
454292828Sobrien
454399461Sobrien  for (i = lowest_restf; i <= MAX_SAVE_FPR; i++)
454499461Sobrien    {
454599461Sobrien      unsigned int fpr = i << 21;
454699461Sobrien      unsigned int stackoff = (1 << 16) - (MAX_SAVE_FPR + 1 - i) * 8;
454799461Sobrien      bfd_put_32 (htab->elf.dynobj, LFD_FR0_0R1 + fpr + stackoff, p);
454892828Sobrien      p += 4;
454992828Sobrien    }
455099461Sobrien  if (lowest_restf <= MAX_SAVE_FPR
455199461Sobrien      || htab->sfpr->_raw_size == 4)
455299461Sobrien    {
455399461Sobrien      bfd_put_32 (htab->elf.dynobj, BLR, p);
455499461Sobrien    }
455592828Sobrien
4556130561Sobrien  return TRUE;
455789857Sobrien}
455889857Sobrien
455989857Sobrien/* Adjust a symbol defined by a dynamic object and referenced by a
456089857Sobrien   regular object.  The current definition is in some section of the
456189857Sobrien   dynamic object, but we're not including those sections.  We have to
456289857Sobrien   change the definition to something the rest of the link can
456389857Sobrien   understand.  */
456489857Sobrien
4565130561Sobrienstatic bfd_boolean
4566130561Sobrienppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
4567130561Sobrien				 struct elf_link_hash_entry *h)
456889857Sobrien{
456989857Sobrien  struct ppc_link_hash_table *htab;
457089857Sobrien  asection *s;
457189857Sobrien  unsigned int power_of_two;
457289857Sobrien
457389857Sobrien  htab = ppc_hash_table (info);
457489857Sobrien
457589857Sobrien  /* Deal with function syms.  */
457689857Sobrien  if (h->type == STT_FUNC
457789857Sobrien      || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
457889857Sobrien    {
457989857Sobrien      /* Clear procedure linkage table information for any symbol that
458089857Sobrien	 won't need a .plt entry.  */
4581130561Sobrien      struct plt_entry *ent;
4582130561Sobrien      for (ent = h->plt.plist; ent != NULL; ent = ent->next)
4583130561Sobrien	if (ent->plt.refcount > 0)
4584130561Sobrien	  break;
458589857Sobrien      if (!((struct ppc_link_hash_entry *) h)->is_func_descriptor
4586130561Sobrien	  || ent == NULL
4587130561Sobrien	  || SYMBOL_CALLS_LOCAL (info, h)
4588130561Sobrien	  || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
4589130561Sobrien	      && h->root.type == bfd_link_hash_undefweak))
459089857Sobrien	{
4591130561Sobrien	  h->plt.plist = NULL;
459289857Sobrien	  h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
459389857Sobrien	}
459489857Sobrien    }
459589857Sobrien  else
4596130561Sobrien    h->plt.plist = NULL;
459789857Sobrien
459889857Sobrien  /* If this is a weak symbol, and there is a real definition, the
459989857Sobrien     processor independent code will have arranged for us to see the
460089857Sobrien     real definition first, and we can just use the same value.  */
460189857Sobrien  if (h->weakdef != NULL)
460289857Sobrien    {
460389857Sobrien      BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
460489857Sobrien		  || h->weakdef->root.type == bfd_link_hash_defweak);
460589857Sobrien      h->root.u.def.section = h->weakdef->root.u.def.section;
460689857Sobrien      h->root.u.def.value = h->weakdef->root.u.def.value;
4607130561Sobrien      if (ELIMINATE_COPY_RELOCS)
4608130561Sobrien	h->elf_link_hash_flags
4609130561Sobrien	  = ((h->elf_link_hash_flags & ~ELF_LINK_NON_GOT_REF)
4610130561Sobrien	     | (h->weakdef->elf_link_hash_flags & ELF_LINK_NON_GOT_REF));
4611130561Sobrien      return TRUE;
461289857Sobrien    }
461389857Sobrien
461489857Sobrien  /* If we are creating a shared library, we must presume that the
461589857Sobrien     only references to the symbol are via the global offset table.
461689857Sobrien     For such cases we need not do anything here; the relocations will
461789857Sobrien     be handled correctly by relocate_section.  */
461889857Sobrien  if (info->shared)
4619130561Sobrien    return TRUE;
462089857Sobrien
462189857Sobrien  /* If there are no references to this symbol that do not use the
462289857Sobrien     GOT, we don't need to generate a copy reloc.  */
462389857Sobrien  if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0)
4624130561Sobrien    return TRUE;
462589857Sobrien
4626130561Sobrien  if (ELIMINATE_COPY_RELOCS)
462789857Sobrien    {
4628130561Sobrien      struct ppc_link_hash_entry * eh;
4629130561Sobrien      struct ppc_dyn_relocs *p;
4630130561Sobrien
4631130561Sobrien      eh = (struct ppc_link_hash_entry *) h;
4632130561Sobrien      for (p = eh->dyn_relocs; p != NULL; p = p->next)
4633130561Sobrien	{
4634130561Sobrien	  s = p->sec->output_section;
4635130561Sobrien	  if (s != NULL && (s->flags & SEC_READONLY) != 0)
4636130561Sobrien	    break;
4637130561Sobrien	}
4638130561Sobrien
4639130561Sobrien      /* If we didn't find any dynamic relocs in read-only sections, then
4640130561Sobrien	 we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
4641130561Sobrien      if (p == NULL)
4642130561Sobrien	{
4643130561Sobrien	  h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF;
4644130561Sobrien	  return TRUE;
4645130561Sobrien	}
464689857Sobrien    }
464789857Sobrien
4648130561Sobrien  if (h->plt.plist != NULL)
464989857Sobrien    {
4650130561Sobrien      /* We should never get here, but unfortunately there are versions
4651130561Sobrien	 of gcc out there that improperly (for this ABI) put initialized
4652130561Sobrien	 function pointers, vtable refs and suchlike in read-only
4653130561Sobrien	 sections.  Allow them to proceed, but warn that this might
4654130561Sobrien	 break at runtime.  */
4655130561Sobrien      (*_bfd_error_handler)
4656130561Sobrien	(_("copy reloc against `%s' requires lazy plt linking; "
4657130561Sobrien	   "avoid setting LD_BIND_NOW=1 or upgrade gcc"),
4658130561Sobrien	 h->root.root.string);
465989857Sobrien    }
466089857Sobrien
4661130561Sobrien  /* This is a reference to a symbol defined by a dynamic object which
4662130561Sobrien     is not a function.  */
4663130561Sobrien
466489857Sobrien  /* We must allocate the symbol in our .dynbss section, which will
466589857Sobrien     become part of the .bss section of the executable.  There will be
466689857Sobrien     an entry for this symbol in the .dynsym section.  The dynamic
466789857Sobrien     object will contain position independent code, so all references
466889857Sobrien     from the dynamic object to this symbol will go through the global
466989857Sobrien     offset table.  The dynamic linker will use the .dynsym entry to
467089857Sobrien     determine the address it must put in the global offset table, so
467189857Sobrien     both the dynamic object and the regular object will refer to the
467289857Sobrien     same memory location for the variable.  */
467389857Sobrien
4674130561Sobrien  /* We must generate a R_PPC64_COPY reloc to tell the dynamic linker
4675130561Sobrien     to copy the initial value out of the dynamic object and into the
467689857Sobrien     runtime process image.  We need to remember the offset into the
467789857Sobrien     .rela.bss section we are going to use.  */
467889857Sobrien  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
467989857Sobrien    {
4680130561Sobrien      htab->relbss->_raw_size += sizeof (Elf64_External_Rela);
468189857Sobrien      h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
468289857Sobrien    }
468389857Sobrien
468489857Sobrien  /* We need to figure out the alignment required for this symbol.  I
468589857Sobrien     have no idea how ELF linkers handle this.  */
468689857Sobrien  power_of_two = bfd_log2 (h->size);
468789857Sobrien  if (power_of_two > 4)
468889857Sobrien    power_of_two = 4;
468989857Sobrien
469089857Sobrien  /* Apply the required alignment.  */
4691130561Sobrien  s = htab->dynbss;
469289857Sobrien  s->_raw_size = BFD_ALIGN (s->_raw_size, (bfd_size_type) (1 << power_of_two));
469389857Sobrien  if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))
469489857Sobrien    {
469589857Sobrien      if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two))
4696130561Sobrien	return FALSE;
469789857Sobrien    }
469889857Sobrien
469989857Sobrien  /* Define the symbol as being at this point in the section.  */
470089857Sobrien  h->root.u.def.section = s;
470189857Sobrien  h->root.u.def.value = s->_raw_size;
470289857Sobrien
470389857Sobrien  /* Increment the section size to make room for the symbol.  */
470489857Sobrien  s->_raw_size += h->size;
470589857Sobrien
4706130561Sobrien  return TRUE;
470789857Sobrien}
470889857Sobrien
470989857Sobrien/* If given a function descriptor symbol, hide both the function code
471089857Sobrien   sym and the descriptor.  */
471189857Sobrienstatic void
4712130561Sobrienppc64_elf_hide_symbol (struct bfd_link_info *info,
4713130561Sobrien		       struct elf_link_hash_entry *h,
4714130561Sobrien		       bfd_boolean force_local)
471589857Sobrien{
471689857Sobrien  _bfd_elf_link_hash_hide_symbol (info, h, force_local);
471789857Sobrien
471889857Sobrien  if (((struct ppc_link_hash_entry *) h)->is_func_descriptor)
471989857Sobrien    {
4720104834Sobrien      struct elf_link_hash_entry *fh = ((struct ppc_link_hash_entry *) h)->oh;
472189857Sobrien
4722104834Sobrien      if (fh == NULL)
4723104834Sobrien	{
4724104834Sobrien	  const char *p, *q;
4725104834Sobrien	  struct ppc_link_hash_table *htab;
4726104834Sobrien	  char save;
4727104834Sobrien
4728104834Sobrien	  /* We aren't supposed to use alloca in BFD because on
4729104834Sobrien	     systems which do not have alloca the version in libiberty
4730104834Sobrien	     calls xmalloc, which might cause the program to crash
4731104834Sobrien	     when it runs out of memory.  This function doesn't have a
4732104834Sobrien	     return status, so there's no way to gracefully return an
4733104834Sobrien	     error.  So cheat.  We know that string[-1] can be safely
4734104834Sobrien	     dereferenced;  It's either a string in an ELF string
4735104834Sobrien	     table, or allocated in an objalloc structure.  */
4736104834Sobrien
4737104834Sobrien	  p = h->root.root.string - 1;
4738104834Sobrien	  save = *p;
4739104834Sobrien	  *(char *) p = '.';
4740104834Sobrien	  htab = ppc_hash_table (info);
4741130561Sobrien	  fh = elf_link_hash_lookup (&htab->elf, p, FALSE, FALSE, FALSE);
4742104834Sobrien	  *(char *) p = save;
4743104834Sobrien
4744104834Sobrien	  /* Unfortunately, if it so happens that the string we were
4745104834Sobrien	     looking for was allocated immediately before this string,
4746104834Sobrien	     then we overwrote the string terminator.  That's the only
4747104834Sobrien	     reason the lookup should fail.  */
4748104834Sobrien	  if (fh == NULL)
4749104834Sobrien	    {
4750104834Sobrien	      q = h->root.root.string + strlen (h->root.root.string);
4751104834Sobrien	      while (q >= h->root.root.string && *q == *p)
4752104834Sobrien		--q, --p;
4753104834Sobrien	      if (q < h->root.root.string && *p == '.')
4754130561Sobrien		fh = elf_link_hash_lookup (&htab->elf, p, FALSE, FALSE, FALSE);
4755104834Sobrien	    }
4756104834Sobrien	  if (fh != NULL)
4757104834Sobrien	    {
4758104834Sobrien	      ((struct ppc_link_hash_entry *) h)->oh = fh;
4759104834Sobrien	      ((struct ppc_link_hash_entry *) fh)->oh = h;
4760104834Sobrien	    }
4761104834Sobrien	}
476289857Sobrien      if (fh != NULL)
476389857Sobrien	_bfd_elf_link_hash_hide_symbol (info, fh, force_local);
476489857Sobrien    }
476589857Sobrien}
476689857Sobrien
4767130561Sobrienstatic bfd_boolean
4768130561Sobrienget_sym_h (struct elf_link_hash_entry **hp, Elf_Internal_Sym **symp,
4769130561Sobrien	   asection **symsecp, char **tls_maskp, Elf_Internal_Sym **locsymsp,
4770130561Sobrien	   unsigned long r_symndx, bfd *ibfd)
4771104834Sobrien{
4772130561Sobrien  Elf_Internal_Shdr *symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
4773130561Sobrien
4774130561Sobrien  if (r_symndx >= symtab_hdr->sh_info)
4775130561Sobrien    {
4776130561Sobrien      struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (ibfd);
4777130561Sobrien      struct elf_link_hash_entry *h;
4778130561Sobrien
4779130561Sobrien      h = sym_hashes[r_symndx - symtab_hdr->sh_info];
4780130561Sobrien      while (h->root.type == bfd_link_hash_indirect
4781130561Sobrien	     || h->root.type == bfd_link_hash_warning)
4782130561Sobrien	h = (struct elf_link_hash_entry *) h->root.u.i.link;
4783130561Sobrien
4784130561Sobrien      if (hp != NULL)
4785130561Sobrien	*hp = h;
4786130561Sobrien
4787130561Sobrien      if (symp != NULL)
4788130561Sobrien	*symp = NULL;
4789130561Sobrien
4790130561Sobrien      if (symsecp != NULL)
4791130561Sobrien	{
4792130561Sobrien	  asection *symsec = NULL;
4793130561Sobrien	  if (h->root.type == bfd_link_hash_defined
4794130561Sobrien	      || h->root.type == bfd_link_hash_defweak)
4795130561Sobrien	    symsec = h->root.u.def.section;
4796130561Sobrien	  *symsecp = symsec;
4797130561Sobrien	}
4798130561Sobrien
4799130561Sobrien      if (tls_maskp != NULL)
4800130561Sobrien	{
4801130561Sobrien	  struct ppc_link_hash_entry *eh;
4802130561Sobrien
4803130561Sobrien	  eh = (struct ppc_link_hash_entry *) h;
4804130561Sobrien	  *tls_maskp = &eh->tls_mask;
4805130561Sobrien	}
4806130561Sobrien    }
4807130561Sobrien  else
4808130561Sobrien    {
4809130561Sobrien      Elf_Internal_Sym *sym;
4810130561Sobrien      Elf_Internal_Sym *locsyms = *locsymsp;
4811130561Sobrien
4812130561Sobrien      if (locsyms == NULL)
4813130561Sobrien	{
4814130561Sobrien	  locsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
4815130561Sobrien	  if (locsyms == NULL)
4816130561Sobrien	    locsyms = bfd_elf_get_elf_syms (ibfd, symtab_hdr,
4817130561Sobrien					    symtab_hdr->sh_info,
4818130561Sobrien					    0, NULL, NULL, NULL);
4819130561Sobrien	  if (locsyms == NULL)
4820130561Sobrien	    return FALSE;
4821130561Sobrien	  *locsymsp = locsyms;
4822130561Sobrien	}
4823130561Sobrien      sym = locsyms + r_symndx;
4824130561Sobrien
4825130561Sobrien      if (hp != NULL)
4826130561Sobrien	*hp = NULL;
4827130561Sobrien
4828130561Sobrien      if (symp != NULL)
4829130561Sobrien	*symp = sym;
4830130561Sobrien
4831130561Sobrien      if (symsecp != NULL)
4832130561Sobrien	{
4833130561Sobrien	  asection *symsec = NULL;
4834130561Sobrien	  if ((sym->st_shndx != SHN_UNDEF
4835130561Sobrien	       && sym->st_shndx < SHN_LORESERVE)
4836130561Sobrien	      || sym->st_shndx > SHN_HIRESERVE)
4837130561Sobrien	    symsec = bfd_section_from_elf_index (ibfd, sym->st_shndx);
4838130561Sobrien	  *symsecp = symsec;
4839130561Sobrien	}
4840130561Sobrien
4841130561Sobrien      if (tls_maskp != NULL)
4842130561Sobrien	{
4843130561Sobrien	  struct got_entry **lgot_ents;
4844130561Sobrien	  char *tls_mask;
4845130561Sobrien
4846130561Sobrien	  tls_mask = NULL;
4847130561Sobrien	  lgot_ents = elf_local_got_ents (ibfd);
4848130561Sobrien	  if (lgot_ents != NULL)
4849130561Sobrien	    {
4850130561Sobrien	      char *lgot_masks = (char *) (lgot_ents + symtab_hdr->sh_info);
4851130561Sobrien	      tls_mask = &lgot_masks[r_symndx];
4852130561Sobrien	    }
4853130561Sobrien	  *tls_maskp = tls_mask;
4854130561Sobrien	}
4855130561Sobrien    }
4856130561Sobrien  return TRUE;
4857130561Sobrien}
4858130561Sobrien
4859130561Sobrien/* Returns TLS_MASKP for the given REL symbol.  Function return is 0 on
4860130561Sobrien   error, 2 on a toc GD type suitable for optimization, 3 on a toc LD
4861130561Sobrien   type suitable for optimization, and 1 otherwise.  */
4862130561Sobrien
4863130561Sobrienstatic int
4864130561Sobrienget_tls_mask (char **tls_maskp, unsigned long *toc_symndx,
4865130561Sobrien	      Elf_Internal_Sym **locsymsp,
4866130561Sobrien	      const Elf_Internal_Rela *rel, bfd *ibfd)
4867130561Sobrien{
4868130561Sobrien  unsigned long r_symndx;
4869130561Sobrien  int next_r;
4870130561Sobrien  struct elf_link_hash_entry *h;
4871130561Sobrien  Elf_Internal_Sym *sym;
4872130561Sobrien  asection *sec;
4873130561Sobrien  bfd_vma off;
4874130561Sobrien
4875130561Sobrien  r_symndx = ELF64_R_SYM (rel->r_info);
4876130561Sobrien  if (!get_sym_h (&h, &sym, &sec, tls_maskp, locsymsp, r_symndx, ibfd))
4877130561Sobrien    return 0;
4878130561Sobrien
4879130561Sobrien  if ((*tls_maskp != NULL && **tls_maskp != 0)
4880130561Sobrien      || sec == NULL
4881130561Sobrien      || ppc64_elf_section_data (sec)->t_symndx == NULL)
4882130561Sobrien    return 1;
4883130561Sobrien
4884130561Sobrien  /* Look inside a TOC section too.  */
4885130561Sobrien  if (h != NULL)
4886130561Sobrien    {
4887130561Sobrien      BFD_ASSERT (h->root.type == bfd_link_hash_defined);
4888130561Sobrien      off = h->root.u.def.value;
4889130561Sobrien    }
4890130561Sobrien  else
4891130561Sobrien    off = sym->st_value;
4892130561Sobrien  off += rel->r_addend;
4893130561Sobrien  BFD_ASSERT (off % 8 == 0);
4894130561Sobrien  r_symndx = ppc64_elf_section_data (sec)->t_symndx[off / 8];
4895130561Sobrien  next_r = ppc64_elf_section_data (sec)->t_symndx[off / 8 + 1];
4896130561Sobrien  if (!get_sym_h (&h, &sym, &sec, tls_maskp, locsymsp, r_symndx, ibfd))
4897130561Sobrien    return 0;
4898130561Sobrien  if (toc_symndx != NULL)
4899130561Sobrien    *toc_symndx = r_symndx;
4900130561Sobrien  if ((h == NULL
4901130561Sobrien       || ((h->root.type == bfd_link_hash_defined
4902130561Sobrien	    || h->root.type == bfd_link_hash_defweak)
4903130561Sobrien	   && !(h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC)))
4904130561Sobrien      && (next_r == -1 || next_r == -2))
4905130561Sobrien    return 1 - next_r;
4906130561Sobrien  return 1;
4907130561Sobrien}
4908130561Sobrien
4909130561Sobrien/* Adjust all global syms defined in opd sections.  In gcc generated
4910130561Sobrien   code these will already have been done, but I suppose we have to
4911130561Sobrien   cater for all sorts of hand written assembly.  */
4912130561Sobrien
4913130561Sobrienstatic bfd_boolean
4914130561Sobrienadjust_opd_syms (struct elf_link_hash_entry *h, void *inf ATTRIBUTE_UNUSED)
4915130561Sobrien{
4916130561Sobrien  struct ppc_link_hash_entry *eh;
4917130561Sobrien  asection *sym_sec;
4918130561Sobrien  long *opd_adjust;
4919130561Sobrien
4920130561Sobrien  if (h->root.type == bfd_link_hash_indirect)
4921130561Sobrien    return TRUE;
4922130561Sobrien
4923130561Sobrien  if (h->root.type == bfd_link_hash_warning)
4924130561Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
4925130561Sobrien
4926130561Sobrien  if (h->root.type != bfd_link_hash_defined
4927130561Sobrien      && h->root.type != bfd_link_hash_defweak)
4928130561Sobrien    return TRUE;
4929130561Sobrien
4930130561Sobrien  eh = (struct ppc_link_hash_entry *) h;
4931130561Sobrien  if (eh->adjust_done)
4932130561Sobrien    return TRUE;
4933130561Sobrien
4934130561Sobrien  sym_sec = eh->elf.root.u.def.section;
4935130561Sobrien  if (sym_sec != NULL
4936130561Sobrien      && elf_section_data (sym_sec) != NULL
4937130561Sobrien      && (opd_adjust = ppc64_elf_section_data (sym_sec)->opd.adjust) != NULL)
4938130561Sobrien    {
4939130561Sobrien      eh->elf.root.u.def.value += opd_adjust[eh->elf.root.u.def.value / 24];
4940130561Sobrien      eh->adjust_done = 1;
4941130561Sobrien    }
4942130561Sobrien  return TRUE;
4943130561Sobrien}
4944130561Sobrien
4945130561Sobrien/* Remove unused Official Procedure Descriptor entries.  Currently we
4946130561Sobrien   only remove those associated with functions in discarded link-once
4947130561Sobrien   sections, or weakly defined functions that have been overridden.  It
4948130561Sobrien   would be possible to remove many more entries for statically linked
4949130561Sobrien   applications.  */
4950130561Sobrien
4951130561Sobrienbfd_boolean
4952130561Sobrienppc64_elf_edit_opd (bfd *obfd, struct bfd_link_info *info)
4953130561Sobrien{
4954104834Sobrien  bfd *ibfd;
4955130561Sobrien  bfd_boolean some_edited = FALSE;
4956104834Sobrien
4957130561Sobrien  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
4958104834Sobrien    {
4959104834Sobrien      asection *sec;
4960104834Sobrien      Elf_Internal_Rela *relstart, *rel, *relend;
4961104834Sobrien      Elf_Internal_Shdr *symtab_hdr;
4962104834Sobrien      Elf_Internal_Sym *local_syms;
4963104834Sobrien      struct elf_link_hash_entry **sym_hashes;
4964104834Sobrien      bfd_vma offset;
4965130561Sobrien      bfd_size_type amt;
4966104834Sobrien      long *adjust;
4967130561Sobrien      bfd_boolean need_edit;
4968104834Sobrien
4969104834Sobrien      sec = bfd_get_section_by_name (ibfd, ".opd");
4970104834Sobrien      if (sec == NULL)
4971104834Sobrien	continue;
4972104834Sobrien
4973130561Sobrien      amt = sec->_raw_size * sizeof (long) / 24;
4974130561Sobrien      adjust = ppc64_elf_section_data (sec)->opd.adjust;
4975130561Sobrien      if (adjust == NULL)
4976130561Sobrien	{
4977130561Sobrien	  /* Must be a ld -r link.  ie. check_relocs hasn't been
4978130561Sobrien	     called.  */
4979130561Sobrien	  adjust = bfd_zalloc (obfd, amt);
4980130561Sobrien	  ppc64_elf_section_data (sec)->opd.adjust = adjust;
4981130561Sobrien	}
4982130561Sobrien      memset (adjust, 0, amt);
4983104834Sobrien
4984104834Sobrien      if (sec->output_section == bfd_abs_section_ptr)
4985104834Sobrien	continue;
4986104834Sobrien
4987104834Sobrien      /* Look through the section relocs.  */
4988104834Sobrien      if ((sec->flags & SEC_RELOC) == 0 || sec->reloc_count == 0)
4989104834Sobrien	continue;
4990104834Sobrien
4991104834Sobrien      local_syms = NULL;
4992104834Sobrien      symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
4993104834Sobrien      sym_hashes = elf_sym_hashes (ibfd);
4994104834Sobrien
4995104834Sobrien      /* Read the relocations.  */
4996130561Sobrien      relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
4997130561Sobrien					    info->keep_memory);
4998104834Sobrien      if (relstart == NULL)
4999130561Sobrien	return FALSE;
5000104834Sobrien
5001104834Sobrien      /* First run through the relocs to check they are sane, and to
5002104834Sobrien	 determine whether we need to edit this opd section.  */
5003130561Sobrien      need_edit = FALSE;
5004104834Sobrien      offset = 0;
5005104834Sobrien      relend = relstart + sec->reloc_count;
5006130561Sobrien      for (rel = relstart; rel < relend; )
5007104834Sobrien	{
5008130561Sobrien	  enum elf_ppc64_reloc_type r_type;
5009104834Sobrien	  unsigned long r_symndx;
5010104834Sobrien	  asection *sym_sec;
5011104834Sobrien	  struct elf_link_hash_entry *h;
5012104834Sobrien	  Elf_Internal_Sym *sym;
5013104834Sobrien
5014104834Sobrien	  /* .opd contains a regular array of 24 byte entries.  We're
5015104834Sobrien	     only interested in the reloc pointing to a function entry
5016104834Sobrien	     point.  */
5017130561Sobrien	  if (rel->r_offset != offset
5018130561Sobrien	      || rel + 1 >= relend
5019130561Sobrien	      || (rel + 1)->r_offset != offset + 8)
5020104834Sobrien	    {
5021104834Sobrien	      /* If someone messes with .opd alignment then after a
5022104834Sobrien		 "ld -r" we might have padding in the middle of .opd.
5023104834Sobrien		 Also, there's nothing to prevent someone putting
5024104834Sobrien		 something silly in .opd with the assembler.  No .opd
5025130561Sobrien		 optimization for them!  */
5026104834Sobrien	      (*_bfd_error_handler)
5027104834Sobrien		(_("%s: .opd is not a regular array of opd entries"),
5028104834Sobrien		 bfd_archive_filename (ibfd));
5029130561Sobrien	      need_edit = FALSE;
5030104834Sobrien	      break;
5031104834Sobrien	    }
5032104834Sobrien
5033130561Sobrien	  if ((r_type = ELF64_R_TYPE (rel->r_info)) != R_PPC64_ADDR64
5034130561Sobrien	      || (r_type = ELF64_R_TYPE ((rel + 1)->r_info)) != R_PPC64_TOC)
5035104834Sobrien	    {
5036130561Sobrien	      (*_bfd_error_handler)
5037130561Sobrien		(_("%s: unexpected reloc type %u in .opd section"),
5038130561Sobrien		 bfd_archive_filename (ibfd), r_type);
5039130561Sobrien	      need_edit = FALSE;
5040130561Sobrien	      break;
5041104834Sobrien	    }
5042104834Sobrien
5043130561Sobrien	  r_symndx = ELF64_R_SYM (rel->r_info);
5044130561Sobrien	  if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms,
5045130561Sobrien			  r_symndx, ibfd))
5046130561Sobrien	    goto error_ret;
5047130561Sobrien
5048104834Sobrien	  if (sym_sec == NULL || sym_sec->owner == NULL)
5049104834Sobrien	    {
5050130561Sobrien	      const char *sym_name;
5051130561Sobrien	      if (h != NULL)
5052130561Sobrien		sym_name = h->root.root.string;
5053130561Sobrien	      else
5054130561Sobrien		sym_name = bfd_elf_local_sym_name (ibfd, sym);
5055130561Sobrien
5056104834Sobrien	      (*_bfd_error_handler)
5057104834Sobrien		(_("%s: undefined sym `%s' in .opd section"),
5058104834Sobrien		 bfd_archive_filename (ibfd),
5059130561Sobrien		 sym_name);
5060130561Sobrien	      need_edit = FALSE;
5061104834Sobrien	      break;
5062104834Sobrien	    }
5063104834Sobrien
5064104834Sobrien	  /* opd entries are always for functions defined in the
5065104834Sobrien	     current input bfd.  If the symbol isn't defined in the
5066104834Sobrien	     input bfd, then we won't be using the function in this
5067104834Sobrien	     bfd;  It must be defined in a linkonce section in another
5068104834Sobrien	     bfd, or is weak.  It's also possible that we are
5069104834Sobrien	     discarding the function due to a linker script /DISCARD/,
5070104834Sobrien	     which we test for via the output_section.  */
5071104834Sobrien	  if (sym_sec->owner != ibfd
5072104834Sobrien	      || sym_sec->output_section == bfd_abs_section_ptr)
5073130561Sobrien	    need_edit = TRUE;
5074104834Sobrien
5075104834Sobrien	  offset += 24;
5076130561Sobrien	  rel += 2;
5077130561Sobrien	  /* Allow for the possibility of a reloc on the third word.  */
5078130561Sobrien	  if (rel < relend
5079130561Sobrien	      && rel->r_offset == offset - 8)
5080130561Sobrien	    rel += 1;
5081104834Sobrien	}
5082104834Sobrien
5083104834Sobrien      if (need_edit)
5084104834Sobrien	{
5085104834Sobrien	  Elf_Internal_Rela *write_rel;
5086104834Sobrien	  bfd_byte *rptr, *wptr;
5087130561Sobrien	  bfd_boolean skip;
5088104834Sobrien
5089104834Sobrien	  /* This seems a waste of time as input .opd sections are all
5090104834Sobrien	     zeros as generated by gcc, but I suppose there's no reason
5091104834Sobrien	     this will always be so.  We might start putting something in
5092104834Sobrien	     the third word of .opd entries.  */
5093104834Sobrien	  if ((sec->flags & SEC_IN_MEMORY) == 0)
5094104834Sobrien	    {
5095104834Sobrien	      bfd_byte *loc = bfd_alloc (ibfd, sec->_raw_size);
5096104834Sobrien	      if (loc == NULL
5097130561Sobrien		  || !bfd_get_section_contents (ibfd, sec, loc, 0,
5098104834Sobrien						sec->_raw_size))
5099104834Sobrien		{
5100130561Sobrien		error_ret:
5101104834Sobrien		  if (local_syms != NULL
5102104834Sobrien		      && symtab_hdr->contents != (unsigned char *) local_syms)
5103104834Sobrien		    free (local_syms);
5104104834Sobrien		  if (elf_section_data (sec)->relocs != relstart)
5105104834Sobrien		    free (relstart);
5106130561Sobrien		  return FALSE;
5107104834Sobrien		}
5108104834Sobrien	      sec->contents = loc;
5109104834Sobrien	      sec->flags |= (SEC_IN_MEMORY | SEC_HAS_CONTENTS);
5110104834Sobrien	    }
5111104834Sobrien
5112104834Sobrien	  elf_section_data (sec)->relocs = relstart;
5113104834Sobrien
5114104834Sobrien	  wptr = sec->contents;
5115104834Sobrien	  rptr = sec->contents;
5116104834Sobrien	  write_rel = relstart;
5117130561Sobrien	  skip = FALSE;
5118104834Sobrien	  offset = 0;
5119104834Sobrien	  for (rel = relstart; rel < relend; rel++)
5120104834Sobrien	    {
5121130561Sobrien	      unsigned long r_symndx;
5122130561Sobrien	      asection *sym_sec;
5123130561Sobrien	      struct elf_link_hash_entry *h;
5124130561Sobrien	      Elf_Internal_Sym *sym;
5125130561Sobrien
5126130561Sobrien	      r_symndx = ELF64_R_SYM (rel->r_info);
5127130561Sobrien	      if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms,
5128130561Sobrien			      r_symndx, ibfd))
5129130561Sobrien		goto error_ret;
5130130561Sobrien
5131104834Sobrien	      if (rel->r_offset == offset)
5132104834Sobrien		{
5133130561Sobrien		  struct ppc_link_hash_entry *fdh = NULL;
5134130561Sobrien		  if (h != NULL)
5135130561Sobrien		    fdh = get_fdh ((struct ppc_link_hash_entry *) h,
5136130561Sobrien				   ppc_hash_table (info));
5137104834Sobrien
5138104834Sobrien		  skip = (sym_sec->owner != ibfd
5139104834Sobrien			  || sym_sec->output_section == bfd_abs_section_ptr);
5140104834Sobrien		  if (skip)
5141104834Sobrien		    {
5142104834Sobrien		      if (h != NULL && sym_sec->owner == ibfd)
5143104834Sobrien			{
5144104834Sobrien			  /* Arrange for the function descriptor sym
5145104834Sobrien			     to be dropped.  */
5146130561Sobrien			  fdh->elf.root.u.def.value = 0;
5147130561Sobrien			  fdh->elf.root.u.def.section = sym_sec;
5148104834Sobrien			}
5149104834Sobrien		    }
5150104834Sobrien		  else
5151104834Sobrien		    {
5152104834Sobrien		      /* We'll be keeping this opd entry.  */
5153104834Sobrien
5154104834Sobrien		      if (h != NULL)
5155104834Sobrien			{
5156130561Sobrien			  /* Redefine the function descriptor symbol to
5157130561Sobrien			     this location in the opd section.  It is
5158130561Sobrien			     necessary to update the value here rather
5159130561Sobrien			     than using an array of adjustments as we do
5160130561Sobrien			     for local symbols, because various places
5161130561Sobrien			     in the generic ELF code use the value
5162130561Sobrien			     stored in u.def.value.  */
5163130561Sobrien			  fdh->elf.root.u.def.value = wptr - sec->contents;
5164130561Sobrien			  fdh->adjust_done = 1;
5165104834Sobrien			}
5166104834Sobrien
5167130561Sobrien		      /* Local syms are a bit tricky.  We could
5168130561Sobrien			 tweak them as they can be cached, but
5169130561Sobrien			 we'd need to look through the local syms
5170130561Sobrien			 for the function descriptor sym which we
5171130561Sobrien			 don't have at the moment.  So keep an
5172130561Sobrien			 array of adjustments.  */
5173130561Sobrien		      adjust[rel->r_offset / 24] = wptr - rptr;
5174130561Sobrien
5175104834Sobrien		      if (wptr != rptr)
5176104834Sobrien			memcpy (wptr, rptr, 24);
5177104834Sobrien		      wptr += 24;
5178104834Sobrien		    }
5179104834Sobrien		  rptr += 24;
5180104834Sobrien		  offset += 24;
5181104834Sobrien		}
5182104834Sobrien
5183130561Sobrien	      if (skip)
5184104834Sobrien		{
5185130561Sobrien		  BFD_ASSERT (MUST_BE_DYN_RELOC (ELF64_R_TYPE (rel->r_info)));
5186130561Sobrien		  if (info->shared)
5187130561Sobrien		    {
5188130561Sobrien		      /* We won't be needing dynamic relocs here.  */
5189130561Sobrien		      struct ppc_dyn_relocs **pp;
5190130561Sobrien		      struct ppc_dyn_relocs *p;
5191130561Sobrien
5192130561Sobrien		      if (h != NULL)
5193130561Sobrien			pp = &((struct ppc_link_hash_entry *) h)->dyn_relocs;
5194130561Sobrien		      else if (sym_sec != NULL)
5195130561Sobrien			pp = ((struct ppc_dyn_relocs **)
5196130561Sobrien			      &elf_section_data (sym_sec)->local_dynrel);
5197130561Sobrien		      else
5198130561Sobrien			pp = ((struct ppc_dyn_relocs **)
5199130561Sobrien			      &elf_section_data (sec)->local_dynrel);
5200130561Sobrien		      while ((p = *pp) != NULL)
5201130561Sobrien			{
5202130561Sobrien			  if (p->sec == sec)
5203130561Sobrien			    {
5204130561Sobrien			      p->count -= 1;
5205130561Sobrien			      if (p->count == 0)
5206130561Sobrien				*pp = p->next;
5207130561Sobrien			      break;
5208130561Sobrien			    }
5209130561Sobrien			  pp = &p->next;
5210130561Sobrien			}
5211130561Sobrien		    }
5212130561Sobrien		}
5213130561Sobrien	      else
5214130561Sobrien		{
5215130561Sobrien		  /* We need to adjust any reloc offsets to point to the
5216130561Sobrien		     new opd entries.  While we're at it, we may as well
5217130561Sobrien		     remove redundant relocs.  */
5218104834Sobrien		  rel->r_offset += wptr - rptr;
5219104834Sobrien		  if (write_rel != rel)
5220104834Sobrien		    memcpy (write_rel, rel, sizeof (*rel));
5221104834Sobrien		  ++write_rel;
5222104834Sobrien		}
5223104834Sobrien	    }
5224104834Sobrien
5225104834Sobrien	  sec->_cooked_size = wptr - sec->contents;
5226104834Sobrien	  sec->reloc_count = write_rel - relstart;
5227130561Sobrien	  /* Fudge the size too, as this is used later in
5228130561Sobrien	     elf_bfd_final_link if we are emitting relocs.  */
5229130561Sobrien	  elf_section_data (sec)->rel_hdr.sh_size
5230130561Sobrien	    = sec->reloc_count * elf_section_data (sec)->rel_hdr.sh_entsize;
5231130561Sobrien	  BFD_ASSERT (elf_section_data (sec)->rel_hdr2 == NULL);
5232130561Sobrien	  some_edited = TRUE;
5233104834Sobrien	}
5234104834Sobrien      else if (elf_section_data (sec)->relocs != relstart)
5235104834Sobrien	free (relstart);
5236104834Sobrien
5237104834Sobrien      if (local_syms != NULL
5238104834Sobrien	  && symtab_hdr->contents != (unsigned char *) local_syms)
5239104834Sobrien	{
5240104834Sobrien	  if (!info->keep_memory)
5241104834Sobrien	    free (local_syms);
5242104834Sobrien	  else
5243104834Sobrien	    symtab_hdr->contents = (unsigned char *) local_syms;
5244104834Sobrien	}
5245104834Sobrien    }
5246104834Sobrien
5247130561Sobrien  if (some_edited)
5248130561Sobrien    elf_link_hash_traverse (elf_hash_table (info), adjust_opd_syms, NULL);
5249130561Sobrien
5250130561Sobrien  return TRUE;
5251104834Sobrien}
525289857Sobrien
5253130561Sobrien/* Set htab->tls_get_addr and call the generic ELF tls_setup function.  */
5254130561Sobrien
5255130561Sobrienasection *
5256130561Sobrienppc64_elf_tls_setup (bfd *obfd, struct bfd_link_info *info)
5257130561Sobrien{
5258130561Sobrien  struct ppc_link_hash_table *htab;
5259130561Sobrien
5260130561Sobrien  htab = ppc_hash_table (info);
5261130561Sobrien  if (htab->tls_get_addr != NULL)
5262130561Sobrien    {
5263130561Sobrien      struct elf_link_hash_entry *h = htab->tls_get_addr;
5264130561Sobrien
5265130561Sobrien      while (h->root.type == bfd_link_hash_indirect
5266130561Sobrien	     || h->root.type == bfd_link_hash_warning)
5267130561Sobrien	h = (struct elf_link_hash_entry *) h->root.u.i.link;
5268130561Sobrien
5269130561Sobrien      htab->tls_get_addr = h;
5270130561Sobrien    }
5271130561Sobrien
5272130561Sobrien  return _bfd_elf_tls_setup (obfd, info);
5273130561Sobrien}
5274130561Sobrien
5275130561Sobrien/* Run through all the TLS relocs looking for optimization
5276130561Sobrien   opportunities.  The linker has been hacked (see ppc64elf.em) to do
5277130561Sobrien   a preliminary section layout so that we know the TLS segment
5278130561Sobrien   offsets.  We can't optimize earlier because some optimizations need
5279130561Sobrien   to know the tp offset, and we need to optimize before allocating
5280130561Sobrien   dynamic relocations.  */
5281130561Sobrien
5282130561Sobrienbfd_boolean
5283130561Sobrienppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
5284130561Sobrien{
5285130561Sobrien  bfd *ibfd;
5286130561Sobrien  asection *sec;
5287130561Sobrien  struct ppc_link_hash_table *htab;
5288130561Sobrien
5289130561Sobrien  if (info->relocatable || info->shared)
5290130561Sobrien    return TRUE;
5291130561Sobrien
5292130561Sobrien  htab = ppc_hash_table (info);
5293130561Sobrien  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
5294130561Sobrien    {
5295130561Sobrien      Elf_Internal_Sym *locsyms = NULL;
5296130561Sobrien
5297130561Sobrien      for (sec = ibfd->sections; sec != NULL; sec = sec->next)
5298130561Sobrien	if (sec->has_tls_reloc && !bfd_is_abs_section (sec->output_section))
5299130561Sobrien	  {
5300130561Sobrien	    Elf_Internal_Rela *relstart, *rel, *relend;
5301130561Sobrien	    int expecting_tls_get_addr;
5302130561Sobrien
5303130561Sobrien	    /* Read the relocations.  */
5304130561Sobrien	    relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
5305130561Sobrien						  info->keep_memory);
5306130561Sobrien	    if (relstart == NULL)
5307130561Sobrien	      return FALSE;
5308130561Sobrien
5309130561Sobrien	    expecting_tls_get_addr = 0;
5310130561Sobrien	    relend = relstart + sec->reloc_count;
5311130561Sobrien	    for (rel = relstart; rel < relend; rel++)
5312130561Sobrien	      {
5313130561Sobrien		enum elf_ppc64_reloc_type r_type;
5314130561Sobrien		unsigned long r_symndx;
5315130561Sobrien		struct elf_link_hash_entry *h;
5316130561Sobrien		Elf_Internal_Sym *sym;
5317130561Sobrien		asection *sym_sec;
5318130561Sobrien		char *tls_mask;
5319130561Sobrien		char tls_set, tls_clear, tls_type = 0;
5320130561Sobrien		bfd_vma value;
5321130561Sobrien		bfd_boolean ok_tprel, is_local;
5322130561Sobrien
5323130561Sobrien		r_symndx = ELF64_R_SYM (rel->r_info);
5324130561Sobrien		if (!get_sym_h (&h, &sym, &sym_sec, &tls_mask, &locsyms,
5325130561Sobrien				r_symndx, ibfd))
5326130561Sobrien		  {
5327130561Sobrien		  err_free_rel:
5328130561Sobrien		    if (elf_section_data (sec)->relocs != relstart)
5329130561Sobrien		      free (relstart);
5330130561Sobrien		    if (locsyms != NULL
5331130561Sobrien			&& (elf_tdata (ibfd)->symtab_hdr.contents
5332130561Sobrien			    != (unsigned char *) locsyms))
5333130561Sobrien		      free (locsyms);
5334130561Sobrien		    return FALSE;
5335130561Sobrien		  }
5336130561Sobrien
5337130561Sobrien		if (h != NULL)
5338130561Sobrien		  {
5339130561Sobrien		    if (h->root.type != bfd_link_hash_defined
5340130561Sobrien			&& h->root.type != bfd_link_hash_defweak)
5341130561Sobrien		      continue;
5342130561Sobrien		    value = h->root.u.def.value;
5343130561Sobrien		  }
5344130561Sobrien		else
5345130561Sobrien		  {
5346130561Sobrien		    value = sym->st_value;
5347130561Sobrien
5348130561Sobrien		    if (elf_section_data (sym_sec) != NULL)
5349130561Sobrien		      {
5350130561Sobrien			long *adjust;
5351130561Sobrien			adjust = ppc64_elf_section_data (sym_sec)->opd.adjust;
5352130561Sobrien			if (adjust != NULL)
5353130561Sobrien			  value += adjust[value / 24];
5354130561Sobrien		      }
5355130561Sobrien		  }
5356130561Sobrien
5357130561Sobrien		ok_tprel = FALSE;
5358130561Sobrien		is_local = FALSE;
5359130561Sobrien		if (h == NULL
5360130561Sobrien		    || !(h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC))
5361130561Sobrien		  {
5362130561Sobrien		    is_local = TRUE;
5363130561Sobrien		    value += sym_sec->output_offset;
5364130561Sobrien		    value += sym_sec->output_section->vma;
5365130561Sobrien		    value -= htab->elf.tls_sec->vma;
5366130561Sobrien		    ok_tprel = (value + TP_OFFSET + ((bfd_vma) 1 << 31)
5367130561Sobrien				< (bfd_vma) 1 << 32);
5368130561Sobrien		  }
5369130561Sobrien
5370130561Sobrien		r_type = ELF64_R_TYPE (rel->r_info);
5371130561Sobrien		switch (r_type)
5372130561Sobrien		  {
5373130561Sobrien		  case R_PPC64_GOT_TLSLD16:
5374130561Sobrien		  case R_PPC64_GOT_TLSLD16_LO:
5375130561Sobrien		  case R_PPC64_GOT_TLSLD16_HI:
5376130561Sobrien		  case R_PPC64_GOT_TLSLD16_HA:
5377130561Sobrien		    /* These relocs should never be against a symbol
5378130561Sobrien		       defined in a shared lib.  Leave them alone if
5379130561Sobrien		       that turns out to be the case.  */
5380130561Sobrien		    ppc64_tlsld_got (ibfd)->refcount -= 1;
5381130561Sobrien		    if (!is_local)
5382130561Sobrien		      continue;
5383130561Sobrien
5384130561Sobrien		    /* LD -> LE */
5385130561Sobrien		    tls_set = 0;
5386130561Sobrien		    tls_clear = TLS_LD;
5387130561Sobrien		    tls_type = TLS_TLS | TLS_LD;
5388130561Sobrien		    expecting_tls_get_addr = 1;
5389130561Sobrien		    break;
5390130561Sobrien
5391130561Sobrien		  case R_PPC64_GOT_TLSGD16:
5392130561Sobrien		  case R_PPC64_GOT_TLSGD16_LO:
5393130561Sobrien		  case R_PPC64_GOT_TLSGD16_HI:
5394130561Sobrien		  case R_PPC64_GOT_TLSGD16_HA:
5395130561Sobrien		    if (ok_tprel)
5396130561Sobrien		      /* GD -> LE */
5397130561Sobrien		      tls_set = 0;
5398130561Sobrien		    else
5399130561Sobrien		      /* GD -> IE */
5400130561Sobrien		      tls_set = TLS_TLS | TLS_TPRELGD;
5401130561Sobrien		    tls_clear = TLS_GD;
5402130561Sobrien		    tls_type = TLS_TLS | TLS_GD;
5403130561Sobrien		    expecting_tls_get_addr = 1;
5404130561Sobrien		    break;
5405130561Sobrien
5406130561Sobrien		  case R_PPC64_GOT_TPREL16_DS:
5407130561Sobrien		  case R_PPC64_GOT_TPREL16_LO_DS:
5408130561Sobrien		  case R_PPC64_GOT_TPREL16_HI:
5409130561Sobrien		  case R_PPC64_GOT_TPREL16_HA:
5410130561Sobrien		    expecting_tls_get_addr = 0;
5411130561Sobrien		    if (ok_tprel)
5412130561Sobrien		      {
5413130561Sobrien			/* IE -> LE */
5414130561Sobrien			tls_set = 0;
5415130561Sobrien			tls_clear = TLS_TPREL;
5416130561Sobrien			tls_type = TLS_TLS | TLS_TPREL;
5417130561Sobrien			break;
5418130561Sobrien		      }
5419130561Sobrien		    else
5420130561Sobrien		      continue;
5421130561Sobrien
5422130561Sobrien		  case R_PPC64_REL14:
5423130561Sobrien		  case R_PPC64_REL14_BRTAKEN:
5424130561Sobrien		  case R_PPC64_REL14_BRNTAKEN:
5425130561Sobrien		  case R_PPC64_REL24:
5426130561Sobrien		    if (h != NULL
5427130561Sobrien			&& h == htab->tls_get_addr)
5428130561Sobrien		      {
5429130561Sobrien			if (!expecting_tls_get_addr
5430130561Sobrien			    && rel != relstart
5431130561Sobrien			    && ((ELF64_R_TYPE (rel[-1].r_info)
5432130561Sobrien				 == R_PPC64_TOC16)
5433130561Sobrien				|| (ELF64_R_TYPE (rel[-1].r_info)
5434130561Sobrien				    == R_PPC64_TOC16_LO)))
5435130561Sobrien			  {
5436130561Sobrien			    /* Check for toc tls entries.  */
5437130561Sobrien			    char *toc_tls;
5438130561Sobrien			    int retval;
5439130561Sobrien
5440130561Sobrien			    retval = get_tls_mask (&toc_tls, NULL, &locsyms,
5441130561Sobrien						   rel - 1, ibfd);
5442130561Sobrien			    if (retval == 0)
5443130561Sobrien			      goto err_free_rel;
5444130561Sobrien			    if (toc_tls != NULL)
5445130561Sobrien			      expecting_tls_get_addr = retval > 1;
5446130561Sobrien			  }
5447130561Sobrien
5448130561Sobrien			if (expecting_tls_get_addr)
5449130561Sobrien			  {
5450130561Sobrien			    struct plt_entry *ent;
5451130561Sobrien			    for (ent = h->plt.plist; ent; ent = ent->next)
5452130561Sobrien			      if (ent->addend == 0)
5453130561Sobrien				{
5454130561Sobrien				  if (ent->plt.refcount > 0)
5455130561Sobrien				    ent->plt.refcount -= 1;
5456130561Sobrien				  break;
5457130561Sobrien				}
5458130561Sobrien			  }
5459130561Sobrien		      }
5460130561Sobrien		    expecting_tls_get_addr = 0;
5461130561Sobrien		    continue;
5462130561Sobrien
5463130561Sobrien		  case R_PPC64_TPREL64:
5464130561Sobrien		    expecting_tls_get_addr = 0;
5465130561Sobrien		    if (ok_tprel)
5466130561Sobrien		      {
5467130561Sobrien			/* IE -> LE */
5468130561Sobrien			tls_set = TLS_EXPLICIT;
5469130561Sobrien			tls_clear = TLS_TPREL;
5470130561Sobrien			break;
5471130561Sobrien		      }
5472130561Sobrien		    else
5473130561Sobrien		      continue;
5474130561Sobrien
5475130561Sobrien		  case R_PPC64_DTPMOD64:
5476130561Sobrien		    expecting_tls_get_addr = 0;
5477130561Sobrien		    if (rel + 1 < relend
5478130561Sobrien			&& (rel[1].r_info
5479130561Sobrien			    == ELF64_R_INFO (r_symndx, R_PPC64_DTPREL64))
5480130561Sobrien			&& rel[1].r_offset == rel->r_offset + 8)
5481130561Sobrien		      {
5482130561Sobrien			if (ok_tprel)
5483130561Sobrien			  /* GD -> LE */
5484130561Sobrien			  tls_set = TLS_EXPLICIT | TLS_GD;
5485130561Sobrien			else
5486130561Sobrien			  /* GD -> IE */
5487130561Sobrien			  tls_set = TLS_EXPLICIT | TLS_GD | TLS_TPRELGD;
5488130561Sobrien			tls_clear = TLS_GD;
5489130561Sobrien		      }
5490130561Sobrien		    else
5491130561Sobrien		      {
5492130561Sobrien			if (!is_local)
5493130561Sobrien			  continue;
5494130561Sobrien
5495130561Sobrien			/* LD -> LE */
5496130561Sobrien			tls_set = TLS_EXPLICIT;
5497130561Sobrien			tls_clear = TLS_LD;
5498130561Sobrien		      }
5499130561Sobrien		    break;
5500130561Sobrien
5501130561Sobrien		  default:
5502130561Sobrien		    expecting_tls_get_addr = 0;
5503130561Sobrien		    continue;
5504130561Sobrien		  }
5505130561Sobrien
5506130561Sobrien		if ((tls_set & TLS_EXPLICIT) == 0)
5507130561Sobrien		  {
5508130561Sobrien		    struct got_entry *ent;
5509130561Sobrien
5510130561Sobrien		    /* Adjust got entry for this reloc.  */
5511130561Sobrien		    if (h != NULL)
5512130561Sobrien		      ent = h->got.glist;
5513130561Sobrien		    else
5514130561Sobrien		      ent = elf_local_got_ents (ibfd)[r_symndx];
5515130561Sobrien
5516130561Sobrien		    for (; ent != NULL; ent = ent->next)
5517130561Sobrien		      if (ent->addend == rel->r_addend
5518130561Sobrien			  && ent->owner == ibfd
5519130561Sobrien			  && ent->tls_type == tls_type)
5520130561Sobrien			break;
5521130561Sobrien		    if (ent == NULL)
5522130561Sobrien		      abort ();
5523130561Sobrien
5524130561Sobrien		    if (tls_set == 0)
5525130561Sobrien		      {
5526130561Sobrien			/* We managed to get rid of a got entry.  */
5527130561Sobrien			if (ent->got.refcount > 0)
5528130561Sobrien			  ent->got.refcount -= 1;
5529130561Sobrien		      }
5530130561Sobrien		  }
5531130561Sobrien		else if (h != NULL)
5532130561Sobrien		  {
5533130561Sobrien		    struct ppc_link_hash_entry * eh;
5534130561Sobrien		    struct ppc_dyn_relocs **pp;
5535130561Sobrien		    struct ppc_dyn_relocs *p;
5536130561Sobrien
5537130561Sobrien		    /* Adjust dynamic relocs.  */
5538130561Sobrien		    eh = (struct ppc_link_hash_entry *) h;
5539130561Sobrien		    for (pp = &eh->dyn_relocs;
5540130561Sobrien			 (p = *pp) != NULL;
5541130561Sobrien			 pp = &p->next)
5542130561Sobrien		      if (p->sec == sec)
5543130561Sobrien			{
5544130561Sobrien			  /* If we got rid of a DTPMOD/DTPREL reloc
5545130561Sobrien			     pair then we'll lose one or two dyn
5546130561Sobrien			     relocs.  */
5547130561Sobrien			  if (tls_set == (TLS_EXPLICIT | TLS_GD))
5548130561Sobrien			    p->count -= 1;
5549130561Sobrien			  p->count -= 1;
5550130561Sobrien			  if (p->count == 0)
5551130561Sobrien			    *pp = p->next;
5552130561Sobrien			  break;
5553130561Sobrien			}
5554130561Sobrien		  }
5555130561Sobrien
5556130561Sobrien		*tls_mask |= tls_set;
5557130561Sobrien		*tls_mask &= ~tls_clear;
5558130561Sobrien	      }
5559130561Sobrien
5560130561Sobrien	    if (elf_section_data (sec)->relocs != relstart)
5561130561Sobrien	      free (relstart);
5562130561Sobrien	  }
5563130561Sobrien
5564130561Sobrien      if (locsyms != NULL
5565130561Sobrien	  && (elf_tdata (ibfd)->symtab_hdr.contents
5566130561Sobrien	      != (unsigned char *) locsyms))
5567130561Sobrien	{
5568130561Sobrien	  if (!info->keep_memory)
5569130561Sobrien	    free (locsyms);
5570130561Sobrien	  else
5571130561Sobrien	    elf_tdata (ibfd)->symtab_hdr.contents = (unsigned char *) locsyms;
5572130561Sobrien	}
5573130561Sobrien    }
5574130561Sobrien  return TRUE;
5575130561Sobrien}
5576130561Sobrien
557789857Sobrien/* Allocate space in .plt, .got and associated reloc sections for
557889857Sobrien   dynamic relocs.  */
557989857Sobrien
5580130561Sobrienstatic bfd_boolean
5581130561Sobrienallocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
558289857Sobrien{
558389857Sobrien  struct bfd_link_info *info;
558489857Sobrien  struct ppc_link_hash_table *htab;
558589857Sobrien  asection *s;
558689857Sobrien  struct ppc_link_hash_entry *eh;
558789857Sobrien  struct ppc_dyn_relocs *p;
5588130561Sobrien  struct got_entry *gent;
558989857Sobrien
559094536Sobrien  if (h->root.type == bfd_link_hash_indirect)
5591130561Sobrien    return TRUE;
559289857Sobrien
559394536Sobrien  if (h->root.type == bfd_link_hash_warning)
559494536Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
559594536Sobrien
559689857Sobrien  info = (struct bfd_link_info *) inf;
559789857Sobrien  htab = ppc_hash_table (info);
559889857Sobrien
559989857Sobrien  if (htab->elf.dynamic_sections_created
5600130561Sobrien      && h->dynindx != -1
5601130561Sobrien      && WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
560289857Sobrien    {
5603130561Sobrien      struct plt_entry *pent;
5604130561Sobrien      bfd_boolean doneone = FALSE;
5605130561Sobrien      for (pent = h->plt.plist; pent != NULL; pent = pent->next)
5606130561Sobrien	if (pent->plt.refcount > 0)
5607130561Sobrien	  {
5608130561Sobrien	    BFD_ASSERT (((struct ppc_link_hash_entry *) h)->is_func_descriptor);
560989857Sobrien
5610130561Sobrien	    /* If this is the first .plt entry, make room for the special
5611130561Sobrien	       first entry.  */
5612130561Sobrien	    s = htab->plt;
5613130561Sobrien	    if (s->_raw_size == 0)
5614130561Sobrien	      s->_raw_size += PLT_INITIAL_ENTRY_SIZE;
561589857Sobrien
5616130561Sobrien	    pent->plt.offset = s->_raw_size;
561789857Sobrien
5618130561Sobrien	    /* Make room for this entry.  */
5619130561Sobrien	    s->_raw_size += PLT_ENTRY_SIZE;
562089857Sobrien
5621130561Sobrien	    /* Make room for the .glink code.  */
5622130561Sobrien	    s = htab->glink;
5623130561Sobrien	    if (s->_raw_size == 0)
5624130561Sobrien	      s->_raw_size += GLINK_CALL_STUB_SIZE;
5625130561Sobrien	    /* We need bigger stubs past index 32767.  */
5626130561Sobrien	    if (s->_raw_size >= GLINK_CALL_STUB_SIZE + 32768*2*4)
5627130561Sobrien	      s->_raw_size += 4;
5628130561Sobrien	    s->_raw_size += 2*4;
562989857Sobrien
5630130561Sobrien	    /* We also need to make an entry in the .rela.plt section.  */
5631130561Sobrien	    s = htab->relplt;
5632130561Sobrien	    s->_raw_size += sizeof (Elf64_External_Rela);
5633130561Sobrien	    doneone = TRUE;
5634130561Sobrien	  }
5635130561Sobrien	else
5636130561Sobrien	  pent->plt.offset = (bfd_vma) -1;
5637130561Sobrien      if (!doneone)
563889857Sobrien	{
5639130561Sobrien	  h->plt.plist = NULL;
564089857Sobrien	  h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
564189857Sobrien	}
564289857Sobrien    }
564389857Sobrien  else
564489857Sobrien    {
5645130561Sobrien      h->plt.plist = NULL;
564689857Sobrien      h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
564789857Sobrien    }
564889857Sobrien
5649130561Sobrien  eh = (struct ppc_link_hash_entry *) h;
5650130561Sobrien  /* Run through the TLS GD got entries first if we're changing them
5651130561Sobrien     to TPREL.  */
5652130561Sobrien  if ((eh->tls_mask & TLS_TPRELGD) != 0)
5653130561Sobrien    for (gent = h->got.glist; gent != NULL; gent = gent->next)
5654130561Sobrien      if (gent->got.refcount > 0
5655130561Sobrien	  && (gent->tls_type & TLS_GD) != 0)
5656130561Sobrien	{
5657130561Sobrien	  /* This was a GD entry that has been converted to TPREL.  If
5658130561Sobrien	     there happens to be a TPREL entry we can use that one.  */
5659130561Sobrien	  struct got_entry *ent;
5660130561Sobrien	  for (ent = h->got.glist; ent != NULL; ent = ent->next)
5661130561Sobrien	    if (ent->got.refcount > 0
5662130561Sobrien		&& (ent->tls_type & TLS_TPREL) != 0
5663130561Sobrien		&& ent->addend == gent->addend
5664130561Sobrien		&& ent->owner == gent->owner)
5665130561Sobrien	      {
5666130561Sobrien		gent->got.refcount = 0;
5667130561Sobrien		break;
5668130561Sobrien	      }
566989857Sobrien
5670130561Sobrien	  /* If not, then we'll be using our own TPREL entry.  */
5671130561Sobrien	  if (gent->got.refcount != 0)
5672130561Sobrien	    gent->tls_type = TLS_TLS | TLS_TPREL;
567389857Sobrien	}
567489857Sobrien
5675130561Sobrien  for (gent = h->got.glist; gent != NULL; gent = gent->next)
5676130561Sobrien    if (gent->got.refcount > 0)
5677130561Sobrien      {
5678130561Sobrien	bfd_boolean dyn;
567989857Sobrien
5680130561Sobrien	/* Make sure this symbol is output as a dynamic symbol.
5681130561Sobrien	   Undefined weak syms won't yet be marked as dynamic,
5682130561Sobrien	   nor will all TLS symbols.  */
5683130561Sobrien	if (h->dynindx == -1
5684130561Sobrien	    && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
5685130561Sobrien	  {
5686130561Sobrien	    if (! bfd_elf_link_record_dynamic_symbol (info, h))
5687130561Sobrien	      return FALSE;
5688130561Sobrien	  }
5689130561Sobrien
5690130561Sobrien	if ((gent->tls_type & TLS_LD) != 0
5691130561Sobrien	    && !(h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC))
5692130561Sobrien	  {
5693130561Sobrien	    gent->got.offset = ppc64_tlsld_got (gent->owner)->offset;
5694130561Sobrien	    continue;
5695130561Sobrien	  }
5696130561Sobrien
5697130561Sobrien	s = ppc64_elf_tdata (gent->owner)->got;
5698130561Sobrien	gent->got.offset = s->_raw_size;
5699130561Sobrien	s->_raw_size
5700130561Sobrien	  += (gent->tls_type & eh->tls_mask & (TLS_GD | TLS_LD)) ? 16 : 8;
5701130561Sobrien	dyn = htab->elf.dynamic_sections_created;
5702130561Sobrien	if ((info->shared
5703130561Sobrien	     || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
5704130561Sobrien	    && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
5705130561Sobrien		|| h->root.type != bfd_link_hash_undefweak))
5706130561Sobrien	  ppc64_elf_tdata (gent->owner)->relgot->_raw_size
5707130561Sobrien	    += (gent->tls_type & eh->tls_mask & TLS_GD
5708130561Sobrien		? 2 * sizeof (Elf64_External_Rela)
5709130561Sobrien		: sizeof (Elf64_External_Rela));
5710130561Sobrien      }
5711130561Sobrien    else
5712130561Sobrien      gent->got.offset = (bfd_vma) -1;
5713130561Sobrien
571489857Sobrien  if (eh->dyn_relocs == NULL)
5715130561Sobrien    return TRUE;
571689857Sobrien
571789857Sobrien  /* In the shared -Bsymbolic case, discard space allocated for
571889857Sobrien     dynamic pc-relative relocs against symbols which turn out to be
571989857Sobrien     defined in regular objects.  For the normal shared case, discard
572089857Sobrien     space for relocs that have become local due to symbol visibility
572189857Sobrien     changes.  */
572289857Sobrien
572389857Sobrien  if (info->shared)
572489857Sobrien    {
5725130561Sobrien      /* Relocs that use pc_count are those that appear on a call insn,
5726130561Sobrien	 or certain REL relocs (see MUST_BE_DYN_RELOC) that can be
5727130561Sobrien	 generated via assembly.  We want calls to protected symbols to
5728130561Sobrien	 resolve directly to the function rather than going via the plt.
5729130561Sobrien	 If people want function pointer comparisons to work as expected
5730130561Sobrien	 then they should avoid writing weird assembly.  */
5731130561Sobrien      if (SYMBOL_CALLS_LOCAL (info, h))
573289857Sobrien	{
573389857Sobrien	  struct ppc_dyn_relocs **pp;
573489857Sobrien
573589857Sobrien	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
573689857Sobrien	    {
573789857Sobrien	      p->count -= p->pc_count;
573889857Sobrien	      p->pc_count = 0;
573989857Sobrien	      if (p->count == 0)
574089857Sobrien		*pp = p->next;
574189857Sobrien	      else
574289857Sobrien		pp = &p->next;
574389857Sobrien	    }
574489857Sobrien	}
5745130561Sobrien
5746130561Sobrien      /* Also discard relocs on undefined weak syms with non-default
5747130561Sobrien	 visibility.  */
5748130561Sobrien      if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
5749130561Sobrien	  && h->root.type == bfd_link_hash_undefweak)
5750130561Sobrien	eh->dyn_relocs = NULL;
575189857Sobrien    }
5752130561Sobrien  else if (ELIMINATE_COPY_RELOCS)
575389857Sobrien    {
575489857Sobrien      /* For the non-shared case, discard space for relocs against
575589857Sobrien	 symbols which turn out to need copy relocs or are not
575689857Sobrien	 dynamic.  */
575789857Sobrien
575889857Sobrien      if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0
5759130561Sobrien	  && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
5760130561Sobrien	  && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
576189857Sobrien	{
576289857Sobrien	  /* Make sure this symbol is output as a dynamic symbol.
576389857Sobrien	     Undefined weak syms won't yet be marked as dynamic.  */
576489857Sobrien	  if (h->dynindx == -1
576589857Sobrien	      && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
576689857Sobrien	    {
5767130561Sobrien	      if (! bfd_elf_link_record_dynamic_symbol (info, h))
5768130561Sobrien		return FALSE;
576989857Sobrien	    }
577089857Sobrien
577189857Sobrien	  /* If that succeeded, we know we'll be keeping all the
577289857Sobrien	     relocs.  */
577389857Sobrien	  if (h->dynindx != -1)
577489857Sobrien	    goto keep;
577589857Sobrien	}
577689857Sobrien
577789857Sobrien      eh->dyn_relocs = NULL;
577889857Sobrien
577989857Sobrien    keep: ;
578089857Sobrien    }
578189857Sobrien
578289857Sobrien  /* Finally, allocate space.  */
578389857Sobrien  for (p = eh->dyn_relocs; p != NULL; p = p->next)
578489857Sobrien    {
578589857Sobrien      asection *sreloc = elf_section_data (p->sec)->sreloc;
578689857Sobrien      sreloc->_raw_size += p->count * sizeof (Elf64_External_Rela);
578789857Sobrien    }
578889857Sobrien
5789130561Sobrien  return TRUE;
579089857Sobrien}
579189857Sobrien
579289857Sobrien/* Find any dynamic relocs that apply to read-only sections.  */
579389857Sobrien
5794130561Sobrienstatic bfd_boolean
5795130561Sobrienreadonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
579689857Sobrien{
579789857Sobrien  struct ppc_link_hash_entry *eh;
579889857Sobrien  struct ppc_dyn_relocs *p;
579989857Sobrien
580094536Sobrien  if (h->root.type == bfd_link_hash_warning)
580194536Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
580294536Sobrien
580389857Sobrien  eh = (struct ppc_link_hash_entry *) h;
580489857Sobrien  for (p = eh->dyn_relocs; p != NULL; p = p->next)
580589857Sobrien    {
580689857Sobrien      asection *s = p->sec->output_section;
580789857Sobrien
580889857Sobrien      if (s != NULL && (s->flags & SEC_READONLY) != 0)
580989857Sobrien	{
5810130561Sobrien	  struct bfd_link_info *info = inf;
581189857Sobrien
581289857Sobrien	  info->flags |= DF_TEXTREL;
581389857Sobrien
581489857Sobrien	  /* Not an error, just cut short the traversal.  */
5815130561Sobrien	  return FALSE;
581689857Sobrien	}
581789857Sobrien    }
5818130561Sobrien  return TRUE;
581989857Sobrien}
582089857Sobrien
582189857Sobrien/* Set the sizes of the dynamic sections.  */
582289857Sobrien
5823130561Sobrienstatic bfd_boolean
5824130561Sobrienppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
5825130561Sobrien				 struct bfd_link_info *info)
582689857Sobrien{
582789857Sobrien  struct ppc_link_hash_table *htab;
582889857Sobrien  bfd *dynobj;
582989857Sobrien  asection *s;
5830130561Sobrien  bfd_boolean relocs;
583189857Sobrien  bfd *ibfd;
583289857Sobrien
583389857Sobrien  htab = ppc_hash_table (info);
583489857Sobrien  dynobj = htab->elf.dynobj;
583589857Sobrien  if (dynobj == NULL)
583689857Sobrien    abort ();
583789857Sobrien
583889857Sobrien  if (htab->elf.dynamic_sections_created)
583989857Sobrien    {
584089857Sobrien      /* Set the contents of the .interp section to the interpreter.  */
5841130561Sobrien      if (info->executable)
584289857Sobrien	{
584389857Sobrien	  s = bfd_get_section_by_name (dynobj, ".interp");
584489857Sobrien	  if (s == NULL)
584589857Sobrien	    abort ();
584689857Sobrien	  s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
584789857Sobrien	  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
584889857Sobrien	}
584989857Sobrien    }
585089857Sobrien
585189857Sobrien  /* Set up .got offsets for local syms, and space for local dynamic
585289857Sobrien     relocs.  */
585389857Sobrien  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
585489857Sobrien    {
5855130561Sobrien      struct got_entry **lgot_ents;
5856130561Sobrien      struct got_entry **end_lgot_ents;
5857130561Sobrien      char *lgot_masks;
585889857Sobrien      bfd_size_type locsymcount;
585989857Sobrien      Elf_Internal_Shdr *symtab_hdr;
586089857Sobrien      asection *srel;
586189857Sobrien
586289857Sobrien      if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
586389857Sobrien	continue;
586489857Sobrien
5865130561Sobrien      if (ppc64_tlsld_got (ibfd)->refcount > 0)
5866130561Sobrien	{
5867130561Sobrien	  s = ppc64_elf_tdata (ibfd)->got;
5868130561Sobrien	  ppc64_tlsld_got (ibfd)->offset = s->_raw_size;
5869130561Sobrien	  s->_raw_size += 16;
5870130561Sobrien	  if (info->shared)
5871130561Sobrien	    {
5872130561Sobrien	      srel = ppc64_elf_tdata (ibfd)->relgot;
5873130561Sobrien	      srel->_raw_size += sizeof (Elf64_External_Rela);
5874130561Sobrien	    }
5875130561Sobrien	}
5876130561Sobrien      else
5877130561Sobrien	ppc64_tlsld_got (ibfd)->offset = (bfd_vma) -1;
5878130561Sobrien
587989857Sobrien      for (s = ibfd->sections; s != NULL; s = s->next)
588089857Sobrien	{
588189857Sobrien	  struct ppc_dyn_relocs *p;
588289857Sobrien
588389857Sobrien	  for (p = *((struct ppc_dyn_relocs **)
588489857Sobrien		     &elf_section_data (s)->local_dynrel);
588589857Sobrien	       p != NULL;
588689857Sobrien	       p = p->next)
588789857Sobrien	    {
588889857Sobrien	      if (!bfd_is_abs_section (p->sec)
588989857Sobrien		  && bfd_is_abs_section (p->sec->output_section))
589089857Sobrien		{
589189857Sobrien		  /* Input section has been discarded, either because
589289857Sobrien		     it is a copy of a linkonce section or due to
589389857Sobrien		     linker script /DISCARD/, so we'll be discarding
589489857Sobrien		     the relocs too.  */
589589857Sobrien		}
589691041Sobrien	      else if (p->count != 0)
589789857Sobrien		{
589889857Sobrien		  srel = elf_section_data (p->sec)->sreloc;
589989857Sobrien		  srel->_raw_size += p->count * sizeof (Elf64_External_Rela);
590091041Sobrien		  if ((p->sec->output_section->flags & SEC_READONLY) != 0)
590191041Sobrien		    info->flags |= DF_TEXTREL;
590289857Sobrien		}
590389857Sobrien	    }
590489857Sobrien	}
590589857Sobrien
5906130561Sobrien      lgot_ents = elf_local_got_ents (ibfd);
5907130561Sobrien      if (!lgot_ents)
590889857Sobrien	continue;
590989857Sobrien
591089857Sobrien      symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
591189857Sobrien      locsymcount = symtab_hdr->sh_info;
5912130561Sobrien      end_lgot_ents = lgot_ents + locsymcount;
5913130561Sobrien      lgot_masks = (char *) end_lgot_ents;
5914130561Sobrien      s = ppc64_elf_tdata (ibfd)->got;
5915130561Sobrien      srel = ppc64_elf_tdata (ibfd)->relgot;
5916130561Sobrien      for (; lgot_ents < end_lgot_ents; ++lgot_ents, ++lgot_masks)
591789857Sobrien	{
5918130561Sobrien	  struct got_entry *ent;
5919130561Sobrien
5920130561Sobrien	  for (ent = *lgot_ents; ent != NULL; ent = ent->next)
5921130561Sobrien	    if (ent->got.refcount > 0)
5922130561Sobrien	      {
5923130561Sobrien		if ((ent->tls_type & *lgot_masks & TLS_LD) != 0)
5924130561Sobrien		  {
5925130561Sobrien		    if (ppc64_tlsld_got (ibfd)->offset == (bfd_vma) -1)
5926130561Sobrien		      {
5927130561Sobrien			ppc64_tlsld_got (ibfd)->offset = s->_raw_size;
5928130561Sobrien			s->_raw_size += 16;
5929130561Sobrien			if (info->shared)
5930130561Sobrien			  srel->_raw_size += sizeof (Elf64_External_Rela);
5931130561Sobrien		      }
5932130561Sobrien		    ent->got.offset = ppc64_tlsld_got (ibfd)->offset;
5933130561Sobrien		  }
5934130561Sobrien		else
5935130561Sobrien		  {
5936130561Sobrien		    ent->got.offset = s->_raw_size;
5937130561Sobrien		    if ((ent->tls_type & *lgot_masks & TLS_GD) != 0)
5938130561Sobrien		      {
5939130561Sobrien			s->_raw_size += 16;
5940130561Sobrien			if (info->shared)
5941130561Sobrien			  srel->_raw_size += 2 * sizeof (Elf64_External_Rela);
5942130561Sobrien		      }
5943130561Sobrien		    else
5944130561Sobrien		      {
5945130561Sobrien			s->_raw_size += 8;
5946130561Sobrien			if (info->shared)
5947130561Sobrien			  srel->_raw_size += sizeof (Elf64_External_Rela);
5948130561Sobrien		      }
5949130561Sobrien		  }
5950130561Sobrien	      }
5951130561Sobrien	    else
5952130561Sobrien	      ent->got.offset = (bfd_vma) -1;
595389857Sobrien	}
595489857Sobrien    }
595589857Sobrien
595689857Sobrien  /* Allocate global sym .plt and .got entries, and space for global
595789857Sobrien     sym dynamic relocs.  */
5958130561Sobrien  elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
595989857Sobrien
596089857Sobrien  /* We now have determined the sizes of the various dynamic sections.
596189857Sobrien     Allocate memory for them.  */
5962130561Sobrien  relocs = FALSE;
596389857Sobrien  for (s = dynobj->sections; s != NULL; s = s->next)
596489857Sobrien    {
596589857Sobrien      if ((s->flags & SEC_LINKER_CREATED) == 0)
596689857Sobrien	continue;
596789857Sobrien
5968130561Sobrien      /* Reset _cooked_size since prelim layout will set it wrongly,
5969130561Sobrien	 and a non-zero _cooked_size sticks.  */
5970130561Sobrien      s->_cooked_size = 0;
5971130561Sobrien
5972130561Sobrien      if (s == htab->brlt || s == htab->relbrlt)
5973104834Sobrien	/* These haven't been allocated yet;  don't strip.  */
5974104834Sobrien	continue;
5975130561Sobrien      else if (s == htab->got
5976130561Sobrien	       || s == htab->plt
5977130561Sobrien	       || s == htab->glink)
597889857Sobrien	{
597989857Sobrien	  /* Strip this section if we don't need it; see the
598089857Sobrien	     comment below.  */
598189857Sobrien	}
598289857Sobrien      else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0)
598389857Sobrien	{
598489857Sobrien	  if (s->_raw_size == 0)
598589857Sobrien	    {
598689857Sobrien	      /* If we don't need this section, strip it from the
598789857Sobrien		 output file.  This is mostly to handle .rela.bss and
598889857Sobrien		 .rela.plt.  We must create both sections in
598989857Sobrien		 create_dynamic_sections, because they must be created
599089857Sobrien		 before the linker maps input sections to output
599189857Sobrien		 sections.  The linker does that before
599289857Sobrien		 adjust_dynamic_symbol is called, and it is that
599389857Sobrien		 function which decides whether anything needs to go
599489857Sobrien		 into these sections.  */
599589857Sobrien	    }
599689857Sobrien	  else
599789857Sobrien	    {
5998130561Sobrien	      if (s != htab->relplt)
5999130561Sobrien		relocs = TRUE;
600089857Sobrien
600189857Sobrien	      /* We use the reloc_count field as a counter if we need
600289857Sobrien		 to copy relocs into the output file.  */
600389857Sobrien	      s->reloc_count = 0;
600489857Sobrien	    }
600589857Sobrien	}
600689857Sobrien      else
600789857Sobrien	{
600889857Sobrien	  /* It's not one of our sections, so don't allocate space.  */
600989857Sobrien	  continue;
601089857Sobrien	}
601189857Sobrien
601289857Sobrien      if (s->_raw_size == 0)
601389857Sobrien	{
601489857Sobrien	  _bfd_strip_section_from_output (info, s);
601589857Sobrien	  continue;
601689857Sobrien	}
601789857Sobrien
6018104834Sobrien      /* .plt is in the bss section.  We don't initialise it.  */
6019130561Sobrien      if (s == htab->plt)
6020104834Sobrien	continue;
6021104834Sobrien
602289857Sobrien      /* Allocate memory for the section contents.  We use bfd_zalloc
602389857Sobrien	 here in case unused entries are not reclaimed before the
602489857Sobrien	 section's contents are written out.  This should not happen,
6025130561Sobrien	 but this way if it does we get a R_PPC64_NONE reloc in .rela
6026130561Sobrien	 sections instead of garbage.
6027130561Sobrien	 We also rely on the section contents being zero when writing
6028130561Sobrien	 the GOT.  */
6029130561Sobrien      s->contents = bfd_zalloc (dynobj, s->_raw_size);
603089857Sobrien      if (s->contents == NULL)
6031130561Sobrien	return FALSE;
603289857Sobrien    }
603389857Sobrien
6034130561Sobrien  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
6035130561Sobrien    {
6036209867Snwhitehorn      /* Skip this BFD if it is not ELF */
6037209867Snwhitehorn      if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
6038209867Snwhitehorn	continue;
6039209867Snwhitehorn
6040130561Sobrien      s = ppc64_elf_tdata (ibfd)->got;
6041130561Sobrien      if (s != NULL && s != htab->got)
6042130561Sobrien	{
6043130561Sobrien	  s->_cooked_size = 0;
6044130561Sobrien	  if (s->_raw_size == 0)
6045130561Sobrien	    _bfd_strip_section_from_output (info, s);
6046130561Sobrien	  else
6047130561Sobrien	    {
6048130561Sobrien	      s->contents = bfd_zalloc (ibfd, s->_raw_size);
6049130561Sobrien	      if (s->contents == NULL)
6050130561Sobrien		return FALSE;
6051130561Sobrien	    }
6052130561Sobrien	}
6053130561Sobrien      s = ppc64_elf_tdata (ibfd)->relgot;
6054130561Sobrien      if (s != NULL)
6055130561Sobrien	{
6056130561Sobrien	  s->_cooked_size = 0;
6057130561Sobrien	  if (s->_raw_size == 0)
6058130561Sobrien	    _bfd_strip_section_from_output (info, s);
6059130561Sobrien	  else
6060130561Sobrien	    {
6061130561Sobrien	      s->contents = bfd_zalloc (ibfd, s->_raw_size);
6062130561Sobrien	      if (s->contents == NULL)
6063130561Sobrien		return FALSE;
6064130561Sobrien	      relocs = TRUE;
6065130561Sobrien	      s->reloc_count = 0;
6066130561Sobrien	    }
6067130561Sobrien	}
6068130561Sobrien    }
6069130561Sobrien
607089857Sobrien  if (htab->elf.dynamic_sections_created)
607189857Sobrien    {
607289857Sobrien      /* Add some entries to the .dynamic section.  We fill in the
607389857Sobrien	 values later, in ppc64_elf_finish_dynamic_sections, but we
607489857Sobrien	 must add the entries now so that we get the correct size for
607589857Sobrien	 the .dynamic section.  The DT_DEBUG entry is filled in by the
607689857Sobrien	 dynamic linker and used by the debugger.  */
607789857Sobrien#define add_dynamic_entry(TAG, VAL) \
6078130561Sobrien  _bfd_elf_add_dynamic_entry (info, TAG, VAL)
607989857Sobrien
6080130561Sobrien      if (info->executable)
608189857Sobrien	{
608289857Sobrien	  if (!add_dynamic_entry (DT_DEBUG, 0))
6083130561Sobrien	    return FALSE;
608489857Sobrien	}
608589857Sobrien
6086130561Sobrien      if (htab->plt != NULL && htab->plt->_raw_size != 0)
608789857Sobrien	{
608889857Sobrien	  if (!add_dynamic_entry (DT_PLTGOT, 0)
608989857Sobrien	      || !add_dynamic_entry (DT_PLTRELSZ, 0)
609089857Sobrien	      || !add_dynamic_entry (DT_PLTREL, DT_RELA)
609189857Sobrien	      || !add_dynamic_entry (DT_JMPREL, 0)
609289857Sobrien	      || !add_dynamic_entry (DT_PPC64_GLINK, 0))
6093130561Sobrien	    return FALSE;
609489857Sobrien	}
609589857Sobrien
609691041Sobrien      if (NO_OPD_RELOCS)
609791041Sobrien	{
609891041Sobrien	  if (!add_dynamic_entry (DT_PPC64_OPD, 0)
609991041Sobrien	      || !add_dynamic_entry (DT_PPC64_OPDSZ, 0))
6100130561Sobrien	    return FALSE;
610191041Sobrien	}
610291041Sobrien
610389857Sobrien      if (relocs)
610489857Sobrien	{
610589857Sobrien	  if (!add_dynamic_entry (DT_RELA, 0)
610689857Sobrien	      || !add_dynamic_entry (DT_RELASZ, 0)
610789857Sobrien	      || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
6108130561Sobrien	    return FALSE;
610989857Sobrien
611089857Sobrien	  /* If any dynamic relocs apply to a read-only section,
611189857Sobrien	     then we need a DT_TEXTREL entry.  */
611291041Sobrien	  if ((info->flags & DF_TEXTREL) == 0)
6113130561Sobrien	    elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info);
611489857Sobrien
611589857Sobrien	  if ((info->flags & DF_TEXTREL) != 0)
611689857Sobrien	    {
611789857Sobrien	      if (!add_dynamic_entry (DT_TEXTREL, 0))
6118130561Sobrien		return FALSE;
611989857Sobrien	    }
612089857Sobrien	}
612189857Sobrien    }
612289857Sobrien#undef add_dynamic_entry
612389857Sobrien
6124130561Sobrien  return TRUE;
612589857Sobrien}
612689857Sobrien
6127104834Sobrien/* Determine the type of stub needed, if any, for a call.  */
612889857Sobrien
6129130561Sobrienstatic inline enum ppc_stub_type
6130130561Sobrienppc_type_of_stub (asection *input_sec,
6131130561Sobrien		  const Elf_Internal_Rela *rel,
6132130561Sobrien		  struct ppc_link_hash_entry **hash,
6133130561Sobrien		  bfd_vma destination)
613489857Sobrien{
6135104834Sobrien  struct ppc_link_hash_entry *h = *hash;
6136104834Sobrien  bfd_vma location;
6137104834Sobrien  bfd_vma branch_offset;
6138104834Sobrien  bfd_vma max_branch_offset;
6139130561Sobrien  enum elf_ppc64_reloc_type r_type;
614099461Sobrien
6141104834Sobrien  if (h != NULL)
614289857Sobrien    {
6143104834Sobrien      if (h->oh != NULL
6144104834Sobrien	  && h->oh->dynindx != -1)
6145104834Sobrien	{
6146130561Sobrien	  struct plt_entry *ent;
6147130561Sobrien	  for (ent = h->oh->plt.plist; ent != NULL; ent = ent->next)
6148130561Sobrien	    if (ent->addend == rel->r_addend
6149130561Sobrien		&& ent->plt.offset != (bfd_vma) -1)
6150130561Sobrien	      {
6151130561Sobrien		*hash = (struct ppc_link_hash_entry *) h->oh;
6152130561Sobrien		return ppc_stub_plt_call;
6153130561Sobrien	      }
6154104834Sobrien	}
615589857Sobrien
6156130561Sobrien      if (!(h->elf.root.type == bfd_link_hash_defined
6157130561Sobrien	    || h->elf.root.type == bfd_link_hash_defweak)
6158130561Sobrien	  || h->elf.root.u.def.section->output_section == NULL)
6159104834Sobrien	return ppc_stub_none;
616099461Sobrien    }
616189857Sobrien
6162104834Sobrien  /* Determine where the call point is.  */
6163104834Sobrien  location = (input_sec->output_offset
6164104834Sobrien	      + input_sec->output_section->vma
6165104834Sobrien	      + rel->r_offset);
616689857Sobrien
6167104834Sobrien  branch_offset = destination - location;
6168104834Sobrien  r_type = ELF64_R_TYPE (rel->r_info);
616989857Sobrien
6170104834Sobrien  /* Determine if a long branch stub is needed.  */
6171104834Sobrien  max_branch_offset = 1 << 25;
6172130561Sobrien  if (r_type != R_PPC64_REL24)
6173104834Sobrien    max_branch_offset = 1 << 15;
617489857Sobrien
6175104834Sobrien  if (branch_offset + max_branch_offset >= 2 * max_branch_offset)
6176104834Sobrien    /* We need a stub.  Figure out whether a long_branch or plt_branch
6177104834Sobrien       is needed later.  */
6178104834Sobrien    return ppc_stub_long_branch;
617989857Sobrien
6180104834Sobrien  return ppc_stub_none;
618189857Sobrien}
618289857Sobrien
618389857Sobrien/* Build a .plt call stub.  */
618489857Sobrien
6185130561Sobrienstatic inline bfd_byte *
6186130561Sobrienbuild_plt_stub (bfd *obfd, bfd_byte *p, int offset)
618789857Sobrien{
618889857Sobrien#define PPC_LO(v) ((v) & 0xffff)
618989857Sobrien#define PPC_HI(v) (((v) >> 16) & 0xffff)
619089857Sobrien#define PPC_HA(v) PPC_HI ((v) + 0x8000)
619189857Sobrien
619289857Sobrien  bfd_put_32 (obfd, ADDIS_R12_R2 | PPC_HA (offset), p),	p += 4;
6193130561Sobrien  bfd_put_32 (obfd, STD_R2_40R1, p),			p += 4;
619489857Sobrien  bfd_put_32 (obfd, LD_R11_0R12 | PPC_LO (offset), p),	p += 4;
619589857Sobrien  if (PPC_HA (offset + 8) != PPC_HA (offset))
6196130561Sobrien    bfd_put_32 (obfd, ADDIS_R12_R12 | 1, p),		p += 4;
619789857Sobrien  offset += 8;
619889857Sobrien  bfd_put_32 (obfd, LD_R2_0R12 | PPC_LO (offset), p),	p += 4;
619989857Sobrien  if (PPC_HA (offset + 8) != PPC_HA (offset))
6200130561Sobrien    bfd_put_32 (obfd, ADDIS_R12_R12 | 1, p),		p += 4;
620189857Sobrien  offset += 8;
620289857Sobrien  bfd_put_32 (obfd, MTCTR_R11, p),			p += 4;
620389857Sobrien  bfd_put_32 (obfd, LD_R11_0R12 | PPC_LO (offset), p),	p += 4;
620489857Sobrien  bfd_put_32 (obfd, BCTR, p),				p += 4;
620589857Sobrien  return p;
620689857Sobrien}
620789857Sobrien
6208130561Sobrienstatic bfd_boolean
6209130561Sobrienppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
621089857Sobrien{
6211104834Sobrien  struct ppc_stub_hash_entry *stub_entry;
6212104834Sobrien  struct ppc_branch_hash_entry *br_entry;
621389857Sobrien  struct bfd_link_info *info;
621489857Sobrien  struct ppc_link_hash_table *htab;
6215104834Sobrien  bfd_byte *loc;
6216104834Sobrien  bfd_byte *p;
6217104834Sobrien  unsigned int indx;
6218130561Sobrien  struct plt_entry *ent;
6219104834Sobrien  bfd_vma off;
6220104834Sobrien  int size;
622189857Sobrien
6222104834Sobrien  /* Massage our args to the form they really have.  */
6223104834Sobrien  stub_entry = (struct ppc_stub_hash_entry *) gen_entry;
6224130561Sobrien  info = in_arg;
622589857Sobrien
622689857Sobrien  htab = ppc_hash_table (info);
622789857Sobrien
6228104834Sobrien  /* Make a note of the offset within the stubs for this entry.  */
6229130561Sobrien  stub_entry->stub_offset = stub_entry->stub_sec->_cooked_size;
6230130561Sobrien  loc = stub_entry->stub_sec->contents + stub_entry->stub_offset;
6231104834Sobrien
6232130561Sobrien  htab->stub_count[stub_entry->stub_type - 1] += 1;
6233104834Sobrien  switch (stub_entry->stub_type)
623489857Sobrien    {
6235104834Sobrien    case ppc_stub_long_branch:
6236130561Sobrien    case ppc_stub_long_branch_r2off:
6237104834Sobrien      /* Branches are relative.  This is where we are going to.  */
6238104834Sobrien      off = (stub_entry->target_value
6239104834Sobrien	     + stub_entry->target_section->output_offset
6240104834Sobrien	     + stub_entry->target_section->output_section->vma);
624189857Sobrien
6242104834Sobrien      /* And this is where we are coming from.  */
6243104834Sobrien      off -= (stub_entry->stub_offset
6244130561Sobrien	      + stub_entry->stub_sec->output_offset
6245130561Sobrien	      + stub_entry->stub_sec->output_section->vma);
624689857Sobrien
6247130561Sobrien      if (stub_entry->stub_type != ppc_stub_long_branch_r2off)
6248130561Sobrien	size = 4;
6249130561Sobrien      else
6250130561Sobrien	{
6251130561Sobrien	  bfd_vma r2off;
6252130561Sobrien
6253130561Sobrien	  r2off = (htab->stub_group[stub_entry->target_section->id].toc_off
6254130561Sobrien		   - htab->stub_group[stub_entry->id_sec->id].toc_off);
6255130561Sobrien	  bfd_put_32 (htab->stub_bfd, STD_R2_40R1, loc);
6256130561Sobrien	  loc += 4;
6257130561Sobrien	  bfd_put_32 (htab->stub_bfd, ADDIS_R2_R2 | PPC_HA (r2off), loc);
6258130561Sobrien	  loc += 4;
6259130561Sobrien	  bfd_put_32 (htab->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
6260130561Sobrien	  loc += 4;
6261130561Sobrien	  off -= 12;
6262130561Sobrien	  size = 16;
6263130561Sobrien	}
6264130561Sobrien      bfd_put_32 (htab->stub_bfd, B_DOT | (off & 0x3fffffc), loc);
6265130561Sobrien
6266104834Sobrien      BFD_ASSERT (off + (1 << 25) < (bfd_vma) (1 << 26));
6267104834Sobrien      break;
626889857Sobrien
6269104834Sobrien    case ppc_stub_plt_branch:
6270130561Sobrien    case ppc_stub_plt_branch_r2off:
6271104834Sobrien      br_entry = ppc_branch_hash_lookup (&htab->branch_hash_table,
6272104834Sobrien					 stub_entry->root.string + 9,
6273130561Sobrien					 FALSE, FALSE);
6274104834Sobrien      if (br_entry == NULL)
6275104834Sobrien	{
6276104834Sobrien	  (*_bfd_error_handler) (_("can't find branch stub `%s'"),
6277104834Sobrien				 stub_entry->root.string + 9);
6278130561Sobrien	  htab->stub_error = TRUE;
6279130561Sobrien	  return FALSE;
6280104834Sobrien	}
628189857Sobrien
6282104834Sobrien      off = (stub_entry->target_value
6283104834Sobrien	     + stub_entry->target_section->output_offset
6284104834Sobrien	     + stub_entry->target_section->output_section->vma);
6285104834Sobrien
6286130561Sobrien      bfd_put_64 (htab->brlt->owner, off,
6287130561Sobrien		  htab->brlt->contents + br_entry->offset);
6288104834Sobrien
6289104834Sobrien      if (info->shared)
629089857Sobrien	{
6291104834Sobrien	  /* Create a reloc for the branch lookup table entry.  */
6292104834Sobrien	  Elf_Internal_Rela rela;
6293130561Sobrien	  bfd_byte *rl;
6294104834Sobrien
6295104834Sobrien	  rela.r_offset = (br_entry->offset
6296130561Sobrien			   + htab->brlt->output_offset
6297130561Sobrien			   + htab->brlt->output_section->vma);
6298104834Sobrien	  rela.r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE);
6299104834Sobrien	  rela.r_addend = off;
6300104834Sobrien
6301130561Sobrien	  rl = htab->relbrlt->contents;
6302130561Sobrien	  rl += htab->relbrlt->reloc_count++ * sizeof (Elf64_External_Rela);
6303130561Sobrien	  bfd_elf64_swap_reloca_out (htab->relbrlt->owner, &rela, rl);
6304104834Sobrien	}
6305104834Sobrien
6306104834Sobrien      off = (br_entry->offset
6307130561Sobrien	     + htab->brlt->output_offset
6308130561Sobrien	     + htab->brlt->output_section->vma
6309130561Sobrien	     - elf_gp (htab->brlt->output_section->owner)
6310130561Sobrien	     - htab->stub_group[stub_entry->id_sec->id].toc_off);
6311104834Sobrien
6312130561Sobrien      if (off + 0x80008000 > 0xffffffff || (off & 7) != 0)
6313104834Sobrien	{
631489857Sobrien	  (*_bfd_error_handler)
631589857Sobrien	    (_("linkage table error against `%s'"),
6316104834Sobrien	     stub_entry->root.string);
631789857Sobrien	  bfd_set_error (bfd_error_bad_value);
6318130561Sobrien	  htab->stub_error = TRUE;
6319130561Sobrien	  return FALSE;
632089857Sobrien	}
632189857Sobrien
6322104834Sobrien      indx = off;
6323130561Sobrien      if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
6324130561Sobrien	{
6325130561Sobrien	  bfd_put_32 (htab->stub_bfd, ADDIS_R12_R2 | PPC_HA (indx), loc);
6326130561Sobrien	  loc += 4;
6327130561Sobrien	  bfd_put_32 (htab->stub_bfd, LD_R11_0R12 | PPC_LO (indx), loc);
6328130561Sobrien	  size = 16;
6329130561Sobrien	}
6330130561Sobrien      else
6331130561Sobrien	{
6332130561Sobrien	  bfd_vma r2off;
6333130561Sobrien
6334130561Sobrien	  r2off = (htab->stub_group[stub_entry->target_section->id].toc_off
6335130561Sobrien		   - htab->stub_group[stub_entry->id_sec->id].toc_off);
6336130561Sobrien	  bfd_put_32 (htab->stub_bfd, STD_R2_40R1, loc);
6337130561Sobrien	  loc += 4;
6338130561Sobrien	  bfd_put_32 (htab->stub_bfd, ADDIS_R12_R2 | PPC_HA (indx), loc);
6339130561Sobrien	  loc += 4;
6340130561Sobrien	  bfd_put_32 (htab->stub_bfd, LD_R11_0R12 | PPC_LO (indx), loc);
6341130561Sobrien	  loc += 4;
6342130561Sobrien	  bfd_put_32 (htab->stub_bfd, ADDIS_R2_R2 | PPC_HA (r2off), loc);
6343130561Sobrien	  loc += 4;
6344130561Sobrien	  bfd_put_32 (htab->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
6345130561Sobrien	  size = 28;
6346130561Sobrien	}
6347130561Sobrien      loc += 4;
6348130561Sobrien      bfd_put_32 (htab->stub_bfd, MTCTR_R11, loc);
6349130561Sobrien      loc += 4;
6350130561Sobrien      bfd_put_32 (htab->stub_bfd, BCTR, loc);
6351104834Sobrien      break;
635289857Sobrien
6353104834Sobrien    case ppc_stub_plt_call:
6354104834Sobrien      /* Do the best we can for shared libraries built without
6355104834Sobrien	 exporting ".foo" for each "foo".  This can happen when symbol
6356104834Sobrien	 versioning scripts strip all bar a subset of symbols.  */
6357104834Sobrien      if (stub_entry->h->oh->root.type != bfd_link_hash_defined
6358104834Sobrien	  && stub_entry->h->oh->root.type != bfd_link_hash_defweak)
635989857Sobrien	{
6360104834Sobrien	  /* Point the symbol at the stub.  There may be multiple stubs,
6361104834Sobrien	     we don't really care;  The main thing is to make this sym
6362130561Sobrien	     defined somewhere.  Maybe defining the symbol in the stub
6363130561Sobrien	     section is a silly idea.  If we didn't do this, htab->top_id
6364130561Sobrien	     could disappear.  */
6365104834Sobrien	  stub_entry->h->oh->root.type = bfd_link_hash_defined;
6366104834Sobrien	  stub_entry->h->oh->root.u.def.section = stub_entry->stub_sec;
6367104834Sobrien	  stub_entry->h->oh->root.u.def.value = stub_entry->stub_offset;
636889857Sobrien	}
6369104834Sobrien
6370104834Sobrien      /* Now build the stub.  */
6371130561Sobrien      off = (bfd_vma) -1;
6372130561Sobrien      for (ent = stub_entry->h->elf.plt.plist; ent != NULL; ent = ent->next)
6373130561Sobrien	if (ent->addend == stub_entry->addend)
6374130561Sobrien	  {
6375130561Sobrien	    off = ent->plt.offset;
6376130561Sobrien	    break;
6377130561Sobrien	  }
6378104834Sobrien      if (off >= (bfd_vma) -2)
6379104834Sobrien	abort ();
6380104834Sobrien
6381104834Sobrien      off &= ~ (bfd_vma) 1;
6382130561Sobrien      off += (htab->plt->output_offset
6383130561Sobrien	      + htab->plt->output_section->vma
6384130561Sobrien	      - elf_gp (htab->plt->output_section->owner)
6385130561Sobrien	      - htab->stub_group[stub_entry->id_sec->id].toc_off);
6386104834Sobrien
6387130561Sobrien      if (off + 0x80008000 > 0xffffffff || (off & 7) != 0)
638889857Sobrien	{
6389104834Sobrien	  (*_bfd_error_handler)
6390104834Sobrien	    (_("linkage table error against `%s'"),
6391104834Sobrien	     stub_entry->h->elf.root.root.string);
6392104834Sobrien	  bfd_set_error (bfd_error_bad_value);
6393130561Sobrien	  htab->stub_error = TRUE;
6394130561Sobrien	  return FALSE;
639589857Sobrien	}
6396104834Sobrien
6397130561Sobrien      p = build_plt_stub (htab->stub_bfd, loc, off);
6398104834Sobrien      size = p - loc;
6399104834Sobrien      break;
6400104834Sobrien
6401104834Sobrien    default:
6402104834Sobrien      BFD_FAIL ();
6403130561Sobrien      return FALSE;
640489857Sobrien    }
6405104834Sobrien
6406130561Sobrien  stub_entry->stub_sec->_cooked_size += size;
6407130561Sobrien
6408130561Sobrien  if (htab->emit_stub_syms
6409130561Sobrien      && !(stub_entry->stub_type == ppc_stub_plt_call
6410130561Sobrien	   && stub_entry->h->oh->root.type == bfd_link_hash_defined
6411130561Sobrien	   && stub_entry->h->oh->root.u.def.section == stub_entry->stub_sec
6412130561Sobrien	   && stub_entry->h->oh->root.u.def.value == stub_entry->stub_offset))
6413130561Sobrien    {
6414130561Sobrien      struct elf_link_hash_entry *h;
6415130561Sobrien      h = elf_link_hash_lookup (&htab->elf, stub_entry->root.string,
6416130561Sobrien				TRUE, FALSE, FALSE);
6417130561Sobrien      if (h == NULL)
6418130561Sobrien	return FALSE;
6419130561Sobrien      if (h->root.type == bfd_link_hash_new)
6420130561Sobrien	{
6421130561Sobrien	  h->root.type = bfd_link_hash_defined;
6422130561Sobrien	  h->root.u.def.section = stub_entry->stub_sec;
6423130561Sobrien	  h->root.u.def.value = stub_entry->stub_offset;
6424130561Sobrien	  h->elf_link_hash_flags = (ELF_LINK_HASH_REF_REGULAR
6425130561Sobrien				    | ELF_LINK_HASH_DEF_REGULAR
6426130561Sobrien				    | ELF_LINK_HASH_REF_REGULAR_NONWEAK
6427130561Sobrien				    | ELF_LINK_FORCED_LOCAL);
6428130561Sobrien	}
6429130561Sobrien    }
6430130561Sobrien
6431130561Sobrien  return TRUE;
643289857Sobrien}
643389857Sobrien
6434104834Sobrien/* As above, but don't actually build the stub.  Just bump offset so
6435104834Sobrien   we know stub section sizes, and select plt_branch stubs where
6436104834Sobrien   long_branch stubs won't do.  */
6437104834Sobrien
6438130561Sobrienstatic bfd_boolean
6439130561Sobrienppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
6440104834Sobrien{
6441104834Sobrien  struct ppc_stub_hash_entry *stub_entry;
6442130561Sobrien  struct bfd_link_info *info;
6443104834Sobrien  struct ppc_link_hash_table *htab;
6444104834Sobrien  bfd_vma off;
6445104834Sobrien  int size;
6446104834Sobrien
6447104834Sobrien  /* Massage our args to the form they really have.  */
6448104834Sobrien  stub_entry = (struct ppc_stub_hash_entry *) gen_entry;
6449130561Sobrien  info = in_arg;
6450104834Sobrien
6451130561Sobrien  htab = ppc_hash_table (info);
6452130561Sobrien
6453104834Sobrien  if (stub_entry->stub_type == ppc_stub_plt_call)
6454104834Sobrien    {
6455130561Sobrien      struct plt_entry *ent;
6456130561Sobrien      off = (bfd_vma) -1;
6457130561Sobrien      for (ent = stub_entry->h->elf.plt.plist; ent != NULL; ent = ent->next)
6458130561Sobrien	if (ent->addend == stub_entry->addend)
6459130561Sobrien	  {
6460130561Sobrien	    off = ent->plt.offset & ~(bfd_vma) 1;
6461130561Sobrien	    break;
6462130561Sobrien	  }
6463130561Sobrien      if (off >= (bfd_vma) -2)
6464130561Sobrien	abort ();
6465130561Sobrien      off += (htab->plt->output_offset
6466130561Sobrien	      + htab->plt->output_section->vma
6467130561Sobrien	      - elf_gp (htab->plt->output_section->owner)
6468130561Sobrien	      - htab->stub_group[stub_entry->id_sec->id].toc_off);
6469104834Sobrien
6470130561Sobrien      size = PLT_CALL_STUB_SIZE;
6471130561Sobrien      if (PPC_HA (off + 16) != PPC_HA (off))
6472104834Sobrien	size += 4;
6473104834Sobrien    }
6474104834Sobrien  else
6475104834Sobrien    {
6476130561Sobrien      /* ppc_stub_long_branch or ppc_stub_plt_branch, or their r2off
6477130561Sobrien	 variants.  */
6478104834Sobrien      off = (stub_entry->target_value
6479104834Sobrien	     + stub_entry->target_section->output_offset
6480104834Sobrien	     + stub_entry->target_section->output_section->vma);
6481104834Sobrien      off -= (stub_entry->stub_sec->_raw_size
6482104834Sobrien	      + stub_entry->stub_sec->output_offset
6483104834Sobrien	      + stub_entry->stub_sec->output_section->vma);
6484104834Sobrien
6485130561Sobrien      /* Reset the stub type from the plt variant in case we now
6486130561Sobrien	 can reach with a shorter stub.  */
6487130561Sobrien      if (stub_entry->stub_type >= ppc_stub_plt_branch)
6488130561Sobrien	stub_entry->stub_type += ppc_stub_long_branch - ppc_stub_plt_branch;
6489130561Sobrien
6490130561Sobrien      size = 4;
6491130561Sobrien      if (stub_entry->stub_type == ppc_stub_long_branch_r2off)
6492130561Sobrien	{
6493130561Sobrien	  off -= 12;
6494130561Sobrien	  size = 16;
6495130561Sobrien	}
6496130561Sobrien
6497130561Sobrien      /* If the branch offset if too big, use a ppc_stub_plt_branch.  */
6498104834Sobrien      if (off + (1 << 25) >= (bfd_vma) (1 << 26))
6499104834Sobrien	{
6500104834Sobrien	  struct ppc_branch_hash_entry *br_entry;
6501104834Sobrien
6502104834Sobrien	  br_entry = ppc_branch_hash_lookup (&htab->branch_hash_table,
6503104834Sobrien					     stub_entry->root.string + 9,
6504130561Sobrien					     TRUE, FALSE);
6505104834Sobrien	  if (br_entry == NULL)
6506104834Sobrien	    {
6507104834Sobrien	      (*_bfd_error_handler) (_("can't build branch stub `%s'"),
6508104834Sobrien				     stub_entry->root.string + 9);
6509130561Sobrien	      htab->stub_error = TRUE;
6510130561Sobrien	      return FALSE;
6511104834Sobrien	    }
6512104834Sobrien
6513104834Sobrien	  if (br_entry->iter != htab->stub_iteration)
6514104834Sobrien	    {
6515104834Sobrien	      br_entry->iter = htab->stub_iteration;
6516130561Sobrien	      br_entry->offset = htab->brlt->_raw_size;
6517130561Sobrien	      htab->brlt->_raw_size += 8;
6518130561Sobrien
6519130561Sobrien	      if (info->shared)
6520130561Sobrien		htab->relbrlt->_raw_size += sizeof (Elf64_External_Rela);
6521104834Sobrien	    }
6522130561Sobrien
6523130561Sobrien	  stub_entry->stub_type += ppc_stub_plt_branch - ppc_stub_long_branch;
6524104834Sobrien	  size = 16;
6525130561Sobrien	  if (stub_entry->stub_type != ppc_stub_plt_branch)
6526130561Sobrien	    size = 28;
6527104834Sobrien	}
6528104834Sobrien    }
6529104834Sobrien
6530104834Sobrien  stub_entry->stub_sec->_raw_size += size;
6531130561Sobrien  return TRUE;
6532104834Sobrien}
6533104834Sobrien
6534104834Sobrien/* Set up various things so that we can make a list of input sections
6535104834Sobrien   for each output section included in the link.  Returns -1 on error,
6536104834Sobrien   0 when no stubs will be needed, and 1 on success.  */
6537104834Sobrien
6538104834Sobrienint
6539130561Sobrienppc64_elf_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info)
654089857Sobrien{
6541104834Sobrien  bfd *input_bfd;
6542130561Sobrien  int top_id, top_index, id;
6543104834Sobrien  asection *section;
6544130561Sobrien  asection **input_list;
6545104834Sobrien  bfd_size_type amt;
654689857Sobrien  struct ppc_link_hash_table *htab = ppc_hash_table (info);
654789857Sobrien
6548130561Sobrien  if (htab->brlt == NULL)
6549104834Sobrien    return 0;
655089857Sobrien
6551104834Sobrien  /* Find the top input section id.  */
6552130561Sobrien  for (input_bfd = info->input_bfds, top_id = 3;
6553104834Sobrien       input_bfd != NULL;
6554104834Sobrien       input_bfd = input_bfd->link_next)
6555104834Sobrien    {
6556104834Sobrien      for (section = input_bfd->sections;
6557104834Sobrien	   section != NULL;
6558104834Sobrien	   section = section->next)
6559104834Sobrien	{
6560104834Sobrien	  if (top_id < section->id)
6561104834Sobrien	    top_id = section->id;
6562104834Sobrien	}
6563104834Sobrien    }
656489857Sobrien
6565130561Sobrien  htab->top_id = top_id;
6566104834Sobrien  amt = sizeof (struct map_stub) * (top_id + 1);
6567130561Sobrien  htab->stub_group = bfd_zmalloc (amt);
6568104834Sobrien  if (htab->stub_group == NULL)
6569104834Sobrien    return -1;
6570104834Sobrien
6571130561Sobrien  /* Set toc_off for com, und, abs and ind sections.  */
6572130561Sobrien  for (id = 0; id < 3; id++)
6573130561Sobrien    htab->stub_group[id].toc_off = TOC_BASE_OFF;
6574130561Sobrien
6575130561Sobrien  elf_gp (output_bfd) = htab->toc_curr = ppc64_elf_toc (output_bfd);
6576130561Sobrien
6577104834Sobrien  /* We can't use output_bfd->section_count here to find the top output
6578104834Sobrien     section index as some sections may have been removed, and
6579104834Sobrien     _bfd_strip_section_from_output doesn't renumber the indices.  */
6580104834Sobrien  for (section = output_bfd->sections, top_index = 0;
6581104834Sobrien       section != NULL;
6582104834Sobrien       section = section->next)
658389857Sobrien    {
6584104834Sobrien      if (top_index < section->index)
6585104834Sobrien	top_index = section->index;
658689857Sobrien    }
658789857Sobrien
6588104834Sobrien  htab->top_index = top_index;
6589104834Sobrien  amt = sizeof (asection *) * (top_index + 1);
6590130561Sobrien  input_list = bfd_zmalloc (amt);
6591104834Sobrien  htab->input_list = input_list;
6592104834Sobrien  if (input_list == NULL)
6593104834Sobrien    return -1;
659489857Sobrien
6595130561Sobrien  return 1;
6596130561Sobrien}
659789857Sobrien
6598130561Sobrien/* The linker repeatedly calls this function for each TOC input section
6599130561Sobrien   and linker generated GOT section.  Group input bfds such that the toc
6600130561Sobrien   within a group is less than 64k in size.  Will break with cute linker
6601130561Sobrien   scripts that play games with dot in the output toc section.  */
6602130561Sobrien
6603130561Sobrienvoid
6604130561Sobrienppc64_elf_next_toc_section (struct bfd_link_info *info, asection *isec)
6605130561Sobrien{
6606130561Sobrien  struct ppc_link_hash_table *htab = ppc_hash_table (info);
6607130561Sobrien
6608130561Sobrien  if (!htab->no_multi_toc)
6609104834Sobrien    {
6610130561Sobrien      bfd_vma addr = isec->output_offset + isec->output_section->vma;
6611130561Sobrien      bfd_vma off = addr - htab->toc_curr;
6612130561Sobrien      if (off + isec->_raw_size > 0x10000)
6613130561Sobrien	{
6614130561Sobrien	  htab->toc_curr = addr;
6615130561Sobrien	  htab->multi_toc_needed = 1;
6616130561Sobrien	}
6617130561Sobrien      elf_gp (isec->owner) = (htab->toc_curr
6618130561Sobrien			      - elf_gp (isec->output_section->owner)
6619130561Sobrien			      + TOC_BASE_OFF);
6620104834Sobrien    }
6621130561Sobrien}
662289857Sobrien
6623130561Sobrien/* Called after the last call to the above function.  */
6624130561Sobrien
6625130561Sobrienvoid
6626130561Sobrienppc64_elf_reinit_toc (bfd *output_bfd ATTRIBUTE_UNUSED,
6627130561Sobrien		      struct bfd_link_info *info)
6628130561Sobrien{
6629130561Sobrien  struct ppc_link_hash_table *htab = ppc_hash_table (info);
6630130561Sobrien
6631130561Sobrien  /* toc_curr tracks the TOC offset used for code sections below in
6632130561Sobrien     ppc64_elf_next_input_section.  Start off at 0x8000.  */
6633130561Sobrien  htab->toc_curr = TOC_BASE_OFF;
6634104834Sobrien}
6635104834Sobrien
6636130561Sobrien/* No toc references were found in ISEC.  If the code in ISEC makes no
6637130561Sobrien   calls, then there's no need to use toc adjusting stubs when branching
6638130561Sobrien   into ISEC.  Actually, indirect calls from ISEC are OK as they will
6639130561Sobrien   load r2.  */
6640130561Sobrien
6641130561Sobrienstatic int
6642130561Sobrientoc_adjusting_stub_needed (struct bfd_link_info *info, asection *isec)
6643130561Sobrien{
6644130561Sobrien  bfd_byte *contents;
6645130561Sobrien  bfd_size_type i;
6646130561Sobrien  int ret;
6647130561Sobrien  int branch_ok;
6648130561Sobrien
6649130561Sobrien  /* We know none of our code bearing sections will need toc stubs.  */
6650130561Sobrien  if ((isec->flags & SEC_LINKER_CREATED) != 0)
6651130561Sobrien    return 0;
6652130561Sobrien
6653130561Sobrien  if (isec->_raw_size == 0)
6654130561Sobrien    return 0;
6655130561Sobrien
6656130561Sobrien  /* Hack for linux kernel.  .fixup contains branches, but only back to
6657130561Sobrien     the function that hit an exception.  */
6658130561Sobrien  branch_ok = strcmp (isec->name, ".fixup") == 0;
6659130561Sobrien
6660130561Sobrien  contents = elf_section_data (isec)->this_hdr.contents;
6661130561Sobrien  if (contents == NULL)
6662130561Sobrien    {
6663130561Sobrien      contents = bfd_malloc (isec->_raw_size);
6664130561Sobrien      if (contents == NULL)
6665130561Sobrien	return -1;
6666130561Sobrien      if (! bfd_get_section_contents (isec->owner, isec, contents,
6667130561Sobrien				      0, isec->_raw_size))
6668130561Sobrien	{
6669130561Sobrien	  free (contents);
6670130561Sobrien	  return -1;
6671130561Sobrien	}
6672130561Sobrien      if (info->keep_memory)
6673130561Sobrien	elf_section_data (isec)->this_hdr.contents = contents;
6674130561Sobrien    }
6675130561Sobrien
6676130561Sobrien  /* Code scan, because we don't necessarily have relocs on calls to
6677130561Sobrien     static functions.  */
6678130561Sobrien  ret = 0;
6679130561Sobrien  for (i = 0; i < isec->_raw_size; i += 4)
6680130561Sobrien    {
6681130561Sobrien      unsigned long insn = bfd_get_32 (isec->owner, contents + i);
6682130561Sobrien      /* Is this a branch?  */
6683130561Sobrien      if ((insn & (0x3f << 26)) == (18 << 26)
6684130561Sobrien	  /* If branch and link, it's a function call.  */
6685130561Sobrien	  && ((insn & 1) != 0
6686130561Sobrien	      /* Sibling calls use a plain branch.  I don't know a way
6687130561Sobrien		 of deciding whether a branch is really a sibling call.  */
6688130561Sobrien	      || !branch_ok))
6689130561Sobrien	{
6690130561Sobrien	  ret = 1;
6691130561Sobrien	  break;
6692130561Sobrien	}
6693130561Sobrien    }
6694130561Sobrien
6695130561Sobrien  if (elf_section_data (isec)->this_hdr.contents != contents)
6696130561Sobrien    free (contents);
6697130561Sobrien  return ret;
6698130561Sobrien}
6699130561Sobrien
6700104834Sobrien/* The linker repeatedly calls this function for each input section,
6701104834Sobrien   in the order that input sections are linked into output sections.
6702104834Sobrien   Build lists of input sections to determine groupings between which
6703104834Sobrien   we may insert linker stubs.  */
6704104834Sobrien
6705130561Sobrienbfd_boolean
6706130561Sobrienppc64_elf_next_input_section (struct bfd_link_info *info, asection *isec)
6707104834Sobrien{
6708104834Sobrien  struct ppc_link_hash_table *htab = ppc_hash_table (info);
6709130561Sobrien  int ret;
6710104834Sobrien
6711130561Sobrien  if ((isec->output_section->flags & SEC_CODE) != 0
6712130561Sobrien      && isec->output_section->index <= htab->top_index)
671389857Sobrien    {
6714104834Sobrien      asection **list = htab->input_list + isec->output_section->index;
6715130561Sobrien      /* Steal the link_sec pointer for our list.  */
6716104834Sobrien#define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
6717130561Sobrien      /* This happens to make the list in reverse order,
6718130561Sobrien	 which is what we want.  */
6719130561Sobrien      PREV_SEC (isec) = *list;
6720130561Sobrien      *list = isec;
672189857Sobrien    }
6722130561Sobrien
6723130561Sobrien  /* If a code section has a function that uses the TOC then we need
6724130561Sobrien     to use the right TOC (obviously).  Also, make sure that .opd gets
6725130561Sobrien     the correct TOC value for R_PPC64_TOC relocs that don't have or
6726130561Sobrien     can't find their function symbol (shouldn't ever happen now).  */
6727130561Sobrien  if (isec->has_gp_reloc || (isec->flags & SEC_CODE) == 0)
6728130561Sobrien    {
6729130561Sobrien      if (elf_gp (isec->owner) != 0)
6730130561Sobrien	htab->toc_curr = elf_gp (isec->owner);
6731130561Sobrien    }
6732130561Sobrien  else if ((ret = toc_adjusting_stub_needed (info, isec)) < 0)
6733130561Sobrien    return FALSE;
6734130561Sobrien  else
6735130561Sobrien    isec->has_gp_reloc = ret;
6736130561Sobrien
6737130561Sobrien  /* Functions that don't use the TOC can belong in any TOC group.
6738130561Sobrien     Use the last TOC base.  This happens to make _init and _fini
6739130561Sobrien     pasting work.  */
6740130561Sobrien  htab->stub_group[isec->id].toc_off = htab->toc_curr;
6741130561Sobrien  return TRUE;
674289857Sobrien}
674389857Sobrien
6744104834Sobrien/* See whether we can group stub sections together.  Grouping stub
6745104834Sobrien   sections may result in fewer stubs.  More importantly, we need to
6746104834Sobrien   put all .init* and .fini* stubs at the beginning of the .init or
6747104834Sobrien   .fini output sections respectively, because glibc splits the
6748104834Sobrien   _init and _fini functions into multiple parts.  Putting a stub in
6749104834Sobrien   the middle of a function is not a good idea.  */
675089857Sobrien
6751104834Sobrienstatic void
6752130561Sobriengroup_sections (struct ppc_link_hash_table *htab,
6753130561Sobrien		bfd_size_type stub_group_size,
6754130561Sobrien		bfd_boolean stubs_always_before_branch)
675589857Sobrien{
6756104834Sobrien  asection **list = htab->input_list + htab->top_index;
6757104834Sobrien  do
6758104834Sobrien    {
6759104834Sobrien      asection *tail = *list;
6760104834Sobrien      while (tail != NULL)
6761104834Sobrien	{
6762104834Sobrien	  asection *curr;
6763104834Sobrien	  asection *prev;
6764104834Sobrien	  bfd_size_type total;
6765130561Sobrien	  bfd_boolean big_sec;
6766130561Sobrien	  bfd_vma curr_toc;
676789857Sobrien
6768104834Sobrien	  curr = tail;
6769104834Sobrien	  if (tail->_cooked_size)
6770104834Sobrien	    total = tail->_cooked_size;
6771104834Sobrien	  else
6772104834Sobrien	    total = tail->_raw_size;
6773130561Sobrien	  big_sec = total >= stub_group_size;
6774130561Sobrien	  curr_toc = htab->stub_group[tail->id].toc_off;
6775130561Sobrien
6776104834Sobrien	  while ((prev = PREV_SEC (curr)) != NULL
6777104834Sobrien		 && ((total += curr->output_offset - prev->output_offset)
6778130561Sobrien		     < stub_group_size)
6779130561Sobrien		 && htab->stub_group[prev->id].toc_off == curr_toc)
6780104834Sobrien	    curr = prev;
678189857Sobrien
6782104834Sobrien	  /* OK, the size from the start of CURR to the end is less
6783104834Sobrien	     than stub_group_size and thus can be handled by one stub
6784104834Sobrien	     section.  (or the tail section is itself larger than
6785104834Sobrien	     stub_group_size, in which case we may be toast.)  We
6786104834Sobrien	     should really be keeping track of the total size of stubs
6787104834Sobrien	     added here, as stubs contribute to the final output
6788104834Sobrien	     section size.  That's a little tricky, and this way will
6789104834Sobrien	     only break if stubs added make the total size more than
6790104834Sobrien	     2^25, ie. for the default stub_group_size, if stubs total
6791130561Sobrien	     more than 2097152 bytes, or nearly 75000 plt call stubs.  */
6792104834Sobrien	  do
6793104834Sobrien	    {
6794104834Sobrien	      prev = PREV_SEC (tail);
6795104834Sobrien	      /* Set up this stub group.  */
6796104834Sobrien	      htab->stub_group[tail->id].link_sec = curr;
6797104834Sobrien	    }
6798104834Sobrien	  while (tail != curr && (tail = prev) != NULL);
6799104834Sobrien
6800104834Sobrien	  /* But wait, there's more!  Input sections up to stub_group_size
6801130561Sobrien	     bytes before the stub section can be handled by it too.
6802130561Sobrien	     Don't do this if we have a really large section after the
6803130561Sobrien	     stubs, as adding more stubs increases the chance that
6804130561Sobrien	     branches may not reach into the stub section.  */
6805130561Sobrien	  if (!stubs_always_before_branch && !big_sec)
6806104834Sobrien	    {
6807104834Sobrien	      total = 0;
6808104834Sobrien	      while (prev != NULL
6809104834Sobrien		     && ((total += tail->output_offset - prev->output_offset)
6810130561Sobrien			 < stub_group_size)
6811130561Sobrien		     && htab->stub_group[prev->id].toc_off == curr_toc)
6812104834Sobrien		{
6813104834Sobrien		  tail = prev;
6814104834Sobrien		  prev = PREV_SEC (tail);
6815104834Sobrien		  htab->stub_group[tail->id].link_sec = curr;
6816104834Sobrien		}
6817104834Sobrien	    }
6818104834Sobrien	  tail = prev;
6819104834Sobrien	}
6820104834Sobrien    }
6821104834Sobrien  while (list-- != htab->input_list);
6822104834Sobrien  free (htab->input_list);
6823104834Sobrien#undef PREV_SEC
6824104834Sobrien}
6825104834Sobrien
6826104834Sobrien/* Determine and set the size of the stub section for a final link.
6827104834Sobrien
6828104834Sobrien   The basic idea here is to examine all the relocations looking for
6829104834Sobrien   PC-relative calls to a target that is unreachable with a "bl"
6830104834Sobrien   instruction.  */
6831104834Sobrien
6832130561Sobrienbfd_boolean
6833130561Sobrienppc64_elf_size_stubs (bfd *output_bfd,
6834130561Sobrien		      struct bfd_link_info *info,
6835130561Sobrien		      bfd_signed_vma group_size,
6836130561Sobrien		      asection *(*add_stub_section) (const char *, asection *),
6837130561Sobrien		      void (*layout_sections_again) (void))
6838104834Sobrien{
6839104834Sobrien  bfd_size_type stub_group_size;
6840130561Sobrien  bfd_boolean stubs_always_before_branch;
6841104834Sobrien  struct ppc_link_hash_table *htab = ppc_hash_table (info);
6842104834Sobrien
6843104834Sobrien  /* Stash our params away.  */
6844104834Sobrien  htab->add_stub_section = add_stub_section;
6845104834Sobrien  htab->layout_sections_again = layout_sections_again;
6846104834Sobrien  stubs_always_before_branch = group_size < 0;
6847104834Sobrien  if (group_size < 0)
6848104834Sobrien    stub_group_size = -group_size;
6849104834Sobrien  else
6850104834Sobrien    stub_group_size = group_size;
6851104834Sobrien  if (stub_group_size == 1)
6852104834Sobrien    {
6853104834Sobrien      /* Default values.  */
6854130561Sobrien      if (stubs_always_before_branch)
6855130561Sobrien	{
6856130561Sobrien	  stub_group_size = 0x1e00000;
6857130561Sobrien	  if (htab->has_14bit_branch)
6858130561Sobrien	    stub_group_size = 0x7800;
6859130561Sobrien	}
6860130561Sobrien      else
6861130561Sobrien	{
6862130561Sobrien	  stub_group_size = 0x1c00000;
6863130561Sobrien	  if (htab->has_14bit_branch)
6864130561Sobrien	    stub_group_size = 0x7000;
6865130561Sobrien	}
6866104834Sobrien    }
6867104834Sobrien
6868104834Sobrien  group_sections (htab, stub_group_size, stubs_always_before_branch);
6869104834Sobrien
6870104834Sobrien  while (1)
6871104834Sobrien    {
6872104834Sobrien      bfd *input_bfd;
6873104834Sobrien      unsigned int bfd_indx;
6874104834Sobrien      asection *stub_sec;
6875130561Sobrien      bfd_boolean stub_changed;
6876104834Sobrien
6877104834Sobrien      htab->stub_iteration += 1;
6878130561Sobrien      stub_changed = FALSE;
6879104834Sobrien
6880104834Sobrien      for (input_bfd = info->input_bfds, bfd_indx = 0;
6881104834Sobrien	   input_bfd != NULL;
6882104834Sobrien	   input_bfd = input_bfd->link_next, bfd_indx++)
6883104834Sobrien	{
6884104834Sobrien	  Elf_Internal_Shdr *symtab_hdr;
6885104834Sobrien	  asection *section;
6886104834Sobrien	  Elf_Internal_Sym *local_syms = NULL;
6887104834Sobrien
6888104834Sobrien	  /* We'll need the symbol table in a second.  */
6889104834Sobrien	  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
6890104834Sobrien	  if (symtab_hdr->sh_info == 0)
6891104834Sobrien	    continue;
6892104834Sobrien
6893104834Sobrien	  /* Walk over each section attached to the input bfd.  */
6894104834Sobrien	  for (section = input_bfd->sections;
6895104834Sobrien	       section != NULL;
6896104834Sobrien	       section = section->next)
6897104834Sobrien	    {
6898104834Sobrien	      Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
6899104834Sobrien
6900104834Sobrien	      /* If there aren't any relocs, then there's nothing more
6901104834Sobrien		 to do.  */
6902104834Sobrien	      if ((section->flags & SEC_RELOC) == 0
6903104834Sobrien		  || section->reloc_count == 0)
6904104834Sobrien		continue;
6905104834Sobrien
6906104834Sobrien	      /* If this section is a link-once section that will be
6907104834Sobrien		 discarded, then don't create any stubs.  */
6908104834Sobrien	      if (section->output_section == NULL
6909104834Sobrien		  || section->output_section->owner != output_bfd)
6910104834Sobrien		continue;
6911104834Sobrien
6912104834Sobrien	      /* Get the relocs.  */
6913104834Sobrien	      internal_relocs
6914130561Sobrien		= _bfd_elf_link_read_relocs (input_bfd, section, NULL, NULL,
6915130561Sobrien					     info->keep_memory);
6916104834Sobrien	      if (internal_relocs == NULL)
6917104834Sobrien		goto error_ret_free_local;
6918104834Sobrien
6919104834Sobrien	      /* Now examine each relocation.  */
6920104834Sobrien	      irela = internal_relocs;
6921104834Sobrien	      irelaend = irela + section->reloc_count;
6922104834Sobrien	      for (; irela < irelaend; irela++)
6923104834Sobrien		{
6924130561Sobrien		  enum elf_ppc64_reloc_type r_type;
6925130561Sobrien		  unsigned int r_indx;
6926104834Sobrien		  enum ppc_stub_type stub_type;
6927104834Sobrien		  struct ppc_stub_hash_entry *stub_entry;
6928104834Sobrien		  asection *sym_sec;
6929104834Sobrien		  bfd_vma sym_value;
6930104834Sobrien		  bfd_vma destination;
6931104834Sobrien		  struct ppc_link_hash_entry *hash;
6932130561Sobrien		  struct elf_link_hash_entry *h;
6933130561Sobrien		  Elf_Internal_Sym *sym;
6934104834Sobrien		  char *stub_name;
6935104834Sobrien		  const asection *id_sec;
6936104834Sobrien
6937104834Sobrien		  r_type = ELF64_R_TYPE (irela->r_info);
6938104834Sobrien		  r_indx = ELF64_R_SYM (irela->r_info);
6939104834Sobrien
6940130561Sobrien		  if (r_type >= R_PPC64_max)
6941104834Sobrien		    {
6942104834Sobrien		      bfd_set_error (bfd_error_bad_value);
6943104834Sobrien		      goto error_ret_free_internal;
6944104834Sobrien		    }
6945104834Sobrien
6946104834Sobrien		  /* Only look for stubs on branch instructions.  */
6947130561Sobrien		  if (r_type != R_PPC64_REL24
6948130561Sobrien		      && r_type != R_PPC64_REL14
6949130561Sobrien		      && r_type != R_PPC64_REL14_BRTAKEN
6950130561Sobrien		      && r_type != R_PPC64_REL14_BRNTAKEN)
6951104834Sobrien		    continue;
6952104834Sobrien
6953104834Sobrien		  /* Now determine the call target, its name, value,
6954104834Sobrien		     section.  */
6955104834Sobrien		  destination = 0;
6956130561Sobrien		  if (!get_sym_h (&h, &sym, &sym_sec, NULL, &local_syms,
6957130561Sobrien				  r_indx, input_bfd))
6958130561Sobrien		    goto error_ret_free_internal;
6959130561Sobrien		  hash = (struct ppc_link_hash_entry *) h;
6960130561Sobrien
6961130561Sobrien		  if (hash == NULL)
6962104834Sobrien		    {
6963104834Sobrien		      /* It's a local symbol.  */
6964130561Sobrien		      sym_value = sym->st_value;
6965104834Sobrien		      destination = (sym_value + irela->r_addend
6966104834Sobrien				     + sym_sec->output_offset
6967104834Sobrien				     + sym_sec->output_section->vma);
6968104834Sobrien		    }
6969104834Sobrien		  else
6970104834Sobrien		    {
6971104834Sobrien		      /* It's an external symbol.  */
6972130561Sobrien		      sym_value = 0;
6973104834Sobrien		      if (hash->elf.root.type == bfd_link_hash_defined
6974104834Sobrien			  || hash->elf.root.type == bfd_link_hash_defweak)
6975104834Sobrien			{
6976104834Sobrien			  sym_value = hash->elf.root.u.def.value;
6977104834Sobrien			  if (sym_sec->output_section != NULL)
6978104834Sobrien			    destination = (sym_value + irela->r_addend
6979104834Sobrien					   + sym_sec->output_offset
6980104834Sobrien					   + sym_sec->output_section->vma);
6981104834Sobrien			}
6982104834Sobrien		      else if (hash->elf.root.type == bfd_link_hash_undefweak)
6983104834Sobrien			;
6984104834Sobrien		      else if (hash->elf.root.type == bfd_link_hash_undefined)
6985104834Sobrien			;
6986104834Sobrien		      else
6987104834Sobrien			{
6988104834Sobrien			  bfd_set_error (bfd_error_bad_value);
6989104834Sobrien			  goto error_ret_free_internal;
6990104834Sobrien			}
6991104834Sobrien		    }
6992104834Sobrien
6993104834Sobrien		  /* Determine what (if any) linker stub is needed.  */
6994104834Sobrien		  stub_type = ppc_type_of_stub (section, irela, &hash,
6995104834Sobrien						destination);
6996130561Sobrien
6997130561Sobrien		  if (stub_type != ppc_stub_plt_call)
6998130561Sobrien		    {
6999130561Sobrien		      /* Check whether we need a TOC adjusting stub.
7000130561Sobrien			 Since the linker pastes together pieces from
7001130561Sobrien			 different object files when creating the
7002130561Sobrien			 _init and _fini functions, it may be that a
7003130561Sobrien			 call to what looks like a local sym is in
7004130561Sobrien			 fact a call needing a TOC adjustment.  */
7005130561Sobrien		      if (sym_sec != NULL
7006130561Sobrien			  && sym_sec->output_section != NULL
7007130561Sobrien			  && (htab->stub_group[sym_sec->id].toc_off
7008130561Sobrien			      != htab->stub_group[section->id].toc_off)
7009130561Sobrien			  && sym_sec->has_gp_reloc
7010130561Sobrien			  && section->has_gp_reloc)
7011130561Sobrien			stub_type = ppc_stub_long_branch_r2off;
7012130561Sobrien		    }
7013130561Sobrien
7014104834Sobrien		  if (stub_type == ppc_stub_none)
7015104834Sobrien		    continue;
7016104834Sobrien
7017130561Sobrien		  /* __tls_get_addr calls might be eliminated.  */
7018130561Sobrien		  if (stub_type != ppc_stub_plt_call
7019130561Sobrien		      && hash != NULL
7020130561Sobrien		      && &hash->elf == htab->tls_get_addr
7021130561Sobrien		      && section->has_tls_reloc
7022130561Sobrien		      && irela != internal_relocs)
7023130561Sobrien		    {
7024130561Sobrien		      /* Get tls info.  */
7025130561Sobrien		      char *tls_mask;
7026130561Sobrien
7027130561Sobrien		      if (!get_tls_mask (&tls_mask, NULL, &local_syms,
7028130561Sobrien					 irela - 1, input_bfd))
7029130561Sobrien			goto error_ret_free_internal;
7030130561Sobrien		      if (*tls_mask != 0)
7031130561Sobrien			continue;
7032130561Sobrien		    }
7033130561Sobrien
7034104834Sobrien		  /* Support for grouping stub sections.  */
7035104834Sobrien		  id_sec = htab->stub_group[section->id].link_sec;
7036104834Sobrien
7037104834Sobrien		  /* Get the name of this stub.  */
7038104834Sobrien		  stub_name = ppc_stub_name (id_sec, sym_sec, hash, irela);
7039104834Sobrien		  if (!stub_name)
7040104834Sobrien		    goto error_ret_free_internal;
7041104834Sobrien
7042104834Sobrien		  stub_entry = ppc_stub_hash_lookup (&htab->stub_hash_table,
7043130561Sobrien						     stub_name, FALSE, FALSE);
7044104834Sobrien		  if (stub_entry != NULL)
7045104834Sobrien		    {
7046104834Sobrien		      /* The proper stub has already been created.  */
7047104834Sobrien		      free (stub_name);
7048104834Sobrien		      continue;
7049104834Sobrien		    }
7050104834Sobrien
7051104834Sobrien		  stub_entry = ppc_add_stub (stub_name, section, htab);
7052104834Sobrien		  if (stub_entry == NULL)
7053104834Sobrien		    {
7054104834Sobrien		      free (stub_name);
7055104834Sobrien		    error_ret_free_internal:
7056104834Sobrien		      if (elf_section_data (section)->relocs == NULL)
7057104834Sobrien			free (internal_relocs);
7058104834Sobrien		    error_ret_free_local:
7059104834Sobrien		      if (local_syms != NULL
7060104834Sobrien			  && (symtab_hdr->contents
7061104834Sobrien			      != (unsigned char *) local_syms))
7062104834Sobrien			free (local_syms);
7063130561Sobrien		      return FALSE;
7064104834Sobrien		    }
7065104834Sobrien
7066130561Sobrien		  stub_entry->stub_type = stub_type;
7067104834Sobrien		  stub_entry->target_value = sym_value;
7068104834Sobrien		  stub_entry->target_section = sym_sec;
7069104834Sobrien		  stub_entry->h = hash;
7070130561Sobrien		  stub_entry->addend = irela->r_addend;
7071130561Sobrien		  stub_changed = TRUE;
7072104834Sobrien		}
7073104834Sobrien
7074104834Sobrien	      /* We're done with the internal relocs, free them.  */
7075104834Sobrien	      if (elf_section_data (section)->relocs != internal_relocs)
7076104834Sobrien		free (internal_relocs);
7077104834Sobrien	    }
7078104834Sobrien
7079104834Sobrien	  if (local_syms != NULL
7080104834Sobrien	      && symtab_hdr->contents != (unsigned char *) local_syms)
7081104834Sobrien	    {
7082104834Sobrien	      if (!info->keep_memory)
7083104834Sobrien		free (local_syms);
7084104834Sobrien	      else
7085104834Sobrien		symtab_hdr->contents = (unsigned char *) local_syms;
7086104834Sobrien	    }
7087104834Sobrien	}
7088104834Sobrien
7089104834Sobrien      if (!stub_changed)
7090104834Sobrien	break;
7091104834Sobrien
7092104834Sobrien      /* OK, we've added some stubs.  Find out the new size of the
7093104834Sobrien	 stub sections.  */
7094104834Sobrien      for (stub_sec = htab->stub_bfd->sections;
7095104834Sobrien	   stub_sec != NULL;
7096104834Sobrien	   stub_sec = stub_sec->next)
7097130561Sobrien	if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
7098130561Sobrien	  {
7099130561Sobrien	    stub_sec->_raw_size = 0;
7100130561Sobrien	    stub_sec->_cooked_size = 0;
7101130561Sobrien	  }
7102130561Sobrien      htab->brlt->_raw_size = 0;
7103130561Sobrien      htab->brlt->_cooked_size = 0;
7104130561Sobrien      if (info->shared)
7105104834Sobrien	{
7106130561Sobrien	  htab->relbrlt->_raw_size = 0;
7107130561Sobrien	  htab->relbrlt->_cooked_size = 0;
7108104834Sobrien	}
7109104834Sobrien
7110130561Sobrien      bfd_hash_traverse (&htab->stub_hash_table, ppc_size_one_stub, info);
7111104834Sobrien
7112104834Sobrien      /* Ask the linker to do its stuff.  */
7113104834Sobrien      (*htab->layout_sections_again) ();
7114104834Sobrien    }
7115104834Sobrien
7116104834Sobrien  /* It would be nice to strip .branch_lt from the output if the
7117104834Sobrien     section is empty, but it's too late.  If we strip sections here,
7118104834Sobrien     the dynamic symbol table is corrupted since the section symbol
7119104834Sobrien     for the stripped section isn't written.  */
7120104834Sobrien
7121130561Sobrien  return TRUE;
712289857Sobrien}
712389857Sobrien
7124104834Sobrien/* Called after we have determined section placement.  If sections
7125104834Sobrien   move, we'll be called again.  Provide a value for TOCstart.  */
7126104834Sobrien
7127104834Sobrienbfd_vma
7128130561Sobrienppc64_elf_toc (bfd *obfd)
7129104834Sobrien{
7130104834Sobrien  asection *s;
7131104834Sobrien  bfd_vma TOCstart;
7132104834Sobrien
7133104834Sobrien  /* The TOC consists of sections .got, .toc, .tocbss, .plt in that
7134104834Sobrien     order.  The TOC starts where the first of these sections starts.  */
7135104834Sobrien  s = bfd_get_section_by_name (obfd, ".got");
7136104834Sobrien  if (s == NULL)
7137104834Sobrien    s = bfd_get_section_by_name (obfd, ".toc");
7138104834Sobrien  if (s == NULL)
7139104834Sobrien    s = bfd_get_section_by_name (obfd, ".tocbss");
7140104834Sobrien  if (s == NULL)
7141104834Sobrien    s = bfd_get_section_by_name (obfd, ".plt");
7142104834Sobrien  if (s == NULL)
7143104834Sobrien    {
7144104834Sobrien      /* This may happen for
7145104834Sobrien	 o  references to TOC base (SYM@toc / TOC[tc0]) without a
7146104834Sobrien	 .toc directive
7147104834Sobrien	 o  bad linker script
7148104834Sobrien	 o --gc-sections and empty TOC sections
7149104834Sobrien
7150104834Sobrien	 FIXME: Warn user?  */
7151104834Sobrien
7152104834Sobrien      /* Look for a likely section.  We probably won't even be
7153104834Sobrien	 using TOCstart.  */
7154104834Sobrien      for (s = obfd->sections; s != NULL; s = s->next)
7155104834Sobrien	if ((s->flags & (SEC_ALLOC | SEC_SMALL_DATA | SEC_READONLY))
7156104834Sobrien	    == (SEC_ALLOC | SEC_SMALL_DATA))
7157104834Sobrien	  break;
7158104834Sobrien      if (s == NULL)
7159104834Sobrien	for (s = obfd->sections; s != NULL; s = s->next)
7160104834Sobrien	  if ((s->flags & (SEC_ALLOC | SEC_SMALL_DATA))
7161104834Sobrien	      == (SEC_ALLOC | SEC_SMALL_DATA))
7162104834Sobrien	    break;
7163104834Sobrien      if (s == NULL)
7164104834Sobrien	for (s = obfd->sections; s != NULL; s = s->next)
7165104834Sobrien	  if ((s->flags & (SEC_ALLOC | SEC_READONLY)) == SEC_ALLOC)
7166104834Sobrien	    break;
7167104834Sobrien      if (s == NULL)
7168104834Sobrien	for (s = obfd->sections; s != NULL; s = s->next)
7169104834Sobrien	  if ((s->flags & SEC_ALLOC) == SEC_ALLOC)
7170104834Sobrien	    break;
7171104834Sobrien    }
7172104834Sobrien
7173104834Sobrien  TOCstart = 0;
7174104834Sobrien  if (s != NULL)
7175104834Sobrien    TOCstart = s->output_section->vma + s->output_offset;
7176104834Sobrien
7177104834Sobrien  return TOCstart;
7178104834Sobrien}
7179104834Sobrien
7180104834Sobrien/* Build all the stubs associated with the current output file.
7181104834Sobrien   The stubs are kept in a hash table attached to the main linker
7182104834Sobrien   hash table.  This function is called via gldelf64ppc_finish.  */
7183104834Sobrien
7184130561Sobrienbfd_boolean
7185130561Sobrienppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
7186130561Sobrien		       struct bfd_link_info *info,
7187130561Sobrien		       char **stats)
7188104834Sobrien{
7189104834Sobrien  struct ppc_link_hash_table *htab = ppc_hash_table (info);
7190104834Sobrien  asection *stub_sec;
7191104834Sobrien  bfd_byte *p;
7192130561Sobrien  int stub_sec_count = 0;
7193104834Sobrien
7194130561Sobrien  htab->emit_stub_syms = emit_stub_syms;
7195104834Sobrien  for (stub_sec = htab->stub_bfd->sections;
7196104834Sobrien       stub_sec != NULL;
7197104834Sobrien       stub_sec = stub_sec->next)
7198130561Sobrien    if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
7199130561Sobrien      {
7200130561Sobrien	bfd_size_type size;
7201104834Sobrien
7202130561Sobrien	/* Allocate memory to hold the linker stubs.  */
7203130561Sobrien	size = stub_sec->_raw_size;
7204130561Sobrien	if (size != 0)
7205130561Sobrien	  {
7206130561Sobrien	    stub_sec->contents = bfd_zalloc (htab->stub_bfd, size);
7207130561Sobrien	    if (stub_sec->contents == NULL)
7208130561Sobrien	      return FALSE;
7209130561Sobrien	  }
7210130561Sobrien	stub_sec->_cooked_size = 0;
7211130561Sobrien      }
7212104834Sobrien
7213209867Snwhitehorn  if (htab->glink != NULL && htab->glink->contents != NULL)
7214104834Sobrien    {
7215104834Sobrien      unsigned int indx;
7216130561Sobrien      bfd_vma plt0;
7217104834Sobrien
7218104834Sobrien      /* Build the .glink plt call stub.  */
7219130561Sobrien      plt0 = (htab->plt->output_section->vma
7220130561Sobrien	      + htab->plt->output_offset
7221130561Sobrien	      - (htab->glink->output_section->vma
7222130561Sobrien		 + htab->glink->output_offset
7223130561Sobrien		 + GLINK_CALL_STUB_SIZE));
7224130561Sobrien      if (plt0 + 0x80008000 > 0xffffffff)
7225104834Sobrien	{
7226130561Sobrien	  (*_bfd_error_handler) (_(".glink and .plt too far apart"));
7227130561Sobrien	  bfd_set_error (bfd_error_bad_value);
7228130561Sobrien	  return FALSE;
7229104834Sobrien	}
7230104834Sobrien
7231130561Sobrien      if (htab->emit_stub_syms)
7232130561Sobrien	{
7233130561Sobrien	  struct elf_link_hash_entry *h;
7234130561Sobrien	  h = elf_link_hash_lookup (&htab->elf, "__glink", TRUE, FALSE, FALSE);
7235130561Sobrien	  if (h == NULL)
7236130561Sobrien	    return FALSE;
7237130561Sobrien	  if (h->root.type == bfd_link_hash_new)
7238130561Sobrien	    {
7239130561Sobrien	      h->root.type = bfd_link_hash_defined;
7240130561Sobrien	      h->root.u.def.section = htab->glink;
7241130561Sobrien	      h->root.u.def.value = 0;
7242130561Sobrien	      h->elf_link_hash_flags = (ELF_LINK_HASH_REF_REGULAR
7243130561Sobrien					| ELF_LINK_HASH_DEF_REGULAR
7244130561Sobrien					| ELF_LINK_HASH_REF_REGULAR_NONWEAK
7245130561Sobrien					| ELF_LINK_FORCED_LOCAL);
7246130561Sobrien	    }
7247130561Sobrien	}
7248130561Sobrien      p = htab->glink->contents;
7249130561Sobrien      bfd_put_32 (htab->glink->owner, MFCTR_R12, p);
7250130561Sobrien      p += 4;
7251130561Sobrien      bfd_put_32 (htab->glink->owner, SLDI_R11_R0_3, p);
7252130561Sobrien      p += 4;
7253130561Sobrien      bfd_put_32 (htab->glink->owner, ADDIC_R2_R0_32K, p);
7254130561Sobrien      p += 4;
7255130561Sobrien      bfd_put_32 (htab->glink->owner, SUB_R12_R12_R11, p);
7256130561Sobrien      p += 4;
7257130561Sobrien      bfd_put_32 (htab->glink->owner, SRADI_R2_R2_63, p);
7258130561Sobrien      p += 4;
7259130561Sobrien      bfd_put_32 (htab->glink->owner, SLDI_R11_R0_2, p);
7260130561Sobrien      p += 4;
7261130561Sobrien      bfd_put_32 (htab->glink->owner, AND_R2_R2_R11, p);
7262130561Sobrien      p += 4;
7263130561Sobrien      bfd_put_32 (htab->glink->owner, SUB_R12_R12_R11, p);
7264130561Sobrien      p += 4;
7265130561Sobrien      bfd_put_32 (htab->glink->owner, ADD_R12_R12_R2, p);
7266130561Sobrien      p += 4;
7267130561Sobrien      bfd_put_32 (htab->glink->owner, ADDIS_R12_R12 | PPC_HA (plt0), p);
7268130561Sobrien      p += 4;
7269130561Sobrien      bfd_put_32 (htab->glink->owner, LD_R11_0R12 | PPC_LO (plt0), p);
7270130561Sobrien      p += 4;
7271130561Sobrien      bfd_put_32 (htab->glink->owner, ADDI_R12_R12 | PPC_LO (plt0), p);
7272130561Sobrien      p += 4;
7273130561Sobrien      bfd_put_32 (htab->glink->owner, LD_R2_0R12 | 8, p);
7274130561Sobrien      p += 4;
7275130561Sobrien      bfd_put_32 (htab->glink->owner, MTCTR_R11, p);
7276130561Sobrien      p += 4;
7277130561Sobrien      bfd_put_32 (htab->glink->owner, LD_R11_0R12 | 16, p);
7278130561Sobrien      p += 4;
7279130561Sobrien      bfd_put_32 (htab->glink->owner, BCTR, p);
7280130561Sobrien      p += 4;
7281130561Sobrien
7282104834Sobrien      /* Build the .glink lazy link call stubs.  */
7283104834Sobrien      indx = 0;
7284130561Sobrien      while (p < htab->glink->contents + htab->glink->_raw_size)
7285104834Sobrien	{
7286104834Sobrien	  if (indx < 0x8000)
7287104834Sobrien	    {
7288130561Sobrien	      bfd_put_32 (htab->glink->owner, LI_R0_0 | indx, p);
7289104834Sobrien	      p += 4;
7290104834Sobrien	    }
7291104834Sobrien	  else
7292104834Sobrien	    {
7293130561Sobrien	      bfd_put_32 (htab->glink->owner, LIS_R0_0 | PPC_HI (indx), p);
7294104834Sobrien	      p += 4;
7295130561Sobrien	      bfd_put_32 (htab->glink->owner, ORI_R0_R0_0 | PPC_LO (indx), p);
7296104834Sobrien	      p += 4;
7297104834Sobrien	    }
7298130561Sobrien	  bfd_put_32 (htab->glink->owner,
7299130561Sobrien		      B_DOT | ((htab->glink->contents - p) & 0x3fffffc), p);
7300104834Sobrien	  indx++;
7301104834Sobrien	  p += 4;
7302104834Sobrien	}
7303130561Sobrien      htab->glink->_cooked_size = p - htab->glink->contents;
7304104834Sobrien    }
7305104834Sobrien
7306130561Sobrien  if (htab->brlt->_raw_size != 0)
7307104834Sobrien    {
7308130561Sobrien      htab->brlt->contents = bfd_zalloc (htab->brlt->owner,
7309130561Sobrien					 htab->brlt->_raw_size);
7310130561Sobrien      if (htab->brlt->contents == NULL)
7311130561Sobrien	return FALSE;
7312104834Sobrien    }
7313130561Sobrien  if (info->shared && htab->relbrlt->_raw_size != 0)
7314130561Sobrien    {
7315130561Sobrien      htab->relbrlt->contents = bfd_zalloc (htab->relbrlt->owner,
7316130561Sobrien					    htab->relbrlt->_raw_size);
7317130561Sobrien      if (htab->relbrlt->contents == NULL)
7318130561Sobrien	return FALSE;
7319130561Sobrien    }
7320104834Sobrien
7321104834Sobrien  /* Build the stubs as directed by the stub hash table.  */
7322104834Sobrien  bfd_hash_traverse (&htab->stub_hash_table, ppc_build_one_stub, info);
7323104834Sobrien
7324104834Sobrien  for (stub_sec = htab->stub_bfd->sections;
7325104834Sobrien       stub_sec != NULL;
7326104834Sobrien       stub_sec = stub_sec->next)
7327130561Sobrien    if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
7328130561Sobrien      {
7329130561Sobrien	stub_sec_count += 1;
7330130561Sobrien	if (stub_sec->_raw_size != stub_sec->_cooked_size)
7331130561Sobrien	  break;
7332130561Sobrien      }
7333104834Sobrien
7334104834Sobrien  if (stub_sec != NULL
7335130561Sobrien      || htab->glink->_raw_size != htab->glink->_cooked_size)
7336104834Sobrien    {
7337130561Sobrien      htab->stub_error = TRUE;
7338104834Sobrien      (*_bfd_error_handler) (_("stubs don't match calculated size"));
7339104834Sobrien    }
7340104834Sobrien
7341130561Sobrien  if (htab->stub_error)
7342130561Sobrien    return FALSE;
7343130561Sobrien
7344130561Sobrien  if (stats != NULL)
7345130561Sobrien    {
7346130561Sobrien      *stats = bfd_malloc (500);
7347130561Sobrien      if (*stats == NULL)
7348130561Sobrien	return FALSE;
7349130561Sobrien
7350130561Sobrien      sprintf (*stats, _("linker stubs in %u groups\n"
7351130561Sobrien			 "  branch       %lu\n"
7352130561Sobrien			 "  toc adjust   %lu\n"
7353130561Sobrien			 "  long branch  %lu\n"
7354130561Sobrien			 "  long toc adj %lu\n"
7355130561Sobrien			 "  plt call     %lu"),
7356130561Sobrien	       stub_sec_count,
7357130561Sobrien	       htab->stub_count[ppc_stub_long_branch - 1],
7358130561Sobrien	       htab->stub_count[ppc_stub_long_branch_r2off - 1],
7359130561Sobrien	       htab->stub_count[ppc_stub_plt_branch - 1],
7360130561Sobrien	       htab->stub_count[ppc_stub_plt_branch_r2off - 1],
7361130561Sobrien	       htab->stub_count[ppc_stub_plt_call - 1]);
7362130561Sobrien    }
7363130561Sobrien  return TRUE;
7364104834Sobrien}
7365104834Sobrien
736689857Sobrien/* The RELOCATE_SECTION function is called by the ELF backend linker
736789857Sobrien   to handle the relocations for a section.
736889857Sobrien
736989857Sobrien   The relocs are always passed as Rela structures; if the section
737089857Sobrien   actually uses Rel structures, the r_addend field will always be
737189857Sobrien   zero.
737289857Sobrien
737389857Sobrien   This function is responsible for adjust the section contents as
737489857Sobrien   necessary, and (if using Rela relocs and generating a
7375130561Sobrien   relocatable output file) adjusting the reloc addend as
737689857Sobrien   necessary.
737789857Sobrien
737889857Sobrien   This function does not have to worry about setting the reloc
737989857Sobrien   address or the reloc symbol index.
738089857Sobrien
738189857Sobrien   LOCAL_SYMS is a pointer to the swapped in local symbols.
738289857Sobrien
738389857Sobrien   LOCAL_SECTIONS is an array giving the section in the input file
738489857Sobrien   corresponding to the st_shndx field of each local symbol.
738589857Sobrien
738689857Sobrien   The global hash table entry for the global symbols can be found
738789857Sobrien   via elf_sym_hashes (input_bfd).
738889857Sobrien
7389130561Sobrien   When generating relocatable output, this function must handle
739089857Sobrien   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
739189857Sobrien   going to be the section symbol corresponding to the output
739289857Sobrien   section, which means that the addend must be adjusted
739389857Sobrien   accordingly.  */
739489857Sobrien
7395130561Sobrienstatic bfd_boolean
7396130561Sobrienppc64_elf_relocate_section (bfd *output_bfd,
7397130561Sobrien			    struct bfd_link_info *info,
7398130561Sobrien			    bfd *input_bfd,
7399130561Sobrien			    asection *input_section,
7400130561Sobrien			    bfd_byte *contents,
7401130561Sobrien			    Elf_Internal_Rela *relocs,
7402130561Sobrien			    Elf_Internal_Sym *local_syms,
7403130561Sobrien			    asection **local_sections)
740489857Sobrien{
740589857Sobrien  struct ppc_link_hash_table *htab;
740689857Sobrien  Elf_Internal_Shdr *symtab_hdr;
740789857Sobrien  struct elf_link_hash_entry **sym_hashes;
740889857Sobrien  Elf_Internal_Rela *rel;
740989857Sobrien  Elf_Internal_Rela *relend;
7410130561Sobrien  Elf_Internal_Rela outrel;
7411130561Sobrien  bfd_byte *loc;
7412130561Sobrien  struct got_entry **local_got_ents;
741389857Sobrien  bfd_vma TOCstart;
7414130561Sobrien  bfd_boolean ret = TRUE;
7415130561Sobrien  bfd_boolean is_opd;
741692828Sobrien  /* Disabled until we sort out how ld should choose 'y' vs 'at'.  */
7417130561Sobrien  bfd_boolean is_power4 = FALSE;
741889857Sobrien
7419130561Sobrien  if (info->relocatable)
7420130561Sobrien    return TRUE;
742199461Sobrien
742289857Sobrien  /* Initialize howto table if needed.  */
742389857Sobrien  if (!ppc64_elf_howto_table[R_PPC64_ADDR32])
742489857Sobrien    ppc_howto_init ();
742589857Sobrien
742689857Sobrien  htab = ppc_hash_table (info);
7427130561Sobrien  local_got_ents = elf_local_got_ents (input_bfd);
742889857Sobrien  TOCstart = elf_gp (output_bfd);
742989857Sobrien  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
743089857Sobrien  sym_hashes = elf_sym_hashes (input_bfd);
7431130561Sobrien  is_opd = ppc64_elf_section_data (input_section)->opd.adjust != NULL;
743289857Sobrien
743389857Sobrien  rel = relocs;
743489857Sobrien  relend = relocs + input_section->reloc_count;
743589857Sobrien  for (; rel < relend; rel++)
743689857Sobrien    {
7437130561Sobrien      enum elf_ppc64_reloc_type r_type;
743889857Sobrien      bfd_vma addend;
743989857Sobrien      bfd_reloc_status_type r;
744089857Sobrien      Elf_Internal_Sym *sym;
744189857Sobrien      asection *sec;
744289857Sobrien      struct elf_link_hash_entry *h;
7443104834Sobrien      struct elf_link_hash_entry *fdh;
744489857Sobrien      const char *sym_name;
7445130561Sobrien      unsigned long r_symndx, toc_symndx;
7446130561Sobrien      char tls_mask, tls_gd, tls_type;
7447130561Sobrien      char sym_type;
744889857Sobrien      bfd_vma relocation;
7449130561Sobrien      bfd_boolean unresolved_reloc;
7450130561Sobrien      bfd_boolean warned;
7451130561Sobrien      unsigned long insn, mask;
7452104834Sobrien      struct ppc_stub_hash_entry *stub_entry;
7453104834Sobrien      bfd_vma max_br_offset;
745499461Sobrien      bfd_vma from;
745589857Sobrien
7456130561Sobrien      r_type = ELF64_R_TYPE (rel->r_info);
745789857Sobrien      r_symndx = ELF64_R_SYM (rel->r_info);
745889857Sobrien
7459130561Sobrien      /* For old style R_PPC64_TOC relocs with a zero symbol, use the
7460130561Sobrien	 symbol of the previous ADDR64 reloc.  The symbol gives us the
7461130561Sobrien	 proper TOC base to use.  */
7462130561Sobrien      if (rel->r_info == ELF64_R_INFO (0, R_PPC64_TOC)
7463130561Sobrien	  && rel != relocs
7464130561Sobrien	  && ELF64_R_TYPE (rel[-1].r_info) == R_PPC64_ADDR64
7465130561Sobrien	  && is_opd)
7466130561Sobrien	r_symndx = ELF64_R_SYM (rel[-1].r_info);
7467130561Sobrien
7468130561Sobrien      sym = NULL;
7469130561Sobrien      sec = NULL;
7470130561Sobrien      h = NULL;
7471130561Sobrien      sym_name = NULL;
7472130561Sobrien      unresolved_reloc = FALSE;
7473130561Sobrien      warned = FALSE;
7474130561Sobrien
7475130561Sobrien      if (r_symndx < symtab_hdr->sh_info)
747689857Sobrien	{
747789857Sobrien	  /* It's a local symbol.  */
747889857Sobrien	  sym = local_syms + r_symndx;
747989857Sobrien	  sec = local_sections[r_symndx];
7480130561Sobrien	  sym_name = bfd_elf_local_sym_name (input_bfd, sym);
7481130561Sobrien	  sym_type = ELF64_ST_TYPE (sym->st_info);
7482130561Sobrien	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
7483104834Sobrien	  if (elf_section_data (sec) != NULL)
7484104834Sobrien	    {
7485104834Sobrien	      long *opd_sym_adjust;
7486104834Sobrien
7487130561Sobrien	      opd_sym_adjust = ppc64_elf_section_data (sec)->opd.adjust;
7488130561Sobrien	      if (opd_sym_adjust != NULL)
7489104834Sobrien		relocation += opd_sym_adjust[sym->st_value / 24];
7490104834Sobrien	    }
749189857Sobrien	}
749289857Sobrien      else
749389857Sobrien	{
7494130561Sobrien	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
7495130561Sobrien				   r_symndx, symtab_hdr, sym_hashes,
7496130561Sobrien				   h, sec, relocation,
7497130561Sobrien				   unresolved_reloc, warned);
749889857Sobrien	  sym_name = h->root.root.string;
7499130561Sobrien	  sym_type = h->type;
7500130561Sobrien	}
7501130561Sobrien
7502130561Sobrien      /* TLS optimizations.  Replace instruction sequences and relocs
7503130561Sobrien	 based on information we collected in tls_optimize.  We edit
7504130561Sobrien	 RELOCS so that --emit-relocs will output something sensible
7505130561Sobrien	 for the final instruction stream.  */
7506130561Sobrien      tls_mask = 0;
7507130561Sobrien      tls_gd = 0;
7508130561Sobrien      toc_symndx = 0;
7509130561Sobrien      if (IS_PPC64_TLS_RELOC (r_type))
7510130561Sobrien	{
7511130561Sobrien	  if (h != NULL)
7512130561Sobrien	    tls_mask = ((struct ppc_link_hash_entry *) h)->tls_mask;
7513130561Sobrien	  else if (local_got_ents != NULL)
7514130561Sobrien	    {
7515130561Sobrien	      char *lgot_masks;
7516130561Sobrien	      lgot_masks = (char *) (local_got_ents + symtab_hdr->sh_info);
7517130561Sobrien	      tls_mask = lgot_masks[r_symndx];
7518130561Sobrien	    }
7519130561Sobrien	  if (tls_mask == 0 && r_type == R_PPC64_TLS)
7520130561Sobrien	    {
7521130561Sobrien	      /* Check for toc tls entries.  */
7522130561Sobrien	      char *toc_tls;
7523130561Sobrien
7524130561Sobrien	      if (!get_tls_mask (&toc_tls, &toc_symndx, &local_syms,
7525130561Sobrien				 rel, input_bfd))
7526130561Sobrien		return FALSE;
7527130561Sobrien
7528130561Sobrien	      if (toc_tls)
7529130561Sobrien		tls_mask = *toc_tls;
7530130561Sobrien	    }
7531130561Sobrien	}
7532130561Sobrien
7533130561Sobrien      /* Check that tls relocs are used with tls syms, and non-tls
7534130561Sobrien	 relocs are used with non-tls syms.  */
7535130561Sobrien      if (r_symndx != 0
7536130561Sobrien	  && r_type != R_PPC64_NONE
7537130561Sobrien	  && (h == NULL
7538130561Sobrien	      || h->root.type == bfd_link_hash_defined
753989857Sobrien	      || h->root.type == bfd_link_hash_defweak)
7540130561Sobrien	  && IS_PPC64_TLS_RELOC (r_type) != (sym_type == STT_TLS))
7541130561Sobrien	{
7542130561Sobrien	  if (r_type == R_PPC64_TLS && tls_mask != 0)
7543130561Sobrien	    /* R_PPC64_TLS is OK against a symbol in the TOC.  */
7544130561Sobrien	    ;
7545130561Sobrien	  else
7546130561Sobrien	    (*_bfd_error_handler)
7547130561Sobrien	      (sym_type == STT_TLS
7548130561Sobrien	       ? _("%s(%s+0x%lx): %s used with TLS symbol %s")
7549130561Sobrien	       : _("%s(%s+0x%lx): %s used with non-TLS symbol %s"),
7550130561Sobrien	       bfd_archive_filename (input_bfd),
7551130561Sobrien	       input_section->name,
7552130561Sobrien	       (long) rel->r_offset,
7553130561Sobrien	       ppc64_elf_howto_table[r_type]->name,
7554130561Sobrien	       sym_name);
7555130561Sobrien	}
7556130561Sobrien
7557130561Sobrien      /* Ensure reloc mapping code below stays sane.  */
7558130561Sobrien      if (R_PPC64_TOC16_LO_DS != R_PPC64_TOC16_DS + 1
7559130561Sobrien	  || R_PPC64_TOC16_LO != R_PPC64_TOC16 + 1
7560130561Sobrien	  || (R_PPC64_GOT_TLSLD16 & 3)    != (R_PPC64_GOT_TLSGD16 & 3)
7561130561Sobrien	  || (R_PPC64_GOT_TLSLD16_LO & 3) != (R_PPC64_GOT_TLSGD16_LO & 3)
7562130561Sobrien	  || (R_PPC64_GOT_TLSLD16_HI & 3) != (R_PPC64_GOT_TLSGD16_HI & 3)
7563130561Sobrien	  || (R_PPC64_GOT_TLSLD16_HA & 3) != (R_PPC64_GOT_TLSGD16_HA & 3)
7564130561Sobrien	  || (R_PPC64_GOT_TLSLD16 & 3)    != (R_PPC64_GOT_TPREL16_DS & 3)
7565130561Sobrien	  || (R_PPC64_GOT_TLSLD16_LO & 3) != (R_PPC64_GOT_TPREL16_LO_DS & 3)
7566130561Sobrien	  || (R_PPC64_GOT_TLSLD16_HI & 3) != (R_PPC64_GOT_TPREL16_HI & 3)
7567130561Sobrien	  || (R_PPC64_GOT_TLSLD16_HA & 3) != (R_PPC64_GOT_TPREL16_HA & 3))
7568130561Sobrien	abort ();
7569130561Sobrien
7570130561Sobrien      switch (r_type)
7571130561Sobrien	{
7572130561Sobrien	default:
7573130561Sobrien	  break;
7574130561Sobrien
7575130561Sobrien	case R_PPC64_TOC16:
7576130561Sobrien	case R_PPC64_TOC16_LO:
7577130561Sobrien	case R_PPC64_TOC16_DS:
7578130561Sobrien	case R_PPC64_TOC16_LO_DS:
7579130561Sobrien	  {
7580130561Sobrien	    /* Check for toc tls entries.  */
7581130561Sobrien	    char *toc_tls;
7582130561Sobrien	    int retval;
7583130561Sobrien
7584130561Sobrien	    retval = get_tls_mask (&toc_tls, &toc_symndx, &local_syms,
7585130561Sobrien				   rel, input_bfd);
7586130561Sobrien	    if (retval == 0)
7587130561Sobrien	      return FALSE;
7588130561Sobrien
7589130561Sobrien	    if (toc_tls)
7590130561Sobrien	      {
7591130561Sobrien		tls_mask = *toc_tls;
7592130561Sobrien		if (r_type == R_PPC64_TOC16_DS
7593130561Sobrien		    || r_type == R_PPC64_TOC16_LO_DS)
7594130561Sobrien		  {
7595130561Sobrien		    if (tls_mask != 0
7596130561Sobrien			&& (tls_mask & (TLS_DTPREL | TLS_TPREL)) == 0)
7597130561Sobrien		      goto toctprel;
7598130561Sobrien		  }
7599130561Sobrien		else
7600130561Sobrien		  {
7601130561Sobrien		    /* If we found a GD reloc pair, then we might be
7602130561Sobrien		       doing a GD->IE transition.  */
7603130561Sobrien		    if (retval == 2)
7604130561Sobrien		      {
7605130561Sobrien			tls_gd = TLS_TPRELGD;
7606130561Sobrien			if (tls_mask != 0 && (tls_mask & TLS_GD) == 0)
7607130561Sobrien			  goto tls_get_addr_check;
7608130561Sobrien		      }
7609130561Sobrien		    else if (retval == 3)
7610130561Sobrien		      {
7611130561Sobrien			if (tls_mask != 0 && (tls_mask & TLS_LD) == 0)
7612130561Sobrien			  goto tls_get_addr_check;
7613130561Sobrien		      }
7614130561Sobrien		  }
7615130561Sobrien	      }
7616130561Sobrien	  }
7617130561Sobrien	  break;
7618130561Sobrien
7619130561Sobrien	case R_PPC64_GOT_TPREL16_DS:
7620130561Sobrien	case R_PPC64_GOT_TPREL16_LO_DS:
7621130561Sobrien	  if (tls_mask != 0
7622130561Sobrien	      && (tls_mask & TLS_TPREL) == 0)
762389857Sobrien	    {
7624130561Sobrien	    toctprel:
7625130561Sobrien	      insn = bfd_get_32 (output_bfd, contents + rel->r_offset - 2);
7626130561Sobrien	      insn &= 31 << 21;
7627130561Sobrien	      insn |= 0x3c0d0000;	/* addis 0,13,0 */
7628130561Sobrien	      bfd_put_32 (output_bfd, insn, contents + rel->r_offset - 2);
7629130561Sobrien	      r_type = R_PPC64_TPREL16_HA;
7630130561Sobrien	      if (toc_symndx != 0)
7631130561Sobrien		{
7632130561Sobrien		  rel->r_info = ELF64_R_INFO (toc_symndx, r_type);
7633130561Sobrien		  /* We changed the symbol.  Start over in order to
7634130561Sobrien		     get h, sym, sec etc. right.  */
7635130561Sobrien		  rel--;
7636130561Sobrien		  continue;
7637130561Sobrien		}
763889857Sobrien	      else
7639130561Sobrien		rel->r_info = ELF64_R_INFO (r_symndx, r_type);
764089857Sobrien	    }
7641130561Sobrien	  break;
7642130561Sobrien
7643130561Sobrien	case R_PPC64_TLS:
7644130561Sobrien	  if (tls_mask != 0
7645130561Sobrien	      && (tls_mask & TLS_TPREL) == 0)
7646130561Sobrien	    {
7647130561Sobrien	      bfd_vma rtra;
7648130561Sobrien	      insn = bfd_get_32 (output_bfd, contents + rel->r_offset);
7649130561Sobrien	      if ((insn & ((0x3f << 26) | (31 << 11)))
7650130561Sobrien		  == ((31 << 26) | (13 << 11)))
7651130561Sobrien		rtra = insn & ((1 << 26) - (1 << 16));
7652130561Sobrien	      else if ((insn & ((0x3f << 26) | (31 << 16)))
7653130561Sobrien		       == ((31 << 26) | (13 << 16)))
7654130561Sobrien		rtra = (insn & (31 << 21)) | ((insn & (31 << 11)) << 5);
7655130561Sobrien	      else
7656130561Sobrien		abort ();
7657130561Sobrien	      if ((insn & ((1 << 11) - (1 << 1))) == 266 << 1)
7658130561Sobrien		/* add -> addi.  */
7659130561Sobrien		insn = 14 << 26;
7660130561Sobrien	      else if ((insn & (31 << 1)) == 23 << 1
7661130561Sobrien		       && ((insn & (31 << 6)) < 14 << 6
7662130561Sobrien			   || ((insn & (31 << 6)) >= 16 << 6
7663130561Sobrien			       && (insn & (31 << 6)) < 24 << 6)))
7664130561Sobrien		/* load and store indexed -> dform.  */
7665130561Sobrien		insn = (32 | ((insn >> 6) & 31)) << 26;
7666130561Sobrien	      else if ((insn & (31 << 1)) == 21 << 1
7667130561Sobrien		       && (insn & (0x1a << 6)) == 0)
7668130561Sobrien		/* ldx, ldux, stdx, stdux -> ld, ldu, std, stdu.  */
7669130561Sobrien		insn = (((58 | ((insn >> 6) & 4)) << 26)
7670130561Sobrien			| ((insn >> 6) & 1));
7671130561Sobrien	      else if ((insn & (31 << 1)) == 21 << 1
7672130561Sobrien		       && (insn & ((1 << 11) - (1 << 1))) == 341 << 1)
7673130561Sobrien		/* lwax -> lwa.  */
7674130561Sobrien		insn = (58 << 26) | 2;
7675130561Sobrien	      else
7676130561Sobrien		abort ();
7677130561Sobrien	      insn |= rtra;
7678130561Sobrien	      bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
7679130561Sobrien	      /* Was PPC64_TLS which sits on insn boundary, now
7680130561Sobrien		 PPC64_TPREL16_LO which is at insn+2.  */
7681130561Sobrien	      rel->r_offset += 2;
7682130561Sobrien	      r_type = R_PPC64_TPREL16_LO;
7683130561Sobrien	      if (toc_symndx != 0)
7684130561Sobrien		{
7685130561Sobrien		  rel->r_info = ELF64_R_INFO (toc_symndx, r_type);
7686130561Sobrien		  /* We changed the symbol.  Start over in order to
7687130561Sobrien		     get h, sym, sec etc. right.  */
7688130561Sobrien		  rel--;
7689130561Sobrien		  continue;
7690130561Sobrien		}
7691130561Sobrien	      else
7692130561Sobrien		rel->r_info = ELF64_R_INFO (r_symndx, r_type);
7693130561Sobrien	    }
7694130561Sobrien	  break;
7695130561Sobrien
7696130561Sobrien	case R_PPC64_GOT_TLSGD16_HI:
7697130561Sobrien	case R_PPC64_GOT_TLSGD16_HA:
7698130561Sobrien	  tls_gd = TLS_TPRELGD;
7699130561Sobrien	  if (tls_mask != 0 && (tls_mask & TLS_GD) == 0)
7700130561Sobrien	    goto tls_gdld_hi;
7701130561Sobrien	  break;
7702130561Sobrien
7703130561Sobrien	case R_PPC64_GOT_TLSLD16_HI:
7704130561Sobrien	case R_PPC64_GOT_TLSLD16_HA:
7705130561Sobrien	  if (tls_mask != 0 && (tls_mask & TLS_LD) == 0)
7706130561Sobrien	    {
7707130561Sobrien	    tls_gdld_hi:
7708130561Sobrien	      if ((tls_mask & tls_gd) != 0)
7709130561Sobrien		r_type = (((r_type - (R_PPC64_GOT_TLSGD16 & 3)) & 3)
7710130561Sobrien			  + R_PPC64_GOT_TPREL16_DS);
7711130561Sobrien	      else
7712130561Sobrien		{
7713130561Sobrien		  bfd_put_32 (output_bfd, NOP, contents + rel->r_offset);
7714130561Sobrien		  rel->r_offset -= 2;
7715130561Sobrien		  r_type = R_PPC64_NONE;
7716130561Sobrien		}
7717130561Sobrien	      rel->r_info = ELF64_R_INFO (r_symndx, r_type);
7718130561Sobrien	    }
7719130561Sobrien	  break;
7720130561Sobrien
7721130561Sobrien	case R_PPC64_GOT_TLSGD16:
7722130561Sobrien	case R_PPC64_GOT_TLSGD16_LO:
7723130561Sobrien	  tls_gd = TLS_TPRELGD;
7724130561Sobrien	  if (tls_mask != 0 && (tls_mask & TLS_GD) == 0)
7725130561Sobrien	    goto tls_get_addr_check;
7726130561Sobrien	  break;
7727130561Sobrien
7728130561Sobrien	case R_PPC64_GOT_TLSLD16:
7729130561Sobrien	case R_PPC64_GOT_TLSLD16_LO:
7730130561Sobrien	  if (tls_mask != 0 && (tls_mask & TLS_LD) == 0)
7731130561Sobrien	    {
7732130561Sobrien	    tls_get_addr_check:
7733130561Sobrien	      if (rel + 1 < relend)
7734130561Sobrien		{
7735130561Sobrien		  enum elf_ppc64_reloc_type r_type2;
7736130561Sobrien		  unsigned long r_symndx2;
7737130561Sobrien		  struct elf_link_hash_entry *h2;
7738130561Sobrien		  bfd_vma insn1, insn2, insn3;
7739130561Sobrien		  bfd_vma offset;
7740130561Sobrien
7741130561Sobrien		  /* The next instruction should be a call to
7742130561Sobrien		     __tls_get_addr.  Peek at the reloc to be sure.  */
7743130561Sobrien		  r_type2 = ELF64_R_TYPE (rel[1].r_info);
7744130561Sobrien		  r_symndx2 = ELF64_R_SYM (rel[1].r_info);
7745130561Sobrien		  if (r_symndx2 < symtab_hdr->sh_info
7746130561Sobrien		      || (r_type2 != R_PPC64_REL14
7747130561Sobrien			  && r_type2 != R_PPC64_REL14_BRTAKEN
7748130561Sobrien			  && r_type2 != R_PPC64_REL14_BRNTAKEN
7749130561Sobrien			  && r_type2 != R_PPC64_REL24))
7750130561Sobrien		    break;
7751130561Sobrien
7752130561Sobrien		  h2 = sym_hashes[r_symndx2 - symtab_hdr->sh_info];
7753130561Sobrien		  while (h2->root.type == bfd_link_hash_indirect
7754130561Sobrien			 || h2->root.type == bfd_link_hash_warning)
7755130561Sobrien		    h2 = (struct elf_link_hash_entry *) h2->root.u.i.link;
7756130561Sobrien		  if (h2 == NULL || h2 != htab->tls_get_addr)
7757130561Sobrien		    break;
7758130561Sobrien
7759130561Sobrien		  /* OK, it checks out.  Replace the call.  */
7760130561Sobrien		  offset = rel[1].r_offset;
7761130561Sobrien		  insn1 = bfd_get_32 (output_bfd,
7762130561Sobrien				      contents + rel->r_offset - 2);
7763130561Sobrien		  insn3 = bfd_get_32 (output_bfd,
7764130561Sobrien				      contents + offset + 4);
7765130561Sobrien		  if ((tls_mask & tls_gd) != 0)
7766130561Sobrien		    {
7767130561Sobrien		      /* IE */
7768130561Sobrien		      insn1 &= (1 << 26) - (1 << 2);
7769130561Sobrien		      insn1 |= 58 << 26;	/* ld */
7770130561Sobrien		      insn2 = 0x7c636a14;	/* add 3,3,13 */
7771130561Sobrien		      rel[1].r_info = ELF64_R_INFO (r_symndx2, R_PPC64_NONE);
7772130561Sobrien		      if ((tls_mask & TLS_EXPLICIT) == 0)
7773130561Sobrien			r_type = (((r_type - (R_PPC64_GOT_TLSGD16 & 3)) & 3)
7774130561Sobrien				  + R_PPC64_GOT_TPREL16_DS);
7775130561Sobrien		      else
7776130561Sobrien			r_type += R_PPC64_TOC16_DS - R_PPC64_TOC16;
7777130561Sobrien		      rel->r_info = ELF64_R_INFO (r_symndx, r_type);
7778130561Sobrien		    }
7779130561Sobrien		  else
7780130561Sobrien		    {
7781130561Sobrien		      /* LE */
7782130561Sobrien		      insn1 = 0x3c6d0000;	/* addis 3,13,0 */
7783130561Sobrien		      insn2 = 0x38630000;	/* addi 3,3,0 */
7784130561Sobrien		      if (tls_gd == 0)
7785130561Sobrien			{
7786130561Sobrien			  /* Was an LD reloc.  */
7787130561Sobrien			  r_symndx = 0;
7788130561Sobrien			  rel->r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
7789130561Sobrien			  rel[1].r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
7790130561Sobrien			}
7791130561Sobrien		      else if (toc_symndx != 0)
7792130561Sobrien			r_symndx = toc_symndx;
7793130561Sobrien		      r_type = R_PPC64_TPREL16_HA;
7794130561Sobrien		      rel->r_info = ELF64_R_INFO (r_symndx, r_type);
7795130561Sobrien		      rel[1].r_info = ELF64_R_INFO (r_symndx,
7796130561Sobrien						    R_PPC64_TPREL16_LO);
7797130561Sobrien		      rel[1].r_offset += 2;
7798130561Sobrien		    }
7799130561Sobrien		  if (insn3 == NOP
7800130561Sobrien		      || insn3 == CROR_151515 || insn3 == CROR_313131)
7801130561Sobrien		    {
7802130561Sobrien		      insn3 = insn2;
7803130561Sobrien		      insn2 = NOP;
7804130561Sobrien		      rel[1].r_offset += 4;
7805130561Sobrien		    }
7806130561Sobrien		  bfd_put_32 (output_bfd, insn1, contents + rel->r_offset - 2);
7807130561Sobrien		  bfd_put_32 (output_bfd, insn2, contents + offset);
7808130561Sobrien		  bfd_put_32 (output_bfd, insn3, contents + offset + 4);
7809130561Sobrien		  if (tls_gd == 0 || toc_symndx != 0)
7810130561Sobrien		    {
7811130561Sobrien		      /* We changed the symbol.  Start over in order
7812130561Sobrien			 to get h, sym, sec etc. right.  */
7813130561Sobrien		      rel--;
7814130561Sobrien		      continue;
7815130561Sobrien		    }
7816130561Sobrien		}
7817130561Sobrien	    }
7818130561Sobrien	  break;
7819130561Sobrien
7820130561Sobrien	case R_PPC64_DTPMOD64:
7821130561Sobrien	  if (rel + 1 < relend
7822130561Sobrien	      && rel[1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_DTPREL64)
7823130561Sobrien	      && rel[1].r_offset == rel->r_offset + 8)
7824130561Sobrien	    {
7825130561Sobrien	      if ((tls_mask & TLS_GD) == 0)
7826130561Sobrien		{
7827130561Sobrien		  rel[1].r_info = ELF64_R_INFO (r_symndx, R_PPC64_NONE);
7828130561Sobrien		  if ((tls_mask & TLS_TPRELGD) != 0)
7829130561Sobrien		    r_type = R_PPC64_TPREL64;
7830130561Sobrien		  else
7831130561Sobrien		    {
7832130561Sobrien		      bfd_put_64 (output_bfd, 1, contents + rel->r_offset);
7833130561Sobrien		      r_type = R_PPC64_NONE;
7834130561Sobrien		    }
7835130561Sobrien		  rel->r_info = ELF64_R_INFO (r_symndx, r_type);
7836130561Sobrien		}
7837130561Sobrien	    }
783889857Sobrien	  else
783989857Sobrien	    {
7840130561Sobrien	      if ((tls_mask & TLS_LD) == 0)
7841130561Sobrien		{
7842130561Sobrien		  bfd_put_64 (output_bfd, 1, contents + rel->r_offset);
7843130561Sobrien		  r_type = R_PPC64_NONE;
7844130561Sobrien		  rel->r_info = ELF64_R_INFO (r_symndx, r_type);
7845130561Sobrien		}
784689857Sobrien	    }
7847130561Sobrien	  break;
7848130561Sobrien
7849130561Sobrien	case R_PPC64_TPREL64:
7850130561Sobrien	  if ((tls_mask & TLS_TPREL) == 0)
7851130561Sobrien	    {
7852130561Sobrien	      r_type = R_PPC64_NONE;
7853130561Sobrien	      rel->r_info = ELF64_R_INFO (r_symndx, r_type);
7854130561Sobrien	    }
7855130561Sobrien	  break;
785689857Sobrien	}
785789857Sobrien
7858130561Sobrien      /* Handle other relocations that tweak non-addend part of insn.  */
785989857Sobrien      insn = 0;
786089857Sobrien      switch (r_type)
786189857Sobrien	{
786289857Sobrien	default:
786389857Sobrien	  break;
786489857Sobrien
786589857Sobrien	  /* Branch taken prediction relocations.  */
786689857Sobrien	case R_PPC64_ADDR14_BRTAKEN:
786789857Sobrien	case R_PPC64_REL14_BRTAKEN:
7868104834Sobrien	  insn = 0x01 << 21; /* 'y' or 't' bit, lowest bit of BO field.  */
7869104834Sobrien	  /* Fall thru.  */
787089857Sobrien
787189857Sobrien	  /* Branch not taken prediction relocations.  */
787289857Sobrien	case R_PPC64_ADDR14_BRNTAKEN:
787389857Sobrien	case R_PPC64_REL14_BRNTAKEN:
7874130561Sobrien	  insn |= bfd_get_32 (output_bfd,
7875130561Sobrien			      contents + rel->r_offset) & ~(0x01 << 21);
787692828Sobrien	  if (is_power4)
787792828Sobrien	    {
787892828Sobrien	      /* Set 'a' bit.  This is 0b00010 in BO field for branch
787992828Sobrien		 on CR(BI) insns (BO == 001at or 011at), and 0b01000
788092828Sobrien		 for branch on CTR insns (BO == 1a00t or 1a01t).  */
788192828Sobrien	      if ((insn & (0x14 << 21)) == (0x04 << 21))
788292828Sobrien		insn |= 0x02 << 21;
788392828Sobrien	      else if ((insn & (0x14 << 21)) == (0x10 << 21))
788492828Sobrien		insn |= 0x08 << 21;
788592828Sobrien	      else
788692828Sobrien		break;
788792828Sobrien	    }
788889857Sobrien	  else
788992828Sobrien	    {
7890130561Sobrien	      from = (rel->r_offset
789199461Sobrien		      + input_section->output_offset
789299461Sobrien		      + input_section->output_section->vma);
789399461Sobrien
789492828Sobrien	      /* Invert 'y' bit if not the default.  */
7895130561Sobrien	      if ((bfd_signed_vma) (relocation + rel->r_addend - from) < 0)
789692828Sobrien		insn ^= 0x01 << 21;
789792828Sobrien	    }
789889857Sobrien
7899130561Sobrien	  bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
790089857Sobrien	  break;
790189857Sobrien
790289857Sobrien	case R_PPC64_REL24:
7903130561Sobrien	  /* Calls to functions with a different TOC, such as calls to
7904130561Sobrien	     shared objects, need to alter the TOC pointer.  This is
7905130561Sobrien	     done using a linkage stub.  A REL24 branching to these
7906130561Sobrien	     linkage stubs needs to be followed by a nop, as the nop
7907130561Sobrien	     will be replaced with an instruction to restore the TOC
7908130561Sobrien	     base pointer.  */
7909130561Sobrien	  if (((h != NULL
7910130561Sobrien		&& (fdh = ((struct ppc_link_hash_entry *) h)->oh) != NULL
7911130561Sobrien		&& fdh->plt.plist != NULL)
7912130561Sobrien	       || ((fdh = h, sec) != NULL
7913130561Sobrien		   && sec->output_section != NULL
7914130561Sobrien		   && (htab->stub_group[sec->id].toc_off
7915130561Sobrien		       != htab->stub_group[input_section->id].toc_off)))
7916104834Sobrien	      && (stub_entry = ppc_get_stub_entry (input_section, sec, fdh,
7917130561Sobrien						   rel, htab)) != NULL
7918130561Sobrien	      && (stub_entry->stub_type == ppc_stub_plt_call
7919130561Sobrien		  || stub_entry->stub_type == ppc_stub_plt_branch_r2off
7920130561Sobrien		  || stub_entry->stub_type == ppc_stub_long_branch_r2off))
792189857Sobrien	    {
7922130561Sobrien	      bfd_boolean can_plt_call = 0;
792389857Sobrien
7924130561Sobrien	      if (rel->r_offset + 8 <= input_section->_cooked_size)
792589857Sobrien		{
7926130561Sobrien		  insn = bfd_get_32 (input_bfd, contents + rel->r_offset + 4);
792799461Sobrien		  if (insn == NOP
792899461Sobrien		      || insn == CROR_151515 || insn == CROR_313131)
792989857Sobrien		    {
7930130561Sobrien		      bfd_put_32 (input_bfd, LD_R2_40R1,
7931130561Sobrien				  contents + rel->r_offset + 4);
793299461Sobrien		      can_plt_call = 1;
793389857Sobrien		    }
793489857Sobrien		}
793599461Sobrien
793699461Sobrien	      if (!can_plt_call)
793799461Sobrien		{
7938130561Sobrien		  if (stub_entry->stub_type == ppc_stub_plt_call)
7939130561Sobrien		    {
7940130561Sobrien		      /* If this is a plain branch rather than a branch
7941130561Sobrien			 and link, don't require a nop.  */
7942130561Sobrien		      insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
7943130561Sobrien		      if ((insn & 1) == 0)
7944130561Sobrien			can_plt_call = 1;
7945130561Sobrien		    }
7946130561Sobrien		  else if (h != NULL
7947130561Sobrien			   && strcmp (h->root.root.string,
7948130561Sobrien				      ".__libc_start_main") == 0)
7949130561Sobrien		    {
7950130561Sobrien		      /* Allow crt1 branch to go via a toc adjusting stub.  */
7951130561Sobrien		      can_plt_call = 1;
7952130561Sobrien		    }
7953130561Sobrien		  else
7954130561Sobrien		    {
7955130561Sobrien		      if (strcmp (input_section->output_section->name,
7956130561Sobrien				  ".init") == 0
7957130561Sobrien			  || strcmp (input_section->output_section->name,
7958130561Sobrien				     ".fini") == 0)
7959130561Sobrien			(*_bfd_error_handler)
7960130561Sobrien			  (_("%s(%s+0x%lx): automatic multiple TOCs "
7961130561Sobrien			     "not supported using your crt files; "
7962130561Sobrien			     "recompile with -mminimal-toc or upgrade gcc"),
7963130561Sobrien			   bfd_archive_filename (input_bfd),
7964130561Sobrien			   input_section->name,
7965130561Sobrien			   (long) rel->r_offset);
7966130561Sobrien		      else
7967130561Sobrien			(*_bfd_error_handler)
7968130561Sobrien			  (_("%s(%s+0x%lx): sibling call optimization to `%s' "
7969130561Sobrien			     "does not allow automatic multiple TOCs; "
7970130561Sobrien			     "recompile with -mminimal-toc or "
7971130561Sobrien			     "-fno-optimize-sibling-calls, "
7972130561Sobrien			     "or make `%s' extern"),
7973130561Sobrien			   bfd_archive_filename (input_bfd),
7974130561Sobrien			   input_section->name,
7975130561Sobrien			   (long) rel->r_offset,
7976130561Sobrien			   sym_name,
7977130561Sobrien			   sym_name);
7978130561Sobrien		      bfd_set_error (bfd_error_bad_value);
7979130561Sobrien		      ret = FALSE;
7980130561Sobrien		    }
798199461Sobrien		}
798299461Sobrien
798399461Sobrien	      if (can_plt_call)
798499461Sobrien		{
7985104834Sobrien		  relocation = (stub_entry->stub_offset
7986104834Sobrien				+ stub_entry->stub_sec->output_offset
7987104834Sobrien				+ stub_entry->stub_sec->output_section->vma);
7988130561Sobrien		  if (stub_entry->stub_type == ppc_stub_plt_call)
7989130561Sobrien		    unresolved_reloc = FALSE;
799099461Sobrien		}
799189857Sobrien	    }
799289857Sobrien
799389857Sobrien	  if (h != NULL
799489857Sobrien	      && h->root.type == bfd_link_hash_undefweak
799599461Sobrien	      && relocation == 0
7996130561Sobrien	      && rel->r_addend == 0)
799789857Sobrien	    {
799899461Sobrien	      /* Tweak calls to undefined weak functions to point at a
799999461Sobrien		 blr.  We can thus call a weak function without first
800099461Sobrien		 checking whether the function is defined.  We have a
800199461Sobrien		 blr at the end of .sfpr.  */
800299461Sobrien	      BFD_ASSERT (htab->sfpr->_raw_size != 0);
800399461Sobrien	      relocation = (htab->sfpr->_raw_size - 4
800499461Sobrien			    + htab->sfpr->output_offset
800599461Sobrien			    + htab->sfpr->output_section->vma);
8006130561Sobrien	      from = (rel->r_offset
800799461Sobrien		      + input_section->output_offset
800899461Sobrien		      + input_section->output_section->vma);
800999461Sobrien
801099461Sobrien	      /* But let's not be silly about it.  If the blr isn't in
801199461Sobrien		 reach, just go to the next instruction.  */
801299461Sobrien	      if (relocation - from + (1 << 25) >= (1 << 26)
801399461Sobrien		  || htab->sfpr->_raw_size == 0)
801499461Sobrien		relocation = from + 4;
801589857Sobrien	    }
801689857Sobrien	  break;
801789857Sobrien	}
801889857Sobrien
801989857Sobrien      /* Set `addend'.  */
8020130561Sobrien      tls_type = 0;
8021130561Sobrien      addend = rel->r_addend;
802289857Sobrien      switch (r_type)
802389857Sobrien	{
802489857Sobrien	default:
802589857Sobrien	  (*_bfd_error_handler)
802689857Sobrien	    (_("%s: unknown relocation type %d for symbol %s"),
802789857Sobrien	     bfd_archive_filename (input_bfd), (int) r_type, sym_name);
802889857Sobrien
802989857Sobrien	  bfd_set_error (bfd_error_bad_value);
8030130561Sobrien	  ret = FALSE;
803189857Sobrien	  continue;
803289857Sobrien
803389857Sobrien	case R_PPC64_NONE:
8034130561Sobrien	case R_PPC64_TLS:
8035130561Sobrien	case R_PPC64_GNU_VTINHERIT:
8036130561Sobrien	case R_PPC64_GNU_VTENTRY:
803789857Sobrien	  continue;
803889857Sobrien
803989857Sobrien	  /* GOT16 relocations.  Like an ADDR16 using the symbol's
804089857Sobrien	     address in the GOT as relocation value instead of the
8041130561Sobrien	     symbol's value itself.  Also, create a GOT entry for the
804289857Sobrien	     symbol and put the symbol value there.  */
8043130561Sobrien	case R_PPC64_GOT_TLSGD16:
8044130561Sobrien	case R_PPC64_GOT_TLSGD16_LO:
8045130561Sobrien	case R_PPC64_GOT_TLSGD16_HI:
8046130561Sobrien	case R_PPC64_GOT_TLSGD16_HA:
8047130561Sobrien	  tls_type = TLS_TLS | TLS_GD;
8048130561Sobrien	  goto dogot;
8049130561Sobrien
8050130561Sobrien	case R_PPC64_GOT_TLSLD16:
8051130561Sobrien	case R_PPC64_GOT_TLSLD16_LO:
8052130561Sobrien	case R_PPC64_GOT_TLSLD16_HI:
8053130561Sobrien	case R_PPC64_GOT_TLSLD16_HA:
8054130561Sobrien	  tls_type = TLS_TLS | TLS_LD;
8055130561Sobrien	  goto dogot;
8056130561Sobrien
8057130561Sobrien	case R_PPC64_GOT_TPREL16_DS:
8058130561Sobrien	case R_PPC64_GOT_TPREL16_LO_DS:
8059130561Sobrien	case R_PPC64_GOT_TPREL16_HI:
8060130561Sobrien	case R_PPC64_GOT_TPREL16_HA:
8061130561Sobrien	  tls_type = TLS_TLS | TLS_TPREL;
8062130561Sobrien	  goto dogot;
8063130561Sobrien
8064130561Sobrien	case R_PPC64_GOT_DTPREL16_DS:
8065130561Sobrien	case R_PPC64_GOT_DTPREL16_LO_DS:
8066130561Sobrien	case R_PPC64_GOT_DTPREL16_HI:
8067130561Sobrien	case R_PPC64_GOT_DTPREL16_HA:
8068130561Sobrien	  tls_type = TLS_TLS | TLS_DTPREL;
8069130561Sobrien	  goto dogot;
8070130561Sobrien
807189857Sobrien	case R_PPC64_GOT16:
807289857Sobrien	case R_PPC64_GOT16_LO:
807389857Sobrien	case R_PPC64_GOT16_HI:
807489857Sobrien	case R_PPC64_GOT16_HA:
807589857Sobrien	case R_PPC64_GOT16_DS:
807689857Sobrien	case R_PPC64_GOT16_LO_DS:
8077130561Sobrien	dogot:
807889857Sobrien	  {
807989857Sobrien	    /* Relocation is to the entry for this symbol in the global
808089857Sobrien	       offset table.  */
8081130561Sobrien	    asection *got;
8082130561Sobrien	    bfd_vma *offp;
808389857Sobrien	    bfd_vma off;
8084130561Sobrien	    unsigned long indx = 0;
808589857Sobrien
8086130561Sobrien	    if (tls_type == (TLS_TLS | TLS_LD)
8087130561Sobrien		&& (h == NULL
8088130561Sobrien		    || !(h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC)))
8089130561Sobrien	      offp = &ppc64_tlsld_got (input_bfd)->offset;
8090130561Sobrien	    else
809189857Sobrien	      {
8092130561Sobrien		struct got_entry *ent;
809389857Sobrien
8094130561Sobrien		if (h != NULL)
809589857Sobrien		  {
8096130561Sobrien		    bfd_boolean dyn = htab->elf.dynamic_sections_created;
8097130561Sobrien		    if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
8098130561Sobrien			|| (info->shared
8099130561Sobrien			    && SYMBOL_REFERENCES_LOCAL (info, h)))
8100130561Sobrien		      /* This is actually a static link, or it is a
8101130561Sobrien			 -Bsymbolic link and the symbol is defined
8102130561Sobrien			 locally, or the symbol was forced to be local
8103130561Sobrien			 because of a version file.  */
8104130561Sobrien		      ;
810589857Sobrien		    else
810689857Sobrien		      {
8107130561Sobrien			indx = h->dynindx;
8108130561Sobrien			unresolved_reloc = FALSE;
810989857Sobrien		      }
8110130561Sobrien		    ent = h->got.glist;
811189857Sobrien		  }
811289857Sobrien		else
8113130561Sobrien		  {
8114130561Sobrien		    if (local_got_ents == NULL)
8115130561Sobrien		      abort ();
8116130561Sobrien		    ent = local_got_ents[r_symndx];
8117130561Sobrien		  }
8118130561Sobrien
8119130561Sobrien		for (; ent != NULL; ent = ent->next)
8120130561Sobrien		  if (ent->addend == rel->r_addend
8121130561Sobrien		      && ent->owner == input_bfd
8122130561Sobrien		      && ent->tls_type == tls_type)
8123130561Sobrien		    break;
8124130561Sobrien		if (ent == NULL)
8125130561Sobrien		  abort ();
8126130561Sobrien		offp = &ent->got.offset;
812789857Sobrien	      }
8128130561Sobrien
8129130561Sobrien	    got = ppc64_elf_tdata (input_bfd)->got;
8130130561Sobrien	    if (got == NULL)
8131130561Sobrien	      abort ();
8132130561Sobrien
8133130561Sobrien	    /* The offset must always be a multiple of 8.  We use the
8134130561Sobrien	       least significant bit to record whether we have already
8135130561Sobrien	       processed this entry.  */
8136130561Sobrien	    off = *offp;
8137130561Sobrien	    if ((off & 1) != 0)
8138130561Sobrien	      off &= ~1;
813989857Sobrien	    else
814089857Sobrien	      {
8141130561Sobrien		/* Generate relocs for the dynamic linker, except in
8142130561Sobrien		   the case of TLSLD where we'll use one entry per
8143130561Sobrien		   module.  */
8144130561Sobrien		asection *relgot = ppc64_elf_tdata (input_bfd)->relgot;
814589857Sobrien
8146130561Sobrien		*offp = off | 1;
8147130561Sobrien		if ((info->shared || indx != 0)
8148130561Sobrien		    && (h == NULL
8149130561Sobrien			|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
8150130561Sobrien			|| h->root.type != bfd_link_hash_undefweak))
8151130561Sobrien		  {
8152130561Sobrien		    outrel.r_offset = (got->output_section->vma
8153130561Sobrien				       + got->output_offset
8154130561Sobrien				       + off);
8155130561Sobrien		    outrel.r_addend = rel->r_addend;
8156130561Sobrien		    if (tls_type & (TLS_LD | TLS_GD))
8157130561Sobrien		      {
8158130561Sobrien			outrel.r_addend = 0;
8159130561Sobrien			outrel.r_info = ELF64_R_INFO (indx, R_PPC64_DTPMOD64);
8160130561Sobrien			if (tls_type == (TLS_TLS | TLS_GD))
8161130561Sobrien			  {
8162130561Sobrien			    loc = relgot->contents;
8163130561Sobrien			    loc += (relgot->reloc_count++
8164130561Sobrien				    * sizeof (Elf64_External_Rela));
8165130561Sobrien			    bfd_elf64_swap_reloca_out (output_bfd,
8166130561Sobrien						       &outrel, loc);
8167130561Sobrien			    outrel.r_offset += 8;
8168130561Sobrien			    outrel.r_addend = rel->r_addend;
8169130561Sobrien			    outrel.r_info
8170130561Sobrien			      = ELF64_R_INFO (indx, R_PPC64_DTPREL64);
8171130561Sobrien			  }
8172130561Sobrien		      }
8173130561Sobrien		    else if (tls_type == (TLS_TLS | TLS_DTPREL))
8174130561Sobrien		      outrel.r_info = ELF64_R_INFO (indx, R_PPC64_DTPREL64);
8175130561Sobrien		    else if (tls_type == (TLS_TLS | TLS_TPREL))
8176130561Sobrien		      outrel.r_info = ELF64_R_INFO (indx, R_PPC64_TPREL64);
8177130561Sobrien		    else if (indx == 0)
8178130561Sobrien		      {
8179130561Sobrien			outrel.r_info = ELF64_R_INFO (indx, R_PPC64_RELATIVE);
818089857Sobrien
8181130561Sobrien			/* Write the .got section contents for the sake
8182130561Sobrien			   of prelink.  */
8183130561Sobrien			loc = got->contents + off;
8184130561Sobrien			bfd_put_64 (output_bfd, outrel.r_addend + relocation,
8185130561Sobrien				    loc);
8186130561Sobrien		      }
8187130561Sobrien		    else
8188130561Sobrien		      outrel.r_info = ELF64_R_INFO (indx, R_PPC64_GLOB_DAT);
8189130561Sobrien
8190130561Sobrien		    if (indx == 0 && tls_type != (TLS_TLS | TLS_LD))
8191130561Sobrien		      {
8192130561Sobrien			outrel.r_addend += relocation;
8193130561Sobrien			if (tls_type & (TLS_GD | TLS_DTPREL | TLS_TPREL))
8194130561Sobrien			  outrel.r_addend -= htab->elf.tls_sec->vma;
8195130561Sobrien		      }
8196130561Sobrien		    loc = relgot->contents;
8197130561Sobrien		    loc += (relgot->reloc_count++
8198130561Sobrien			    * sizeof (Elf64_External_Rela));
8199130561Sobrien		    bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
8200130561Sobrien		  }
8201130561Sobrien
8202130561Sobrien		/* Init the .got section contents here if we're not
8203130561Sobrien		   emitting a reloc.  */
820489857Sobrien		else
820589857Sobrien		  {
8206130561Sobrien		    relocation += rel->r_addend;
8207130561Sobrien		    if (tls_type == (TLS_TLS | TLS_LD))
8208130561Sobrien		      relocation = 1;
8209130561Sobrien		    else if (tls_type != 0)
821089857Sobrien		      {
8211130561Sobrien			relocation -= htab->elf.tls_sec->vma + DTP_OFFSET;
8212130561Sobrien			if (tls_type == (TLS_TLS | TLS_TPREL))
8213130561Sobrien			  relocation += DTP_OFFSET - TP_OFFSET;
821489857Sobrien
8215130561Sobrien			if (tls_type == (TLS_TLS | TLS_GD))
8216130561Sobrien			  {
8217130561Sobrien			    bfd_put_64 (output_bfd, relocation,
8218130561Sobrien					got->contents + off + 8);
8219130561Sobrien			    relocation = 1;
8220130561Sobrien			  }
822189857Sobrien		      }
822289857Sobrien
8223130561Sobrien		    bfd_put_64 (output_bfd, relocation,
8224130561Sobrien				got->contents + off);
822589857Sobrien		  }
822689857Sobrien	      }
822789857Sobrien
822889857Sobrien	    if (off >= (bfd_vma) -2)
822989857Sobrien	      abort ();
823089857Sobrien
8231130561Sobrien	    relocation = got->output_offset + off;
823289857Sobrien
823389857Sobrien	    /* TOC base (r2) is TOC start plus 0x8000.  */
8234130561Sobrien	    addend = -TOC_BASE_OFF;
823589857Sobrien	  }
823689857Sobrien	  break;
823789857Sobrien
823889857Sobrien	case R_PPC64_PLT16_HA:
823989857Sobrien	case R_PPC64_PLT16_HI:
824089857Sobrien	case R_PPC64_PLT16_LO:
824189857Sobrien	case R_PPC64_PLT32:
824289857Sobrien	case R_PPC64_PLT64:
824389857Sobrien	  /* Relocation is to the entry for this symbol in the
824489857Sobrien	     procedure linkage table.  */
824589857Sobrien
824689857Sobrien	  /* Resolve a PLT reloc against a local symbol directly,
824789857Sobrien	     without using the procedure linkage table.  */
824889857Sobrien	  if (h == NULL)
824989857Sobrien	    break;
825089857Sobrien
8251130561Sobrien	  /* It's possible that we didn't make a PLT entry for this
8252130561Sobrien	     symbol.  This happens when statically linking PIC code,
8253130561Sobrien	     or when using -Bsymbolic.  Go find a match if there is a
8254130561Sobrien	     PLT entry.  */
8255130561Sobrien	  if (htab->plt != NULL)
825689857Sobrien	    {
8257130561Sobrien	      struct plt_entry *ent;
8258130561Sobrien	      for (ent = h->plt.plist; ent != NULL; ent = ent->next)
8259130561Sobrien		if (ent->addend == rel->r_addend
8260130561Sobrien		    && ent->plt.offset != (bfd_vma) -1)
8261130561Sobrien		  {
8262130561Sobrien		    relocation = (htab->plt->output_section->vma
8263130561Sobrien				  + htab->plt->output_offset
8264130561Sobrien				  + ent->plt.offset);
8265130561Sobrien		    unresolved_reloc = FALSE;
8266130561Sobrien		  }
826789857Sobrien	    }
826889857Sobrien	  break;
826989857Sobrien
8270130561Sobrien	case R_PPC64_TOC:
8271130561Sobrien	  /* Relocation value is TOC base.  */
8272130561Sobrien	  relocation = TOCstart;
8273130561Sobrien	  if (r_symndx == 0)
8274130561Sobrien	    relocation += htab->stub_group[input_section->id].toc_off;
8275130561Sobrien	  else if (unresolved_reloc)
8276130561Sobrien	    ;
8277130561Sobrien	  else if (sec != NULL && sec->id <= htab->top_id)
8278130561Sobrien	    relocation += htab->stub_group[sec->id].toc_off;
8279130561Sobrien	  else
8280130561Sobrien	    unresolved_reloc = TRUE;
8281130561Sobrien	  goto dodyn2;
8282130561Sobrien
828389857Sobrien	  /* TOC16 relocs.  We want the offset relative to the TOC base,
828489857Sobrien	     which is the address of the start of the TOC plus 0x8000.
828589857Sobrien	     The TOC consists of sections .got, .toc, .tocbss, and .plt,
828689857Sobrien	     in this order.  */
828789857Sobrien	case R_PPC64_TOC16:
828889857Sobrien	case R_PPC64_TOC16_LO:
828989857Sobrien	case R_PPC64_TOC16_HI:
829089857Sobrien	case R_PPC64_TOC16_DS:
829189857Sobrien	case R_PPC64_TOC16_LO_DS:
829289857Sobrien	case R_PPC64_TOC16_HA:
8293130561Sobrien	  addend -= TOCstart + htab->stub_group[input_section->id].toc_off;
829489857Sobrien	  break;
829589857Sobrien
829689857Sobrien	  /* Relocate against the beginning of the section.  */
829789857Sobrien	case R_PPC64_SECTOFF:
829889857Sobrien	case R_PPC64_SECTOFF_LO:
829989857Sobrien	case R_PPC64_SECTOFF_HI:
830089857Sobrien	case R_PPC64_SECTOFF_DS:
830189857Sobrien	case R_PPC64_SECTOFF_LO_DS:
830289857Sobrien	case R_PPC64_SECTOFF_HA:
8303130561Sobrien	  if (sec != NULL)
830489857Sobrien	    addend -= sec->output_section->vma;
830589857Sobrien	  break;
830689857Sobrien
8307104834Sobrien	case R_PPC64_REL14:
8308104834Sobrien	case R_PPC64_REL14_BRNTAKEN:
8309104834Sobrien	case R_PPC64_REL14_BRTAKEN:
831089857Sobrien	case R_PPC64_REL24:
831189857Sobrien	  break;
831289857Sobrien
8313130561Sobrien	case R_PPC64_TPREL16:
8314130561Sobrien	case R_PPC64_TPREL16_LO:
8315130561Sobrien	case R_PPC64_TPREL16_HI:
8316130561Sobrien	case R_PPC64_TPREL16_HA:
8317130561Sobrien	case R_PPC64_TPREL16_DS:
8318130561Sobrien	case R_PPC64_TPREL16_LO_DS:
8319130561Sobrien	case R_PPC64_TPREL16_HIGHER:
8320130561Sobrien	case R_PPC64_TPREL16_HIGHERA:
8321130561Sobrien	case R_PPC64_TPREL16_HIGHEST:
8322130561Sobrien	case R_PPC64_TPREL16_HIGHESTA:
8323130561Sobrien	  addend -= htab->elf.tls_sec->vma + TP_OFFSET;
8324130561Sobrien	  if (info->shared)
8325130561Sobrien	    /* The TPREL16 relocs shouldn't really be used in shared
8326130561Sobrien	       libs as they will result in DT_TEXTREL being set, but
8327130561Sobrien	       support them anyway.  */
8328130561Sobrien	    goto dodyn;
8329130561Sobrien	  break;
8330130561Sobrien
8331130561Sobrien	case R_PPC64_DTPREL16:
8332130561Sobrien	case R_PPC64_DTPREL16_LO:
8333130561Sobrien	case R_PPC64_DTPREL16_HI:
8334130561Sobrien	case R_PPC64_DTPREL16_HA:
8335130561Sobrien	case R_PPC64_DTPREL16_DS:
8336130561Sobrien	case R_PPC64_DTPREL16_LO_DS:
8337130561Sobrien	case R_PPC64_DTPREL16_HIGHER:
8338130561Sobrien	case R_PPC64_DTPREL16_HIGHERA:
8339130561Sobrien	case R_PPC64_DTPREL16_HIGHEST:
8340130561Sobrien	case R_PPC64_DTPREL16_HIGHESTA:
8341130561Sobrien	  addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
8342130561Sobrien	  break;
8343130561Sobrien
8344130561Sobrien	case R_PPC64_DTPMOD64:
8345130561Sobrien	  relocation = 1;
8346130561Sobrien	  addend = 0;
8347130561Sobrien	  goto dodyn;
8348130561Sobrien
8349130561Sobrien	case R_PPC64_TPREL64:
8350130561Sobrien	  addend -= htab->elf.tls_sec->vma + TP_OFFSET;
8351130561Sobrien	  goto dodyn;
8352130561Sobrien
8353130561Sobrien	case R_PPC64_DTPREL64:
8354130561Sobrien	  addend -= htab->elf.tls_sec->vma + DTP_OFFSET;
8355130561Sobrien	  /* Fall thru */
8356130561Sobrien
835789857Sobrien	  /* Relocations that may need to be propagated if this is a
835889857Sobrien	     dynamic object.  */
8359130561Sobrien	case R_PPC64_REL30:
836089857Sobrien	case R_PPC64_REL32:
836189857Sobrien	case R_PPC64_REL64:
836289857Sobrien	case R_PPC64_ADDR14:
836389857Sobrien	case R_PPC64_ADDR14_BRNTAKEN:
836489857Sobrien	case R_PPC64_ADDR14_BRTAKEN:
836589857Sobrien	case R_PPC64_ADDR16:
836689857Sobrien	case R_PPC64_ADDR16_DS:
836789857Sobrien	case R_PPC64_ADDR16_HA:
836889857Sobrien	case R_PPC64_ADDR16_HI:
836989857Sobrien	case R_PPC64_ADDR16_HIGHER:
837089857Sobrien	case R_PPC64_ADDR16_HIGHERA:
837189857Sobrien	case R_PPC64_ADDR16_HIGHEST:
837289857Sobrien	case R_PPC64_ADDR16_HIGHESTA:
837389857Sobrien	case R_PPC64_ADDR16_LO:
837489857Sobrien	case R_PPC64_ADDR16_LO_DS:
837589857Sobrien	case R_PPC64_ADDR24:
837689857Sobrien	case R_PPC64_ADDR32:
837789857Sobrien	case R_PPC64_ADDR64:
837889857Sobrien	case R_PPC64_UADDR16:
837989857Sobrien	case R_PPC64_UADDR32:
838089857Sobrien	case R_PPC64_UADDR64:
838189857Sobrien	  /* r_symndx will be zero only for relocs against symbols
838289857Sobrien	     from removed linkonce sections, or sections discarded by
838389857Sobrien	     a linker script.  */
8384130561Sobrien	dodyn:
838589857Sobrien	  if (r_symndx == 0)
838689857Sobrien	    break;
838789857Sobrien	  /* Fall thru.  */
838889857Sobrien
8389130561Sobrien	dodyn2:
839089857Sobrien	  if ((input_section->flags & SEC_ALLOC) == 0)
839189857Sobrien	    break;
839289857Sobrien
839389857Sobrien	  if (NO_OPD_RELOCS && is_opd)
839489857Sobrien	    break;
839589857Sobrien
839689857Sobrien	  if ((info->shared
8397130561Sobrien	       && (h == NULL
8398130561Sobrien		   || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
8399130561Sobrien		   || h->root.type != bfd_link_hash_undefweak)
8400130561Sobrien	       && (MUST_BE_DYN_RELOC (r_type)
8401130561Sobrien		   || !SYMBOL_CALLS_LOCAL (info, h)))
8402130561Sobrien	      || (ELIMINATE_COPY_RELOCS
8403130561Sobrien		  && !info->shared
840489857Sobrien		  && h != NULL
840589857Sobrien		  && h->dynindx != -1
840689857Sobrien		  && (h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0
8407130561Sobrien		  && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
8408130561Sobrien		  && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0))
840989857Sobrien	    {
841089857Sobrien	      Elf_Internal_Rela outrel;
8411130561Sobrien	      bfd_boolean skip, relocate;
841289857Sobrien	      asection *sreloc;
8413130561Sobrien	      bfd_byte *loc;
8414130561Sobrien	      bfd_vma out_off;
841589857Sobrien
841689857Sobrien	      /* When generating a dynamic object, these relocations
841789857Sobrien		 are copied into the output file to be resolved at run
841889857Sobrien		 time.  */
841989857Sobrien
8420130561Sobrien	      skip = FALSE;
8421130561Sobrien	      relocate = FALSE;
842289857Sobrien
8423130561Sobrien	      out_off = _bfd_elf_section_offset (output_bfd, info,
8424130561Sobrien						 input_section, rel->r_offset);
8425130561Sobrien	      if (out_off == (bfd_vma) -1)
8426130561Sobrien		skip = TRUE;
8427130561Sobrien	      else if (out_off == (bfd_vma) -2)
8428130561Sobrien		skip = TRUE, relocate = TRUE;
8429130561Sobrien	      out_off += (input_section->output_section->vma
8430130561Sobrien			  + input_section->output_offset);
8431130561Sobrien	      outrel.r_offset = out_off;
8432130561Sobrien	      outrel.r_addend = rel->r_addend;
843389857Sobrien
8434130561Sobrien	      /* Optimize unaligned reloc use.  */
8435130561Sobrien	      if ((r_type == R_PPC64_ADDR64 && (out_off & 7) != 0)
8436130561Sobrien		  || (r_type == R_PPC64_UADDR64 && (out_off & 7) == 0))
8437130561Sobrien		r_type ^= R_PPC64_ADDR64 ^ R_PPC64_UADDR64;
8438130561Sobrien	      else if ((r_type == R_PPC64_ADDR32 && (out_off & 3) != 0)
8439130561Sobrien		       || (r_type == R_PPC64_UADDR32 && (out_off & 3) == 0))
8440130561Sobrien		r_type ^= R_PPC64_ADDR32 ^ R_PPC64_UADDR32;
8441130561Sobrien	      else if ((r_type == R_PPC64_ADDR16 && (out_off & 1) != 0)
8442130561Sobrien		       || (r_type == R_PPC64_UADDR16 && (out_off & 1) == 0))
8443130561Sobrien		r_type ^= R_PPC64_ADDR16 ^ R_PPC64_UADDR16;
8444130561Sobrien
844589857Sobrien	      if (skip)
844691041Sobrien		memset (&outrel, 0, sizeof outrel);
8447130561Sobrien	      else if (!SYMBOL_REFERENCES_LOCAL (info, h)
844889857Sobrien		       && !is_opd
8449130561Sobrien		       && r_type != R_PPC64_TOC)
845091041Sobrien		outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
845189857Sobrien	      else
845289857Sobrien		{
845389857Sobrien		  /* This symbol is local, or marked to become local,
845489857Sobrien		     or this is an opd section reloc which must point
845589857Sobrien		     at a local function.  */
845689857Sobrien		  outrel.r_addend += relocation;
845789857Sobrien		  if (r_type == R_PPC64_ADDR64 || r_type == R_PPC64_TOC)
845889857Sobrien		    {
8459104834Sobrien		      if (is_opd && h != NULL)
8460104834Sobrien			{
8461104834Sobrien			  /* Lie about opd entries.  This case occurs
8462104834Sobrien			     when building shared libraries and we
8463104834Sobrien			     reference a function in another shared
8464104834Sobrien			     lib.  The same thing happens for a weak
8465104834Sobrien			     definition in an application that's
8466104834Sobrien			     overridden by a strong definition in a
8467104834Sobrien			     shared lib.  (I believe this is a generic
8468104834Sobrien			     bug in binutils handling of weak syms.)
8469104834Sobrien			     In these cases we won't use the opd
8470104834Sobrien			     entry in this lib.  */
8471130561Sobrien			  unresolved_reloc = FALSE;
8472104834Sobrien			}
847389857Sobrien		      outrel.r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE);
8474130561Sobrien
8475130561Sobrien		      /* We need to relocate .opd contents for ld.so.
8476130561Sobrien			 Prelink also wants simple and consistent rules
8477130561Sobrien			 for relocs.  This make all RELATIVE relocs have
8478130561Sobrien			 *r_offset equal to r_addend.  */
8479130561Sobrien		      relocate = TRUE;
848089857Sobrien		    }
848189857Sobrien		  else
848289857Sobrien		    {
848389857Sobrien		      long indx = 0;
848489857Sobrien
848589857Sobrien		      if (bfd_is_abs_section (sec))
848689857Sobrien			;
848789857Sobrien		      else if (sec == NULL || sec->owner == NULL)
848889857Sobrien			{
848989857Sobrien			  bfd_set_error (bfd_error_bad_value);
8490130561Sobrien			  return FALSE;
849189857Sobrien			}
849289857Sobrien		      else
849389857Sobrien			{
849489857Sobrien			  asection *osec;
849589857Sobrien
849689857Sobrien			  osec = sec->output_section;
849789857Sobrien			  indx = elf_section_data (osec)->dynindx;
849889857Sobrien
849989857Sobrien			  /* We are turning this relocation into one
850089857Sobrien			     against a section symbol, so subtract out
850189857Sobrien			     the output section's address but not the
850289857Sobrien			     offset of the input section in the output
850389857Sobrien			     section.  */
850489857Sobrien			  outrel.r_addend -= osec->vma;
850589857Sobrien			}
850689857Sobrien
850789857Sobrien		      outrel.r_info = ELF64_R_INFO (indx, r_type);
850889857Sobrien		    }
850989857Sobrien		}
851089857Sobrien
851189857Sobrien	      sreloc = elf_section_data (input_section)->sreloc;
851289857Sobrien	      if (sreloc == NULL)
851389857Sobrien		abort ();
851489857Sobrien
8515130561Sobrien	      loc = sreloc->contents;
8516130561Sobrien	      loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
851789857Sobrien	      bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
851889857Sobrien
851989857Sobrien	      /* If this reloc is against an external symbol, it will
852089857Sobrien		 be computed at runtime, so there's no need to do
8521130561Sobrien		 anything now.  However, for the sake of prelink ensure
8522130561Sobrien		 that the section contents are a known value.  */
852389857Sobrien	      if (! relocate)
8524130561Sobrien		{
8525130561Sobrien		  unresolved_reloc = FALSE;
8526130561Sobrien		  /* The value chosen here is quite arbitrary as ld.so
8527130561Sobrien		     ignores section contents except for the special
8528130561Sobrien		     case of .opd where the contents might be accessed
8529130561Sobrien		     before relocation.  Choose zero, as that won't
8530130561Sobrien		     cause reloc overflow.  */
8531130561Sobrien		  relocation = 0;
8532130561Sobrien		  addend = 0;
8533130561Sobrien		  /* Use *r_offset == r_addend for R_PPC64_ADDR64 relocs
8534130561Sobrien		     to improve backward compatibility with older
8535130561Sobrien		     versions of ld.  */
8536130561Sobrien		  if (r_type == R_PPC64_ADDR64)
8537130561Sobrien		    addend = outrel.r_addend;
8538130561Sobrien		  /* Adjust pc_relative relocs to have zero in *r_offset.  */
8539130561Sobrien		  else if (ppc64_elf_howto_table[r_type]->pc_relative)
8540130561Sobrien		    addend = (input_section->output_section->vma
8541130561Sobrien			      + input_section->output_offset
8542130561Sobrien			      + rel->r_offset);
8543130561Sobrien		}
854489857Sobrien	    }
854589857Sobrien	  break;
854689857Sobrien
854789857Sobrien	case R_PPC64_COPY:
854889857Sobrien	case R_PPC64_GLOB_DAT:
854989857Sobrien	case R_PPC64_JMP_SLOT:
855089857Sobrien	case R_PPC64_RELATIVE:
855189857Sobrien	  /* We shouldn't ever see these dynamic relocs in relocatable
855289857Sobrien	     files.  */
8553130561Sobrien	  /* Fall through.  */
855489857Sobrien
855589857Sobrien	case R_PPC64_PLTGOT16:
855689857Sobrien	case R_PPC64_PLTGOT16_DS:
855789857Sobrien	case R_PPC64_PLTGOT16_HA:
855889857Sobrien	case R_PPC64_PLTGOT16_HI:
855989857Sobrien	case R_PPC64_PLTGOT16_LO:
856089857Sobrien	case R_PPC64_PLTGOT16_LO_DS:
856189857Sobrien	case R_PPC64_PLTREL32:
856289857Sobrien	case R_PPC64_PLTREL64:
856389857Sobrien	  /* These ones haven't been implemented yet.  */
856489857Sobrien
856589857Sobrien	  (*_bfd_error_handler)
8566130561Sobrien	    (_("%s: relocation %s is not supported for symbol %s."),
856789857Sobrien	     bfd_archive_filename (input_bfd),
8568130561Sobrien	     ppc64_elf_howto_table[r_type]->name, sym_name);
856989857Sobrien
857089857Sobrien	  bfd_set_error (bfd_error_invalid_operation);
8571130561Sobrien	  ret = FALSE;
857289857Sobrien	  continue;
857389857Sobrien	}
857489857Sobrien
857589857Sobrien      /* Do any further special processing.  */
857689857Sobrien      switch (r_type)
857789857Sobrien	{
857889857Sobrien	default:
857989857Sobrien	  break;
858089857Sobrien
858189857Sobrien	case R_PPC64_ADDR16_HA:
858289857Sobrien	case R_PPC64_ADDR16_HIGHERA:
858389857Sobrien	case R_PPC64_ADDR16_HIGHESTA:
8584130561Sobrien	case R_PPC64_GOT16_HA:
8585130561Sobrien	case R_PPC64_PLTGOT16_HA:
858689857Sobrien	case R_PPC64_PLT16_HA:
858789857Sobrien	case R_PPC64_TOC16_HA:
858889857Sobrien	case R_PPC64_SECTOFF_HA:
8589130561Sobrien	case R_PPC64_TPREL16_HA:
8590130561Sobrien	case R_PPC64_DTPREL16_HA:
8591130561Sobrien	case R_PPC64_GOT_TLSGD16_HA:
8592130561Sobrien	case R_PPC64_GOT_TLSLD16_HA:
8593130561Sobrien	case R_PPC64_GOT_TPREL16_HA:
8594130561Sobrien	case R_PPC64_GOT_DTPREL16_HA:
8595130561Sobrien	case R_PPC64_TPREL16_HIGHER:
8596130561Sobrien	case R_PPC64_TPREL16_HIGHERA:
8597130561Sobrien	case R_PPC64_TPREL16_HIGHEST:
8598130561Sobrien	case R_PPC64_TPREL16_HIGHESTA:
8599130561Sobrien	case R_PPC64_DTPREL16_HIGHER:
8600130561Sobrien	case R_PPC64_DTPREL16_HIGHERA:
8601130561Sobrien	case R_PPC64_DTPREL16_HIGHEST:
8602130561Sobrien	case R_PPC64_DTPREL16_HIGHESTA:
860389857Sobrien	  /* It's just possible that this symbol is a weak symbol
860489857Sobrien	     that's not actually defined anywhere. In that case,
860589857Sobrien	     'sec' would be NULL, and we should leave the symbol
860689857Sobrien	     alone (it will be set to zero elsewhere in the link).  */
860789857Sobrien	  if (sec != NULL)
8608130561Sobrien	    /* Add 0x10000 if sign bit in 0:15 is set.
8609130561Sobrien	       Bits 0:15 are not used.  */
8610130561Sobrien	    addend += 0x8000;
861189857Sobrien	  break;
861289857Sobrien
861389857Sobrien	case R_PPC64_ADDR16_DS:
861489857Sobrien	case R_PPC64_ADDR16_LO_DS:
861589857Sobrien	case R_PPC64_GOT16_DS:
861689857Sobrien	case R_PPC64_GOT16_LO_DS:
861789857Sobrien	case R_PPC64_PLT16_LO_DS:
861889857Sobrien	case R_PPC64_SECTOFF_DS:
861989857Sobrien	case R_PPC64_SECTOFF_LO_DS:
862089857Sobrien	case R_PPC64_TOC16_DS:
862189857Sobrien	case R_PPC64_TOC16_LO_DS:
862289857Sobrien	case R_PPC64_PLTGOT16_DS:
862389857Sobrien	case R_PPC64_PLTGOT16_LO_DS:
8624130561Sobrien	case R_PPC64_GOT_TPREL16_DS:
8625130561Sobrien	case R_PPC64_GOT_TPREL16_LO_DS:
8626130561Sobrien	case R_PPC64_GOT_DTPREL16_DS:
8627130561Sobrien	case R_PPC64_GOT_DTPREL16_LO_DS:
8628130561Sobrien	case R_PPC64_TPREL16_DS:
8629130561Sobrien	case R_PPC64_TPREL16_LO_DS:
8630130561Sobrien	case R_PPC64_DTPREL16_DS:
8631130561Sobrien	case R_PPC64_DTPREL16_LO_DS:
8632130561Sobrien	  insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
8633130561Sobrien	  mask = 3;
8634130561Sobrien	  /* If this reloc is against an lq insn, then the value must be
8635130561Sobrien	     a multiple of 16.  This is somewhat of a hack, but the
8636130561Sobrien	     "correct" way to do this by defining _DQ forms of all the
8637130561Sobrien	     _DS relocs bloats all reloc switches in this file.  It
8638130561Sobrien	     doesn't seem to make much sense to use any of these relocs
8639130561Sobrien	     in data, so testing the insn should be safe.  */
8640130561Sobrien	  if ((insn & (0x3f << 26)) == (56u << 26))
8641130561Sobrien	    mask = 15;
8642130561Sobrien	  if (((relocation + addend) & mask) != 0)
864389857Sobrien	    {
864489857Sobrien	      (*_bfd_error_handler)
8645130561Sobrien		(_("%s: error: relocation %s not a multiple of %d"),
864689857Sobrien		 bfd_archive_filename (input_bfd),
8647130561Sobrien		 ppc64_elf_howto_table[r_type]->name,
8648130561Sobrien		 mask + 1);
864989857Sobrien	      bfd_set_error (bfd_error_bad_value);
8650130561Sobrien	      ret = FALSE;
865189857Sobrien	      continue;
865289857Sobrien	    }
865389857Sobrien	  break;
8654104834Sobrien
8655104834Sobrien	case R_PPC64_REL14:
8656104834Sobrien	case R_PPC64_REL14_BRNTAKEN:
8657104834Sobrien	case R_PPC64_REL14_BRTAKEN:
8658104834Sobrien	  max_br_offset = 1 << 15;
8659104834Sobrien	  goto branch_check;
8660104834Sobrien
8661104834Sobrien	case R_PPC64_REL24:
8662104834Sobrien	  max_br_offset = 1 << 25;
8663104834Sobrien
8664104834Sobrien	branch_check:
8665130561Sobrien	  /* If the branch is out of reach or the TOC register needs
8666130561Sobrien	     adjusting, then redirect the call to the local stub for
8667130561Sobrien	     this function.  */
8668130561Sobrien	  from = (rel->r_offset
8669104834Sobrien		  + input_section->output_offset
8670104834Sobrien		  + input_section->output_section->vma);
8671130561Sobrien	  if ((relocation + addend - from + max_br_offset >= 2 * max_br_offset
8672130561Sobrien	       || (sec != NULL
8673130561Sobrien		   && sec->output_section != NULL
8674130561Sobrien		   && sec->id <= htab->top_id
8675130561Sobrien		   && (htab->stub_group[sec->id].toc_off
8676130561Sobrien		       != htab->stub_group[input_section->id].toc_off)))
8677104834Sobrien	      && (stub_entry = ppc_get_stub_entry (input_section, sec, h,
8678104834Sobrien						   rel, htab)) != NULL)
8679104834Sobrien	    {
8680104834Sobrien	      /* Munge up the value and addend so that we call the stub
8681104834Sobrien		 rather than the procedure directly.  */
8682104834Sobrien	      relocation = (stub_entry->stub_offset
8683104834Sobrien			    + stub_entry->stub_sec->output_offset
8684104834Sobrien			    + stub_entry->stub_sec->output_section->vma);
8685104834Sobrien	      addend = 0;
8686104834Sobrien	    }
8687104834Sobrien	  break;
868889857Sobrien	}
868989857Sobrien
8690104834Sobrien      /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
8691104834Sobrien	 because such sections are not SEC_ALLOC and thus ld.so will
8692104834Sobrien	 not process them.  */
869389857Sobrien      if (unresolved_reloc
8694104834Sobrien	  && !((input_section->flags & SEC_DEBUGGING) != 0
869589857Sobrien	       && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0))
8696104834Sobrien	{
8697104834Sobrien	  (*_bfd_error_handler)
8698130561Sobrien	    (_("%s(%s+0x%lx): unresolvable %s relocation against symbol `%s'"),
8699104834Sobrien	     bfd_archive_filename (input_bfd),
8700104834Sobrien	     bfd_get_section_name (input_bfd, input_section),
8701104834Sobrien	     (long) rel->r_offset,
8702130561Sobrien	     ppc64_elf_howto_table[(int) r_type]->name,
8703104834Sobrien	     h->root.root.string);
8704130561Sobrien	  ret = FALSE;
8705104834Sobrien	}
870689857Sobrien
870789857Sobrien      r = _bfd_final_link_relocate (ppc64_elf_howto_table[(int) r_type],
870889857Sobrien				    input_bfd,
870989857Sobrien				    input_section,
871089857Sobrien				    contents,
8711130561Sobrien				    rel->r_offset,
871289857Sobrien				    relocation,
871389857Sobrien				    addend);
871489857Sobrien
8715104834Sobrien      if (r != bfd_reloc_ok)
871689857Sobrien	{
8717130561Sobrien	  if (sym_name == NULL)
8718130561Sobrien	    sym_name = "(null)";
8719130561Sobrien	  if (r == bfd_reloc_overflow)
872089857Sobrien	    {
8721130561Sobrien	      if (warned)
8722130561Sobrien		continue;
8723130561Sobrien	      if (h != NULL
8724130561Sobrien		  && h->root.type == bfd_link_hash_undefweak
8725130561Sobrien		  && ppc64_elf_howto_table[r_type]->pc_relative)
872689857Sobrien		{
872789857Sobrien		  /* Assume this is a call protected by other code that
872889857Sobrien		     detects the symbol is undefined.  If this is the case,
872989857Sobrien		     we can safely ignore the overflow.  If not, the
873089857Sobrien		     program is hosed anyway, and a little warning isn't
873189857Sobrien		     going to help.  */
873289857Sobrien
873389857Sobrien		  continue;
873489857Sobrien		}
873589857Sobrien
8736104834Sobrien	      if (!((*info->callbacks->reloc_overflow)
8737130561Sobrien		    (info, sym_name, ppc64_elf_howto_table[r_type]->name,
8738130561Sobrien		     rel->r_addend, input_bfd, input_section, rel->r_offset)))
8739130561Sobrien		return FALSE;
8740104834Sobrien	    }
8741104834Sobrien	  else
8742104834Sobrien	    {
8743104834Sobrien	      (*_bfd_error_handler)
8744130561Sobrien		(_("%s(%s+0x%lx): %s reloc against `%s': error %d"),
8745104834Sobrien		 bfd_archive_filename (input_bfd),
8746104834Sobrien		 bfd_get_section_name (input_bfd, input_section),
8747130561Sobrien		 (long) rel->r_offset,
8748130561Sobrien		 ppc64_elf_howto_table[r_type]->name,
8749130561Sobrien		 sym_name,
8750130561Sobrien		 (int) r);
8751130561Sobrien	      ret = FALSE;
8752104834Sobrien	    }
875389857Sobrien	}
875489857Sobrien    }
875589857Sobrien
875689857Sobrien  return ret;
875789857Sobrien}
875889857Sobrien
8759130561Sobrien/* Adjust the value of any local symbols in opd sections.  */
8760130561Sobrien
8761130561Sobrienstatic bfd_boolean
8762130561Sobrienppc64_elf_output_symbol_hook (struct bfd_link_info *info,
8763130561Sobrien			      const char *name ATTRIBUTE_UNUSED,
8764130561Sobrien			      Elf_Internal_Sym *elfsym,
8765130561Sobrien			      asection *input_sec,
8766130561Sobrien			      struct elf_link_hash_entry *h)
8767130561Sobrien{
8768130561Sobrien  long *adjust;
8769130561Sobrien  bfd_vma value;
8770130561Sobrien
8771130561Sobrien  if (h != NULL
8772130561Sobrien      || input_sec == NULL
8773130561Sobrien      || ppc64_elf_section_data (input_sec) == NULL
8774130561Sobrien      || (adjust = ppc64_elf_section_data (input_sec)->opd.adjust) == NULL)
8775130561Sobrien    return TRUE;
8776130561Sobrien
8777130561Sobrien  value = elfsym->st_value - input_sec->output_offset;
8778130561Sobrien  if (!info->relocatable)
8779130561Sobrien    value -= input_sec->output_section->vma;
8780130561Sobrien
8781130561Sobrien  elfsym->st_value += adjust[value / 24];
8782130561Sobrien  return TRUE;
8783130561Sobrien}
8784130561Sobrien
878589857Sobrien/* Finish up dynamic symbol handling.  We set the contents of various
878689857Sobrien   dynamic sections here.  */
878789857Sobrien
8788130561Sobrienstatic bfd_boolean
8789130561Sobrienppc64_elf_finish_dynamic_symbol (bfd *output_bfd,
8790130561Sobrien				 struct bfd_link_info *info,
8791130561Sobrien				 struct elf_link_hash_entry *h,
8792130561Sobrien				 Elf_Internal_Sym *sym)
879389857Sobrien{
879489857Sobrien  struct ppc_link_hash_table *htab;
879589857Sobrien  bfd *dynobj;
879689857Sobrien
879789857Sobrien  htab = ppc_hash_table (info);
879889857Sobrien  dynobj = htab->elf.dynobj;
879989857Sobrien
8800130561Sobrien  if (((struct ppc_link_hash_entry *) h)->is_func_descriptor)
880189857Sobrien    {
8802130561Sobrien      struct plt_entry *ent;
880389857Sobrien      Elf_Internal_Rela rela;
8804130561Sobrien      bfd_byte *loc;
880589857Sobrien
8806130561Sobrien      for (ent = h->plt.plist; ent != NULL; ent = ent->next)
8807130561Sobrien	if (ent->plt.offset != (bfd_vma) -1)
8808130561Sobrien	  {
8809130561Sobrien	    /* This symbol has an entry in the procedure linkage
8810130561Sobrien	       table.  Set it up.  */
881189857Sobrien
8812130561Sobrien	    if (htab->plt == NULL
8813130561Sobrien		|| htab->relplt == NULL
8814130561Sobrien		|| htab->glink == NULL)
8815130561Sobrien	      abort ();
881689857Sobrien
8817130561Sobrien	    /* Create a JMP_SLOT reloc to inform the dynamic linker to
8818130561Sobrien	       fill in the PLT entry.  */
8819130561Sobrien	    rela.r_offset = (htab->plt->output_section->vma
8820130561Sobrien			     + htab->plt->output_offset
8821130561Sobrien			     + ent->plt.offset);
8822130561Sobrien	    rela.r_info = ELF64_R_INFO (h->dynindx, R_PPC64_JMP_SLOT);
8823130561Sobrien	    rela.r_addend = ent->addend;
882489857Sobrien
8825130561Sobrien	    loc = htab->relplt->contents;
8826130561Sobrien	    loc += ((ent->plt.offset - PLT_INITIAL_ENTRY_SIZE) / PLT_ENTRY_SIZE
8827130561Sobrien		    * sizeof (Elf64_External_Rela));
8828130561Sobrien	    bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
8829130561Sobrien	  }
883089857Sobrien    }
883189857Sobrien
883289857Sobrien  if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)
883389857Sobrien    {
883489857Sobrien      Elf_Internal_Rela rela;
8835130561Sobrien      bfd_byte *loc;
883689857Sobrien
883789857Sobrien      /* This symbol needs a copy reloc.  Set it up.  */
883889857Sobrien
883989857Sobrien      if (h->dynindx == -1
884089857Sobrien	  || (h->root.type != bfd_link_hash_defined
884189857Sobrien	      && h->root.type != bfd_link_hash_defweak)
8842130561Sobrien	  || htab->relbss == NULL)
884389857Sobrien	abort ();
884489857Sobrien
884589857Sobrien      rela.r_offset = (h->root.u.def.value
884689857Sobrien		       + h->root.u.def.section->output_section->vma
884789857Sobrien		       + h->root.u.def.section->output_offset);
884889857Sobrien      rela.r_info = ELF64_R_INFO (h->dynindx, R_PPC64_COPY);
884989857Sobrien      rela.r_addend = 0;
8850130561Sobrien      loc = htab->relbss->contents;
8851130561Sobrien      loc += htab->relbss->reloc_count++ * sizeof (Elf64_External_Rela);
885289857Sobrien      bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
885389857Sobrien    }
885489857Sobrien
885589857Sobrien  /* Mark some specially defined symbols as absolute.  */
885689857Sobrien  if (strcmp (h->root.root.string, "_DYNAMIC") == 0)
885789857Sobrien    sym->st_shndx = SHN_ABS;
885889857Sobrien
8859130561Sobrien  return TRUE;
886089857Sobrien}
886189857Sobrien
886289857Sobrien/* Used to decide how to sort relocs in an optimal manner for the
886389857Sobrien   dynamic linker, before writing them out.  */
886489857Sobrien
886589857Sobrienstatic enum elf_reloc_type_class
8866130561Sobrienppc64_elf_reloc_type_class (const Elf_Internal_Rela *rela)
886789857Sobrien{
8868130561Sobrien  enum elf_ppc64_reloc_type r_type;
886989857Sobrien
8870130561Sobrien  r_type = ELF64_R_TYPE (rela->r_info);
887189857Sobrien  switch (r_type)
887289857Sobrien    {
887389857Sobrien    case R_PPC64_RELATIVE:
887489857Sobrien      return reloc_class_relative;
887589857Sobrien    case R_PPC64_JMP_SLOT:
887689857Sobrien      return reloc_class_plt;
887789857Sobrien    case R_PPC64_COPY:
887889857Sobrien      return reloc_class_copy;
887989857Sobrien    default:
888089857Sobrien      return reloc_class_normal;
888189857Sobrien    }
888289857Sobrien}
888389857Sobrien
888489857Sobrien/* Finish up the dynamic sections.  */
888589857Sobrien
8886130561Sobrienstatic bfd_boolean
8887130561Sobrienppc64_elf_finish_dynamic_sections (bfd *output_bfd,
8888130561Sobrien				   struct bfd_link_info *info)
888989857Sobrien{
889089857Sobrien  struct ppc_link_hash_table *htab;
889189857Sobrien  bfd *dynobj;
889289857Sobrien  asection *sdyn;
889389857Sobrien
889489857Sobrien  htab = ppc_hash_table (info);
889589857Sobrien  dynobj = htab->elf.dynobj;
889689857Sobrien  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
889789857Sobrien
889889857Sobrien  if (htab->elf.dynamic_sections_created)
889989857Sobrien    {
890089857Sobrien      Elf64_External_Dyn *dyncon, *dynconend;
890189857Sobrien
8902130561Sobrien      if (sdyn == NULL || htab->got == NULL)
890389857Sobrien	abort ();
890489857Sobrien
890589857Sobrien      dyncon = (Elf64_External_Dyn *) sdyn->contents;
890689857Sobrien      dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
890789857Sobrien      for (; dyncon < dynconend; dyncon++)
890889857Sobrien	{
890989857Sobrien	  Elf_Internal_Dyn dyn;
891091041Sobrien	  asection *s;
891189857Sobrien
891289857Sobrien	  bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
891389857Sobrien
891489857Sobrien	  switch (dyn.d_tag)
891589857Sobrien	    {
891689857Sobrien	    default:
891789857Sobrien	      continue;
891889857Sobrien
891989857Sobrien	    case DT_PPC64_GLINK:
8920130561Sobrien	      s = htab->glink;
8921130561Sobrien	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
8922130561Sobrien	      /* We stupidly defined DT_PPC64_GLINK to be the start
8923130561Sobrien		 of glink rather than the first entry point, which is
8924130561Sobrien		 what ld.so needs, and now have a bigger stub to
8925130561Sobrien		 support automatic multiple TOCs.  */
8926130561Sobrien	      dyn.d_un.d_ptr += GLINK_CALL_STUB_SIZE - 32;
892789857Sobrien	      break;
892889857Sobrien
892991041Sobrien	    case DT_PPC64_OPD:
893091041Sobrien	      s = bfd_get_section_by_name (output_bfd, ".opd");
8931130561Sobrien	      if (s == NULL)
8932130561Sobrien		continue;
8933130561Sobrien	      dyn.d_un.d_ptr = s->vma;
893491041Sobrien	      break;
893591041Sobrien
893691041Sobrien	    case DT_PPC64_OPDSZ:
893791041Sobrien	      s = bfd_get_section_by_name (output_bfd, ".opd");
8938130561Sobrien	      if (s == NULL)
8939130561Sobrien		continue;
8940130561Sobrien	      dyn.d_un.d_val = s->_raw_size;
894191041Sobrien	      break;
894291041Sobrien
894389857Sobrien	    case DT_PLTGOT:
8944130561Sobrien	      s = htab->plt;
8945130561Sobrien	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
894689857Sobrien	      break;
894789857Sobrien
894889857Sobrien	    case DT_JMPREL:
8949130561Sobrien	      s = htab->relplt;
8950130561Sobrien	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
895189857Sobrien	      break;
895289857Sobrien
895389857Sobrien	    case DT_PLTRELSZ:
8954130561Sobrien	      dyn.d_un.d_val = htab->relplt->_raw_size;
895589857Sobrien	      break;
895689857Sobrien
895789857Sobrien	    case DT_RELASZ:
895889857Sobrien	      /* Don't count procedure linkage table relocs in the
895989857Sobrien		 overall reloc count.  */
8960130561Sobrien	      s = htab->relplt;
8961130561Sobrien	      if (s == NULL)
8962130561Sobrien		continue;
8963130561Sobrien	      dyn.d_un.d_val -= s->_raw_size;
896489857Sobrien	      break;
8965130561Sobrien
8966130561Sobrien	    case DT_RELA:
8967130561Sobrien	      /* We may not be using the standard ELF linker script.
8968130561Sobrien		 If .rela.plt is the first .rela section, we adjust
8969130561Sobrien		 DT_RELA to not include it.  */
8970130561Sobrien	      s = htab->relplt;
8971130561Sobrien	      if (s == NULL)
8972130561Sobrien		continue;
8973130561Sobrien	      if (dyn.d_un.d_ptr != s->output_section->vma + s->output_offset)
8974130561Sobrien		continue;
8975130561Sobrien	      dyn.d_un.d_ptr += s->_raw_size;
8976130561Sobrien	      break;
897789857Sobrien	    }
897889857Sobrien
897989857Sobrien	  bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
898089857Sobrien	}
898189857Sobrien    }
898289857Sobrien
8983130561Sobrien  if (htab->got != NULL && htab->got->_raw_size != 0)
898489857Sobrien    {
898589857Sobrien      /* Fill in the first entry in the global offset table.
898689857Sobrien	 We use it to hold the link-time TOCbase.  */
898789857Sobrien      bfd_put_64 (output_bfd,
898889857Sobrien		  elf_gp (output_bfd) + TOC_BASE_OFF,
8989130561Sobrien		  htab->got->contents);
899089857Sobrien
899189857Sobrien      /* Set .got entry size.  */
8992130561Sobrien      elf_section_data (htab->got->output_section)->this_hdr.sh_entsize = 8;
899389857Sobrien    }
899489857Sobrien
8995130561Sobrien  if (htab->plt != NULL && htab->plt->_raw_size != 0)
899689857Sobrien    {
899789857Sobrien      /* Set .plt entry size.  */
8998130561Sobrien      elf_section_data (htab->plt->output_section)->this_hdr.sh_entsize
899989857Sobrien	= PLT_ENTRY_SIZE;
900089857Sobrien    }
900189857Sobrien
9002130561Sobrien  /* We need to handle writing out multiple GOT sections ourselves,
9003130561Sobrien     since we didn't add them to DYNOBJ.  */
9004130561Sobrien  while ((dynobj = dynobj->link_next) != NULL)
9005130561Sobrien    {
9006130561Sobrien      asection *s;
9007209867Snwhitehorn
9008209867Snwhitehorn      if (bfd_get_flavour (dynobj) != bfd_target_elf_flavour)
9009209867Snwhitehorn	continue;
9010209867Snwhitehorn
9011130561Sobrien      s = ppc64_elf_tdata (dynobj)->got;
9012130561Sobrien      if (s != NULL
9013130561Sobrien	  && s->_raw_size != 0
9014130561Sobrien	  && s->output_section != bfd_abs_section_ptr
9015130561Sobrien	  && !bfd_set_section_contents (output_bfd, s->output_section,
9016130561Sobrien					s->contents, s->output_offset,
9017130561Sobrien					s->_raw_size))
9018130561Sobrien	return FALSE;
9019130561Sobrien      s = ppc64_elf_tdata (dynobj)->relgot;
9020130561Sobrien      if (s != NULL
9021130561Sobrien	  && s->_raw_size != 0
9022130561Sobrien	  && s->output_section != bfd_abs_section_ptr
9023130561Sobrien	  && !bfd_set_section_contents (output_bfd, s->output_section,
9024130561Sobrien					s->contents, s->output_offset,
9025130561Sobrien					s->_raw_size))
9026130561Sobrien	return FALSE;
9027130561Sobrien    }
9028130561Sobrien
9029130561Sobrien  return TRUE;
903089857Sobrien}
903189857Sobrien
903289857Sobrien#include "elf64-target.h"
9033